个人用户管理开发
Some checks failed
Node CI / build (14.x, macOS-latest) (push) Has been cancelled
Node CI / build (14.x, ubuntu-latest) (push) Has been cancelled
Node CI / build (14.x, windows-latest) (push) Has been cancelled
Node CI / build (16.x, macOS-latest) (push) Has been cancelled
Node CI / build (16.x, ubuntu-latest) (push) Has been cancelled
Node CI / build (16.x, windows-latest) (push) Has been cancelled
coverage CI / build (push) Has been cancelled
Node pnpm CI / build (16.x, macOS-latest) (push) Has been cancelled
Node pnpm CI / build (16.x, ubuntu-latest) (push) Has been cancelled
Node pnpm CI / build (16.x, windows-latest) (push) Has been cancelled

This commit is contained in:
francis-fh
2026-07-16 20:15:25 +08:00
parent 03a0f7fd29
commit d2311d0c5b
5 changed files with 311 additions and 2 deletions

View File

@@ -0,0 +1,50 @@
---
name: shz-admin-page-naming
description: Naming convention for new page directories in shz-admin. Use when creating a new page folder under src/pages/.
---
# shz-admin 页面目录命名规范
新建页面时,文件夹命名遵循:**首单词首字母大写,其余字母全部小写**。
## 规则
```
src/pages/{PageName}/
```
- 第一个单词的首字母 **大写**
- 其余所有字母(包括后续单词)**小写**
- 不允许多个大写字母(驼峰)
- 多个单词直接连写,不用分隔符
## 示例
```
✅ Talentcollect ❌ TalentCollect
✅ Mobileusers ❌ MobileUsers
✅ Management ❌ ManagementList
✅ Jobfair ❌ JobFair
✅ Livemgmt ❌ LiveMgmt
✅ Usermgmt ❌ UserMgmt
```
## 目录结构
新建页面时的标准文件结构:
```
src/pages/{PageName}/
└── List/
└── index.tsx
```
如果页面有弹窗子组件,放在同级的 `components/` 下:
```
src/pages/{PageName}/
├── List/
│ └── index.tsx
└── components/
└── SomeModal.tsx
```

View File

