feat(前端):终端列表
parent
af9e040f01
commit
e1fc19aeab
|
@ -15,6 +15,7 @@
|
||||||
"@umijs/max": "^4.4.11",
|
"@umijs/max": "^4.4.11",
|
||||||
"antd": "^5.4.0",
|
"antd": "^5.4.0",
|
||||||
"dayjs": "^1.11.13",
|
"dayjs": "^1.11.13",
|
||||||
|
"moment": "^2.30.1",
|
||||||
"spark-md5": "^3.0.2",
|
"spark-md5": "^3.0.2",
|
||||||
"uuid": "^11.1.0"
|
"uuid": "^11.1.0"
|
||||||
},
|
},
|
||||||
|
|
|
@ -23,9 +23,9 @@ export const GENDER_MAP = {
|
||||||
|
|
||||||
// priority
|
// priority
|
||||||
export const PRIORITY_MAP = {
|
export const PRIORITY_MAP = {
|
||||||
1: '低',
|
1: '一级',
|
||||||
2: '中',
|
2: '二级',
|
||||||
3: '高',
|
3: '三级',
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const USER_TYPE_OPTIONS = [
|
export const USER_TYPE_OPTIONS = [
|
||||||
|
@ -42,3 +42,9 @@ export const GENDER_OPTIONS = [
|
||||||
{ value: 1, label: '女' },
|
{ value: 1, label: '女' },
|
||||||
{ value: 2, label: '男' },
|
{ value: 2, label: '男' },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export const PRIOPRITY_OPTIONS = [
|
||||||
|
{ value: 1, label: '一级' },
|
||||||
|
{ value: 2, label: '二级' },
|
||||||
|
{ value: 3, label: '三级' },
|
||||||
|
];
|
||||||
|
|
|
@ -16,6 +16,7 @@ import {
|
||||||
message,
|
message,
|
||||||
Popconfirm,
|
Popconfirm,
|
||||||
Popover,
|
Popover,
|
||||||
|
Spin,
|
||||||
Table,
|
Table,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
} from 'antd';
|
} from 'antd';
|
||||||
|
@ -34,6 +35,7 @@ const UserListPage: React.FC = () => {
|
||||||
const [searchText, setSearchText] = useState<string>('');
|
const [searchText, setSearchText] = useState<string>('');
|
||||||
const [selectedRowKeys, setSelectedRowKeys] = useState<[]>([]);
|
const [selectedRowKeys, setSelectedRowKeys] = useState<[]>([]);
|
||||||
const [orgSearchText, setOrgSearchText] = useState<string>('');
|
const [orgSearchText, setOrgSearchText] = useState<string>('');
|
||||||
|
const [spinning, setSpinning] = useState<boolean>(false);
|
||||||
|
|
||||||
// 分页参数
|
// 分页参数
|
||||||
const [currentPage, setCurrentPage] = useState<number>(1);
|
const [currentPage, setCurrentPage] = useState<number>(1);
|
||||||
|
@ -42,7 +44,7 @@ const UserListPage: React.FC = () => {
|
||||||
// 添加分组
|
// 添加分组
|
||||||
const [visible, setVisible] = useState<boolean>(false);
|
const [visible, setVisible] = useState<boolean>(false);
|
||||||
// 编辑用户
|
// 编辑用户
|
||||||
const [currentUserInfo, setCurrentUserInfo] = useState<any>({
|
const [currentDeviceInfo, setCurrentDeviceInfo] = useState<any>({
|
||||||
visible: false,
|
visible: false,
|
||||||
});
|
});
|
||||||
const [bindUserDta, setBindUserData] = useState<any>({
|
const [bindUserDta, setBindUserData] = useState<any>({
|
||||||
|
@ -55,7 +57,7 @@ const UserListPage: React.FC = () => {
|
||||||
|
|
||||||
// 获取用户分组组织树
|
// 获取用户分组组织树
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// getGroupList();
|
getGroupList();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const filterTreeData = (
|
const filterTreeData = (
|
||||||
|
@ -91,28 +93,34 @@ const UserListPage: React.FC = () => {
|
||||||
|
|
||||||
// 获取用户列表数据
|
// 获取用户列表数据
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// if (selectedOrg) {
|
getDataSource();
|
||||||
// getDataSource();
|
|
||||||
// }
|
|
||||||
}, [searchText, selectedOrg, currentPage, pageSize]);
|
}, [searchText, selectedOrg, currentPage, pageSize]);
|
||||||
|
|
||||||
const getGroupList = async () => {
|
const getGroupList = async () => {
|
||||||
|
setSpinning(true);
|
||||||
const params = {
|
const params = {
|
||||||
type: 2,
|
type: 2,
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
const result = await getGroupTree(params);
|
const result = await getGroupTree(params);
|
||||||
if (result.error_code === ERROR_CODE) {
|
console.log('result=====', result);
|
||||||
setOrgTreeData(result.data.data || []);
|
const { code, data = [] } = result || {};
|
||||||
if (result.data.data.length > 0) {
|
if (code === ERROR_CODE) {
|
||||||
setSelectedOrg(result.data.data[0].id as number);
|
if (data.length > 0) {
|
||||||
|
const { children = [] } = data[0] || {};
|
||||||
|
setOrgTreeData(children);
|
||||||
|
// if (children.length > 0) {
|
||||||
|
// setSelectedOrg(children[0].id);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
setSpinning(false);
|
||||||
} else {
|
} else {
|
||||||
|
setSpinning(false);
|
||||||
message.error(result.message || '获取终端分组失败');
|
message.error(result.message || '获取终端分组失败');
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
message.error('获取终端分组失败');
|
message.error('获取终端分组失败');
|
||||||
setLoading(false);
|
setSpinning(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -121,15 +129,21 @@ const UserListPage: React.FC = () => {
|
||||||
page_size: pageSize,
|
page_size: pageSize,
|
||||||
page_num: currentPage,
|
page_num: currentPage,
|
||||||
};
|
};
|
||||||
|
if (selectedOrg) {
|
||||||
|
params.device_group_id = selectedOrg;
|
||||||
|
}
|
||||||
if (searchText) {
|
if (searchText) {
|
||||||
params.keywords = searchText;
|
params.device_name = searchText;
|
||||||
}
|
}
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
const result = await getTerminalList(params);
|
const result: any = await getTerminalList(params);
|
||||||
if (result.error_code === ERROR_CODE) {
|
console.log('result=====', result);
|
||||||
setDataSource(result.data.data || []);
|
const { code, data } = result || {};
|
||||||
setTotal(result.data.paging.total || 0);
|
const { data: list, total = 0 } = data || {};
|
||||||
|
if (code === ERROR_CODE) {
|
||||||
|
setDataSource(list);
|
||||||
|
setTotal(total);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
} else {
|
} else {
|
||||||
message.error(result.message || '获取终端列表失败');
|
message.error(result.message || '获取终端列表失败');
|
||||||
|
@ -145,11 +159,11 @@ const UserListPage: React.FC = () => {
|
||||||
try {
|
try {
|
||||||
const { id } = device || {};
|
const { id } = device || {};
|
||||||
const payload = {
|
const payload = {
|
||||||
ids: id ? [id] : selectedRowKeys,
|
ids: id ? id : selectedRowKeys,
|
||||||
};
|
};
|
||||||
const res = await deleteDevice(payload);
|
const res: any = await deleteDevice(payload);
|
||||||
const { error_code } = res || {};
|
const { code } = res || {};
|
||||||
if (error_code === ERROR_CODE) {
|
if (code === ERROR_CODE) {
|
||||||
message.success('终端删除成功');
|
message.success('终端删除成功');
|
||||||
setSelectedRowKeys([]);
|
setSelectedRowKeys([]);
|
||||||
getDataSource();
|
getDataSource();
|
||||||
|
@ -159,8 +173,8 @@ const UserListPage: React.FC = () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleEditUserInfo = (device: Termial.TermialItem) => {
|
const handleEditInfo = (device: Termial.TermialItem) => {
|
||||||
setCurrentUserInfo({
|
setCurrentDeviceInfo({
|
||||||
recordData: { ...device },
|
recordData: { ...device },
|
||||||
visible: true,
|
visible: true,
|
||||||
});
|
});
|
||||||
|
@ -186,9 +200,9 @@ const UserListPage: React.FC = () => {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '终端分组',
|
title: '序列号',
|
||||||
dataIndex: 'device_group_name',
|
dataIndex: 'device_id',
|
||||||
key: 'device_group_name',
|
key: 'device_id',
|
||||||
width: 220,
|
width: 220,
|
||||||
align: 'center',
|
align: 'center',
|
||||||
render: (text) => {
|
render: (text) => {
|
||||||
|
@ -196,20 +210,10 @@ const UserListPage: React.FC = () => {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'IP地址',
|
title: '终端分组',
|
||||||
dataIndex: 'ip_addr',
|
dataIndex: 'device_group_name',
|
||||||
key: 'ip_addr',
|
key: 'device_group_name',
|
||||||
width: 150,
|
width: 220,
|
||||||
align: 'center',
|
|
||||||
render: (text) => {
|
|
||||||
return <Tooltip>{text || '--'}</Tooltip>;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '终端标识',
|
|
||||||
dataIndex: 'mac_addr',
|
|
||||||
key: 'mac_addr',
|
|
||||||
ellipsis: true,
|
|
||||||
align: 'center',
|
align: 'center',
|
||||||
render: (text) => {
|
render: (text) => {
|
||||||
return <Tooltip>{text || '--'}</Tooltip>;
|
return <Tooltip>{text || '--'}</Tooltip>;
|
||||||
|
@ -226,6 +230,46 @@ const UserListPage: React.FC = () => {
|
||||||
return <Tooltip>{DEVICE_TYPE_MAP[key] || '--'}</Tooltip>;
|
return <Tooltip>{DEVICE_TYPE_MAP[key] || '--'}</Tooltip>;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: '型号',
|
||||||
|
dataIndex: 'model',
|
||||||
|
key: 'model',
|
||||||
|
width: 150,
|
||||||
|
align: 'center',
|
||||||
|
render: (text) => {
|
||||||
|
return <Tooltip>{text || '--'}</Tooltip>;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'IP地址',
|
||||||
|
dataIndex: 'ip_addr',
|
||||||
|
key: 'ip_addr',
|
||||||
|
width: 150,
|
||||||
|
align: 'center',
|
||||||
|
render: (text) => {
|
||||||
|
return <Tooltip>{text || '--'}</Tooltip>;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'MAC地址',
|
||||||
|
dataIndex: 'mac_addr',
|
||||||
|
key: 'mac_addr',
|
||||||
|
ellipsis: true,
|
||||||
|
align: 'center',
|
||||||
|
render: (text) => {
|
||||||
|
return <Tooltip>{text || '--'}</Tooltip>;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '备注',
|
||||||
|
dataIndex: 'description',
|
||||||
|
key: 'description',
|
||||||
|
ellipsis: true,
|
||||||
|
align: 'center',
|
||||||
|
render: (text) => {
|
||||||
|
return <Tooltip>{text || '--'}</Tooltip>;
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: '操作',
|
title: '操作',
|
||||||
key: 'actions',
|
key: 'actions',
|
||||||
|
@ -234,7 +278,7 @@ const UserListPage: React.FC = () => {
|
||||||
fixed: 'right',
|
fixed: 'right',
|
||||||
render: (_, record) => (
|
render: (_, record) => (
|
||||||
<div style={{ display: 'flex', alignItems: 'center' }}>
|
<div style={{ display: 'flex', alignItems: 'center' }}>
|
||||||
<Button type="link" onClick={() => handleEditUserInfo(record)}>
|
<Button type="link" onClick={() => handleEditInfo(record)}>
|
||||||
编辑
|
编辑
|
||||||
</Button>
|
</Button>
|
||||||
<Popover
|
<Popover
|
||||||
|
@ -315,8 +359,8 @@ const UserListPage: React.FC = () => {
|
||||||
id: selectedOrg,
|
id: selectedOrg,
|
||||||
};
|
};
|
||||||
const res = await deleteUserGroup(params);
|
const res = await deleteUserGroup(params);
|
||||||
const { error_code } = res || {};
|
const { code } = res || {};
|
||||||
if (error_code === ERROR_CODE) {
|
if (code === ERROR_CODE) {
|
||||||
message.success('分组删除成功');
|
message.success('分组删除成功');
|
||||||
getGroupList();
|
getGroupList();
|
||||||
}
|
}
|
||||||
|
@ -326,6 +370,26 @@ const UserListPage: React.FC = () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const onSaveGroup = () => {
|
||||||
|
getGroupList();
|
||||||
|
};
|
||||||
|
|
||||||
|
const onDeviceSave = () => {
|
||||||
|
setCurrentDeviceInfo({
|
||||||
|
recordData: {},
|
||||||
|
visible: false,
|
||||||
|
});
|
||||||
|
getDataSource();
|
||||||
|
};
|
||||||
|
|
||||||
|
const onBindUserSave = () => {
|
||||||
|
setBindUserData({
|
||||||
|
recordData: {},
|
||||||
|
visible: false,
|
||||||
|
});
|
||||||
|
getDataSource();
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.user_content}>
|
<div className={styles.user_content}>
|
||||||
<div className={styles.left_content}>
|
<div className={styles.left_content}>
|
||||||
|
@ -361,16 +425,18 @@ const UserListPage: React.FC = () => {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.tree_box}>
|
<div className={styles.tree_box}>
|
||||||
<CustomTree
|
<Spin spinning={spinning} delay={100}>
|
||||||
treeData={filteredOrgTreeData}
|
<CustomTree
|
||||||
titleField="name"
|
treeData={filteredOrgTreeData}
|
||||||
keyField="id"
|
titleField="name"
|
||||||
childrenField="children"
|
keyField="id"
|
||||||
defaultExpandAll={true}
|
childrenField="children"
|
||||||
onSelect={onOrgSelect}
|
defaultExpandAll={true}
|
||||||
selectedKeys={selectedOrg ? [selectedOrg] : []}
|
onSelect={onOrgSelect}
|
||||||
icon={<TeamOutlined style={{ fontSize: '15px' }} />}
|
selectedKeys={selectedOrg ? [selectedOrg] : []}
|
||||||
/>
|
icon={<TeamOutlined style={{ fontSize: '15px' }} />}
|
||||||
|
/>
|
||||||
|
</Spin>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.right_content}>
|
<div className={styles.right_content}>
|
||||||
|
@ -383,7 +449,7 @@ const UserListPage: React.FC = () => {
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<Popconfirm
|
{/* <Popconfirm
|
||||||
title=""
|
title=""
|
||||||
description="删除操作不可逆,请确认是否删除?"
|
description="删除操作不可逆,请确认是否删除?"
|
||||||
onConfirm={() => onDelete()}
|
onConfirm={() => onDelete()}
|
||||||
|
@ -398,7 +464,7 @@ const UserListPage: React.FC = () => {
|
||||||
>
|
>
|
||||||
删除
|
删除
|
||||||
</Button>
|
</Button>
|
||||||
</Popconfirm>
|
</Popconfirm> */}
|
||||||
<Button style={{ marginRight: '8px' }} onClick={getDataSource}>
|
<Button style={{ marginRight: '8px' }} onClick={getDataSource}>
|
||||||
刷新
|
刷新
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -424,10 +490,10 @@ const UserListPage: React.FC = () => {
|
||||||
dataSource={dataSource}
|
dataSource={dataSource}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
rowKey="id"
|
rowKey="id"
|
||||||
rowSelection={{
|
// rowSelection={{
|
||||||
selectedRowKeys,
|
// selectedRowKeys,
|
||||||
onChange: onSelectChange,
|
// onChange: onSelectChange,
|
||||||
}}
|
// }}
|
||||||
pagination={{
|
pagination={{
|
||||||
current: currentPage,
|
current: currentPage,
|
||||||
pageSize: pageSize,
|
pageSize: pageSize,
|
||||||
|
@ -446,40 +512,47 @@ const UserListPage: React.FC = () => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<CreatGroup
|
{visible && (
|
||||||
visible={visible}
|
<CreatGroup
|
||||||
type={2}
|
visible={visible}
|
||||||
title="新增终端分组"
|
type={2}
|
||||||
onCancel={() => {
|
title="新增终端分组"
|
||||||
setVisible(false);
|
onCancel={() => {
|
||||||
}}
|
setVisible(false);
|
||||||
selectedOrg={selectedOrg}
|
}}
|
||||||
onOk={() => {}}
|
selectedOrg={selectedOrg}
|
||||||
orgTreeData={orgTreeData}
|
onOk={() => {
|
||||||
/>
|
onSaveGroup();
|
||||||
<EditModal
|
}}
|
||||||
selectedOrg={selectedOrg}
|
orgTreeData={orgTreeData}
|
||||||
orgTreeData={orgTreeData}
|
/>
|
||||||
currentUserInfo={currentUserInfo}
|
)}
|
||||||
onCancel={() => {
|
{currentDeviceInfo.visible && (
|
||||||
setCurrentUserInfo({
|
<EditModal
|
||||||
recordData: {},
|
selectedOrg={selectedOrg}
|
||||||
visible: false,
|
orgTreeData={orgTreeData}
|
||||||
});
|
currentDeviceInfo={currentDeviceInfo}
|
||||||
}}
|
onCancel={() => {
|
||||||
onOk={() => {}}
|
setCurrentDeviceInfo({
|
||||||
/>
|
recordData: {},
|
||||||
|
visible: false,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
onOk={() => {
|
||||||
|
onDeviceSave();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
{bindUserDta.visible && (
|
{bindUserDta.visible && (
|
||||||
<BindUserModal
|
<BindUserModal
|
||||||
dataDetial={bindUserDta}
|
dataDetial={bindUserDta}
|
||||||
orgTreeData={orgTreeData}
|
|
||||||
onCancel={() => {
|
onCancel={() => {
|
||||||
setBindUserData({
|
setBindUserData({
|
||||||
recordData: {},
|
recordData: {},
|
||||||
visible: false,
|
visible: false,
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
onOk={() => {}}
|
onOk={() => {onBindUserSave()}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{bindImageDta.visible && (
|
{bindImageDta.visible && (
|
||||||
|
|
|
@ -8,10 +8,8 @@ import SelectConponents from './table';
|
||||||
|
|
||||||
interface SelectedTableProps {
|
interface SelectedTableProps {
|
||||||
placement?: PopoverProps['placement'];
|
placement?: PopoverProps['placement'];
|
||||||
selectedOrg?: number;
|
|
||||||
onCancel?: () => void;
|
onCancel?: () => void;
|
||||||
onOk?: (values: any) => void;
|
onOk?: (values: any) => void;
|
||||||
orgTreeData?: User.OrganizationNode[];
|
|
||||||
value?: any;
|
value?: any;
|
||||||
onChange: (values: any) => void;
|
onChange: (values: any) => void;
|
||||||
}
|
}
|
||||||
|
@ -19,7 +17,6 @@ interface SelectedTableProps {
|
||||||
const SelectedTable: React.FC<SelectedTableProps> = (props) => {
|
const SelectedTable: React.FC<SelectedTableProps> = (props) => {
|
||||||
const {
|
const {
|
||||||
placement = 'bottomLeft',
|
placement = 'bottomLeft',
|
||||||
orgTreeData,
|
|
||||||
value: formValue,
|
value: formValue,
|
||||||
onChange: onBindImageChange,
|
onChange: onBindImageChange,
|
||||||
} = props;
|
} = props;
|
||||||
|
@ -95,7 +92,6 @@ const SelectedTable: React.FC<SelectedTableProps> = (props) => {
|
||||||
const accessPopover = (
|
const accessPopover = (
|
||||||
<div style={{ width: '600px' }}>
|
<div style={{ width: '600px' }}>
|
||||||
<SelectConponents
|
<SelectConponents
|
||||||
treeData={orgTreeData}
|
|
||||||
onUserTableSelect={onUserTableSelect}
|
onUserTableSelect={onUserTableSelect}
|
||||||
selectedRowKeys={selectedRowKeys}
|
selectedRowKeys={selectedRowKeys}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
/* eslint-disable @typescript-eslint/no-use-before-define */
|
/* eslint-disable @typescript-eslint/no-use-before-define */
|
||||||
import { IMAGES_TYPE_MAP } from '@/constants/images.constants';
|
|
||||||
import { ERROR_CODE } from '@/constants/constants';
|
import { ERROR_CODE } from '@/constants/constants';
|
||||||
import { getImagesList } from '@/services/images';
|
import { getImageList } from '@/services/terminal';
|
||||||
import { Input, Table, message,Tooltip } from 'antd';
|
import { Input, message, Table } from 'antd';
|
||||||
import type { ColumnsType } from 'antd/es/table';
|
import type { ColumnsType } from 'antd/es/table';
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import styles from './index.less';
|
import styles from './index.less';
|
||||||
|
|
||||||
interface TableProps {
|
interface TableProps {
|
||||||
treeData?: User.OrganizationNode[];
|
|
||||||
selectedRowKeys?: any[];
|
selectedRowKeys?: any[];
|
||||||
onUserTableSelect?: (keys: any[], row: any[]) => void;
|
onUserTableSelect?: (keys: any[], row: any[]) => void;
|
||||||
}
|
}
|
||||||
|
@ -38,10 +36,13 @@ const TablePage: React.FC<TableProps> = ({
|
||||||
}
|
}
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
const imagesRes = await getImagesList(params);
|
const imagesRes: any = await getImageList(params);
|
||||||
if (imagesRes.error_code === ERROR_CODE) {
|
console.log('imagesRes=========', imagesRes);
|
||||||
setData(imagesRes.data.data || []);
|
const { code, data } = imagesRes || {};
|
||||||
setTotal(imagesRes.data.paging.total || 0);
|
const { data: list = [], total = 0 } = data || {};
|
||||||
|
if (code === ERROR_CODE) {
|
||||||
|
setData(list);
|
||||||
|
setTotal(total);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
} else {
|
} else {
|
||||||
message.error(imagesRes.message || '获取镜像列表失败');
|
message.error(imagesRes.message || '获取镜像列表失败');
|
||||||
|
@ -66,16 +67,6 @@ const TablePage: React.FC<TableProps> = ({
|
||||||
dataIndex: 'image_name',
|
dataIndex: 'image_name',
|
||||||
render: (text: any) => <span>{text || ''}</span>,
|
render: (text: any) => <span>{text || ''}</span>,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
title: '桌面类型',
|
|
||||||
dataIndex: 'image_type',
|
|
||||||
key: 'image_type',
|
|
||||||
width: 200,
|
|
||||||
render: (text: number) => {
|
|
||||||
const key = text as keyof typeof IMAGES_TYPE_MAP;
|
|
||||||
return <Tooltip>{IMAGES_TYPE_MAP[key] || '--'}</Tooltip>;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const handleSearch = (value: string) => {
|
const handleSearch = (value: string) => {
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
// index.tsx
|
// index.tsx
|
||||||
import { Button, Form, Input, message, Modal } from 'antd';
|
import { ERROR_CODE } from '@/constants/constants';
|
||||||
|
import { getBindImageList } from '@/services/terminal';
|
||||||
|
import { Button, Form, message, Modal } from 'antd';
|
||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import SelectedTable from '../ImageSelectedTable/index';
|
import SelectedTable from '../ImageSelectedTable/index';
|
||||||
import styles from './index.less';
|
import styles from './index.less';
|
||||||
|
@ -19,11 +21,20 @@ const BindUserModal: React.FC<UserEditModalProps> = ({
|
||||||
dataDetial,
|
dataDetial,
|
||||||
}) => {
|
}) => {
|
||||||
const { recordData, visible, selectedOrg } = dataDetial || {};
|
const { recordData, visible, selectedOrg } = dataDetial || {};
|
||||||
|
const { id: device_id } = recordData || {};
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// const initialValues = { user_group_id: [selectedOrg], status: 1 };
|
const params = { device_id: device_id };
|
||||||
// form.setFieldsValue(initialValues);
|
getBindImageList(params).then((res: any) => {
|
||||||
|
const { code, data = [] } = res || {};
|
||||||
|
if (code === ERROR_CODE) {
|
||||||
|
if (data && data.length) {
|
||||||
|
const initialValues = { image_list: data };
|
||||||
|
form.setFieldsValue(initialValues);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}, [visible, form, recordData, selectedOrg]);
|
}, [visible, form, recordData, selectedOrg]);
|
||||||
|
|
||||||
const handleOk = async () => {
|
const handleOk = async () => {
|
||||||
|
@ -73,19 +84,19 @@ const BindUserModal: React.FC<UserEditModalProps> = ({
|
||||||
style={{ paddingTop: '20px', paddingBottom: '20px' }}
|
style={{ paddingTop: '20px', paddingBottom: '20px' }}
|
||||||
>
|
>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="user_list"
|
name="image_list"
|
||||||
label="选择镜像"
|
label="选择镜像"
|
||||||
rules={[{ required: true, message: '请输入终端型号' }]}
|
rules={[{ required: true, message: '请输入终端型号' }]}
|
||||||
>
|
>
|
||||||
<SelectedTable />
|
<SelectedTable />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
{/* <Form.Item
|
||||||
name="description"
|
name="description"
|
||||||
label="描述内容"
|
label="描述内容"
|
||||||
rules={[{ required: false, message: '请输入描述内容' }]}
|
rules={[{ required: false, message: '请输入描述内容' }]}
|
||||||
>
|
>
|
||||||
<Input.TextArea rows={4} />
|
<Input.TextArea rows={4} />
|
||||||
</Form.Item>
|
</Form.Item> */}
|
||||||
</Form>
|
</Form>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
|
@ -1,39 +1,129 @@
|
||||||
|
/* eslint-disable array-callback-return */
|
||||||
// index.tsx
|
// index.tsx
|
||||||
import { Button, Form, Input, message, Modal } from 'antd';
|
import { ERROR_CODE } from '@/constants/constants';
|
||||||
import React, { useEffect } from 'react';
|
import { bindUserAdd, getBindUserList } from '@/services/terminal';
|
||||||
|
import { getGroupTree } from '@/services/userList';
|
||||||
|
import { Button, Form, message, Modal } from 'antd';
|
||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
import SelectedTable from '../selectedTable';
|
import SelectedTable from '../selectedTable';
|
||||||
import styles from './index.less';
|
import styles from './index.less';
|
||||||
|
|
||||||
interface UserEditModalProps {
|
interface UserEditModalProps {
|
||||||
// visible: boolean;
|
// visible: boolean;
|
||||||
orgTreeData?: User.OrganizationNode[];
|
// orgTreeData?: User.OrganizationNode[];
|
||||||
onCancel: () => void;
|
onCancel: () => void;
|
||||||
onOk: (values: any) => void;
|
onOk: (values?: any) => void;
|
||||||
confirmLoading?: boolean;
|
confirmLoading?: boolean;
|
||||||
dataDetial?: Termial.ModalBaseNode;
|
dataDetial?: Termial.ModalBaseNode;
|
||||||
selectedOrg?: number;
|
selectedOrg?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const BindUserModal: React.FC<UserEditModalProps> = ({
|
const BindUserModal: React.FC<UserEditModalProps> = ({
|
||||||
orgTreeData,
|
// orgTreeData,
|
||||||
onCancel,
|
onCancel,
|
||||||
onOk,
|
onOk,
|
||||||
confirmLoading = false,
|
confirmLoading = false,
|
||||||
dataDetial,
|
dataDetial,
|
||||||
}) => {
|
}) => {
|
||||||
const { recordData, visible, selectedOrg } = dataDetial || {};
|
const { recordData, visible } = dataDetial || {};
|
||||||
|
const { device_id, device_group_id } = recordData || {};
|
||||||
|
const [orgTreeData, setOrgTreeData] = useState<User.OrganizationNode[]>([]);
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
|
|
||||||
|
const getGroupList = async () => {
|
||||||
|
const params = {
|
||||||
|
type: 1,
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
const result = await getGroupTree(params);
|
||||||
|
console.log('result=====', result);
|
||||||
|
const { code, data = [] } = result || {};
|
||||||
|
if (code === ERROR_CODE) {
|
||||||
|
if (data.length > 0) {
|
||||||
|
const { children = [] } = data[0] || {};
|
||||||
|
setOrgTreeData(children);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
message.error(result.message || '获取终端分组失败');
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
message.error('获取终端分组失败');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// const initialValues = { user_group_id: [selectedOrg], status: 1 };
|
getGroupList();
|
||||||
// form.setFieldsValue(initialValues);
|
}, [visible]);
|
||||||
}, [visible, form, recordData, selectedOrg]);
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!device_id) return;
|
||||||
|
const payload = { device_id: device_id };
|
||||||
|
getBindUserList(payload).then((res: any) => {
|
||||||
|
console.log('res========', res);
|
||||||
|
const { code, data = [] } = res || {};
|
||||||
|
if (code === ERROR_CODE) {
|
||||||
|
if (data && data.length > 0) {
|
||||||
|
const list: any[] = [];
|
||||||
|
data.map((item: any) => {
|
||||||
|
const { type, user_id, user_name, user_group_id, user_group_name } =
|
||||||
|
item || {};
|
||||||
|
if (type === 1) {
|
||||||
|
list.push({ record_id: user_id, name: user_name, ...item });
|
||||||
|
} else {
|
||||||
|
list.push({
|
||||||
|
record_id: user_group_id,
|
||||||
|
name: user_group_name,
|
||||||
|
...item,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const initialValues = { user_list: list, status: 1 };
|
||||||
|
form.setFieldsValue(initialValues);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, [visible, form, recordData]);
|
||||||
|
|
||||||
const handleOk = async () => {
|
const handleOk = async () => {
|
||||||
try {
|
try {
|
||||||
const values = await form.validateFields();
|
const values = await form.validateFields();
|
||||||
console.log("values=====",values)
|
const { user_list = [] } = values || {};
|
||||||
onOk(values);
|
const list: any[] = [];
|
||||||
|
if (user_list && user_list.length > 0) {
|
||||||
|
user_list.forEach((item: any) => {
|
||||||
|
const { record_id, type, id } = item || {};
|
||||||
|
if (type === 1) {
|
||||||
|
// 用户
|
||||||
|
list.push({
|
||||||
|
user_id: record_id,
|
||||||
|
id: id,
|
||||||
|
device_id,
|
||||||
|
device_group_id,
|
||||||
|
type: type,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
//用户分组
|
||||||
|
list.push({
|
||||||
|
user_group_id: record_id,
|
||||||
|
id: id,
|
||||||
|
device_id: device_id,
|
||||||
|
device_group_id,
|
||||||
|
type: type,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const payload = {
|
||||||
|
data: list,
|
||||||
|
};
|
||||||
|
bindUserAdd(payload)
|
||||||
|
.then(() => {
|
||||||
|
message.success('绑定成功');
|
||||||
|
onOk();
|
||||||
|
})
|
||||||
|
.catch(() => {});
|
||||||
|
}
|
||||||
|
console.log('list=====', list);
|
||||||
|
onOk(list);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
message.error('请检查表单字段');
|
message.error('请检查表单字段');
|
||||||
}
|
}
|
||||||
|
@ -78,17 +168,17 @@ const BindUserModal: React.FC<UserEditModalProps> = ({
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="user_list"
|
name="user_list"
|
||||||
label="选择用户"
|
label="选择用户"
|
||||||
rules={[{ required: true, message: '请输入终端型号' }]}
|
rules={[{ required: true, message: '请选择绑定用户' }]}
|
||||||
>
|
>
|
||||||
<SelectedTable orgTreeData={orgTreeData} />
|
<SelectedTable orgTreeData={orgTreeData} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
{/* <Form.Item
|
||||||
name="description"
|
name="description"
|
||||||
label="描述内容"
|
label="描述内容"
|
||||||
rules={[{ required: false, message: '请输入描述内容' }]}
|
rules={[{ required: false, message: '请输入描述内容' }]}
|
||||||
>
|
>
|
||||||
<Input.TextArea rows={4} />
|
<Input.TextArea rows={4} />
|
||||||
</Form.Item>
|
</Form.Item> */}
|
||||||
</Form>
|
</Form>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
|
@ -1,16 +1,15 @@
|
||||||
// index.tsx
|
// index.tsx
|
||||||
import { DEVICE_TYPE_OPTIONS,ERROR_CODE } from '@/constants/constants';
|
import { DEVICE_TYPE_OPTIONS, ERROR_CODE } from '@/constants/constants';
|
||||||
import { } from '@/constants/constants';
|
import { getDevieDetial, saveDevice } from '@/services/terminal';
|
||||||
import { saveDevice } from '@/services/terminal';
|
|
||||||
import { Button, Form, Input, message, Modal, Select, TreeSelect } from 'antd';
|
import { Button, Form, Input, message, Modal, Select, TreeSelect } from 'antd';
|
||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
|
|
||||||
interface UserEditModalProps {
|
interface UserEditModalProps {
|
||||||
orgTreeData: User.OrganizationNode[];
|
orgTreeData: User.OrganizationNode[];
|
||||||
onCancel: () => void;
|
onCancel: () => void;
|
||||||
onOk?: (values: any) => void;
|
onOk?: (values?: any) => void;
|
||||||
confirmLoading?: boolean;
|
confirmLoading?: boolean;
|
||||||
currentUserInfo?: Termial.ModalBaseNode;
|
currentDeviceInfo?: Termial.ModalBaseNode;
|
||||||
selectedOrg?: number;
|
selectedOrg?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,27 +18,34 @@ const UserEditModal: React.FC<UserEditModalProps> = ({
|
||||||
onCancel,
|
onCancel,
|
||||||
onOk,
|
onOk,
|
||||||
confirmLoading = false,
|
confirmLoading = false,
|
||||||
currentUserInfo,
|
currentDeviceInfo,
|
||||||
}) => {
|
}) => {
|
||||||
const { recordData, visible, selectedOrg } = currentUserInfo || {};
|
const { recordData, visible, selectedOrg } = currentDeviceInfo || {};
|
||||||
const { user_id } = recordData || {};
|
const { id, device_name } = recordData || {};
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const initialValues = { user_group_id: [selectedOrg], status: 1 };
|
const params = { id: id };
|
||||||
form.setFieldsValue(initialValues);
|
getDevieDetial(params).then((res: any) => {
|
||||||
|
console.log('res=======', res);
|
||||||
|
const { code, data } = res || {};
|
||||||
|
if (code === ERROR_CODE) {
|
||||||
|
const initialValues = { ...data };
|
||||||
|
form.setFieldsValue(initialValues);
|
||||||
|
}
|
||||||
|
});
|
||||||
}, [visible, form, recordData, selectedOrg]);
|
}, [visible, form, recordData, selectedOrg]);
|
||||||
|
|
||||||
const handleOk = async () => {
|
const handleOk = async () => {
|
||||||
try {
|
try {
|
||||||
const values = await form.validateFields();
|
const values = await form.validateFields();
|
||||||
const params = { ...values, user_id };
|
const params = { ...values, id };
|
||||||
const res = await saveDevice(params);
|
const res: any = await saveDevice(params);
|
||||||
const { error_code } = res || {};
|
const { code } = res || {};
|
||||||
if (error_code === ERROR_CODE) {
|
if (code === ERROR_CODE) {
|
||||||
message.success('保存成功');
|
message.success('保存成功');
|
||||||
|
onOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
message.error('保存失败');
|
message.error('保存失败');
|
||||||
}
|
}
|
||||||
|
@ -58,7 +64,7 @@ const UserEditModal: React.FC<UserEditModalProps> = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
title={user_id ? '编辑用户信息' : '新增用户'}
|
title={id ? `${device_name}终端信息修改` : '新增终端'}
|
||||||
open={visible}
|
open={visible}
|
||||||
onCancel={onCancel}
|
onCancel={onCancel}
|
||||||
onOk={handleOk}
|
onOk={handleOk}
|
||||||
|
@ -124,24 +130,19 @@ const UserEditModal: React.FC<UserEditModalProps> = ({
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="device_typ"
|
name="device_type"
|
||||||
label="终端类型"
|
label="终端类型"
|
||||||
rules={[{ required: false, message: '请输入终端型号' }]}
|
rules={[{ required: true, message: '请输入终端型号' }]}
|
||||||
>
|
>
|
||||||
<Select options={DEVICE_TYPE_OPTIONS} />
|
<Select options={DEVICE_TYPE_OPTIONS} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
{/* <Form.Item
|
name="model"
|
||||||
name="status"
|
label="型号"
|
||||||
label="认证方式"
|
rules={[{ required: false, message: '请输入显示名称' }]}
|
||||||
rules={[{ required: false, message: '请选择认证方式' }]}
|
|
||||||
>
|
>
|
||||||
<Radio.Group optionType="button">
|
<Input />
|
||||||
<Radio value={1}>用户认证</Radio>
|
</Form.Item>
|
||||||
<Radio value={2}>终端认证</Radio>
|
|
||||||
</Radio.Group>
|
|
||||||
</Form.Item> */}
|
|
||||||
|
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="ip_addr"
|
name="ip_addr"
|
||||||
label="IP地址"
|
label="IP地址"
|
||||||
|
@ -150,20 +151,12 @@ const UserEditModal: React.FC<UserEditModalProps> = ({
|
||||||
<Input placeholder="请输入IP地址" />
|
<Input placeholder="请输入IP地址" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="mac addr"
|
name="mac_addr"
|
||||||
label="MAC地址"
|
label="MAC地址"
|
||||||
rules={[{ required: false, message: '请输入MAC地址' }]}
|
rules={[{ required: false, message: '请输入MAC地址' }]}
|
||||||
>
|
>
|
||||||
<Input />
|
<Input />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
{/* <Form.Item
|
|
||||||
name="终端厂商"
|
|
||||||
label="mac_addr"
|
|
||||||
rules={[{ required: true, message: '请输入终端厂商' }]}
|
|
||||||
>
|
|
||||||
<Input />
|
|
||||||
</Form.Item> */}
|
|
||||||
|
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="description"
|
name="description"
|
||||||
label="描述"
|
label="描述"
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
import { Input, Table, TreeSelect } from 'antd';
|
import { ERROR_CODE } from '@/constants/constants';
|
||||||
|
import { getUserList } from '@/services/userList';
|
||||||
|
import { Input, Table, Tooltip, TreeSelect, message } from 'antd';
|
||||||
|
import type { ColumnsType } from 'antd/es/table';
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import styles from './index.less';
|
import styles from './index.less';
|
||||||
|
|
||||||
|
@ -21,30 +24,64 @@ const TablePage: React.FC<TableProps> = ({
|
||||||
selectedRowKeys,
|
selectedRowKeys,
|
||||||
}) => {
|
}) => {
|
||||||
const [data, setData] = useState<any[]>([]);
|
const [data, setData] = useState<any[]>([]);
|
||||||
// const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
|
const [loading, setLoading] = useState<boolean>(false);
|
||||||
|
const [selectedOrg, setSelectedOrg] = useState<any>();
|
||||||
const [searchText, setSearchText] = useState('');
|
const [searchText, setSearchText] = useState('');
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
const [pageSize, setPageSize] = useState(20);
|
const [pageSize, setPageSize] = useState(20);
|
||||||
const [total, setTotal] = useState(0);
|
const [total, setTotal] = useState(0);
|
||||||
|
|
||||||
// Mock data generation
|
const getDataSource = async () => {
|
||||||
useEffect(() => {
|
const params: any = {
|
||||||
const mockData: DataType[] = [];
|
page_size: pageSize,
|
||||||
for (let i = 0; i < 100; i++) {
|
page_num: currentPage,
|
||||||
mockData.push({
|
};
|
||||||
id: i + 99,
|
if (selectedOrg) {
|
||||||
name: `User ${i}`,
|
params.user_group_id = selectedOrg;
|
||||||
});
|
|
||||||
}
|
}
|
||||||
setData(mockData);
|
if (searchText) {
|
||||||
setTotal(mockData.length);
|
params.user_name = searchText;
|
||||||
}, []);
|
}
|
||||||
|
setLoading(true);
|
||||||
|
try {
|
||||||
|
const result = await getUserList(params);
|
||||||
|
console.log('res======', result);
|
||||||
|
const { code, data = {} } = result || {};
|
||||||
|
const { data: list, total = 0 } = data || {};
|
||||||
|
if (code === ERROR_CODE) {
|
||||||
|
setData(list || []);
|
||||||
|
setTotal(total);
|
||||||
|
setLoading(false);
|
||||||
|
} else {
|
||||||
|
message.error(result.message || '获取用户列表失败');
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
message.error('获取用户列表失败');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const columns: TableProps<DataType>['columns'] = [
|
useEffect(() => {
|
||||||
|
getDataSource();
|
||||||
|
}, [selectedOrg, searchText]);
|
||||||
|
|
||||||
|
const columns: ColumnsType<User.UserItem> = [
|
||||||
{
|
{
|
||||||
title: 'Name',
|
title: '序号',
|
||||||
dataIndex: 'name',
|
dataIndex: 'order',
|
||||||
sorter: (a, b) => a.name.localeCompare(b.name),
|
key: 'order',
|
||||||
|
width: 80,
|
||||||
|
align: 'center',
|
||||||
|
render: (_: any, record: any, index: number) => <span>{index + 1}</span>,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '用户名',
|
||||||
|
dataIndex: 'user_name',
|
||||||
|
key: 'user_name',
|
||||||
|
align: 'center',
|
||||||
|
render: (text) => {
|
||||||
|
return <Tooltip>{text || '--'}</Tooltip>;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -63,16 +100,21 @@ const TablePage: React.FC<TableProps> = ({
|
||||||
setPageSize(size);
|
setPageSize(size);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const onTreeChange = (newValue: any) => {
|
||||||
|
setSelectedOrg(newValue);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.content_wrap}>
|
<div className={styles.content_wrap}>
|
||||||
<div className={styles.search_wrap}>
|
<div className={styles.search_wrap}>
|
||||||
<TreeSelect
|
<TreeSelect
|
||||||
style={{ width: '300px' }}
|
style={{ width: '300px' }}
|
||||||
showSearch
|
showSearch
|
||||||
allowClear={false}
|
allowClear={true}
|
||||||
treeDefaultExpandAll
|
treeDefaultExpandAll
|
||||||
placeholder="请选择终端分组"
|
placeholder="请选择用户分组"
|
||||||
treeData={treeData}
|
treeData={treeData}
|
||||||
|
onChange={onTreeChange}
|
||||||
fieldNames={{ label: 'name', value: 'id', children: 'children' }}
|
fieldNames={{ label: 'name', value: 'id', children: 'children' }}
|
||||||
/>
|
/>
|
||||||
<Input.Search
|
<Input.Search
|
||||||
|
@ -85,9 +127,9 @@ const TablePage: React.FC<TableProps> = ({
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Table
|
<Table
|
||||||
// rowSelection={rowSelection}
|
|
||||||
columns={columns}
|
columns={columns}
|
||||||
dataSource={data}
|
dataSource={data}
|
||||||
|
loading={loading}
|
||||||
rowKey="id"
|
rowKey="id"
|
||||||
rowSelection={{
|
rowSelection={{
|
||||||
selectedRowKeys,
|
selectedRowKeys,
|
||||||
|
|
|
@ -47,12 +47,13 @@ const SelectedTable: React.FC<SelectedTableProps> = (props) => {
|
||||||
formValue.forEach((item: any) => {
|
formValue.forEach((item: any) => {
|
||||||
if (item.type === 1) {
|
if (item.type === 1) {
|
||||||
userList.push(item);
|
userList.push(item);
|
||||||
userId.push(item.id);
|
userId.push(item.record_id);
|
||||||
} else {
|
} else {
|
||||||
groupList.push(item);
|
groupList.push(item);
|
||||||
groupId.push(item.id);
|
groupId.push(item.record_id);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
setTableData(formValue);
|
||||||
setSelectedRowKeys(userId);
|
setSelectedRowKeys(userId);
|
||||||
setSelectedRows(userList);
|
setSelectedRows(userList);
|
||||||
setCheckedKeys(groupId);
|
setCheckedKeys(groupId);
|
||||||
|
@ -63,10 +64,10 @@ const SelectedTable: React.FC<SelectedTableProps> = (props) => {
|
||||||
// const onOrgSelect = (selectedKeys: React.Key[], info: any) => {};
|
// const onOrgSelect = (selectedKeys: React.Key[], info: any) => {};
|
||||||
|
|
||||||
const onCheckChange = (keys: any[], info: any) => {
|
const onCheckChange = (keys: any[], info: any) => {
|
||||||
const { checkedNodes } = info;
|
// const { checkedNodes } = info;
|
||||||
console.log('info=========', info);
|
console.log('info=========', info);
|
||||||
setCheckedKeys(keys);
|
setCheckedKeys(keys);
|
||||||
setCheckedRow(checkedNodes);
|
setCheckedRow(info);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onHnadleCancel = () => {
|
const onHnadleCancel = () => {
|
||||||
|
@ -82,15 +83,15 @@ const SelectedTable: React.FC<SelectedTableProps> = (props) => {
|
||||||
// 用户
|
// 用户
|
||||||
(selectedRows || []).forEach((item) => {
|
(selectedRows || []).forEach((item) => {
|
||||||
list.push({
|
list.push({
|
||||||
id: item.id,
|
record_id: item.id,
|
||||||
name: item.name,
|
name: item.user_name,
|
||||||
type: 1,
|
type: 1,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
// 用户组
|
// 用户组
|
||||||
checkedRow.forEach((item) => {
|
(checkedRow || []).forEach((item) => {
|
||||||
list.push({
|
list.push({
|
||||||
id: item.id,
|
record_id: item.id,
|
||||||
name: item.name,
|
name: item.name,
|
||||||
type: 2,
|
type: 2,
|
||||||
});
|
});
|
||||||
|
@ -116,13 +117,13 @@ const SelectedTable: React.FC<SelectedTableProps> = (props) => {
|
||||||
console.log('record=====handleDelete', record);
|
console.log('record=====handleDelete', record);
|
||||||
if (record) {
|
if (record) {
|
||||||
// 单个删除
|
// 单个删除
|
||||||
const { id } = record || {};
|
const { record_id } = record || {};
|
||||||
const newData = tableData.filter((item) => item.id !== id);
|
const newData = tableData.filter((item) => item.record_id !== record_id);
|
||||||
setTableData(newData);
|
setTableData(newData);
|
||||||
} else {
|
} else {
|
||||||
// 批量删除
|
// 批量删除
|
||||||
const newData = tableData.filter(
|
const newData = tableData.filter(
|
||||||
(item) => !bindTableKeys.includes(item.id),
|
(item) => !bindTableKeys.includes(item.record_id),
|
||||||
);
|
);
|
||||||
setTableData(newData);
|
setTableData(newData);
|
||||||
setSelectedRowKeys([]);
|
setSelectedRowKeys([]);
|
||||||
|
@ -131,39 +132,39 @@ const SelectedTable: React.FC<SelectedTableProps> = (props) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const getColumns = (): ColumnsType<any> => {
|
const getColumns = (): ColumnsType<any> => {
|
||||||
const columns: ColumnsType<any> = [
|
const columns: ColumnsType<any> = [
|
||||||
{
|
{
|
||||||
title: '序号',
|
title: '序号',
|
||||||
dataIndex: 'order',
|
dataIndex: 'order',
|
||||||
key: 'order',
|
key: 'order',
|
||||||
width: 80,
|
width: 80,
|
||||||
render: (_, record, index) => <span>{index + 1}</span>,
|
render: (_, record, index) => <span>{index + 1}</span>,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '名称',
|
title: '名称',
|
||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
key: 'name',
|
key: 'name',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '类型',
|
title: '类型',
|
||||||
dataIndex: 'type',
|
dataIndex: 'type',
|
||||||
key: 'type',
|
key: 'type',
|
||||||
render: (text) => (
|
render: (text) => (
|
||||||
<span>{text == 1 ? '用户' : text == 2 ? '用户组' : ''}</span>
|
<span>{text == 1 ? '用户' : text == 2 ? '用户组' : ''}</span>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '操作',
|
title: '操作',
|
||||||
key: 'action',
|
key: 'action',
|
||||||
render: (_, record) => (
|
render: (_, record) => (
|
||||||
<Button type="link" danger onClick={() => handleDelete(record)}>
|
<Button type="link" onClick={() => handleDelete(record)}>
|
||||||
删除
|
删除
|
||||||
</Button>
|
</Button>
|
||||||
),
|
),
|
||||||
}
|
},
|
||||||
];
|
];
|
||||||
return columns;
|
return columns;
|
||||||
};
|
};
|
||||||
|
|
||||||
const accessPopover = (
|
const accessPopover = (
|
||||||
<div style={{ width: '600px' }}>
|
<div style={{ width: '600px' }}>
|
||||||
|
@ -178,6 +179,7 @@ const SelectedTable: React.FC<SelectedTableProps> = (props) => {
|
||||||
<CustomTree
|
<CustomTree
|
||||||
checkable={true}
|
checkable={true}
|
||||||
multiple={true}
|
multiple={true}
|
||||||
|
checkStrictly={true}
|
||||||
treeData={orgTreeData}
|
treeData={orgTreeData}
|
||||||
titleField="name"
|
titleField="name"
|
||||||
keyField="id"
|
keyField="id"
|
||||||
|
@ -240,12 +242,12 @@ const SelectedTable: React.FC<SelectedTableProps> = (props) => {
|
||||||
<Popconfirm
|
<Popconfirm
|
||||||
title=""
|
title=""
|
||||||
description="删除操作不可逆,请确认是否删除?"
|
description="删除操作不可逆,请确认是否删除?"
|
||||||
onConfirm={()=>handleDelete()}
|
onConfirm={() => handleDelete()}
|
||||||
disabled={bindTableKeys.length === 0}
|
disabled={bindTableKeys.length === 0}
|
||||||
okText="删除"
|
okText="删除"
|
||||||
cancelText="取消"
|
cancelText="取消"
|
||||||
>
|
>
|
||||||
<Button disabled={bindTableKeys.length === 0}>删除</Button>
|
<Button disabled={bindTableKeys.length === 0}>删除</Button>
|
||||||
</Popconfirm>
|
</Popconfirm>
|
||||||
</div>
|
</div>
|
||||||
</Popover>
|
</Popover>
|
||||||
|
@ -254,9 +256,9 @@ const SelectedTable: React.FC<SelectedTableProps> = (props) => {
|
||||||
dataSource={tableData}
|
dataSource={tableData}
|
||||||
onDelete={handleDelete}
|
onDelete={handleDelete}
|
||||||
scrollY={400}
|
scrollY={400}
|
||||||
rowKey="id"
|
rowKey="record_id"
|
||||||
pagination={false}
|
pagination={false}
|
||||||
columns={getColumns()}
|
columns={getColumns()}
|
||||||
rowSelection={{
|
rowSelection={{
|
||||||
bindTableKeys,
|
bindTableKeys,
|
||||||
onChange: onSelectChange,
|
onChange: onSelectChange,
|
||||||
|
|
|
@ -62,13 +62,13 @@ const UserListPage: React.FC = () => {
|
||||||
// 获取用户列表数据
|
// 获取用户列表数据
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getDataSource();
|
getDataSource();
|
||||||
}, [searchText,selectedOrg, currentPage, pageSize]);
|
}, [searchText, selectedOrg, currentPage, pageSize]);
|
||||||
|
|
||||||
const getUserGroupList = async () => {
|
const getUserGroupList = async () => {
|
||||||
|
setSpinning(true);
|
||||||
const params = {
|
const params = {
|
||||||
type: 1,
|
type: 1,
|
||||||
};
|
};
|
||||||
setSpinning(true);
|
|
||||||
try {
|
try {
|
||||||
const result = await getGroupTree(params);
|
const result = await getGroupTree(params);
|
||||||
console.log('result=====', result);
|
console.log('result=====', result);
|
||||||
|
@ -144,24 +144,24 @@ const UserListPage: React.FC = () => {
|
||||||
setTotal(total);
|
setTotal(total);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
} else {
|
} else {
|
||||||
message.error(result.message || '获取终端列表失败');
|
message.error(result.message || '获取用户列表失败');
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
message.error('获取终端列表失败');
|
message.error('获取用户列表失败');
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const onDelete = (user?: User.UserItem) => {
|
const onDelete = (user?: User.UserItem) => {
|
||||||
const { user_id } = user || {};
|
const { id } = user || {};
|
||||||
const payload = {
|
const payload = {
|
||||||
ids: user_id ? [user_id] : selectedRowKeys,
|
id: id ? id : selectedRowKeys,
|
||||||
};
|
};
|
||||||
deleteUser(payload as any).then((res) => {
|
deleteUser(payload as any).then((res) => {
|
||||||
console.log('res=====', res);
|
console.log('res=====', res);
|
||||||
const { success } = res || {};
|
const { code } = res || {};
|
||||||
if (success) {
|
if (code === ERROR_CODE) {
|
||||||
message.success('删除成功');
|
message.success('删除成功');
|
||||||
setSelectedRowKeys([]);
|
setSelectedRowKeys([]);
|
||||||
getDataSource();
|
getDataSource();
|
||||||
|
@ -267,7 +267,7 @@ const UserListPage: React.FC = () => {
|
||||||
key: 'cell_phone',
|
key: 'cell_phone',
|
||||||
width: 150,
|
width: 150,
|
||||||
align: 'center',
|
align: 'center',
|
||||||
render: (text:any) => {
|
render: (text: any) => {
|
||||||
return <Tooltip>{text || '--'}</Tooltip>;
|
return <Tooltip>{text || '--'}</Tooltip>;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -277,7 +277,7 @@ const UserListPage: React.FC = () => {
|
||||||
key: 'birthday',
|
key: 'birthday',
|
||||||
width: 150,
|
width: 150,
|
||||||
align: 'center',
|
align: 'center',
|
||||||
render: (text:any) => {
|
render: (text: any) => {
|
||||||
return <Tooltip>{text || '--'}</Tooltip>;
|
return <Tooltip>{text || '--'}</Tooltip>;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -287,7 +287,7 @@ const UserListPage: React.FC = () => {
|
||||||
key: 'identity_no',
|
key: 'identity_no',
|
||||||
width: 150,
|
width: 150,
|
||||||
align: 'center',
|
align: 'center',
|
||||||
render: (text:any) => {
|
render: (text: any) => {
|
||||||
return <Tooltip>{text || '--'}</Tooltip>;
|
return <Tooltip>{text || '--'}</Tooltip>;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -299,9 +299,9 @@ const UserListPage: React.FC = () => {
|
||||||
fixed: 'right',
|
fixed: 'right',
|
||||||
render: (_, record) => (
|
render: (_, record) => (
|
||||||
<div style={{ display: 'flex' }}>
|
<div style={{ display: 'flex' }}>
|
||||||
<Button type="link" onClick={() => handlePassword(record)}>
|
{/* <Button type="link" onClick={() => handlePassword(record)}>
|
||||||
重置密码
|
重置密码
|
||||||
</Button>
|
</Button> */}
|
||||||
<Button type="link" onClick={() => handleEditUserInfo(record)}>
|
<Button type="link" onClick={() => handleEditUserInfo(record)}>
|
||||||
编辑
|
编辑
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -346,6 +346,14 @@ const UserListPage: React.FC = () => {
|
||||||
getUserGroupList();
|
getUserGroupList();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const onSaveUserCallback = () => {
|
||||||
|
setCurrentUserInfo({
|
||||||
|
recordData: {},
|
||||||
|
visible: false,
|
||||||
|
});
|
||||||
|
getDataSource();
|
||||||
|
};
|
||||||
|
|
||||||
const onDeleteGroup = async () => {
|
const onDeleteGroup = async () => {
|
||||||
if (selectedOrg) {
|
if (selectedOrg) {
|
||||||
try {
|
try {
|
||||||
|
@ -440,7 +448,7 @@ const UserListPage: React.FC = () => {
|
||||||
>
|
>
|
||||||
新建用户
|
新建用户
|
||||||
</Button>
|
</Button>
|
||||||
<Popconfirm
|
{/* <Popconfirm
|
||||||
title=""
|
title=""
|
||||||
description="删除操作不可逆,请确认是否删除?"
|
description="删除操作不可逆,请确认是否删除?"
|
||||||
onConfirm={() => onDelete()}
|
onConfirm={() => onDelete()}
|
||||||
|
@ -452,10 +460,11 @@ const UserListPage: React.FC = () => {
|
||||||
<Button
|
<Button
|
||||||
disabled={selectedRowKeys.length === 0}
|
disabled={selectedRowKeys.length === 0}
|
||||||
style={{ marginRight: '8px' }}
|
style={{ marginRight: '8px' }}
|
||||||
|
icon={<DeleteOutlined />}
|
||||||
>
|
>
|
||||||
删除
|
删除
|
||||||
</Button>
|
</Button>
|
||||||
</Popconfirm>
|
</Popconfirm> */}
|
||||||
<Button style={{ marginRight: '8px' }} onClick={getDataSource}>
|
<Button style={{ marginRight: '8px' }} onClick={getDataSource}>
|
||||||
刷新
|
刷新
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -494,38 +503,44 @@ const UserListPage: React.FC = () => {
|
||||||
return `共${total}条数据`;
|
return `共${total}条数据`;
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
rowSelection={{
|
// rowSelection={{
|
||||||
selectedRowKeys,
|
// selectedRowKeys,
|
||||||
onChange: onSelectChange,
|
// onChange: onSelectChange,
|
||||||
}}
|
// }}
|
||||||
scroll={{ x: 'max-content', y: 55 * 12 }}
|
scroll={{ x: 'max-content', y: 55 * 12 }}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<CreatGroup
|
{visible && (
|
||||||
visible={visible}
|
<CreatGroup
|
||||||
type={1}
|
visible={visible}
|
||||||
title="新增用户分组"
|
type={1}
|
||||||
selectedOrg={selectedOrg}
|
title="新增用户分组"
|
||||||
onCancel={() => {
|
selectedOrg={selectedOrg}
|
||||||
setVisible(false);
|
onCancel={() => {
|
||||||
}}
|
setVisible(false);
|
||||||
onOk={onSaveGroup}
|
}}
|
||||||
orgTreeData={orgTreeData}
|
onOk={onSaveGroup}
|
||||||
/>
|
orgTreeData={orgTreeData}
|
||||||
<UserEditModal
|
/>
|
||||||
selectedOrg={selectedOrg}
|
)}
|
||||||
orgTreeData={orgTreeData}
|
{currentUserInfo.visible && (
|
||||||
currentUserInfo={currentUserInfo}
|
<UserEditModal
|
||||||
onCancel={() => {
|
selectedOrg={selectedOrg}
|
||||||
setCurrentUserInfo({
|
orgTreeData={orgTreeData}
|
||||||
recordData: {},
|
currentUserInfo={currentUserInfo}
|
||||||
visible: false,
|
onCancel={() => {
|
||||||
});
|
setCurrentUserInfo({
|
||||||
}}
|
recordData: {},
|
||||||
onOk={() => {}}
|
visible: false,
|
||||||
/>
|
});
|
||||||
|
}}
|
||||||
|
onOk={() => {
|
||||||
|
onSaveUserCallback();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
<PasswordResetModal
|
<PasswordResetModal
|
||||||
visible={eidtPassword.visible}
|
visible={eidtPassword.visible}
|
||||||
onCancel={() => {
|
onCancel={() => {
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
// index.tsx
|
import {
|
||||||
import { GENDER_OPTIONS, USER_TYPE_OPTIONS } from '@/constants/constants';
|
ERROR_CODE,
|
||||||
import { idIDIntl } from '@ant-design/pro-components';
|
GENDER_OPTIONS,
|
||||||
|
PRIOPRITY_OPTIONS,
|
||||||
|
USER_TYPE_OPTIONS,
|
||||||
|
} from '@/constants/constants';
|
||||||
|
import { addUser, editUser, getUserById } from '@/services/userList';
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
Form,
|
Form,
|
||||||
|
@ -10,6 +14,7 @@ import {
|
||||||
Radio,
|
Radio,
|
||||||
Select,
|
Select,
|
||||||
TreeSelect,
|
TreeSelect,
|
||||||
|
DatePicker
|
||||||
} from 'antd';
|
} from 'antd';
|
||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
|
|
||||||
|
@ -17,7 +22,7 @@ interface UserEditModalProps {
|
||||||
// visible: boolean;
|
// visible: boolean;
|
||||||
orgTreeData: User.OrganizationNode[];
|
orgTreeData: User.OrganizationNode[];
|
||||||
onCancel: () => void;
|
onCancel: () => void;
|
||||||
onOk: (values: any) => void;
|
onOk: (values?: any) => void;
|
||||||
confirmLoading?: boolean;
|
confirmLoading?: boolean;
|
||||||
currentUserInfo?: User.UserModalBaseNode;
|
currentUserInfo?: User.UserModalBaseNode;
|
||||||
selectedOrg?: number;
|
selectedOrg?: number;
|
||||||
|
@ -35,14 +40,31 @@ const UserEditModal: React.FC<UserEditModalProps> = ({
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const initialValues = { user_group_id: [selectedOrg], status: 1 };
|
if (id) {
|
||||||
form.setFieldsValue(initialValues);
|
getUserById({ id }).then((res) => {
|
||||||
|
const { data } = res;
|
||||||
|
form.setFieldsValue(data);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const initialValues = { user_group_id: [selectedOrg], status: 1 };
|
||||||
|
form.setFieldsValue(initialValues);
|
||||||
|
}
|
||||||
}, [visible, form, recordData, selectedOrg]);
|
}, [visible, form, recordData, selectedOrg]);
|
||||||
|
|
||||||
const handleOk = async () => {
|
const handleOk = async () => {
|
||||||
|
const values = await form.validateFields();
|
||||||
try {
|
try {
|
||||||
const values = await form.validateFields();
|
const params = { ...values };
|
||||||
onOk(values);
|
if (id) {
|
||||||
|
params.id = id;
|
||||||
|
}
|
||||||
|
const result: any = id ? await editUser(params) : await addUser(params);
|
||||||
|
const { code } = result || {};
|
||||||
|
if (code === ERROR_CODE) {
|
||||||
|
onOk();
|
||||||
|
} else {
|
||||||
|
message.error('保存失败');
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
message.error('请检查表单字段');
|
message.error('请检查表单字段');
|
||||||
}
|
}
|
||||||
|
@ -53,13 +75,41 @@ const UserEditModal: React.FC<UserEditModalProps> = ({
|
||||||
types: {
|
types: {
|
||||||
email: '${label} is not a valid email!',
|
email: '${label} is not a valid email!',
|
||||||
number: '${label} is not a valid number!',
|
number: '${label} is not a valid number!',
|
||||||
cell_phone: '${label} is not a valid cell phone number!',
|
|
||||||
},
|
},
|
||||||
number: {
|
number: {
|
||||||
range: '${label} must be between ${min} and ${max}',
|
range: '${label} must be between ${min} and ${max}',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Password validation rule
|
||||||
|
const passwordValidator = (_: any, value: string) => {
|
||||||
|
if (!value) {
|
||||||
|
return Promise.reject('请输入新密码');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value.length < 6) {
|
||||||
|
return Promise.reject('密码长度至少6位');
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasNumber = /\d/.test(value);
|
||||||
|
const hasLetter = /[a-zA-Z]/.test(value);
|
||||||
|
// const hasSpecialChar = /[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(value);
|
||||||
|
|
||||||
|
if (!hasNumber) {
|
||||||
|
return Promise.reject('密码必须包含数字');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasLetter) {
|
||||||
|
return Promise.reject('密码必须包含字母');
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (!hasSpecialChar) {
|
||||||
|
// return Promise.reject('密码必须包含特殊字符');
|
||||||
|
// }
|
||||||
|
|
||||||
|
return Promise.resolve();
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
title={id ? '编辑用户信息' : '新增用户'}
|
title={id ? '编辑用户信息' : '新增用户'}
|
||||||
|
@ -98,24 +148,23 @@ const UserEditModal: React.FC<UserEditModalProps> = ({
|
||||||
validateMessages={validateMessages}
|
validateMessages={validateMessages}
|
||||||
>
|
>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="loginName"
|
name="user_name"
|
||||||
label="登录名"
|
|
||||||
rules={[
|
|
||||||
{ required: true, message: '请输入登录名' },
|
|
||||||
{ min: 3, message: '登录名至少3个字符' },
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
<Input placeholder="请输入登录名" />
|
|
||||||
</Form.Item>
|
|
||||||
|
|
||||||
<Form.Item
|
|
||||||
name="userName"
|
|
||||||
label="用户姓名"
|
label="用户姓名"
|
||||||
rules={[{ required: true, message: '请输入用户姓名' }]}
|
rules={[{ required: true, message: '请输入用户姓名' }]}
|
||||||
>
|
>
|
||||||
<Input placeholder="请输入用户姓名" />
|
<Input placeholder="请输入用户姓名" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
|
<Form.Item
|
||||||
|
name="password"
|
||||||
|
label="密码"
|
||||||
|
rules={[{ required: true, validator: passwordValidator }]}
|
||||||
|
help="密码必须包含数字和字母,字母区分大小写,且至少6位"
|
||||||
|
style={{ marginBottom: '30px' }}
|
||||||
|
>
|
||||||
|
<Input.Password placeholder="请输入密码" />
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="user_group_id"
|
name="user_group_id"
|
||||||
label="用户分组"
|
label="用户分组"
|
||||||
|
@ -149,6 +198,16 @@ const UserEditModal: React.FC<UserEditModalProps> = ({
|
||||||
>
|
>
|
||||||
<Select placeholder="请选择用户类别" options={USER_TYPE_OPTIONS} />
|
<Select placeholder="请选择用户类别" options={USER_TYPE_OPTIONS} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<Form.Item name="birthday" label="出生日期" >
|
||||||
|
<DatePicker style={{width:"414px"}}/>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
name="priority"
|
||||||
|
label="优先级"
|
||||||
|
rules={[{ required: false, message: '请选择用户优先级' }]}
|
||||||
|
>
|
||||||
|
<Select placeholder="请选择用户类别" options={PRIOPRITY_OPTIONS} />
|
||||||
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="gender"
|
name="gender"
|
||||||
label="性别"
|
label="性别"
|
||||||
|
|
|
@ -6,7 +6,7 @@ import React, { useEffect, useState } from 'react';
|
||||||
|
|
||||||
interface CreatGroupProps {
|
interface CreatGroupProps {
|
||||||
title: string;
|
title: string;
|
||||||
type:number;
|
type: number;
|
||||||
visible: boolean;
|
visible: boolean;
|
||||||
selectedOrg?: number;
|
selectedOrg?: number;
|
||||||
onCancel: () => void;
|
onCancel: () => void;
|
||||||
|
@ -22,14 +22,14 @@ const CreatGroup: React.FC<CreatGroupProps> = (props) => {
|
||||||
onOk,
|
onOk,
|
||||||
orgTreeData,
|
orgTreeData,
|
||||||
selectedOrg,
|
selectedOrg,
|
||||||
type
|
type,
|
||||||
} = props;
|
} = props;
|
||||||
const [loading, setLoading] = useState<boolean>(false);
|
const [loading, setLoading] = useState<boolean>(false);
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedOrg) {
|
if (selectedOrg) {
|
||||||
const initialValues = { parent_id: [selectedOrg] };
|
const initialValues = { parent_id: selectedOrg };
|
||||||
form.setFieldsValue(initialValues);
|
form.setFieldsValue(initialValues);
|
||||||
}
|
}
|
||||||
}, [visible, form, selectedOrg]);
|
}, [visible, form, selectedOrg]);
|
||||||
|
@ -49,10 +49,11 @@ const CreatGroup: React.FC<CreatGroupProps> = (props) => {
|
||||||
try {
|
try {
|
||||||
console.log('values=====', values);
|
console.log('values=====', values);
|
||||||
const { name, parent_id } = values || {};
|
const { name, parent_id } = values || {};
|
||||||
const params: any = { name, type: type };
|
const params: any = { name, type: type, parent_id: parent_id };
|
||||||
if (parent_id) {
|
// if (parent_id) {
|
||||||
params.parent_id = parent_id;
|
// params.parent_id =
|
||||||
}
|
// parent_id && parent_id.length > 0 ? parent_id[0] : null;
|
||||||
|
// }
|
||||||
const res = await addUserGroup(params);
|
const res = await addUserGroup(params);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
const { code } = res || {};
|
const { code } = res || {};
|
||||||
|
|
|
@ -1,28 +1,74 @@
|
||||||
import { request } from '@umijs/max';
|
import { request } from '@umijs/max';
|
||||||
|
|
||||||
const BASE_URL = '/api/v1/terminal';
|
const BASE_URL = '/api/nex/v1';
|
||||||
|
|
||||||
// 根据终端序列号查询镜像列表
|
// 根据终端序列号查询镜像列表
|
||||||
export async function getTerminalList(params:any) {
|
export async function getTerminalList(params: any) {
|
||||||
// console.log('终端列表 params', params);
|
return request<Termial.Termial_ListInfo>(`${BASE_URL}/device/select/page`, {
|
||||||
return request<Termial.Termial_ListInfo>(`${BASE_URL}/query/devicelist`, {
|
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
data: params,
|
data: params,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteDevice(params:any) {
|
// 根据id查询终端信息
|
||||||
// console.log('终端列表 params', params);
|
export async function getDevieDetial(params: any) {
|
||||||
return request<Termial.Termial_ListInfo>(`${BASE_URL}/delete/device`, {
|
return request<Termial.Termial_ListInfo>(`${BASE_URL}/device/query`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
data: params,
|
data: params,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function saveDevice(params:any) {
|
//删除终端
|
||||||
// console.log('终端列表 params', params);
|
export async function deleteDevice(params: any) {
|
||||||
return request<Termial.Termial_ListInfo>(`${BASE_URL}/save/device`, {
|
return request<Termial.Termial_ListInfo>(`${BASE_URL}/device/delete`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
data: params,
|
data: params,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 终端编辑保存
|
||||||
|
export async function saveDevice(params: any) {
|
||||||
|
return request<Termial.Termial_ListInfo>(`${BASE_URL}/device/update`, {
|
||||||
|
method: 'POST',
|
||||||
|
data: params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 终端绑定用户
|
||||||
|
export async function bindUserAdd(params: any) {
|
||||||
|
return request<Termial.Termial_ListInfo>(`${BASE_URL}/device/user/mapping/add`, {
|
||||||
|
method: 'POST',
|
||||||
|
data: params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getBindUserList(params: any) {
|
||||||
|
return request<Termial.Termial_ListInfo>(`${BASE_URL}/device/user/mapping/select`, {
|
||||||
|
method: 'POST',
|
||||||
|
data: params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 镜像列表
|
||||||
|
export async function getImageList(params: any) {
|
||||||
|
return request<Termial.Termial_ListInfo>(`${BASE_URL}/image/select/page`, {
|
||||||
|
method: 'POST',
|
||||||
|
data: params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 终端绑定镜像列表
|
||||||
|
export async function getBindImageList(params: any) {
|
||||||
|
return request<Termial.Termial_ListInfo>(`${BASE_URL}/device/image/mapping/select`, {
|
||||||
|
method: 'POST',
|
||||||
|
data: params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 终端绑定镜像列表
|
||||||
|
export async function getBindImageAdd(params: any) {
|
||||||
|
return request<Termial.Termial_ListInfo>(`${BASE_URL}/device/image/mapping/add`, {
|
||||||
|
method: 'POST',
|
||||||
|
data: params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ export async function getUserById(body?: any) {
|
||||||
//删除用户
|
//删除用户
|
||||||
export async function deleteUser(body?: any) {
|
export async function deleteUser(body?: any) {
|
||||||
return request<any>(`${BASE_URL}/user/delete`, {
|
return request<any>(`${BASE_URL}/user/delete`, {
|
||||||
method: 'DELETE',
|
method: 'POST',
|
||||||
data: body,
|
data: body,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ declare namespace User {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface UserItem {
|
interface UserItem {
|
||||||
|
id?:number;
|
||||||
user_id?: number;
|
user_id?: number;
|
||||||
user_group_id?: number;
|
user_group_id?: number;
|
||||||
user_group_name?: number;
|
user_group_name?: number;
|
||||||
|
|
|
@ -6665,7 +6665,7 @@ minimist-options@4.1.0:
|
||||||
resolved "https://registry.npmmirror.com/minipass/-/minipass-7.1.2.tgz#93a9626ce5e5e66bd4db86849e7515e92340a707"
|
resolved "https://registry.npmmirror.com/minipass/-/minipass-7.1.2.tgz#93a9626ce5e5e66bd4db86849e7515e92340a707"
|
||||||
integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==
|
integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==
|
||||||
|
|
||||||
moment@^2.24.0, moment@^2.29.2, moment@^2.29.4:
|
moment@^2.24.0, moment@^2.29.2, moment@^2.29.4, moment@^2.30.1:
|
||||||
version "2.30.1"
|
version "2.30.1"
|
||||||
resolved "https://registry.npmmirror.com/moment/-/moment-2.30.1.tgz#f8c91c07b7a786e30c59926df530b4eac96974ae"
|
resolved "https://registry.npmmirror.com/moment/-/moment-2.30.1.tgz#f8c91c07b7a786e30c59926df530b4eac96974ae"
|
||||||
integrity sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==
|
integrity sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==
|
||||||
|
@ -9412,7 +9412,16 @@ string-convert@^0.2.0:
|
||||||
resolved "https://registry.npmmirror.com/string-convert/-/string-convert-0.2.1.tgz#6982cc3049fbb4cd85f8b24568b9d9bf39eeff97"
|
resolved "https://registry.npmmirror.com/string-convert/-/string-convert-0.2.1.tgz#6982cc3049fbb4cd85f8b24568b9d9bf39eeff97"
|
||||||
integrity sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A==
|
integrity sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A==
|
||||||
|
|
||||||
"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
|
"string-width-cjs@npm:string-width@^4.2.0":
|
||||||
|
version "4.2.3"
|
||||||
|
resolved "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
||||||
|
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
||||||
|
dependencies:
|
||||||
|
emoji-regex "^8.0.0"
|
||||||
|
is-fullwidth-code-point "^3.0.0"
|
||||||
|
strip-ansi "^6.0.1"
|
||||||
|
|
||||||
|
string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
|
||||||
version "4.2.3"
|
version "4.2.3"
|
||||||
resolved "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
resolved "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
||||||
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
||||||
|
@ -9502,7 +9511,14 @@ string_decoder@~1.1.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
safe-buffer "~5.1.0"
|
safe-buffer "~5.1.0"
|
||||||
|
|
||||||
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
|
||||||
|
version "6.0.1"
|
||||||
|
resolved "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
||||||
|
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||||
|
dependencies:
|
||||||
|
ansi-regex "^5.0.1"
|
||||||
|
|
||||||
|
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
||||||
version "6.0.1"
|
version "6.0.1"
|
||||||
resolved "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
resolved "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
||||||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||||
|
@ -10260,7 +10276,16 @@ word-wrap@^1.2.5:
|
||||||
resolved "https://registry.npmmirror.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34"
|
resolved "https://registry.npmmirror.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34"
|
||||||
integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==
|
integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==
|
||||||
|
|
||||||
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
|
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
|
||||||
|
version "7.0.0"
|
||||||
|
resolved "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
|
||||||
|
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
|
||||||
|
dependencies:
|
||||||
|
ansi-styles "^4.0.0"
|
||||||
|
string-width "^4.1.0"
|
||||||
|
strip-ansi "^6.0.0"
|
||||||
|
|
||||||
|
wrap-ansi@^7.0.0:
|
||||||
version "7.0.0"
|
version "7.0.0"
|
||||||
resolved "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
|
resolved "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
|
||||||
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
|
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
|
||||||
|
|
Loading…
Reference in New Issue