Files
scrm.antd/src/pages/DepartmentsList/index.tsx

426 lines
13 KiB
TypeScript
Raw Normal View History

2023-04-07 17:38:15 +08:00
import { SearchBarPlugin, SearchBottonsCardPlugin } from '@/components/SearchBarPlugin';
import { post } from '@/services/ajax';
import { PageContainer } from '@ant-design/pro-components';
2023-04-14 17:31:45 +08:00
import {
App,
Button,
Col,
Drawer,
Form,
Input,
Modal,
Pagination,
Row,
Spin,
Table,
Tree,
} from 'antd';
2023-04-11 15:29:40 +08:00
import { stringify } from 'qs';
import React, { useEffect, useState } from 'react';
2023-04-14 17:31:45 +08:00
import { IStaffsItem } from '../ChatLogs/ChatLogsType';
import { DepartmentMembersDetail } from './components/DepartmentMemberDetail';
2023-04-07 17:38:15 +08:00
import styles from './index.module.scss';
2023-04-11 15:29:40 +08:00
interface IDepartment {
children: null | IDepartment[];
department_leader: string;
id: number;
name: string;
parent_id: number;
sort: number;
2023-04-07 17:38:15 +08:00
}
2023-04-11 15:29:40 +08:00
interface IStaffsData {
count: number;
data?: IStaffsItem[];
}
type Param = {
curr_page: number;
page_count: number;
dep_id: number;
name?: string;
position?: string;
telephone?: string;
2023-04-14 17:31:45 +08:00
mobile?: string;
2023-04-11 15:29:40 +08:00
};
2023-04-07 17:38:15 +08:00
const DepartmentsList: React.FC = () => {
2023-04-11 15:29:40 +08:00
const [param] = useState<Param>({
2023-04-07 17:38:15 +08:00
curr_page: 1,
page_count: 20,
2023-04-11 15:29:40 +08:00
dep_id: 0,
2023-04-07 17:38:15 +08:00
});
2023-04-17 17:47:31 +08:00
const { notification } = App.useApp();
2023-04-11 15:29:40 +08:00
const [departmentID, setDepartmentsID] = useState<number>(0);
const [departmentsList, setDepartmentsList] = useState<IDepartment[]>([]);
const [staffsData, setStaffsData] = useState<IStaffsData>({ count: 0, data: [] });
const [loadingL, setLoadingL] = useState(false);
const [loading, setLoading] = useState(false);
2023-04-14 17:31:45 +08:00
const [open, setOpen] = useState(false);
const [record, setRecord] = useState<IStaffsItem>();
2023-04-11 15:29:40 +08:00
2023-04-17 17:47:31 +08:00
const getStaffsList = () => {
setLoading(true);
post({ url: '/Staffs/List', data: stringify(param) }).then((res) => {
setLoading(false);
if (res.err_code == 0) {
if (!Array.isArray(res.data)) {
res.data = [];
}
setStaffsData(res as IStaffsData);
}
});
};
2023-04-11 15:29:40 +08:00
const getDepartmentsList = () => {
setLoadingL(true);
post({ url: '/Departments/List' }).then((res) => {
setLoadingL(false);
if (res.err_code == 0) {
2023-04-14 17:31:45 +08:00
if (Array.isArray(res.data) && res.data.length) {
2023-04-11 15:29:40 +08:00
param.dep_id = res.data[0].id;
setDepartmentsID(param.dep_id);
setDepartmentsList(res.data);
getStaffsList();
}
}
});
};
2023-04-07 17:38:15 +08:00
2023-04-11 15:29:40 +08:00
const page = (page: number) => {
param.curr_page = page;
getStaffsList();
};
2023-04-07 17:38:15 +08:00
2023-04-11 15:29:40 +08:00
useEffect(() => {
getDepartmentsList();
}, []);
2023-04-07 17:38:15 +08:00
2023-04-11 15:29:40 +08:00
// const [open, setOpen] = useState(false);
// const [popOpen, setPopOpen] = useState(-1);
2023-04-07 17:38:15 +08:00
2023-04-14 17:31:45 +08:00
const [syncLoading, setSyncLoading] = useState(false);
const [syncOpen, setSyncOpen] = useState('');
const syncDepartments = () => {
setSyncLoading(false);
setSyncOpen('dep');
};
const syncStaffs = () => {
setSyncLoading(false);
setSyncOpen('staff');
};
const syncDepOrStaff = () => {
if (syncLoading) return;
setSyncLoading(true);
if (syncOpen == 'dep') {
post({ url: '/Sync/Departments' }).then((res) => {
setSyncLoading(false);
if (res.err_code == 0) {
notification.success({
message: res.err_msg,
});
getDepartmentsList();
}
});
} else {
post({ url: '/Sync/Staffs' }).then((res) => {
setSyncLoading(false);
if (res.err_code == 0) {
notification.success({
message: res.err_msg,
});
getStaffsList();
}
});
}
};
2023-04-07 17:38:15 +08:00
return (
<PageContainer>
<div style={{ display: 'flex' }}>
<div
style={{
2023-04-14 17:31:45 +08:00
width: 240,
2023-04-07 17:38:15 +08:00
flexShrink: 0,
minHeight: 'calc(100vh - 55px - 60px - 96px)',
maxHeight: 'calc(100vh - 55px - 60px)',
overflow: 'auto',
marginRight: 12,
background: '#fff',
position: 'sticky',
top: 64,
padding: '12px 0',
}}
>
2023-04-11 15:29:40 +08:00
<Spin spinning={loadingL} style={{ display: 'block' }}>
{departmentsList.length ? (
<Tree
className={'department-tree'}
blockNode
selectedKeys={[departmentID]}
defaultExpandAll
2023-04-17 17:47:31 +08:00
treeData={departmentsList as any}
2023-04-11 15:29:40 +08:00
fieldNames={{ title: 'name', key: 'id' }}
onSelect={(selectedKeys) => {
if (selectedKeys.length) {
setDepartmentsID(Number(selectedKeys[0]));
param.dep_id = Number(selectedKeys[0]);
page(1);
}
}}
titleRender={(nodeData: any) => {
// console.log(nodeData);
return (
<div className={styles.departmentItem}>
<div className={styles.name} title={nodeData.name}>
{nodeData.name}
</div>
{/* <div className={styles.btnsBox}>
2023-04-07 17:38:15 +08:00
<FormOutlined
title="修改"
onClick={(e) => {
e.stopPropagation();
setOpen(true);
}}
className={styles.edit}
/>
<Popconfirm
title="确认删除?"
open={popOpen == nodeData.id}
onCancel={(e) => {
setPopOpen(-1);
e?.stopPropagation();
}}
onConfirm={(e) => {
e?.stopPropagation();
console.log(nodeData.id);
}}
>
<DeleteOutlined
title="删除"
onClick={(e) => {
e.stopPropagation();
setPopOpen(nodeData.id);
}}
className={styles.del}
/>
</Popconfirm>
2023-04-11 15:29:40 +08:00
</div> */}
</div>
);
}}
2023-04-17 17:47:31 +08:00
/>
2023-04-11 15:29:40 +08:00
) : null}
</Spin>
2023-04-07 17:38:15 +08:00
</div>
2023-04-14 17:31:45 +08:00
<Modal
title="系统提示"
open={!!syncOpen}
onOk={syncDepOrStaff}
onCancel={() => setSyncOpen('')}
centered
width={300}
>
<Spin spinning={syncLoading}>
<div>{syncOpen == 'dep' ? '确定同步部门?' : '确定同步员工?'}</div>
</Spin>
</Modal>
2023-04-11 15:29:40 +08:00
{/* <Modal
2023-04-07 17:38:15 +08:00
open={open}
title="修改部门"
onCancel={() => setOpen(false)}
centered
onOk={() => {}}
>
<Form>
<Form.Item label="名称">
<Input type="text"></Input>
</Form.Item>
</Form>
2023-04-11 15:29:40 +08:00
</Modal> */}
2023-04-07 17:38:15 +08:00
<div style={{ flexGrow: 1, minWidth: 0 }}>
<SearchBarPlugin>
2023-04-11 15:29:40 +08:00
<Form autoComplete="off">
2023-04-07 17:38:15 +08:00
<Row gutter={{ xs: 0, sm: 16 }}>
2023-04-11 15:29:40 +08:00
<Col xs={24} sm={12} md={8}>
2023-04-17 17:47:31 +08:00
<Form.Item label={<span style={{ textIndent: '1em' }}></span>}>
2023-04-11 15:29:40 +08:00
<Input
autoComplete="off"
onChange={(e) => {
param.name = e.target.value.trim();
}}
allowClear
onPressEnter={() => page(1)}
2023-04-17 17:47:31 +08:00
/>
2023-04-07 17:38:15 +08:00
</Form.Item>
</Col>
2023-04-11 15:29:40 +08:00
<Col xs={24} sm={12} md={8}>
2023-04-17 17:47:31 +08:00
<Form.Item label={<span style={{ textIndent: '1em' }}></span>}>
2023-04-11 15:29:40 +08:00
<Input
autoComplete="off"
onChange={(e) => {
param.position = e.target.value.trim();
}}
allowClear
onPressEnter={() => page(1)}
2023-04-17 17:47:31 +08:00
/>
2023-04-07 17:38:15 +08:00
</Form.Item>
</Col>
2023-04-11 15:29:40 +08:00
<Col xs={24} sm={12} md={8}>
<Form.Item label="手机号">
<Input
autoComplete="off"
onChange={(e) => {
2023-04-14 17:31:45 +08:00
param.mobile = e.target.value.trim();
2023-04-11 15:29:40 +08:00
}}
allowClear
onPressEnter={() => page(1)}
2023-04-17 17:47:31 +08:00
/>
2023-04-07 17:38:15 +08:00
</Form.Item>
</Col>
2023-04-11 15:29:40 +08:00
{/* <Col xs={24} sm={12} md={6}>
2023-04-07 17:38:15 +08:00
<Form.Item label="用户名">
<Select
defaultValue="lucy"
style={{ width: '100%' }}
onChange={() => {}}
options={[
{ value: 'jack', label: 'Jack' },
{ value: 'lucy', label: 'Lucy' },
{ value: 'Yiminghe', label: 'yiminghe' },
]}
/>
</Form.Item>
2023-04-11 15:29:40 +08:00
</Col> */}
2023-04-07 17:38:15 +08:00
</Row>
</Form>
</SearchBarPlugin>
<SearchBottonsCardPlugin>
<Row justify={'center'}>
<Button
type="primary"
onClick={() => {
2023-04-11 15:29:40 +08:00
page(1);
2023-04-07 17:38:15 +08:00
}}
2023-04-14 17:31:45 +08:00
style={{ marginRight: 12 }}
2023-04-07 17:38:15 +08:00
>
</Button>
2023-04-14 17:31:45 +08:00
<Button
type="primary"
onClick={() => {
syncDepartments();
}}
style={{ marginRight: 12 }}
>
</Button>
<Button
type="primary"
onClick={() => {
syncStaffs();
}}
>
</Button>
2023-04-07 17:38:15 +08:00
</Row>
</SearchBottonsCardPlugin>
<Table
2023-04-11 15:29:40 +08:00
tableLayout="fixed"
2023-04-07 17:38:15 +08:00
size="middle"
2023-04-11 15:29:40 +08:00
dataSource={staffsData.data}
2023-04-07 17:38:15 +08:00
style={{ padding: 16, borderRadius: 6, background: '#fff', marginTop: 16 }}
pagination={false}
bordered={true}
2023-04-11 15:29:40 +08:00
rowKey={'user_id'}
loading={loading}
2023-04-07 17:38:15 +08:00
>
2023-04-14 17:31:45 +08:00
<Table.Column
title="姓名"
dataIndex={'name'}
render={(value, record: IStaffsItem) => {
return (
<div
onClick={() => {
setRecord(record);
setOpen(true);
}}
style={{ color: '#1890ff', cursor: 'pointer' }}
>
<span
style={{
display: 'inline-block',
marginRight: record.isleader == 1 ? 4 : 0,
}}
>
{value}
</span>
{record?.isleader == 1 ? (
<span
style={{
color: '#999',
fontSize: 12,
border: '1px solid #ddd',
borderRadius: 4,
padding: '2px 4px',
}}
>
</span>
) : null}
</div>
);
}}
2023-04-17 17:47:31 +08:00
/>
<Table.Column title="职务" width={160} dataIndex={'position'} />
2023-04-14 17:31:45 +08:00
<Table.Column
title="部门"
dataIndex={'dep_name'}
render={(val) => {
return <>{val.join('')}</>;
}}
2023-04-17 17:47:31 +08:00
/>
<Table.Column title="手机号" width={160} dataIndex={'mobile'} />
<Table.Column title="企业邮箱" dataIndex={'biz_mail'} />
2023-04-07 17:38:15 +08:00
</Table>
2023-04-14 17:31:45 +08:00
<Drawer title="成员详情" open={open} onClose={() => setOpen(false)} width={800}>
2023-04-17 17:47:31 +08:00
<DepartmentMembersDetail record={record as IStaffsItem} />
2023-04-14 17:31:45 +08:00
</Drawer>
2023-04-07 17:38:15 +08:00
<Pagination
style={{
background: '#fff',
borderRadius: 6,
marginTop: 16,
padding: 16,
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}
current={param.curr_page}
pageSize={param.page_count}
2023-04-11 15:29:40 +08:00
total={staffsData.count}
2023-04-07 17:38:15 +08:00
pageSizeOptions={[10, 20, 50, 100]}
onShowSizeChange={(current, size) => {
param.page_count = size;
2023-04-11 15:29:40 +08:00
// setParam({ ...param });
page(1);
2023-04-07 17:38:15 +08:00
}}
2023-04-17 17:47:31 +08:00
showTotal={(total) => {
2023-04-07 17:38:15 +08:00
return <span style={{ lineHeight: 1 }}>{total}</span>;
}}
2023-04-17 17:47:31 +08:00
onChange={(curr) => {
2023-04-11 15:29:40 +08:00
page(curr);
2023-04-07 17:38:15 +08:00
}}
/>
</div>
</div>
</PageContainer>
);
};
export default DepartmentsList;