import { Form, Input, Modal, Tree, Button, Spin, Row, Col, Select, Radio, Cascader, Card } from 'antd';
|
import { forwardRef, useImperativeHandle, useState } from 'react';
|
import { useEffect } from 'react';
|
import { DeleteOutlined } from '@ant-design/icons';
|
import '../index.less'
|
import { getDepartmentList, systemPostList, systemRoleList, getSystemUserInfo, getCityList, addSystemUserInfo, editSystemUserInfo, getCascaderData } from '../service';
|
import CryptoJS from 'crypto-js';
|
const formItemLayout = {
|
labelCol: { span: 8 },
|
wrapperCol: { span: 16 },
|
};
|
|
|
const AddAndEdit = ({ visible, onSave, onUpdate, onCancel }, ref) => {
|
const [form] = Form.useForm();
|
const [data, setData] = useState({})
|
const [spinning, setSpinning] = useState(false);
|
|
const [oneCompanyList, setOneCompanyList] = useState([])
|
|
const [twoCompanyList, setTwoCompanyList] = useState([])
|
const [threeCompanyList, setThreeCompanyList] = useState([])
|
const [fourCompanyList, setFourCompanyList] = useState([])
|
|
const [adminLevel, setAdminLevel] = useState(1)
|
|
//所属职位
|
const [positionList, setPositionList] = useState([])
|
//所属角色
|
const [roleList, setRoleList] = useState([])
|
//账号层级
|
const [levelList, setLevelList] = useState([])
|
|
//级联数据
|
const [cascaderData, setCascaderData] = useState([])
|
//选择的层级
|
const [activeLevel, setActiveLevel] = useState('')
|
//所属区县
|
const [countyList, setCountyList] = useState([])
|
const [activeCounty, setActiveCounty] = useState({})
|
//所属街道
|
const [streetList, setStreetList] = useState([])
|
const [activeStreet, setActiveStreet] = useState({})
|
//所属社区
|
const [activeCommunity, setActiveCommunity] = useState({})
|
|
const [accountLevels, setAccountLevels] = useState([
|
{ area: [], isDiscipline: 0, options: [] }
|
]);
|
|
useEffect(() => {
|
// 获取单位
|
|
}, [])
|
|
useImperativeHandle(ref, () => {
|
return {
|
refreshData: (data, companyList) => {
|
getCascaderDatas()
|
setOneCompanyList(() => companyList)
|
systemPostList({ pageNum: 1, pageSize: 10000 }).then(res => {
|
setPositionList(() => res.data.records)
|
})
|
systemRoleList({ pageNum: 1, pageSize: 10000 }).then(res => {
|
setRoleList(() => res.data.records)
|
})
|
|
if (data.id) {
|
getInfo(data.id)
|
}
|
setData(() => data)
|
if (data.unitId) {
|
let result = []
|
findParent(companyList, data.unitId * 1, result)
|
form.setFieldsValue({ DepartmentId: result })
|
}
|
},
|
clean: () => {
|
setSpinning(false)
|
},
|
};
|
});
|
|
// 保存
|
const okHandle = () => {
|
form.validateFields().then((values) => {
|
// 校验accountLevels必填
|
if (!accountLevels.length || accountLevels.some(item => !item.area || item.area.length === 0)) {
|
if (window?.antd?.message?.error) {
|
window.antd.message.error('请完整选择账号所属层级区域!');
|
} else {
|
alert('请完整选择账号所属层级区域!');
|
}
|
return;
|
}
|
// 打印提交时的accountLevels数组
|
console.log('提交时的accountLevels:', accountLevels);
|
// 组装 systemUserLevels,严格按照接口字段,优先用原始字段
|
const systemUserLevels = accountLevels.map(item => {
|
// Get the first selected option's id as the level
|
const firstSelectedOption = item.selectedOptions?.[0];
|
const level = firstSelectedOption?.id || item.level || '';
|
|
// 判断不同级别(假设市级别id为1,区县级别id为2,街道级别id为3,社区级别id为4)
|
const isCityLevel = level === '1';
|
const isDistrictLevel = level === '2';
|
const isStreetLevel = level === '3';
|
const isCommunityLevel = level === '4';
|
|
return {
|
// 市级别:所有下级字段为空
|
// 区县级别:街道和社区字段为空
|
// 街道级别:社区字段为空
|
// 社区级别:不做处理
|
community: (isCityLevel || isDistrictLevel || isStreetLevel) ? '' : (item.community || item.selectedOptions?.[3]?.name || ''),
|
communityId: (isCityLevel || isDistrictLevel || isStreetLevel) ? '' : (item.communityId || item.selectedOptions?.[3]?.id || ''),
|
districts: isCityLevel ? '' : (item.districts || item.selectedOptions?.[1]?.name || ''),
|
districtsCode: isCityLevel ? '' : (item.districtsCode || item.selectedOptions?.[1]?.id || ''),
|
id: item.id || '', // 编辑时可用
|
level: level, // Use the determined level value
|
status: 1,
|
street: (isCityLevel || isDistrictLevel) ? '' : (item.street || item.selectedOptions?.[2]?.name || ''),
|
streetId: (isCityLevel || isDistrictLevel) ? '' : (item.streetId || item.selectedOptions?.[2]?.id || ''),
|
superviseFlag: typeof item.isDiscipline === 'number' ? item.isDiscipline : (item.isDiscipline ? 1 : 0),
|
// systemUserId: 可选,如有需要补充
|
};
|
});
|
values.systemUserLevels = systemUserLevels;
|
if (values.password) {
|
values.password = CryptoJS.MD5(values.password).toString();
|
} else {
|
delete values.password
|
}
|
if (values.DepartmentId) {
|
values.oneDepartmentId = values.DepartmentId.length > 0 ? values.DepartmentId[0] : null
|
values.twoDepartmentId = values.DepartmentId.length > 1 ? values.DepartmentId[1] : null
|
values.threeDepartmentId = values.DepartmentId.length > 2 ? values.DepartmentId[2] : null
|
values.fourDepartmentId = values.DepartmentId.length > 3 ? values.DepartmentId[3] : null
|
}
|
if (data.id) {
|
values.id = data.id
|
onUpdate(values)
|
} else {
|
onSave(values);
|
setAccountLevels([{ area: [], isDiscipline: 0, options: [] }]); // 清空
|
}
|
});
|
};
|
|
// 获取级联数据
|
const getCascaderDatas = () => {
|
getCascaderData().then(res => {
|
// 处理级联数据
|
const processedData = res.data.map(item => {
|
// 根据第一级类型处理数据
|
if (item.children) {
|
// 区县级别
|
if (item.id == 2) { // 假设type=2表示区县
|
// 只保留第一级children
|
item.children = item.children.map(child => {
|
const { children, ...childWithoutChildren } = child;
|
return childWithoutChildren;
|
});
|
}
|
// 街道级别
|
else if (item.id == 3) { // 假设type=3表示街道
|
// 保留区县和街道两级
|
item.children = item.children.map(child => {
|
if (child.children) {
|
child.children = child.children.map(street => {
|
const { children, ...streetWithoutChildren } = street;
|
return streetWithoutChildren;
|
});
|
}
|
return child;
|
});
|
}
|
// 社区级别
|
else if (item.id == 4) { // 假设type=4表示社区
|
// 保留所有层级数据
|
return item;
|
}
|
}
|
return item;
|
});
|
|
let arr = JSON.parse(JSON.stringify(processedData))
|
let accountLevels = localStorage.getItem('userInfo')
|
let accountLevel = JSON.parse(accountLevels).accountLevel
|
if (accountLevel == 2) {
|
arr = arr.filter(item => item.id != 1)
|
} else if (accountLevel == 3) {
|
arr = arr.filter(item => item.id != 1 && item.id != 2)
|
} else if (accountLevel == 4) {
|
arr = arr.filter(item => item.id != 1 && item.id != 2 && item.id != 3)
|
}
|
setCascaderData(() => arr);
|
});
|
}
|
|
|
|
|
|
|
|
|
|
|
const getInfo = (id) => {
|
getSystemUserInfo(id).then(res => {
|
// delete res.data.password
|
|
let departmentId = []
|
if (res.data.oneDepartmentId) {
|
departmentId.push(res.data.oneDepartmentId)
|
}
|
if (res.data.twoDepartmentId) {
|
departmentId.push(res.data.twoDepartmentId)
|
}
|
if (res.data.threeDepartmentId) {
|
departmentId.push(res.data.threeDepartmentId)
|
}
|
if (res.data.fourDepartmentId) {
|
departmentId.push(res.data.fourDepartmentId)
|
}
|
res.data.DepartmentId = departmentId
|
setActiveLevel(() => res.data.accountLevel)
|
|
// 先获取级联数据再回显
|
getCascaderData().then(cascadeRes => {
|
// 处理级联数据
|
const processedData = cascadeRes.data.map(item => {
|
// 根据第一级类型处理数据
|
if (item.children) {
|
// 区县级别
|
if (item.id == 2) { // 假设type=2表示区县
|
// 只保留第一级children
|
item.children = item.children.map(child => {
|
const { children, ...childWithoutChildren } = child;
|
return childWithoutChildren;
|
});
|
}
|
// 街道级别
|
else if (item.id == 3) { // 假设type=3表示街道
|
// 保留区县和街道两级
|
item.children = item.children.map(child => {
|
if (child.children) {
|
child.children = child.children.map(street => {
|
const { children, ...streetWithoutChildren } = street;
|
return streetWithoutChildren;
|
});
|
}
|
return child;
|
});
|
}
|
// 社区级别
|
else if (item.id == 4) { // 假设type=4表示社区
|
// 保留所有层级数据
|
return item;
|
}
|
}
|
return item;
|
});
|
|
let arr = JSON.parse(JSON.stringify(processedData))
|
let accountLevels = localStorage.getItem('userInfo')
|
let accountLevel = JSON.parse(accountLevels).accountLevel
|
if (accountLevel == 2) {
|
arr = arr.filter(item => item.id != 1)
|
} else if (accountLevel == 3) {
|
arr = arr.filter(item => item.id != 1 && item.id != 2)
|
} else if (accountLevel == 4) {
|
arr = arr.filter(item => item.id != 1 && item.id != 2 && item.id != 3)
|
}
|
setCascaderData(() => arr);
|
|
// 回显accountLevels,area始终为4级,id类型统一
|
if (res.data.systemUserLevels && Array.isArray(res.data.systemUserLevels)) {
|
const newAccountLevels = res.data.systemUserLevels.map(level => {
|
const toId = v => (v === undefined || v === null) ? undefined : String(v);
|
const area = [
|
toId(level.level),
|
toId(level.twoLevelId || level.districtsCode),
|
toId(level.threeLevelId || level.streetId),
|
toId(level.fourLevelId || level.communityId)
|
].filter(v => v !== undefined && v !== null && v !== '');
|
return {
|
area,
|
isDiscipline: Number(level.superviseFlag) === 1 ? 1 : 0,
|
options: [],
|
selectedOptions: [
|
level.level ? { id: toId(level.level), name: '' } : undefined,
|
level.twoLevelName ? { id: toId(level.twoLevelId), name: level.twoLevelName } : undefined,
|
level.threeLevelName ? { id: toId(level.threeLevelId), name: level.threeLevelName } : undefined,
|
level.fourLevelName ? { id: toId(level.fourLevelId), name: level.fourLevelName } : undefined,
|
].filter(Boolean),
|
level: toId(level.level) || '',
|
community: level.community || '',
|
communityId: level.communityId || '',
|
districts: level.districts || '',
|
districtsCode: level.districtsCode || '',
|
id: level.id || '',
|
street: level.street || '',
|
streetId: level.streetId || '',
|
};
|
});
|
setAccountLevels(newAccountLevels.length ? newAccountLevels : [{ area: [], isDiscipline: 0, options: [], level: '', community: '', communityId: '', districts: '', districtsCode: '', id: '', street: '', streetId: '' }]);
|
}
|
});
|
|
form.setFieldsValue({ ...res.data, password: '' })
|
})
|
}
|
const findParent = (data, target, result) => {
|
for (let item of data) {
|
if (item.id === target) {
|
//将查找到的目标数据加入结果数组中
|
//可根据需求unshift(item.id)或unshift(item)
|
result.unshift(item.id)
|
return true
|
}
|
if (item.children && item.children.length > 0) {
|
//根据查找到的结果往上找父级节点
|
let isFind = findParent(item.children, target, result)
|
if (isFind) {
|
result.unshift(item.id)
|
return true
|
}
|
}
|
}
|
//走到这说明没找到目标
|
return false
|
}
|
|
// 动态添加账号层级项
|
const addAccountLevel = () => {
|
setAccountLevels([...accountLevels, { area: [], isDiscipline: 0, options: [] }]);
|
};
|
// 删除账号层级项
|
const removeAccountLevel = (idx) => {
|
if (accountLevels.length === 1) return;
|
setAccountLevels(accountLevels.filter((_, i) => i !== idx));
|
};
|
// 纪检委单选变更
|
const handleDisciplineChange = (e, idx) => {
|
setAccountLevels(levels => {
|
const newLevels = [...levels];
|
newLevels[idx].isDiscipline = e.target.value;
|
return newLevels;
|
});
|
};
|
|
return (
|
<Modal
|
getContainer={false}
|
width="75%"
|
destroyOnClose
|
title={data.type == 'detail' ? '人员详情' : data.type == 'edit' ? '编辑人员' : '添加人员'}
|
open={visible}
|
className='addAndEditModal'
|
onCancel={() => onCancel(false)}
|
afterClose={() => {
|
form.resetFields()
|
}}
|
footer={
|
(data.type == 'edit' || data.type == 'add') ?
|
[
|
<Button key="back" onClick={() => onCancel(false)}>取消</Button>,
|
<Button key="submit" type="primary" onClick={okHandle}>
|
确定
|
</Button>
|
]
|
:
|
<Button key="back" onClick={() => onCancel(false)}>关闭</Button>
|
}
|
>
|
<Form layout="horizontal" form={form} scrollToFirstError labelCol={{ span: 6 }} wrapperCol={{ span: 20 }}>
|
<Row gutter={16}>
|
<Col span={8}>
|
<Form.Item
|
name="name"
|
label="姓名"
|
rules={[{ required: true, message: '请输入人员姓名' }]}
|
>
|
<Input disabled={data.type == 'detail'} placeholder='请输入人员姓名' />
|
</Form.Item>
|
</Col>
|
<Col span={8}>
|
<Form.Item
|
name="systemPostId"
|
label="所属职位"
|
rules={[{ required: true, message: '请选择所属职位' }]}
|
>
|
<Select
|
allowClear
|
disabled={data.type == 'detail'}
|
placeholder="请选择"
|
options={positionList}
|
fieldNames={{ label: 'name', value: 'id' }}
|
filterOption={false}
|
/>
|
</Form.Item>
|
</Col>
|
<Col span={8}>
|
<Form.Item
|
name="systemRoleId"
|
label="后台权限"
|
rules={[{ required: true, message: '请选择后台权限' }]}
|
>
|
<Select
|
allowClear
|
disabled={data.type == 'detail'}
|
placeholder="请选择"
|
options={roleList}
|
fieldNames={{ label: 'name', value: 'id' }}
|
filterOption={false}
|
/>
|
</Form.Item>
|
</Col>
|
</Row>
|
<Row gutter={16}>
|
<Col span={24}>
|
<Form.Item
|
label="账号所属层级"
|
colon={true}
|
required
|
labelCol={{ span: 2 }}
|
wrapperCol={{ span: 12 }}
|
style={{ marginBottom: 0 }}
|
>
|
<Button type={'primary'} onClick={addAccountLevel} style={{ marginBottom: 8 }}>添加</Button>
|
{accountLevels.map((item, idx) => (
|
<Card key={idx} style={{ marginBottom: 8 }} size='small' >
|
<div style={{ display: 'flex', alignItems: 'center' }}>
|
<Cascader
|
style={{ width: 320, marginRight: 16 }}
|
placeholder="请选择区域"
|
options={cascaderData}
|
fieldNames={{ label: 'name', value: 'id' }}
|
value={item.area}
|
onChange={(value, selectedOptions) => {
|
setAccountLevels(levels => {
|
const newLevels = [...levels];
|
newLevels[idx] = {
|
...newLevels[idx],
|
area: value,
|
selectedOptions: selectedOptions,
|
// 清空原有数据,确保新选择的数据生效
|
community: '',
|
communityId: '',
|
districts: '',
|
districtsCode: '',
|
street: '',
|
streetId: '',
|
level: selectedOptions?.[0]?.id || ''
|
};
|
return newLevels;
|
});
|
}}
|
/>
|
|
<div style={{ marginLeft: 16, marginTop: 22 }}>
|
<span style={{ marginRight: 8 }}>是否为纪检委账号:</span>
|
<Radio.Group
|
style={{ marginRight: 16 }}
|
value={item.isDiscipline ?? 0}
|
onChange={e => handleDisciplineChange(e, idx)}
|
options={[
|
{ label: '否', value: 0 },
|
{ label: '是', value: 1 }
|
]}
|
/>
|
</div>
|
|
{idx > 0 && <DeleteOutlined style={{ marginRight: 16 }} onClick={() => removeAccountLevel(idx)} disabled={accountLevels.length === 1} />}
|
|
</div>
|
</Card>
|
))}
|
</Form.Item>
|
</Col>
|
</Row>
|
<Row gutter={16}>
|
<Col span={8}>
|
<Form.Item
|
label="联系方式"
|
name="phone"
|
extra={'联系方式将作为登录账号使用'}
|
rules={[{
|
validator: (rule, value) => {
|
return new Promise((resolve, reject) => {
|
if (!value) {
|
reject('请输入联系方式');
|
}
|
const phoneRegex = /^((\+86)?(13|14|15|16|17|18|19)[0-9]{9})|((\+86)?(0[0-9]{2,3})?([2-9][0-9]{6,7}))$/;
|
if (!phoneRegex.test(value)) {
|
reject('请输入正确的电话号码');
|
}
|
resolve('');
|
});
|
},
|
}]}
|
>
|
<Input disabled={data.type == 'detail'} placeholder='请输入联系方式' />
|
</Form.Item>
|
</Col>
|
</Row>
|
<Row gutter={16}>
|
<Col span={8}>
|
<Form.Item
|
required={data.type == 'add'}
|
name="password"
|
label="登录密码"
|
rules={[{
|
validator: (rule, value) => {
|
return new Promise((resolve, reject) => {
|
if (!value && data.type == 'add') {
|
reject('请输入新密码');
|
}
|
const passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/;
|
if (!passwordRegex.test(value) && data.type == 'add') {
|
reject('密码需要包含大小写字母,数字和特殊符号,且长度为8位以上');
|
}
|
resolve('');
|
});
|
},
|
}]}
|
>
|
<Input.Password disabled={data.type == 'detail'} placeholder='请输入' />
|
</Form.Item>
|
</Col>
|
</Row>
|
<Row gutter={16}>
|
<Col span={8}>
|
<Form.Item
|
label="确认密码"
|
name="surePassword"
|
extra={'密码需要包含大小写字母,数字和特殊符号,且长度为8位以上'}
|
required={data.type == 'add'}
|
rules={[{
|
validator: (rule, value) => {
|
return new Promise((resolve, reject) => {
|
if (!value && data.type == 'add') {
|
reject('请再次输入新密码');
|
}
|
if (value != form.getFieldValue('password') && data.type == 'add') {
|
reject('两次密码请保持一致');
|
}
|
resolve('');
|
});
|
},
|
}]}
|
>
|
<Input.Password disabled={data.type == 'detail'} placeholder='请输入' />
|
</Form.Item>
|
</Col>
|
</Row>
|
|
</Form>
|
<Spin spinning={spinning} fullscreen />
|
</Modal >
|
);
|
};
|
|
export default forwardRef(AddAndEdit);
|