import { TreeSelect as ATreeSelect } from 'antd'; import { useIntl } from 'umi'; import type { Field } from '@formily/core'; import { createForm, registerValidateRules } from '@formily/core'; import { createSchemaField } from '@formily/react'; import React, { useEffect, useState } from 'react'; import * as ICONS from '@ant-design/icons'; import { PlusOutlined } from '@ant-design/icons'; import { Form, FormGrid, FormItem, Input, Password, Select, Switch, TreeSelect, } from '@formily/antd'; import type { ISchema } from '@formily/json-schema'; import { action } from '@formily/reactive'; import type { Response } from '@/utils/typings'; import { service } from '@/pages/system/User'; import { Modal, PermissionButton } from '@/components'; import usePermissions from '@/hooks/permission'; import { onlyMessage } from '@/utils/util'; import { getMenuPathByCode } from '@/utils/menu'; interface Props { model: 'add' | 'edit' | 'query'; data: Partial; close: () => void; } const Save = (props: Props) => { const { model } = props; const intl = useIntl(); const { permission: deptPermission } = usePermissions('system/Department'); const { permission: rolePermission } = usePermissions('system/Role'); const [data, setData] = useState>(props.data); const getRole = () => service.queryRoleList(); const getOrg = () => service.queryOrgList({ paging: false }); const departmentPath = getMenuPathByCode('system/Department'); const rolePath = getMenuPathByCode('system/Role'); const useAsyncDataSource = (api: any) => (field: Field) => { field.loading = true; api(field).then( action.bound!((resp: Response) => { field.dataSource = resp.result?.map((item: Record) => ({ ...item, label: item.name, value: item.id, })); field.loading = false; }), ); }; registerValidateRules({ checkStrength(value: string) { if (!value || value.length < 8 || value.length > 64) return true; if (/^[0-9]+$/.test(value) || /^[a-zA-Z]+$/.test(value) || /^[~!@#$%^&*]+$/.test(value)) { return { type: 'error', message: '密码强度不够', }; } return true; }, }); const getUser = async () => { if (props.data.id) { const response: Response = await service.queryDetail(props.data?.id); if (response.status === 200) { const temp = response.result as UserItem; temp.orgIdList = (temp.orgList as { id: string; name: string }[]).map((item) => item.id); temp.roleIdList = (temp.roleList as { id: string; name: string }[]).map((item) => item.id); setData(temp); } } }; useEffect(() => { if (model === 'edit') { getUser(); } else { setData({}); } }, [props.data, props.model]); const form = createForm({ validateFirst: true, initialValues: data, }); const SchemaField = createSchemaField({ components: { FormItem, Input, Password, Switch, Select, TreeSelect, FormGrid, }, scope: { icon(name: any) { return React.createElement(ICONS[name]); }, }, }); const schema: ISchema = { type: 'object', properties: { layout: { type: 'void', 'x-decorator': 'FormGrid', 'x-decorator-props': { maxColumns: 2, minColumns: 2, columnGap: 24, }, properties: { name: { title: intl.formatMessage({ id: 'pages.system.name', defaultMessage: '姓名', }), type: 'string', 'x-decorator': 'FormItem', 'x-component': 'Input', 'x-decorator-props': { gridSpan: 1, }, 'x-component-props': { placeholder: '请输入姓名', }, name: 'name', 'x-validator': [ { max: 64, message: '最多可输入64个字符', }, { required: true, message: '请输入姓名', }, ], // required: true, }, username: { title: intl.formatMessage({ id: 'pages.system.username', defaultMessage: '用户名', }), 'x-decorator-props': { gridSpan: 1, }, type: 'string', 'x-decorator': 'FormItem', 'x-component': 'Input', 'x-component-props': { disabled: model === 'edit', placeholder: '请输入用户名', }, 'x-validator': [ { max: 64, message: '最多可输入64个字符', }, { required: true, message: '请输入用户名', }, { triggerType: 'onBlur', validator: (value: string) => { return new Promise((resolve) => { if (!value) resolve(''); service .validateField('username', value) .then((resp) => { if (resp.status === 200) { if (resp.result.passed) { resolve(''); } else { resolve(model === 'edit' ? '' : resp.result.reason); } } resolve(''); }) .catch(() => { return '验证失败!'; }); }); }, }, ], name: 'username', required: true, }, }, }, password: { type: 'string', title: intl.formatMessage({ id: 'pages.system.password', defaultMessage: '密码', }), 'x-decorator': 'FormItem', 'x-component': 'Password', 'x-component-props': { checkStrength: true, placeholder: '请输入密码', }, 'x-visible': model === 'add', // 'x-reactions': [ // { // dependencies: ['.confirmPassword'], // fulfill: { // state: { // selfErrors: // '{{$deps[0].length > 8 && $deps[0].length > 8 && $self.value && $self.value !==$deps[0] ? "两次密码输入不一致" : ""}}', // }, // }, // }, // ], name: 'password', 'x-validator': [ { max: 64, message: '密码最多可输入64位', }, { min: 8, message: '密码不能少于8位', }, { required: model === 'add', message: '请输入密码', }, { triggerType: 'onBlur', validator: (value: string) => { return new Promise((resolve) => { if (!value || value.length < 8 || value.length > 64) resolve(''); service .validateField('password', value) .then((resp) => { if (resp.status === 200) { if (resp.result.passed) { resolve(''); } else { resolve(model === 'edit' ? '' : resp.result.reason); } } resolve(''); }) .catch(() => { return '验证失败!'; }); }); }, }, // { // checkStrength: true, // }, ], }, confirmPassword: { type: 'string', title: intl.formatMessage({ id: 'pages.system.confirmPassword', defaultMessage: '确认密码?', }), 'x-decorator': 'FormItem', 'x-component': 'Password', 'x-component-props': { checkStrength: true, placeholder: '请再次输入密码', }, 'x-visible': model === 'add', 'x-validator': [ // { // max: 64, // message: '密码最多可输入64位', // }, // { // min: 8, // message: '密码不能少于8位', // }, { required: model === 'add', message: '请输入确认密码', }, // { // checkStrength: true, // }, ], 'x-reactions': [ { dependencies: ['.password'], fulfill: { state: { selfErrors: '{{$deps[0] && $self.value && $self.value !== $deps[0] ? "两次密码输入不一致" : ""}}', }, }, }, ], 'x-decorator-props': {}, name: 'confirmPassword', }, layout2: { type: 'void', 'x-decorator': 'FormGrid', 'x-decorator-props': { maxColumns: 2, minColumns: 2, columnGap: 24, }, properties: { roleIdList: { title: '角色', 'x-decorator': 'FormItem', 'x-component': 'Select', 'x-component-props': { mode: 'multiple', showArrow: true, placeholder: '请选择角色', filterOption: (input: string, option: any) => option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0, }, 'x-reactions': ['{{useAsyncDataSource(getRole)}}'], 'x-decorator-props': { gridSpan: 1, addonAfter: ( { const tab: any = window.open(`${origin}/#${rolePath}?save=true`); tab!.onTabSaveSuccess = (value: any) => { form.setFieldState('roleIdList', async (state) => { state.dataSource = await getRole().then((resp) => resp.result?.map((item: Record) => ({ ...item, label: item.name, value: item.id, })), ); state.value = [...(state.value || []), value.id]; }); }; }} > ), }, }, orgIdList: { title: '组织', 'x-decorator': 'FormItem', 'x-component': 'TreeSelect', 'x-component-props': { multiple: true, showArrow: true, placeholder: '请选择组织', showCheckedStrategy: ATreeSelect.SHOW_ALL, filterOption: (input: string, option: any) => option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0, fieldNames: { label: 'name', value: 'id', }, treeNodeFilterProp: 'name', }, 'x-decorator-props': { gridSpan: 1, addonAfter: ( { const tab: any = window.open(`${origin}/#${departmentPath}?save=true`); tab!.onTabSaveSuccess = (value: any) => { form.setFieldState('orgIdList', async (state) => { state.dataSource = await getOrg().then((resp) => resp.result?.map((item: Record) => ({ ...item, label: item.name, value: item.id, })), ); state.value = [...(state.value || []), value.id]; }); }; }} > ), }, 'x-reactions': ['{{useAsyncDataSource(getOrg)}}'], }, telephone: { title: '手机号', 'x-decorator': 'FormItem', 'x-component': 'Input', 'x-validator': [ { format: 'phone', message: '请输入正确的手机号', }, ], 'x-decorator-props': { gridSpan: 1, }, 'x-component-props': { placeholder: '请输入手机号', }, }, email: { title: '邮箱', 'x-decorator': 'FormItem', 'x-component': 'Input', 'x-validator': [ { format: 'email', message: '请输入正确的邮箱', }, ], 'x-decorator-props': { gridSpan: 1, }, 'x-component-props': { placeholder: '请输入邮箱', }, }, }, }, }, }; const save = async () => { const value = await form.submit(); const temp: any = {}; temp.id = value.id; temp.user = value; temp.user.roleList = []; temp.orgIdList = value.orgIdList; temp.roleIdList = value.roleIdList?.length ? value.roleIdList : null; const response = await service.saveUser(temp, model); if (response.status === 200) { onlyMessage( intl.formatMessage({ id: 'pages.data.option.success', defaultMessage: '操作成功', }), ); props.close(); } else { onlyMessage('操作失败!', 'error'); } }; return (
); }; export default Save;