You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
GHHub/src/views/account/RoleList.jsx

250 lines
7.0 KiB
JavaScript

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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