@@ -18,8 +18,8 @@ function TalentCollectList() {
const [sexEnum, setSexEnum] = useState<any>({});
useEffect(() => {
getDictValueEnum('education', true, true).then((data) => setEducationEnum(data));
getDictValueEnum('area', true, true).then((data) => setAreaEnum(data));
getDictValueEnum('education', false, true).then((data) => setEducationEnum(data));
getDictValueEnum('area', false, true).then((data) => setAreaEnum(data));
getDictValueEnum('sys_user_sex', false).then((data) => setSexEnum(data));
}, []);

View File

@@ -0,0 +1,174 @@
import React, { useEffect, useRef, useState } from 'react';
import { Tag } from 'antd';
import { ActionType, ProColumns, ProTable } from '@ant-design/pro-components';
import { getAppUserList } from '@/services/cms/appuser';
import { getDictValueEnum } from '@/services/system/dict';
import DictTag from '@/components/DictTag';
function AppUserList() {
const actionRef = useRef<ActionType>();
const [educationEnum, setEducationEnum] = useState<Record<string, any>>({});
const [sexEnum, setSexEnum] = useState<Record<string, any>>({});
const [areaEnum, setAreaEnum] = useState<Record<string, any>>({});
const [politicalEnum, setPoliticalEnum] = useState<Record<string, any>>({});
useEffect(() => {
getDictValueEnum('education', true, true).then(setEducationEnum);
getDictValueEnum('sys_user_sex', true).then(setSexEnum);
getDictValueEnum('area', true, true).then(setAreaEnum);
getDictValueEnum('political_affiliation', true, true).then(setPoliticalEnum);
}, []);
const columns: ProColumns<API.CmsAppUser.AppUserRow>[] = [
{
title: '用户ID',
dataIndex: 'userId',
valueType: 'text',
align: 'center',
width: 80,
hideInSearch: true,
},
{
title: '姓名',
dataIndex: 'name',
valueType: 'text',
align: 'center',
width: 120,
},
{
title: '手机号',
dataIndex: 'phone',
valueType: 'text',
align: 'center',
width: 140,
},
{
title: '性别',
dataIndex: 'sex',
valueType: 'select',
align: 'center',
width: 80,
valueEnum: sexEnum,
render: (_, record) => <DictTag enums={sexEnum} value={record.sex} />,
},
{
title: '年龄',
dataIndex: 'age',
valueType: 'text',
align: 'center',
width: 70,
hideInSearch: true,
},
{
title: '学历',
dataIndex: 'education',
valueType: 'select',
align: 'center',
width: 90,
valueEnum: educationEnum,
render: (_, record) => <DictTag enums={educationEnum} value={record.education} />,
},
{
title: '地区',
dataIndex: 'area',
valueType: 'select',
align: 'center',
width: 100,
valueEnum: areaEnum,
render: (_, record) => <DictTag enums={areaEnum} value={record.area} />,
},
{
title: '政治面貌',
dataIndex: 'politicalAffiliation',
valueType: 'select',
align: 'center',
width: 110,
valueEnum: politicalEnum,
render: (_, record) => <DictTag enums={politicalEnum} value={record.politicalAffiliation} />,
},
{
title: '期望薪资',
dataIndex: 'salaryRange',
hideInSearch: true,
align: 'center',
width: 140,
render: (_, record) => {
if (!record.salaryMin && !record.salaryMax) return '-';
return `${record.salaryMin ?? '-'} ~ ${record.salaryMax ?? '-'}`;
},
},
{
title: '身份证号',
dataIndex: 'idCard',
valueType: 'text',
align: 'center',
width: 170,
render: (_, record) => {
if (!record.idCard) return '-';
const idCard = record.idCard.toString();
if (idCard.length < 8) return idCard;
return `${idCard.slice(0, 4)}${'*'.repeat(idCard.length - 8)}${idCard.slice(-4)}`;
},
},
{
title: '最后登录',
dataIndex: 'loginDate',
valueType: 'date',
align: 'center',
width: 110,
hideInSearch: true,
fieldProps: { format: 'YYYY-MM-DD' },
},
{
title: '创建时间',
dataIndex: 'createTime',
valueType: 'dateTime',
align: 'center',
hideInSearch: true,
width: 160,
},
{
title: '更新时间',
dataIndex: 'updateTime',
valueType: 'dateTime',
align: 'center',
hideInSearch: true,
width: 160,
},
];
return (
<div style={{ width: '100%' }}>
<ProTable<API.CmsAppUser.AppUserRow>
actionRef={actionRef}
rowKey="userId"
columns={columns}
request={(params) => {
const { current, pageSize, ...searchParams } = params;
const filteredParams: Record<string, any> = {};
Object.keys(searchParams).forEach((key) => {
const val = searchParams[key];
if (val !== undefined && val !== null && val !== '') {
filteredParams[key] = val;
}
});
return getAppUserList({
pageNum: current,
pageSize,
...filteredParams,
}).then((res) => ({
data: res.rows || [],
total: res.total,
success: true,
}));
}}
search={{ labelWidth: 'auto' }}
scroll={{ x: 'max-content' }}
pagination={{ defaultPageSize: 10, showSizeChanger: true }}
headerTitle="个人用户管理"
/>
</div>
);
}
export default AppUserList;

View File

@@ -0,0 +1,17 @@
import { request } from '@umijs/max';
/**
* 分页查询个人用户管理列表
* GET /cms/appUser/list
*/
export async function getAppUserList(
params?: API.CmsAppUser.ListParams & {
pageNum?: number;
pageSize?: number;
},
) {
return request<API.CmsAppUser.AppUserResult>('/api/cms/appUser/list', {
method: 'GET',
params,
});
}

68
src/types/cms/appuser.d.ts vendored Normal file
View File

@@ -0,0 +1,68 @@
declare namespace API.CmsAppUser {
export interface AppUserResult {
total: number;
rows: AppUserRow[];
code: number;
msg: string;
data?: any;
}
export interface AppUserRow {
createTime: string | null;
updateTime: string | null;
userId: number;
name: string | null;
age: string | null;
sex: string;
birthDate: string | null;
education: string | null;
politicalAffiliation: string | null;
phone: string;
avatar: string;
salaryMin: string | null;
salaryMax: string | null;
area: string | null;
status: string;
loginIp: string;
loginDate: string | null;
jobTitleId: string | null;
experience: string | null;
isRecommend: number;
email: string | null;
jobTitle: string | null;
jobName: string | null;
idCard: string | null;
isCompanyUser: string;
password: string | null;
openid: string | null;
unionid: string | null;
nation: string | null;
workExperience: string | null;
company: string | null;
experiencesList: any;
appSkillsList: any;
fileList: any;
myChart: any;
ytjPassword: string | null;
address: string | null;
domicileAddress: string | null;
lcUserid: string | null;
userType: string | null;
resumeStatus: string | null;
matchLevelDesc: string | null;
applyId: string | null;
}
export interface ListParams {
pageNum?: number;
pageSize?: number;
name?: string;
phone?: string;
sex?: string;
education?: string;
area?: string;
status?: string;
politicalAffiliation?: string;
idCard?: string;
}
}