feat: 新增角色管理界面

perf/export-docx
Jimmy Liow 1 year ago
parent 2cb059cc06
commit 32b097c5b7

Binary file not shown.

@ -18,6 +18,7 @@ import ReservationDetail from "@/views/reservation/Detail";
import ChangePassword from "@/views/account/ChangePassword";
import AccountProfile from "@/views/account/Profile";
import AccountManagement from "@/views/account/Management";
import RoleList from "@/views/account/RoleList";
import FeedbackIndex from "@/views/feedback/Index";
import FeedbackDetail from "@/views/feedback/Detail";
import FeedbackCustomerDetail from "@/views/feedback/CustomerDetail";
@ -32,7 +33,7 @@ import Airticket from "@/views/airticket/Index";
import AirticketPlan from "@/views/airticket/Plan";
import { ThemeContext } from '@/stores/ThemeContext'
import { PERM_ACCOUNT_MANAGEMENT, PERM_OVERSEA, PERM_AIR_TICKET } from '@/config'
import { PERM_ACCOUNT_MANAGEMENT, PERM_ROLE_NEW, PERM_OVERSEA, PERM_AIR_TICKET } from '@/config'
import './i18n';
@ -55,6 +56,7 @@ const router = createBrowserRouter([
{ path: "account/change-password", element: <ChangePassword />},
{ path: "account/profile", element: <AccountProfile />},
{ path: "account/management", element: <RequireAuth subject={PERM_ACCOUNT_MANAGEMENT} result={true}><AccountManagement /></RequireAuth>},
{ path: "account/role-list", element: <RequireAuth subject={PERM_ROLE_NEW} result={true}><RoleList /></RequireAuth>},
{ path: "reservation/newest", element: <RequireAuth subject={PERM_OVERSEA} result={true}><ReservationNewest /></RequireAuth>},
{ path: "reservation/:reservationId", element: <RequireAuth subject={PERM_OVERSEA} result={true}><ReservationDetail /></RequireAuth>},
{ path: "feedback", element: <RequireAuth subject={PERM_OVERSEA} result={true}><FeedbackIndex /></RequireAuth>},

@ -24,6 +24,13 @@ export const postAccountForm = async (formData) => {
return errcode !== 0 ? {} : result
}
export const postRoleForm = async (formData) => {
const { errcode, result } = await postForm(
`${HT_HOST}/service-CooperateSOA/new_or_update_role`, formData)
return errcode !== 0 ? {} : result
}
export const fetchRoleList = async () => {
const { errcode, result } = await fetchJSON(
@ -54,6 +61,15 @@ const useAccountStore = create((set, get) => ({
console.info(result)
},
saveOrUpdateRole: async (formValues) => {
const formData = new FormData()
formData.append('role_id', formValues.role_id)
formData.append('role_name', formValues.role_name)
formData.append('res_ids', '2,3')
return postRoleForm(formData)
},
saveOrUpdateAccount: async (formValues) => {
const { selectedAccount } = get()
const { userId } = usingStorage()

@ -149,8 +149,9 @@ function App() {
{ label: <Link to='/account/change-password'>{t('ChangePassword')}</Link>, key: '0' },
{ label: <Link to='/account/profile'>{t('Profile')}</Link>, key: '1' },
{ label: <Link to='/account/management'>{t('account:management.tile')}</Link>, key: '3' },
{ label: <Link to='/account/role-list'>{t('account:management.roleList')}</Link>, key: '4' },
{ type: 'divider' },
{ label: <Link to='/logout'>{t('Logout')}</Link>, key: '4' },
{ label: <Link to='/logout'>{t('Logout')}</Link>, key: '99' },
],
{ type: 'divider' },
{ label: <>v{BUILD_VERSION}</>, key: 'BUILD_VERSION' },

@ -161,48 +161,32 @@ function Management() {
setPermissionValue(newValue)
}
const onAccountSeleted = async (account) => {
selectAccount(account)
console.info(account)
const roleList = await fetchRoleList()
setRoleAllList(roleList.map(r => {
return {
value: r.role_id,
label: r.role_name,
disabled: r.role_id === 1
}
}))
setAccountModalOpen(true)
}
const [permissionValue, setPermissionValue] = useState(['0-0-0'])
const [isAccountModalOpen, setAccountModalOpen] = useState(false)
const [isRoleModalOpen, setRoleModalOpen] = useState(false)
const [dataLoading, setDataLoading] = useState(false)
const [roleAllList, setRoleAllList] = useState([])
const [editAccountForm, editRoleForm] = Form.useForm()
const [accountForm] = Form.useForm()
const [searchAccountByCriteria, accountList, disableAccount, selectedAccount, saveOrUpdateAccount, selectAccount] =
useAccountStore((state) =>
[state.searchAccountByCriteria, state.accountList, state.disableAccount, state.selectedAccount, state.saveOrUpdateAccount, state.selectAccount])
const { notification, modal } = App.useApp()
const handleAccountOk = () => {
console.info('handleAccountOk')
console.info(editAccountForm)
}
const handleAccountCancel = () => {
setAccountModalOpen(false)
}
const handleRoleOk = () => {
console.info('handleRoleOk')
}
const handleRoleCancel = () => {
setRoleModalOpen(false)
const onAccountSeleted = async (account) => {
accountForm.setFieldsValue(account)
selectAccount(account)
console.info(account)
const roleList = await fetchRoleList()
setRoleAllList(roleList.map(r => {
return {
value: r.role_id,
label: r.role_name,
disabled: r.role_id === 1
}
}))
setAccountModalOpen(true)
}
const onAccountFinish = (values) => {
@ -219,7 +203,7 @@ function Management() {
})
}
const onAccountFinishFailed = (error) => {
const onAccountFailed = (error) => {
console.log('Failed:', error)
// form.resetFields()
}
@ -259,20 +243,20 @@ function Management() {
htmlType: 'submit',
}}
title={t('account:management.newAccount')}
open={isAccountModalOpen} onOk={handleAccountOk} onCancel={handleAccountCancel}
destroyOnClose
open={isAccountModalOpen} onOk={() => setAccountModalOpen(false)} onCancel={() => setAccountModalOpen(false)}
destroyOnClose={true}
clearOnDestroy={true}
modalRender={(dom) => (
<Form
name='AccountForm'
form={editAccountForm}
initialValues={selectedAccount}
form={accountForm}
layout='vertical'
size='large'
style={{
maxWidth: 600,
}}
onFinish={onAccountFinish}
onFinishFailed={onAccountFinishFailed}
onFinishFailed={onAccountFailed}
autoComplete='off'
>
{dom}
@ -341,58 +325,6 @@ function Management() {
</Select>
</Form.Item>
</Modal>
{/* Role Edit */}
<Modal
centered
open={isRoleModalOpen} onOk={handleRoleOk} onCancel={handleRoleCancel}
>
<Form
name='RoleForm'
form={editRoleForm}
layout='vertical'
size='large'
style={{
maxWidth: 800,
}}
onFinish={onAccountFinish}
onFinishFailed={onAccountFinishFailed}
autoComplete='off'
>
<Form.Item><Title level={2}>{t('account:management.newRole')}</Title></Form.Item>
<Form.Item
label={t('account:management.roleName')}
name='roleName'
rules={[
{
required: true,
message: t('account:Validation.roleName'),
},
]}
>
<Input />
</Form.Item>
<Form.Item label={t('account:management.permission')}>
<TreeSelect treeData={permissionData} value={permissionValue}
dropdownStyle={{
maxHeight: 600,
overflow: 'auto',
}}
placement='bottomLeft'
showSearch
allowClear
multiple
treeDefaultExpandAll
treeLine={true}
onChange={onPermissionChange}
treeCheckable={true}
showCheckedStrategy={TreeSelect.SHOW_CHILD}
placeholder={'Please select'}
style={{
width: '100%',
}} />
</Form.Item>
</Form>
</Modal>
<Space direction='vertical' style={{ width: '100%' }}>
<Title level={3}>{t('account:management.tile')}</Title>
<SearchForm
@ -423,9 +355,6 @@ function Management() {
<Col span={24}>
<Space>
<Button onClick={() => setAccountModalOpen(true)}>{t('account:management.newAccount')}</Button>
<RequireAuth subject={PERM_ROLE_NEW}>
<Button onClick={() => setRoleModalOpen(true)}>{t('account:management.newRole')}</Button>
</RequireAuth>
</Space>
</Col>
</Row>

@ -0,0 +1,286 @@
import { useState, useEffect } from 'react'
import { Row, Col, Space, Button, Table, Select, TreeSelect, Typography, Modal, App, Form, Input } from 'antd'
import { ExclamationCircleFilled } from '@ant-design/icons'
import { useTranslation } from 'react-i18next'
import useFormStore from '@/stores/Form'
import useAuthStore from '@/stores/Auth'
import useAccountStore from '@/stores/Account'
import { fetchRoleList } from '@/stores/Account'
import SearchForm from '@/components/SearchForm'
import RequireAuth from '@/components/RequireAuth'
import { PERM_ROLE_NEW } from '@/config'
const { Title } = Typography
const permissionData = [
{
title: '海外供应商',
value: 'oversea-0',
key: 'oversea-0',
children: [
{
title: '所有海外功能',
value: 'oversea-0-0',
key: 'oversea-0-0',
},
],
},
{
title: '机票管理',
value: '0-0',
key: '0-0',
children: [
{
title: '录入机票价格',
value: '0-0-0',
key: '0-0-0',
},
],
},
{
title: '产品管理',
value: '0-1',
key: '0-1',
children: [
{
title: '搜索供应商产品',
value: 'B-1-0',
key: 'B-1-0',
},
{
title: '录入产品价格',
value: '0-1-0',
key: '0-1-0',
},
{
title: '新增产品描述',
value: '0-1-1',
key: '0-1-1',
},
{
title: '复制供应商产品信息',
value: '0-1-2',
key: '0-1-2',
},
],
},
{
title: '账号管理',
value: '2-1',
key: '2-1',
children: [
{
title: '搜索账号',
value: '2-1-01',
key: '2-1-01',
},
{
title: '新增账号',
value: '2-1-11',
key: '2-1-11',
},
{
title: '禁用账号',
value: '2-1-21',
key: '2-1-21',
},
{
title: '重置账号密码',
value: '2-1-31',
key: '2-1-31',
},
{
title: '新增角色',
value: '2-1-41',
key: '2-1-41',
},
],
},
]
function RoleList() {
const { t } = useTranslation()
const roleListColumns = [
{
title: t('account:rolename'),
dataIndex: 'role_name',
render: roleRender
},
{
title: t('account:createdOn'),
dataIndex: 'created_on',
},
{
title: t('account:action'),
dataIndex: 'account:action',
render: actionRender
},
]
function roleRender(text, role) {
return (
<Button type='link' onClick={() => onRoleSeleted(role)}>{text}</Button>
)
}
function actionRender(text, account) {
return (
<Space key='actionRenderSpace' size='middle'>
<Button type='link' key='disable' onClick={() => showDisableConfirm(account)}>{t('account:action.disable')}</Button>
<Button type='link' key='resetPassword' onClick={() => showResetPasswordConfirm(account)}>{t('account:action.resetPassword')}</Button>
</Space>
)
}
const onPermissionChange = (newValue) => {
console.log('onChange ', newValue)
setPermissionValue(newValue)
}
useEffect (() => {
fetchRoleList()
.then(r => {
setRoleAllList(r)
})
}, [])
const [permissionValue, setPermissionValue] = useState(['0-0-0'])
const [isRoleModalOpen, setRoleModalOpen] = useState(false)
const [dataLoading, setDataLoading] = useState(false)
const [roleAllList, setRoleAllList] = useState([])
const [roleForm] = Form.useForm()
const [saveOrUpdateRole] =
useAccountStore((state) =>
[state.saveOrUpdateRole])
const { notification, modal } = App.useApp()
const onRoleSeleted = async (role) => {
roleForm.setFieldsValue(role)
// selectAccount(account)
// console.info(account)
setRoleModalOpen(true)
}
const onRoleFinish = (values) => {
console.log(values)
saveOrUpdateRole(values)
.catch(ex => {
console.info(ex.message)
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:management.newRole')}
open={isRoleModalOpen} onOk={() => setRoleModalOpen(false)} onCancel={() => setRoleModalOpen(false)}
destroyOnClose={true}
clearOnDestroy={true}
modalRender={(dom) => (
<Form
name='RoleForm'
form={roleForm}
layout='vertical'
size='large'
style={{
maxWidth: 600,
}}
onFinish={onRoleFinish}
onFinishFailed={onRoleFailed}
autoComplete='off'
>
{dom}
</Form>
)}
>
<Form.Item
name='role_id'
>
<Input styles={{display: 'none'}} />
</Form.Item>
<Form.Item
label={t('account:management.roleName')}
name='role_name'
rules={[
{
required: true,
message: t('account:Validation.roleName'),
},
]}
>
<Input />
</Form.Item>
<Form.Item label={t('account:management.permission')}>
<TreeSelect treeData={permissionData} value={permissionValue}
dropdownStyle={{
maxHeight: 600,
overflow: 'auto',
}}
placement='bottomLeft'
showSearch
allowClear
multiple
treeDefaultExpandAll
treeLine={true}
onChange={onPermissionChange}
treeCheckable={true}
showCheckedStrategy={TreeSelect.SHOW_CHILD}
placeholder={'Please select'}
style={{
width: '100%',
}} />
</Form.Item>
</Modal>
<Space direction='vertical' style={{ width: '100%' }}>
<Title level={3}>{t('account:management.roleList')}</Title>
<Row>
<Col span={24}>
<Space>
<RequireAuth subject={PERM_ROLE_NEW}>
<Button onClick={() => setRoleModalOpen(true)}>{t('account:management.newRole')}</Button>
</RequireAuth>
</Space>
</Col>
</Row>
<Row>
<Col span={24}>
<Table
bordered
loading={dataLoading}
rowKey='role_id'
pagination={{
showQuickJumper: true,
showLessItems: true,
showSizeChanger: true,
showTotal: (total) => { return t('Total') + `${total}` }
}}
onChange={(pagination) => { onSearchClick(pagination.current) }}
columns={roleListColumns} dataSource={roleAllList}
/>
</Col>
</Row>
</Space>
</>
)
}
export default RoleList
Loading…
Cancel
Save