|
|
import RequireAuth from '@/components/RequireAuth'
|
|
|
import { PERM_ROLE_NEW } from '@/config'
|
|
|
import useAccountStore, { fetchPermissionList, fetchPermissionListByRoleId, fetchRoleList } from '@/stores/Account'
|
|
|
import { isEmpty } from '@/utils/commons'
|
|
|
import {
|
|
|
SyncOutlined,
|
|
|
} from '@ant-design/icons'
|
|
|
import { App, Button, Col, Form, Input, Modal, Row, Space, Table, Tag, TreeSelect, Typography } from 'antd'
|
|
|
import dayjs from 'dayjs'
|
|
|
import { useEffect, useState } from 'react'
|
|
|
import { useTranslation } from 'react-i18next'
|
|
|
|
|
|
const { Title } = Typography
|
|
|
|
|
|
function RoleList() {
|
|
|
const { t } = useTranslation()
|
|
|
|
|
|
const roleListColumns = [
|
|
|
{
|
|
|
title: t('account:roleName'),
|
|
|
dataIndex: 'role_name',
|
|
|
},
|
|
|
{
|
|
|
title: t('account:createdOn'),
|
|
|
dataIndex: 'created_on',
|
|
|
render: (text) => (isEmpty(text) ? '' : dayjs(text).format('YYYY-MM-DD HH:mm:ss'))
|
|
|
},
|
|
|
{
|
|
|
title: t('account:action'),
|
|
|
dataIndex: 'account:action',
|
|
|
render: actionRender
|
|
|
},
|
|
|
]
|
|
|
|
|
|
function actionRender(_, role) {
|
|
|
if (role.role_id == 1) {
|
|
|
return (<Tag icon={<SyncOutlined spin />} color='warning'>不能修改</Tag>)
|
|
|
} else {
|
|
|
return (
|
|
|
<Button type='link' key='edit' onClick={() => onRoleSeleted(role)}>{t('account:action.edit')}</Button>
|
|
|
)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
const onPermissionChange = (newValue) => {
|
|
|
setPermissionValue(newValue)
|
|
|
}
|
|
|
|
|
|
function groupByParam(array, param) {
|
|
|
return array.reduce((result, item) => {
|
|
|
(result[item[param]] = result[item[param]] || []).push(item)
|
|
|
return result
|
|
|
}, {})
|
|
|
}
|
|
|
|
|
|
useEffect(() => {
|
|
|
setDataLoading(true)
|
|
|
fetchRoleList()
|
|
|
.then(r => {
|
|
|
setRoleAllList(r)
|
|
|
})
|
|
|
.finally(() => {
|
|
|
setDataLoading(false)
|
|
|
})
|
|
|
|
|
|
const categoryMap = new Map([
|
|
|
['system', '系统管理'],
|
|
|
['oversea', '海外供应商'],
|
|
|
['domestic', '国内供应商'],
|
|
|
['air-ticket', '机票供应商'],
|
|
|
['train-ticket', '火车票供应商'],
|
|
|
['products', '产品价格'],
|
|
|
['page', '默认页面'],
|
|
|
]);
|
|
|
|
|
|
const permissionTree = []
|
|
|
fetchPermissionList()
|
|
|
.then(r => {
|
|
|
|
|
|
const groupPermissionData = groupByParam(r, 'res_category')
|
|
|
const categoryKeys = Object.keys(groupPermissionData)
|
|
|
|
|
|
categoryKeys.forEach((categoryName) => {
|
|
|
const permissisonList = groupPermissionData[categoryName]
|
|
|
const categoryGroup = {
|
|
|
title: categoryMap.get(categoryName),
|
|
|
value: categoryName,
|
|
|
key: categoryName,
|
|
|
children: permissisonList.map(p => {
|
|
|
return {
|
|
|
disableCheckbox: p.res_id == 1,
|
|
|
title: p.res_name,
|
|
|
value: p.res_id,
|
|
|
key: p.res_id,
|
|
|
}
|
|
|
})
|
|
|
}
|
|
|
permissionTree.push(categoryGroup)
|
|
|
})
|
|
|
|
|
|
setPermissionTreeData(permissionTree)
|
|
|
})
|
|
|
}, [])
|
|
|
|
|
|
const [permissionValue, setPermissionValue] = useState([])
|
|
|
const [permissionTreeData, setPermissionTreeData] = useState([])
|
|
|
const [isRoleModalOpen, setRoleModalOpen] = useState(false)
|
|
|
const [dataLoading, setDataLoading] = useState(false)
|
|
|
const [roleAllList, setRoleAllList] = useState([])
|
|
|
|
|
|
const [roleForm] = Form.useForm()
|
|
|
const [saveOrUpdateRole, newEmptyRole] =
|
|
|
useAccountStore((state) =>
|
|
|
[state.saveOrUpdateRole, state.newEmptyRole])
|
|
|
|
|
|
const { notification } = App.useApp()
|
|
|
|
|
|
const onRoleSeleted = (role) => {
|
|
|
fetchPermissionListByRoleId({ role_id: role.role_id })
|
|
|
.then(result => {
|
|
|
role.res_array = result.map(r => r.res_id)
|
|
|
roleForm.setFieldsValue(role)
|
|
|
})
|
|
|
setRoleModalOpen(true)
|
|
|
}
|
|
|
|
|
|
const onNewRole = () => {
|
|
|
const role = newEmptyRole()
|
|
|
roleForm.setFieldsValue(role)
|
|
|
setRoleModalOpen(true)
|
|
|
}
|
|
|
|
|
|
const onRoleFinish = (values) => {
|
|
|
saveOrUpdateRole(values)
|
|
|
.then(() => {
|
|
|
setRoleModalOpen(false)
|
|
|
fetchRoleList()
|
|
|
.then(r => {
|
|
|
setRoleAllList(r)
|
|
|
})
|
|
|
})
|
|
|
.catch(ex => {
|
|
|
notification.error({
|
|
|
message: 'Notification',
|
|
|
description: ex.message,
|
|
|
placement: 'top',
|
|
|
duration: 4,
|
|
|
})
|
|
|
})
|
|
|
}
|
|
|
|
|
|
const onRoleFailed = (error) => {
|
|
|
console.log('Failed:', error)
|
|
|
// form.resetFields()
|
|
|
}
|
|
|
|
|
|
return (
|
|
|
<>
|
|
|
<Modal
|
|
|
centered
|
|
|
okButtonProps={{
|
|
|
autoFocus: true,
|
|
|
htmlType: 'submit',
|
|
|
}}
|
|
|
title={t('account:detail')}
|
|
|
open={isRoleModalOpen} onCancel={() => setRoleModalOpen(false)}
|
|
|
destroyOnClose
|
|
|
forceRender
|
|
|
modalRender={(dom) => (
|
|
|
<Form
|
|
|
name='RoleForm'
|
|
|
form={roleForm}
|
|
|
layout='vertical'
|
|
|
size='large'
|
|
|
className='max-w-xl'
|
|
|
onFinish={onRoleFinish}
|
|
|
onFinishFailed={onRoleFailed}
|
|
|
autoComplete='off'
|
|
|
>
|
|
|
{dom}
|
|
|
</Form>
|
|
|
)}
|
|
|
>
|
|
|
<Form.Item name='role_id' className='hidden' ><Input /></Form.Item>
|
|
|
<Form.Item
|
|
|
label={t('account:roleName')}
|
|
|
name='role_name'
|
|
|
rules={[
|
|
|
{
|
|
|
required: true,
|
|
|
message: t('account:Validation.roleName'),
|
|
|
},
|
|
|
]}
|
|
|
>
|
|
|
<Input />
|
|
|
</Form.Item>
|
|
|
<Form.Item
|
|
|
label={t('account:permission')}
|
|
|
name='res_array'
|
|
|
>
|
|
|
<TreeSelect treeData={permissionTreeData} value={permissionValue}
|
|
|
popupClassName='max-w-xl overflow-auto'
|
|
|
placement='bottomLeft'
|
|
|
showSearch
|
|
|
allowClear
|
|
|
multiple
|
|
|
treeDefaultExpandAll
|
|
|
treeLine={true}
|
|
|
onChange={onPermissionChange}
|
|
|
treeCheckable={true}
|
|
|
showCheckedStrategy={TreeSelect.SHOW_CHILD}
|
|
|
placeholder={'Please select'}
|
|
|
className='w-full' />
|
|
|
</Form.Item>
|
|
|
</Modal>
|
|
|
<Space direction='vertical' className='w-full'>
|
|
|
<Title level={3}>{t('account:roleList')}</Title>
|
|
|
<Row>
|
|
|
<Col span={24}>
|
|
|
<Space>
|
|
|
<RequireAuth subject={PERM_ROLE_NEW}>
|
|
|
<Button onClick={() => onNewRole()}>{t('account:newRole')}</Button>
|
|
|
</RequireAuth>
|
|
|
</Space>
|
|
|
</Col>
|
|
|
</Row>
|
|
|
<Row>
|
|
|
<Col span={24}>
|
|
|
<Table
|
|
|
bordered
|
|
|
loading={dataLoading}
|
|
|
rowKey='role_id'
|
|
|
pagination={{
|
|
|
pageSize: 20,
|
|
|
showQuickJumper: true,
|
|
|
showLessItems: true,
|
|
|
showSizeChanger: true,
|
|
|
showTotal: (total) => { return t('Total') + `:${total}` }
|
|
|
}}
|
|
|
columns={roleListColumns} dataSource={roleAllList}
|
|
|
/>
|
|
|
</Col>
|
|
|
</Row>
|
|
|
</Space>
|
|
|
</>
|
|
|
)
|
|
|
}
|
|
|
|
|
|
export default RoleList
|