import React , { useState , useEffect , forwardRef , useImperativeHandle , useMemo , } from 'react' ; import { useHistory } from 'react-router-dom' ; import { Form , Input , Button , message } from 'antd' ; import LinCheckbox from '@/components/base/lin-checkbox/LinCheckbox' ; import LoadingWrapper from '@/components/base/loading-wrapper/LoadingWrapper' ; import Admin from '@/lin/models/admin' ; import useFirstMountState from '@/hooks/base/useFirstMountState' ; import { MAX_SUCCESS_CODE } from '@/config/global' ; import { IGroupItem , IAllPermissions , IGroupItemWithPermissions , IPermissionItem , IResponseWithoutData , } from '@/types/model' ; import './style/group-info.scss' ; interface IProps { pageType : string ; data ? : IGroupItem ; } interface IPermissionModuleFormedIds { [ propName ] : number [ ] ; } const addLayout = { labelCol : { span : 3 } , wrapperCol : { span : 16 } } ; const infoLayout = { labelCol : { span : 4 } , wrapperCol : { span : 19 } } ; const permissionsLayout = { labelCol : { span : 24 } , wrapperCol : { span : 24 } } ; const buttonLayout = { wrapperCol : { offset : 3 } } ; function GroupInfo ( { pageType , data = { } as IGroupItem } , ref ) { const [ allPermissions , setAllPermissions ] = useState < IAllPermissions > ( { } ) ; const [ permission_module_name , setPermissionModuleName ] = useState < string [ ] > ( [ ] ) ; const [ permission_module_ids , setPermissionModuleIds ] = useState < IPermissionModuleFormedIds > ( { } ) ; const [ loading , setLoading ] = useState ( true ) ; const [ submitting , setSubmitting ] = useState ( false ) ; const [ form ] = Form . useForm ( ) ; const history = useHistory ( ) ; const isFirstMount = useFirstMountState ( ) ; const isAddPage = pageType === 'add' ; const isInfoPage = pageType === 'info' ; const isPermissionsPage = pageType === 'permissions' ; const { id } = data ; const formLayout = isAddPage ? addLayout : ( isPermissionsPage ? permissionsLayout : infoLayout ) ; let fieldNames , submitFunc ; if ( pageType === 'add' ) { fieldNames = isFirstMount ? [ ] : Object . keys ( form . getFieldsValue ( ) ) ; submitFunc = submitAdd ; } else if ( pageType === 'info' ) { fieldNames = [ 'name' , 'info' ] ; submitFunc = submitInfo ; } else if ( pageType === 'permissions' ) { fieldNames = Object . keys ( allPermissions ) ; submitFunc = submitPermissions ; } useEffect ( ( ) => { async function getGroupAuths ( ) { const allPermissions = await Admin . getAllPermissions ( ) ; setPermissionModuleName ( Object . keys ( allPermissions ) ) ; if ( id || id === 0 ) { const groupInfo = await Admin . getOneGroup ( id ) ; const formedIds = _getFormedPermissionIds ( groupInfo . permissions ) ; setPermissionModuleIds ( formedIds ) ; } setAllPermissions ( allPermissions ) ; setLoading ( false ) ; } function _getFormedPermissionIds ( permissions ) { const formedIds = { } as IPermissionModuleFormedIds ; permissions . forEach ( item => { if ( formedIds [ item . module ] ) { formedIds [ item . module ] . push ( item . id ) ; } else { formedIds [ item . module ] = [ item . id ] ; } } ) ; return formedIds ; } getGroupAuths ( ) ; } , [ ] ) ; useImperativeHandle ( ref , ( ) => ( { onSubmit , onReset } ) ) ; /**
     * 适用不同场景的重置方法
     */ function onReset ( ) { if ( fieldNames === null ) { form . resetFields ( ) ; } else { form . resetFields ( fieldNames ) ; } } param { * } submitType param { * } finalFunc async function onSubmit ( finalFunc ? ) { form . validateFields ( fieldNames ) . then ( async ( values ) => { console . log ( values ) ; setSubmitting ( true ) ; const success = await submitFunc ( values ) ; finalFunc && finalFunc ( success ) ; } ) . catch ( errorInfo => { const errMsg = isAddPage ? '请将信息填写完整' : '请填写正确的信息' ; message . error ( errMsg ) ; finalFunc && finalFunc ( false ) ; } ) ; } async function submitAdd ( fields ) { const { name , info , ... permissionsObj } = fields ; let res ; try { const permissions = _getPermissionsIds ( permissionsObj ) ; res = await Admin . createOneGroup ( name , info , permissions ) ; } catch ( e ) { console . log ( e ) ; setSubmitting ( false ) ; return false ; } const success = res ? res . code < MAX_SUCCESS_CODE : false ; if ( success ) { history . push ( '/admin/group/list' ) ; message . success ( `${ res . message }` ) ; } else { res && message . error ( `${ res . message }` ) ; } setSubmitting ( false ) ; return success ; } async function submitInfo ( fields ) { const { name , info } = fields ; if ( name === data . name && info === data . info ) { return true ; } const res = await Admin . updateOneGroup ( name , info , id ) ; const success = res . code < MAX_SUCCESS_CODE ; if ( success ) { message . success ( `${ res . message }` ) ; } return success ; } async function submitPermissions ( fields ) { const { name , info , ... permissionsObj } = fields ; const permissions = _getPermissionsIds ( permissionsObj ) ; const IOriginalAuths = _getPermissionsIds ( permission_module_ids ) ; const { addPermissions , deletePermissions } = _diffPermissions ( IOriginalAuths , permissions ) ; let addRes = { } as IResponseWithoutData , delRes = { } as IResponseWithoutData ; if ( addPermissions . length === 0 && deletePermissions . length === 0 ) { return true ; } if ( addPermissions . length > 0 ) { addRes = await Admin . dispatchPermissions ( id , addPermissions ) ; } if ( deletePermissions . length > 0 ) { delRes = await Admin . removePermissions ( id , deletePermissions ) ; } const success = addRes . code < MAX_SUCCESS_CODE || delRes . code < MAX_SUCCESS_CODE ; if ( success ) { message . success ( '权限修改成功' ) ; } return success ; } function _getPermissionsIds ( permissionsObj ) { const permissions = [ ] ; for ( const key in permissionsObj ) { if ( Array . isArray ( permissionsObj [ key ] ) ) { permissionsObj [ key ] . forEach ( item => { permissions . push ( item ) ; } ) ; } } return permissions ; } function _diffPermissions ( oldPermissions , newPermissions ) { const addPermissions = [ ] , deletePermissions = [ ] ; newPermissions . forEach ( item => { const hit = oldPermissions . some ( item2 => item === item2 ) ; if ( ! hit ) { addPermissions . push ( item ) ; } } ) ; oldPermissions . forEach ( item => { const hit = newPermissions . some ( item2 => item === item2 ) ; if ( ! hit ) { deletePermissions . push ( item ) ; } } ) ; return { addPermissions , deletePermissions } ; } const initialValues = useMemo ( ( ) => { const infoValues = isPermissionsPage ? { } : { name : isInfoPage ? data . name : null , info : isInfoPage ? data . info : null } ; const permissionsValues = { } ; ! isInfoPage && permission_module_name . forEach ( name => { permissionsValues [ name ] = isPermissionsPage ? permission_module_ids [ name ] || [ ] : [ ] ; } ) ; return Object . assign ( infoValues , permissionsValues ) ; } , [ permission_module_ids ] ) ; useEffect ( ( ) => { form . resetFields ( ) ; } , [ permission_module_ids ] ) ; return ( < div className = 'group-info-container' > < Form form = { form } initialValues = { initialValues } colon = { false } { ... formLayout } > < Form . Item name = 'name' label = '分组名称' validateTrigger = 'onBlur' rules = { [ { required : true , message : '分组名称不能为空' } ] } required r - if = { ! isPermissionsPage } > < Input /> < /Form.Item> < Form . Item name = 'info' label = '分组描述' r - if = { ! isPermissionsPage } > < Input /> < /Form.Item> < Form . Item label = { isAddPage ? '分配权限' : '' } r - if = { ! isInfoPage } > < LoadingWrapper loading = { loading } style = { { marginTop : 8 } } > { permission_module_name . map ( name => ( < Form . Item key = { name } shouldUpdate noStyle > { } { ( ) => ( < LinCheckbox name = { name } moduleName = { name } options = { allPermissions [ name ] } form = { form } itemValueKey = 'id' itemNameKey = 'name' checkAllClassName = 'checkbox-all' checkGroupClassName = 'checkbox-group' checkItemClassName = 'checkbox-item' / > ) } < /Form.Item>))} < /LoadingWrapper> < /Form.Item> < Form . Item r - if = { isAddPage } validateTrigger = 'onBlur' required { ... buttonLayout } > < Button type = 'primary' loading = { submitting } onClick = { ( ) => onSubmit ( ) } style = { { marginRight : 10 } } > 确 定 < /Button> < Button onClick = { onReset } > 重 置 < /Button> < /Form.Item> < /Form> < /div>); } export default forwardRef ( GroupInfo ) ;