fixed: update user role change

This commit is contained in:
LittleBoy 2024-09-10 11:43:25 +08:00
parent 6eeed9b451
commit c67bcc5d07
5 changed files with 70 additions and 48 deletions

View File

@ -52,6 +52,16 @@ export const AuthProvider = ({children}: { children: React.ReactNode }) => {
const [state, dispatch] = useReducer(authReducer, initialState); const [state, dispatch] = useReducer(authReducer, initialState);
// MOCK INIT DATA // MOCK INIT DATA
const refreshUserInfo = async ()=>{
const user = await getUserInfo();
dispatch({
action: 'refresh',
payload: {
isLoggedIn: !!user,
user: getInitUserData(user)
}
})
}
const init = async () => { const init = async () => {
const token = getAuthToken(); const token = getAuthToken();
if (!token) { if (!token) {
@ -141,7 +151,8 @@ export const AuthProvider = ({children}: { children: React.ReactNode }) => {
return (<AuthContext.Provider value={{ return (<AuthContext.Provider value={{
...state, ...state,
login, logout, login, logout,
mockLogin, updateUser mockLogin, updateUser,
refreshUserInfo
}}>{children}</AuthContext.Provider>) }}>{children}</AuthContext.Provider>)
} }
export default AuthContext export default AuthContext

View File

@ -1,5 +1,5 @@
import {useSetState} from "ahooks"; import {useSetState} from "ahooks";
import {Button, Checkbox, Empty, Popconfirm, Select, Space, Toast} from "@douyinfe/semi-ui"; import {Button, Checkbox, Empty, Popconfirm, Select, Space, Spin, Toast} from "@douyinfe/semi-ui";
import {useTranslation} from "react-i18next"; import {useTranslation} from "react-i18next";
import {useEffect, useMemo} from "react"; import {useEffect, useMemo} from "react";
@ -25,6 +25,12 @@ import useAuth from "@/hooks/useAuth.ts";
// 'permission' // 'permission'
// ] // ]
const RoleOptionList = [
{label: 'ROOT', value: 'root'},
{label: 'RO', value: 'ro'},
{label: 'FO', value: 'fo'},
];
type UserPermissionItemProps = { type UserPermissionItemProps = {
it: UserPermission; it: UserPermission;
onChange: (action: 'remove' | 'saved' | 'modify', value: UserPermission) => Promise<void>; onChange: (action: 'remove' | 'saved' | 'modify', value: UserPermission) => Promise<void>;
@ -34,13 +40,15 @@ type UserPermissionItemProps = {
const UserPermissionItem = ({it, onChange, usernameOptionList,roleOptionList}: UserPermissionItemProps) => { const UserPermissionItem = ({it, onChange, usernameOptionList,roleOptionList}: UserPermissionItemProps) => {
const {t} = useTranslation() const {t} = useTranslation()
const {user} = useAuth() const {user,refreshUserInfo} = useAuth()
const [state,setState] = useSetState({ const [state,setState] = useSetState({
loading: false loading: false,
currentRole: it.role
}) })
const onValueChange = (value: { const onValueChange = (value: {
[key: string]: string | boolean [key: string]: string | boolean
}) => { }) => {
onChange('modify', { onChange('modify', {
...it, ...it,
...value ...value
@ -63,8 +71,11 @@ const UserPermissionItem = ({it, onChange, usernameOptionList,roleOptionList}: U
return; return;
} }
setState({loading: true}) setState({loading: true})
onChange('saved', it).finally(()=>{ onChange('saved', it).then(()=>{
if(self) refreshUserInfo().then(()=>console.log('self refresh'));
}).finally(()=>{
setState({loading: false}) setState({loading: false})
}) })
} }
@ -77,7 +88,7 @@ const UserPermissionItem = ({it, onChange, usernameOptionList,roleOptionList}: U
filter filter
optionList={usernameOptionList} optionList={usernameOptionList}
placeholder={t('base.please_select')} placeholder={t('base.please_select')}
defaultValue={it.username} value={it.username}
onChange={(value) => onValueChange({username: String(value)})} onChange={(value) => onValueChange({username: String(value)})}
/>} />}
</div> </div>
@ -87,7 +98,7 @@ const UserPermissionItem = ({it, onChange, usernameOptionList,roleOptionList}: U
<Select <Select
style={{width: '100%'}} style={{width: '100%'}}
optionList={roleOptionList} optionList={roleOptionList}
defaultValue={it.role} value={it.role}
onChange={(value) => onValueChange({role: String(value)})} onChange={(value) => onValueChange({role: String(value)})}
placeholder={t('base.please_select')} placeholder={t('base.please_select')}
/> />
@ -95,37 +106,37 @@ const UserPermissionItem = ({it, onChange, usernameOptionList,roleOptionList}: U
</div> </div>
<div className={`item item-type item-type-manual`}> <div className={`item item-type item-type-manual`}>
<Checkbox <Checkbox
defaultChecked={it.manual_payment} checked={it.manual_payment}
onChange={e => onValueChange({manual_payment: !!e.target.checked})}/> onChange={e => onValueChange({manual_payment: !!e.target.checked})}/>
</div> </div>
<div className={`item item-type item-type-bill-query`}> <div className={`item item-type item-type-bill-query`}>
<Checkbox <Checkbox
defaultChecked={it.bill_page} checked={it.bill_page}
onChange={e => onValueChange({bill_page: !!e.target.checked})}/> onChange={e => onValueChange({bill_page: !!e.target.checked})}/>
</div> </div>
<div className={`item item-type item-type-bill-check`}> <div className={`item item-type item-type-bill-check`}>
<Checkbox <Checkbox
defaultChecked={it.apply_page} checked={it.apply_page}
onChange={e => onValueChange({apply_page: !!e.target.checked})}/> onChange={e => onValueChange({apply_page: !!e.target.checked})}/>
</div> </div>
<div className={`item item-type item-type-bill-pay`}> <div className={`item item-type item-type-bill-pay`}>
<Checkbox <Checkbox
defaultChecked={it.complete_button} checked={it.complete_button}
onChange={e => onValueChange({complete_button: !!e.target.checked})}/> onChange={e => onValueChange({complete_button: !!e.target.checked})}/>
</div> </div>
<div className={`item item-type item-type-bill-btn-confirm`}> <div className={`item item-type item-type-bill-btn-confirm`}>
<Checkbox <Checkbox
defaultChecked={it.confirm_button} checked={it.confirm_button}
onChange={e => onValueChange({confirm_button: !!e.target.checked})}/> onChange={e => onValueChange({confirm_button: !!e.target.checked})}/>
</div> </div>
<div className={`item item-type item-type-bill-btn-check`}> <div className={`item item-type item-type-bill-btn-check`}>
<Checkbox <Checkbox
defaultChecked={it.apply_button} checked={it.apply_button}
onChange={e => onValueChange({apply_button: !!e.target.checked})}/> onChange={e => onValueChange({apply_button: !!e.target.checked})}/>
</div> </div>
{user?.permissions?.role == 'root' && <div className={`item item-type item-type-bill-permission`}> {user?.permissions?.role == 'root' && <div className={`item item-type item-type-bill-permission`}>
<Checkbox <Checkbox
defaultChecked={it.permission_edit} checked={it.permission_edit}
disabled={user?.username == it.username} disabled={user?.username == it.username}
onChange={e => onValueChange({permission_edit: !!e.target.checked})}/> onChange={e => onValueChange({permission_edit: !!e.target.checked})}/>
</div>} </div>}
@ -161,15 +172,10 @@ const Permission = () => {
const usernameOptionList = useMemo(() => (usernameList?usernameList.map(name => ({label: name, value: name})):[]), [usernameList]) const usernameOptionList = useMemo(() => (usernameList?usernameList.map(name => ({label: name, value: name})):[]), [usernameList])
const roleOptionList = useMemo(() => { const roleOptionList = useMemo(() => {
const list = [
{label: 'ROOT', value: 'root'},
{label: 'RO', value: 'ro'},
{label: 'FO', value: 'fo'},
];
const userRole = user?.permissions?.role ?? 'staff'; const userRole = user?.permissions?.role ?? 'staff';
if(userRole == 'root') return list; if(userRole == 'root') return RoleOptionList;
return list.filter(it => (it.value == userRole)); return RoleOptionList//.filter(it => (it.value == userRole));
}, []) }, [user,state.allList])
const buildPermission = (it: UserPermission)=>{ const buildPermission = (it: UserPermission)=>{
it.permission_edit = !!it.permission_edit it.permission_edit = !!it.permission_edit
@ -187,15 +193,15 @@ const Permission = () => {
setState({loading: true}) setState({loading: true})
getUserPermissionList().then(list => { getUserPermissionList().then(list => {
setState({allList:[...list]}) setState({allList:[...list]})
const userRole = user?.permissions?.role ?? 'staff'; const userRole = (user?.permissions?.role ?? 'staff').toLowerCase();
list.forEach(it=>buildPermission(it)) list.forEach(it=>buildPermission(it))
if(userRole != 'root') { if(userRole != 'root') {
list = list.filter(it => (it.role == userRole)); list = list.filter(it => (it.role.toLowerCase() == userRole));
} }
setState({loading: false, list}) setState({loading: false, list})
}) })
} }
useEffect(loadUserPermissionList, []) useEffect(loadUserPermissionList, [user])
// remove a user permission // remove a user permission
const removeItem = (index: number, id: number) => { const removeItem = (index: number, id: number) => {
@ -244,17 +250,19 @@ const Permission = () => {
} }
const process = value.id > 0 ? updateUserPermission : createUserPermission; const process = value.id > 0 ? updateUserPermission : createUserPermission;
try { try {
await process(value).then((newValue) => { await process(value).then(() => {
Toast.success(t('base.save_success')) Toast.success(t('base.save_success'))
const newList = [...state.list]; //loadUserPermissionList();
buildPermission(newValue) // const newList = [...state.list];
newList[index] = { // buildPermission(newValue)
...newValue // newList[index] = {
} // ...newValue
setState({list: newList}) // }
// setState({list: newList})
}) })
} catch (e) { } catch (e) {
Toast.error(t('base.save_failed') + `(${(e as Error).message})`) Toast.error(t('base.save_failed') + `(${(e as Error).message})`)
throw e;
} }
} }
} }
@ -277,20 +285,22 @@ const Permission = () => {
{user?.permissions?.role == 'root' && <div className={`item item-type item-type-bill-permission`}>{t(`permission.title.permission`)}</div>} {user?.permissions?.role == 'root' && <div className={`item item-type item-type-bill-permission`}>{t(`permission.title.permission`)}</div>}
<div className="item item-operation">{t('bill.title_operate')}</div> <div className="item item-operation">{t('bill.title_operate')}</div>
</div> </div>
{state.list.map((it, index) => (<UserPermissionItem <Spin spinning={state.loading}>
key={index} it={it} {state.list.map((it, index) => (<UserPermissionItem
onChange={async (action, value) => { key={index} it={it}
await handleChange(action, value, index) onChange={async (action, value) => {
}} await handleChange(action, value, index)
usernameOptionList={usernameOptionList} }}
roleOptionList={roleOptionList} usernameOptionList={usernameOptionList}
/>))} roleOptionList={roleOptionList}
{state.list.length == 0 && <div style={{backgroundColor: '#fafafa'}}> />))}
<Empty {state.list.length == 0 && <div style={{backgroundColor: '#fafafa'}}>
description={t('permission.message.empty_tips')} <Empty
style={{paddingBottom: 20}} description={t('permission.message.empty_tips')}
/> style={{paddingBottom: 20}}
</div>} />
</div>}
</Spin>
</div> </div>
</div> </div>
{!state.loading && <Space style={{marginTop: 20}}> {!state.loading && <Space style={{marginTop: 20}}>

View File

@ -107,7 +107,6 @@ const BillQuery = () => {
<Button <Button
onClick={() => setShowBill(bill)} size={'small'} theme={'solid'} onClick={() => setShowBill(bill)} size={'small'} theme={'solid'}
type={'primary'}>{t('base.qr-code')}</Button> type={'primary'}>{t('base.qr-code')}</Button>
{AppMode == 'development' && <a href={`/pay?bill=${bill.id}`} target={'_blank'}></a>}
</>} </>}
{ {
bill.status == BillStatus.PAID && <> bill.status == BillStatus.PAID && <>

View File

@ -74,7 +74,8 @@ const RoleSwitcher = ()=>{
<Button theme="borderless"> <Button theme="borderless">
<Space style={{transform:'translateY(3px)'}}> <Space style={{transform:'translateY(3px)'}}>
<IconRoles size={20} color={'white'} /> <IconRoles size={20} color={'white'} />
<span style={{color:'white'}}>{user?.role?.toUpperCase()}</span> {/*{JSON.stringify(user)}*/}
<span style={{color:'white'}}>{user?.permissions?.role.toUpperCase()}</span>
</Space> </Space>
</Button> </Button>
</>) </>)

1
src/types/auth.d.ts vendored
View File

@ -44,6 +44,7 @@ declare type AuthContextType = {
user?: UserProfile | null | undefined; user?: UserProfile | null | undefined;
logout: () => Promise<void>; logout: () => Promise<void>;
mockLogin: () => Promise<void>; mockLogin: () => Promise<void>;
refreshUserInfo: () => Promise<void>;
login: (code: string, state: string) => Promise<void>; login: (code: string, state: string) => Promise<void>;
updateUser: (user: Partial<UserProfile>) => Promise<void>; updateUser: (user: Partial<UserProfile>) => Promise<void>;
}; };