react-toolkits 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/index.css +1 -1
- package/dist/index.css.map +1 -1
- package/dist/index.esm.js +2 -2
- package/dist/index.esm.js.map +1 -1
- package/package.json +8 -3
- package/.eslintignore +0 -2
- package/.eslintrc.js +0 -4
- package/.turbo/turbo-build.log +0 -20
- package/postcss.config.js +0 -9
- package/src/assets/512_orange_nobackground.png +0 -0
- package/src/components/DynamicTags/index.tsx +0 -160
- package/src/components/FilterForm/index.tsx +0 -63
- package/src/components/FormModal/hooks.tsx +0 -47
- package/src/components/FormModal/index.tsx +0 -137
- package/src/components/GameSelect/index.tsx +0 -83
- package/src/components/Highlight/index.tsx +0 -51
- package/src/components/Layout/index.tsx +0 -99
- package/src/components/NavMenu/index.tsx +0 -142
- package/src/components/PermissionButton/index.tsx +0 -36
- package/src/components/QueryList/index.tsx +0 -152
- package/src/components/ReactToolkitsProvider/context.ts +0 -76
- package/src/components/ReactToolkitsProvider/index.tsx +0 -23
- package/src/components/UserWidget/index.tsx +0 -46
- package/src/components/index.ts +0 -51
- package/src/constants/index.ts +0 -1
- package/src/features/permission/components/PermissionCollapse/index.tsx +0 -121
- package/src/features/permission/components/PermissionList/index.tsx +0 -28
- package/src/features/permission/components/PermissionListV1/index.tsx +0 -42
- package/src/features/permission/components/PermissionListV2/index.tsx +0 -146
- package/src/features/permission/hooks/index.ts +0 -140
- package/src/features/permission/index.ts +0 -5
- package/src/features/permission/types/index.ts +0 -40
- package/src/hooks/index.ts +0 -2
- package/src/hooks/use-http-client.ts +0 -85
- package/src/hooks/use-permission.ts +0 -75
- package/src/index.ts +0 -7
- package/src/pages/base/Login/default.tsx +0 -864
- package/src/pages/base/Login/index.tsx +0 -101
- package/src/pages/base/NotFound/index.tsx +0 -27
- package/src/pages/base/index.tsx +0 -20
- package/src/pages/index.ts +0 -4
- package/src/pages/permission/RoleDetail/index.tsx +0 -40
- package/src/pages/permission/RoleList/index.tsx +0 -251
- package/src/pages/permission/UserList/index.tsx +0 -236
- package/src/pages/permission/index.tsx +0 -56
- package/src/shims.d.ts +0 -20
- package/src/stores/index.ts +0 -2
- package/src/stores/query-list.ts +0 -61
- package/src/stores/token.ts +0 -39
- package/src/styles/index.css +0 -5
- package/src/types/index.ts +0 -10
- package/tailwind.config.js +0 -5
- package/tsconfig.json +0 -20
- package/tsup.config.ts +0 -28
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
import type { PermissionEnumItem } from '@/features/permission'
|
|
2
|
-
import type { FC } from 'react'
|
|
3
|
-
import { useCallback, useEffect, useState } from 'react'
|
|
4
|
-
import type { CheckboxChangeEvent } from 'antd/es/checkbox'
|
|
5
|
-
import { Checkbox, Col, Collapse, Row } from 'antd'
|
|
6
|
-
|
|
7
|
-
const { Panel } = Collapse
|
|
8
|
-
|
|
9
|
-
interface PermissionCollapseProps {
|
|
10
|
-
expand?: boolean
|
|
11
|
-
permissions?: PermissionEnumItem[]
|
|
12
|
-
readonly?: boolean
|
|
13
|
-
value?: string[]
|
|
14
|
-
onChange?: (value: string[]) => void
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const PermissionCollapse: FC<PermissionCollapseProps> = props => {
|
|
18
|
-
const { permissions, readonly, expand, value, onChange } = props
|
|
19
|
-
const [activeKey, setActiveKey] = useState<string[]>([])
|
|
20
|
-
const [checkedMap, setCheckedMap] = useState<Record<string, boolean>>({})
|
|
21
|
-
const [internalValue, setInternalValue] = useState<string[]>(value ?? [])
|
|
22
|
-
|
|
23
|
-
const onCollapseChange = useCallback((key: string | string[]) => {
|
|
24
|
-
setActiveKey(key as string[])
|
|
25
|
-
}, [])
|
|
26
|
-
|
|
27
|
-
const getCheckedValue = (checkedValue: boolean, codes: string[]) => {
|
|
28
|
-
let tempValue: string[] = []
|
|
29
|
-
|
|
30
|
-
if (checkedValue) {
|
|
31
|
-
tempValue = [...new Set(internalValue.concat(codes))]
|
|
32
|
-
} else {
|
|
33
|
-
tempValue = internalValue.slice()
|
|
34
|
-
|
|
35
|
-
codes.forEach(code => {
|
|
36
|
-
const index = tempValue.findIndex(item => item === code)
|
|
37
|
-
if (index > -1) {
|
|
38
|
-
tempValue.splice(index, 1)
|
|
39
|
-
}
|
|
40
|
-
})
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
return tempValue
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const onCheckChange = (e: CheckboxChangeEvent, category: string, codes: string[]) => {
|
|
47
|
-
const checkedValue = getCheckedValue(e.target.checked, codes)
|
|
48
|
-
setInternalValue(checkedValue)
|
|
49
|
-
onChange?.(checkedValue)
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
useEffect(() => {
|
|
53
|
-
setInternalValue(value ?? [])
|
|
54
|
-
}, [value])
|
|
55
|
-
|
|
56
|
-
useEffect(() => {
|
|
57
|
-
if (expand) {
|
|
58
|
-
setActiveKey((permissions ?? []).map(({ category }) => category))
|
|
59
|
-
}
|
|
60
|
-
}, [expand, permissions])
|
|
61
|
-
|
|
62
|
-
useEffect(() => {
|
|
63
|
-
const checkedValue = (permissions ?? []).reduce(
|
|
64
|
-
(acc, curr) => {
|
|
65
|
-
acc[curr.category] = curr.permissions.every(item => internalValue.includes(item.value))
|
|
66
|
-
return acc
|
|
67
|
-
},
|
|
68
|
-
{} as Record<string, boolean>,
|
|
69
|
-
)
|
|
70
|
-
|
|
71
|
-
setCheckedMap(checkedValue)
|
|
72
|
-
}, [internalValue, permissions])
|
|
73
|
-
|
|
74
|
-
return (
|
|
75
|
-
<Collapse
|
|
76
|
-
style={{ width: '100%' }}
|
|
77
|
-
collapsible="header"
|
|
78
|
-
activeKey={activeKey}
|
|
79
|
-
items={(permissions ?? []).map(item => ({
|
|
80
|
-
key: item.category,
|
|
81
|
-
label: item.category,
|
|
82
|
-
extra: !readonly && (
|
|
83
|
-
<Checkbox
|
|
84
|
-
checked={checkedMap[item.category]}
|
|
85
|
-
onChange={e => {
|
|
86
|
-
onCheckChange(
|
|
87
|
-
e,
|
|
88
|
-
item.category,
|
|
89
|
-
item.permissions.map(permission => permission.value),
|
|
90
|
-
)
|
|
91
|
-
}}
|
|
92
|
-
>
|
|
93
|
-
全选
|
|
94
|
-
</Checkbox>
|
|
95
|
-
),
|
|
96
|
-
children: (
|
|
97
|
-
<Checkbox.Group style={{ width: '100%' }} value={internalValue}>
|
|
98
|
-
<Row gutter={[10, 10]} style={{ width: '100%' }}>
|
|
99
|
-
{item.permissions.map(permission => (
|
|
100
|
-
<Col key={permission.value} span={6}>
|
|
101
|
-
<Checkbox
|
|
102
|
-
disabled={readonly}
|
|
103
|
-
value={permission.value}
|
|
104
|
-
onChange={e => {
|
|
105
|
-
onCheckChange(e, item.category, [permission.value])
|
|
106
|
-
}}
|
|
107
|
-
>
|
|
108
|
-
{permission.label}
|
|
109
|
-
</Checkbox>
|
|
110
|
-
</Col>
|
|
111
|
-
))}
|
|
112
|
-
</Row>
|
|
113
|
-
</Checkbox.Group>
|
|
114
|
-
),
|
|
115
|
-
}))}
|
|
116
|
-
onChange={onCollapseChange}
|
|
117
|
-
/>
|
|
118
|
-
)
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
export default PermissionCollapse
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import type { RoleV1, RoleV2 } from '@/features/permission'
|
|
2
|
-
import { useReactToolkitsContext } from '@/components'
|
|
3
|
-
import type { FC } from 'react'
|
|
4
|
-
import PermissionListV1 from '../PermissionListV1'
|
|
5
|
-
import PermissionListV2 from '../PermissionListV2'
|
|
6
|
-
|
|
7
|
-
export interface PermissionListPropsBase {
|
|
8
|
-
expand?: boolean
|
|
9
|
-
readonly?: boolean
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
interface PermissionListProps extends PermissionListPropsBase {
|
|
13
|
-
value?: RoleV1['permissions'] | RoleV2['permissions']
|
|
14
|
-
onChange?: (checkedValue: RoleV1['permissions'] | RoleV2['permissions']) => void
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const PermissionList: FC<PermissionListProps> = (props: PermissionListProps) => {
|
|
18
|
-
const { value } = props
|
|
19
|
-
const isPermissionV2 = useReactToolkitsContext(state => state.isPermissionV2)
|
|
20
|
-
|
|
21
|
-
if (isPermissionV2) {
|
|
22
|
-
return <PermissionListV2 {...props} value={value as RoleV2['permissions']} />
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
return <PermissionListV1 {...props} value={value as RoleV1['permissions']} />
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export default PermissionList
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { Skeleton, Typography } from 'antd'
|
|
2
|
-
import { useAllPermissions } from '../../hooks'
|
|
3
|
-
import PermissionCollapse from '../PermissionCollapse'
|
|
4
|
-
import type { RoleV1 } from '../../types'
|
|
5
|
-
import type { PermissionListPropsBase } from '../PermissionList'
|
|
6
|
-
import type { FC } from 'react'
|
|
7
|
-
|
|
8
|
-
const { Text } = Typography
|
|
9
|
-
|
|
10
|
-
interface PermissionListV1Props extends PermissionListPropsBase {
|
|
11
|
-
value?: RoleV1['permissions']
|
|
12
|
-
onChange?: (checkedValue: RoleV1['permissions']) => void
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const PermissionListV1: FC<PermissionListV1Props> = props => {
|
|
16
|
-
const { expand = true, value, readonly, onChange } = props
|
|
17
|
-
const { data: permissions, isLoading, error } = useAllPermissions()
|
|
18
|
-
|
|
19
|
-
if (error) {
|
|
20
|
-
return (
|
|
21
|
-
<div className="flex justify-center">
|
|
22
|
-
<Text type="danger">权限获取失败</Text>
|
|
23
|
-
</div>
|
|
24
|
-
)
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
return (
|
|
28
|
-
<Skeleton active loading={isLoading}>
|
|
29
|
-
<PermissionCollapse
|
|
30
|
-
value={value}
|
|
31
|
-
permissions={permissions}
|
|
32
|
-
readonly={readonly}
|
|
33
|
-
expand={expand}
|
|
34
|
-
onChange={newValue => {
|
|
35
|
-
onChange?.(newValue)
|
|
36
|
-
}}
|
|
37
|
-
/>
|
|
38
|
-
</Skeleton>
|
|
39
|
-
)
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export default PermissionListV1
|
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
import { Button, Card, Divider, Empty, Select, Skeleton, Space, Typography } from 'antd'
|
|
2
|
-
import type { FC } from 'react'
|
|
3
|
-
import { useEffect, useState } from 'react'
|
|
4
|
-
import type { RoleV2 } from '../../types'
|
|
5
|
-
import { useAllPermissionsV2 } from '../../hooks'
|
|
6
|
-
import PermissionCollapse from '../PermissionCollapse'
|
|
7
|
-
import type { PermissionListPropsBase } from '../PermissionList'
|
|
8
|
-
|
|
9
|
-
const { Text } = Typography
|
|
10
|
-
const { Option } = Select
|
|
11
|
-
|
|
12
|
-
interface PermissionListV2Props extends PermissionListPropsBase {
|
|
13
|
-
value?: RoleV2['permissions']
|
|
14
|
-
onChange?: (checkedValue: RoleV2['permissions']) => void
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const PermissionListV2: FC<PermissionListV2Props> = props => {
|
|
18
|
-
const { expand = true, value, readonly, onChange } = props
|
|
19
|
-
const { data: permissions, isLoading, error } = useAllPermissionsV2()
|
|
20
|
-
const [gameList, setGameList] = useState<{ gameId: string; permissions: string[] }[]>([])
|
|
21
|
-
|
|
22
|
-
useEffect(() => {
|
|
23
|
-
const list: { gameId: string; permissions: string[] }[] = []
|
|
24
|
-
|
|
25
|
-
Object.keys(value ?? {}).forEach(key => {
|
|
26
|
-
if (key !== 'global') {
|
|
27
|
-
list.push({ gameId: key, permissions: value?.[key] ?? [] })
|
|
28
|
-
}
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
setGameList(list)
|
|
32
|
-
}, [value])
|
|
33
|
-
|
|
34
|
-
if (error) {
|
|
35
|
-
return (
|
|
36
|
-
<div className="flex justify-center">
|
|
37
|
-
<Text type="danger">权限获取失败</Text>
|
|
38
|
-
</div>
|
|
39
|
-
)
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const addGame = () => {
|
|
43
|
-
setGameList(prev => [...prev, { gameId: '', permissions: [] }])
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const removeGame = (index: number) => {
|
|
47
|
-
setGameList(prev => prev.filter((_, i) => i !== index))
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
return (
|
|
51
|
-
<div className="flex flex-col w-full">
|
|
52
|
-
<div className="mb-12">
|
|
53
|
-
<Divider dashed>平台基础权限</Divider>
|
|
54
|
-
</div>
|
|
55
|
-
<Skeleton active loading={isLoading}>
|
|
56
|
-
<PermissionCollapse
|
|
57
|
-
value={value?.global}
|
|
58
|
-
readonly={readonly}
|
|
59
|
-
permissions={permissions?.permission?.slice(0, 2)}
|
|
60
|
-
expand={expand}
|
|
61
|
-
onChange={newValue => {
|
|
62
|
-
onChange?.({
|
|
63
|
-
...value,
|
|
64
|
-
global: newValue,
|
|
65
|
-
})
|
|
66
|
-
}}
|
|
67
|
-
/>
|
|
68
|
-
</Skeleton>
|
|
69
|
-
<div className="my-12">
|
|
70
|
-
<Divider dashed>游戏权限</Divider>
|
|
71
|
-
</div>
|
|
72
|
-
{gameList.map((item, index) => (
|
|
73
|
-
<Card
|
|
74
|
-
title={
|
|
75
|
-
<Space>
|
|
76
|
-
<Text>游戏</Text>
|
|
77
|
-
{readonly ? (
|
|
78
|
-
<Text>{permissions?.game?.find(game => game.id === item.gameId)?.name}</Text>
|
|
79
|
-
) : (
|
|
80
|
-
<Select
|
|
81
|
-
disabled={readonly}
|
|
82
|
-
value={gameList[index].gameId || undefined}
|
|
83
|
-
style={{ width: '160px' }}
|
|
84
|
-
placeholder="请选择游戏"
|
|
85
|
-
onChange={selectedValue => {
|
|
86
|
-
setGameList(pev => {
|
|
87
|
-
const temp = pev.slice()
|
|
88
|
-
temp[index].gameId = selectedValue
|
|
89
|
-
return temp
|
|
90
|
-
})
|
|
91
|
-
}}
|
|
92
|
-
>
|
|
93
|
-
{permissions?.game?.map(game => (
|
|
94
|
-
<Option key={game.id} value={game.id} disabled={gameList.some(({ gameId }) => gameId === game.id)}>
|
|
95
|
-
{game.name}
|
|
96
|
-
</Option>
|
|
97
|
-
))}
|
|
98
|
-
</Select>
|
|
99
|
-
)}
|
|
100
|
-
</Space>
|
|
101
|
-
}
|
|
102
|
-
key={index}
|
|
103
|
-
className="mb-6"
|
|
104
|
-
extra={
|
|
105
|
-
!readonly && (
|
|
106
|
-
<Button
|
|
107
|
-
type="link"
|
|
108
|
-
onClick={() => {
|
|
109
|
-
removeGame(index)
|
|
110
|
-
}}
|
|
111
|
-
>
|
|
112
|
-
移除
|
|
113
|
-
</Button>
|
|
114
|
-
)
|
|
115
|
-
}
|
|
116
|
-
>
|
|
117
|
-
{gameList[index].gameId ? (
|
|
118
|
-
<Skeleton active loading={isLoading}>
|
|
119
|
-
<PermissionCollapse
|
|
120
|
-
value={value?.[gameList[index].gameId]}
|
|
121
|
-
readonly={readonly}
|
|
122
|
-
expand={expand}
|
|
123
|
-
permissions={permissions?.permission?.slice(2)}
|
|
124
|
-
onChange={newValue => {
|
|
125
|
-
onChange?.({
|
|
126
|
-
...value,
|
|
127
|
-
[gameList[index].gameId]: newValue,
|
|
128
|
-
})
|
|
129
|
-
}}
|
|
130
|
-
/>
|
|
131
|
-
</Skeleton>
|
|
132
|
-
) : (
|
|
133
|
-
<Empty description="请先选择游戏" />
|
|
134
|
-
)}
|
|
135
|
-
</Card>
|
|
136
|
-
))}
|
|
137
|
-
{!readonly && (
|
|
138
|
-
<Button block type="dashed" onClick={addGame}>
|
|
139
|
-
添加游戏权限
|
|
140
|
-
</Button>
|
|
141
|
-
)}
|
|
142
|
-
</div>
|
|
143
|
-
)
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
export default PermissionListV2
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
import { useHttpClient, usePermission } from '@/hooks'
|
|
2
|
-
import useSWR from 'swr'
|
|
3
|
-
import useSWRMutation from 'swr/mutation'
|
|
4
|
-
import type { PermissionEnumItem, RoleEnumItem, RoleV1, RoleV2 } from '../types'
|
|
5
|
-
import type { GameType } from '@/components/GameSelect'
|
|
6
|
-
import { useReactToolkitsContext } from '@/components'
|
|
7
|
-
|
|
8
|
-
export function useAllPermissions() {
|
|
9
|
-
return useSWR<PermissionEnumItem[]>({
|
|
10
|
-
url: '/api/usystem/user/allPermssions',
|
|
11
|
-
})
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export function useAllPermissionsV2() {
|
|
15
|
-
return useSWR<{
|
|
16
|
-
game: GameType[]
|
|
17
|
-
permission: PermissionEnumItem[]
|
|
18
|
-
}>({
|
|
19
|
-
url: '/api/usystem/user/allPermissionsV2',
|
|
20
|
-
})
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export function useAllRoles() {
|
|
24
|
-
const { accessible } = usePermission('200005')
|
|
25
|
-
|
|
26
|
-
return useSWR<RoleEnumItem[]>(
|
|
27
|
-
accessible
|
|
28
|
-
? {
|
|
29
|
-
url: '/api/usystem/role/all',
|
|
30
|
-
}
|
|
31
|
-
: null,
|
|
32
|
-
)
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export function useRole(name: string) {
|
|
36
|
-
const isPermissionV2 = useReactToolkitsContext(state => state.isPermissionV2)
|
|
37
|
-
|
|
38
|
-
return useSWR<RoleV1 | RoleV2>({
|
|
39
|
-
url: isPermissionV2 ? '/api/usystem/role/infoV2' : '/api/usystem/role/info',
|
|
40
|
-
params: { name },
|
|
41
|
-
})
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export function useCreateRole() {
|
|
45
|
-
const httpClient = useHttpClient()
|
|
46
|
-
const isPermissionV2 = useReactToolkitsContext(state => state.isPermissionV2)
|
|
47
|
-
|
|
48
|
-
return useSWRMutation(
|
|
49
|
-
isPermissionV2 ? '/api/usystem/role/createV2' : '/api/usystem/role/create',
|
|
50
|
-
(
|
|
51
|
-
url: string,
|
|
52
|
-
{
|
|
53
|
-
arg,
|
|
54
|
-
}: {
|
|
55
|
-
arg: { name: string; permissions: RoleV1['permissions'] | RoleV2['permissions'] }
|
|
56
|
-
},
|
|
57
|
-
) => httpClient.post(url, arg),
|
|
58
|
-
)
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export function useUpdateRole() {
|
|
62
|
-
const httpClient = useHttpClient()
|
|
63
|
-
const isPermissionV2 = useReactToolkitsContext(state => state.isPermissionV2)
|
|
64
|
-
|
|
65
|
-
return useSWRMutation(
|
|
66
|
-
isPermissionV2 ? '/api/usystem/role/updateV2' : '/api/usystem/role/update',
|
|
67
|
-
(
|
|
68
|
-
url: string,
|
|
69
|
-
{
|
|
70
|
-
arg,
|
|
71
|
-
}: {
|
|
72
|
-
arg: { id: number; name: string; permissions: RoleV1['permissions'] | RoleV2['permissions'] }
|
|
73
|
-
},
|
|
74
|
-
) => httpClient.post(url, arg),
|
|
75
|
-
)
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export function useRemoveRole() {
|
|
79
|
-
const httpClient = useHttpClient()
|
|
80
|
-
|
|
81
|
-
return useSWRMutation(
|
|
82
|
-
'/api/usystem/role/delete',
|
|
83
|
-
(
|
|
84
|
-
url,
|
|
85
|
-
{
|
|
86
|
-
arg,
|
|
87
|
-
}: {
|
|
88
|
-
arg: { id: number; name: string }
|
|
89
|
-
},
|
|
90
|
-
) => httpClient.post(url, arg),
|
|
91
|
-
)
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
export function useCreateUser() {
|
|
95
|
-
const httpClient = useHttpClient()
|
|
96
|
-
|
|
97
|
-
return useSWRMutation(
|
|
98
|
-
'/api/usystem/user/create',
|
|
99
|
-
(
|
|
100
|
-
url,
|
|
101
|
-
{
|
|
102
|
-
arg,
|
|
103
|
-
}: {
|
|
104
|
-
arg: { name: string; roles: string[] }
|
|
105
|
-
},
|
|
106
|
-
) => httpClient.post(url, arg),
|
|
107
|
-
)
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
export function useUpdateUser() {
|
|
111
|
-
const httpClient = useHttpClient()
|
|
112
|
-
|
|
113
|
-
return useSWRMutation(
|
|
114
|
-
'/api/usystem/user/update',
|
|
115
|
-
(
|
|
116
|
-
url,
|
|
117
|
-
{
|
|
118
|
-
arg,
|
|
119
|
-
}: {
|
|
120
|
-
arg: { id: string; name: string; roles: string[] }
|
|
121
|
-
},
|
|
122
|
-
) => httpClient.post(url, arg),
|
|
123
|
-
)
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
export function useRemoveUser() {
|
|
127
|
-
const httpClient = useHttpClient()
|
|
128
|
-
|
|
129
|
-
return useSWRMutation(
|
|
130
|
-
'/api/usystem/user/delete',
|
|
131
|
-
(
|
|
132
|
-
url,
|
|
133
|
-
{
|
|
134
|
-
arg,
|
|
135
|
-
}: {
|
|
136
|
-
arg: { id: string; name: string }
|
|
137
|
-
},
|
|
138
|
-
) => httpClient.post(url, arg),
|
|
139
|
-
)
|
|
140
|
-
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
export interface PermissionEnumItem {
|
|
2
|
-
category: string
|
|
3
|
-
permissions: {
|
|
4
|
-
label: string
|
|
5
|
-
value: string
|
|
6
|
-
route: string
|
|
7
|
-
}[]
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export interface RoleEnumItem {
|
|
11
|
-
id: string
|
|
12
|
-
name: string
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export interface RoleListItem {
|
|
16
|
-
id: number
|
|
17
|
-
name: string
|
|
18
|
-
ctime: string
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export interface RoleV1 {
|
|
22
|
-
id: number
|
|
23
|
-
name: string
|
|
24
|
-
ctime: string
|
|
25
|
-
permissions: string[]
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export interface RoleV2 {
|
|
29
|
-
id: number
|
|
30
|
-
name: string
|
|
31
|
-
ctime: string
|
|
32
|
-
permissions: Record<string, string[]>
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export interface UserListItem {
|
|
36
|
-
id: string
|
|
37
|
-
name: string
|
|
38
|
-
ctime: string
|
|
39
|
-
roles: string[]
|
|
40
|
-
}
|
package/src/hooks/index.ts
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import {useTokenStore} from '@/stores'
|
|
2
|
-
import type {AxiosInstance, AxiosRequestConfig} from 'axios'
|
|
3
|
-
import axios from 'axios'
|
|
4
|
-
import type {Merge} from 'ts-essentials'
|
|
5
|
-
import {useReactToolkitsContext} from '@/components'
|
|
6
|
-
|
|
7
|
-
// 覆盖 AxiosInstance 各种请求方法的返回值,为了方便我们在 interceptors.response 里把 AxiosResponse 直接打平成后端返回的数据,去掉了 axios 的封装。
|
|
8
|
-
type ShimmedAxiosInstance = Merge<
|
|
9
|
-
AxiosInstance,
|
|
10
|
-
{
|
|
11
|
-
request<T = unknown, D = unknown>(config: AxiosRequestConfig<D>): Promise<T>
|
|
12
|
-
get<T = unknown, D = unknown>(url: string, config?: AxiosRequestConfig<D>): Promise<T>
|
|
13
|
-
delete<T = unknown, D = unknown>(url: string, config?: AxiosRequestConfig<D>): Promise<T>
|
|
14
|
-
head<T = unknown, D = unknown>(url: string, config?: AxiosRequestConfig<D>): Promise<T>
|
|
15
|
-
post<T = unknown, D = unknown>(url: string, data?: unknown, config?: AxiosRequestConfig<D>): Promise<T>
|
|
16
|
-
put<T = unknown, D = unknown>(url: string, data?: unknown, config?: AxiosRequestConfig<D>): Promise<T>
|
|
17
|
-
patch<T = unknown, D = unknown>(url: string, data?: unknown, config?: AxiosRequestConfig<D>): Promise<T>
|
|
18
|
-
}
|
|
19
|
-
>
|
|
20
|
-
|
|
21
|
-
export class HttpClientError extends Error {
|
|
22
|
-
code?: number
|
|
23
|
-
// 跳过错误提示
|
|
24
|
-
skip: boolean
|
|
25
|
-
|
|
26
|
-
constructor(message: string, code?: number, skip = false) {
|
|
27
|
-
super(message)
|
|
28
|
-
this.code = code
|
|
29
|
-
this.skip = skip
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export function useHttpClient() {
|
|
34
|
-
const token = useTokenStore(state => state.token)
|
|
35
|
-
const { game, isGlobalNS, isPermissionV2 } = useReactToolkitsContext(state => state)
|
|
36
|
-
|
|
37
|
-
const defaultOptions: AxiosRequestConfig = {
|
|
38
|
-
withCredentials: true,
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const instance = axios.create(defaultOptions) as ShimmedAxiosInstance
|
|
42
|
-
|
|
43
|
-
instance.interceptors.request.use(config => {
|
|
44
|
-
const headers = config.headers
|
|
45
|
-
headers.set('Authorization', `Bearer ${token}`)
|
|
46
|
-
|
|
47
|
-
if (isPermissionV2) {
|
|
48
|
-
if (!headers.has('App-ID')) {
|
|
49
|
-
headers.set('App-ID', isGlobalNS ? 'global' : game?.id)
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
return config
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
instance.interceptors.response.use(
|
|
57
|
-
response => {
|
|
58
|
-
if (response.data.code === 0 || response.data.status === 0) {
|
|
59
|
-
return response.data.data
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
throw new HttpClientError(response.data.msg, 0)
|
|
63
|
-
},
|
|
64
|
-
error => {
|
|
65
|
-
if (error.response) {
|
|
66
|
-
// 请求成功发出且服务器也响应了状态码,但状态码超出了 2xx 的范围
|
|
67
|
-
if (error.response.status === 401) {
|
|
68
|
-
throw new HttpClientError('未登录或登录已过期', error.response.status)
|
|
69
|
-
} else if (error.response.status === 403) {
|
|
70
|
-
throw new HttpClientError('无权限,请联系管理员进行授权', error.response.status)
|
|
71
|
-
} else if ([404, 405].includes(error.response.status)) {
|
|
72
|
-
throw new HttpClientError('Not Found or Method not Allowed', error.response.status, true)
|
|
73
|
-
} else if (error.response.status === 412) {
|
|
74
|
-
throw new HttpClientError('未注册用户', error.response.status)
|
|
75
|
-
} else {
|
|
76
|
-
throw new HttpClientError(error.response.data?.msg, error.response.status)
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
throw new HttpClientError('无响应')
|
|
81
|
-
},
|
|
82
|
-
)
|
|
83
|
-
|
|
84
|
-
return instance
|
|
85
|
-
}
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import useSWRImmutable from 'swr/immutable'
|
|
2
|
-
import { useNavigate } from 'react-router-dom'
|
|
3
|
-
import { useHttpClient } from './use-http-client'
|
|
4
|
-
import { useReactToolkitsContext } from '@/components'
|
|
5
|
-
|
|
6
|
-
export interface PermissionCheckResult {
|
|
7
|
-
[k: string]: boolean
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export function usePermissions(codes: string[], isGlobalNS = false) {
|
|
11
|
-
const httpClient = useHttpClient()
|
|
12
|
-
const navigate = useNavigate()
|
|
13
|
-
const isPermissionV2 = useReactToolkitsContext(state => state.isPermissionV2)
|
|
14
|
-
const url = isPermissionV2 ? '/api/usystem/user/checkV2' : '/api/usystem/user/check'
|
|
15
|
-
|
|
16
|
-
const { data, isLoading } = useSWRImmutable(
|
|
17
|
-
codes.length > 0
|
|
18
|
-
? {
|
|
19
|
-
method: 'POST',
|
|
20
|
-
url,
|
|
21
|
-
data: { permissions: codes },
|
|
22
|
-
headers: isGlobalNS
|
|
23
|
-
? {
|
|
24
|
-
'App-ID': 'global',
|
|
25
|
-
}
|
|
26
|
-
: {},
|
|
27
|
-
}
|
|
28
|
-
: null,
|
|
29
|
-
config =>
|
|
30
|
-
httpClient.request<PermissionCheckResult>(config).then(res => {
|
|
31
|
-
if (res.has_all) {
|
|
32
|
-
return codes.reduce(
|
|
33
|
-
(acc, curr) => {
|
|
34
|
-
acc[curr] = true
|
|
35
|
-
return acc
|
|
36
|
-
},
|
|
37
|
-
{} as Record<string, boolean>,
|
|
38
|
-
)
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
return codes.reduce(
|
|
42
|
-
(acc, curr) => {
|
|
43
|
-
acc[curr] = (res as Record<string, boolean>)[curr]
|
|
44
|
-
return acc
|
|
45
|
-
},
|
|
46
|
-
{} as Record<string, boolean>,
|
|
47
|
-
)
|
|
48
|
-
}),
|
|
49
|
-
{
|
|
50
|
-
suspense: true,
|
|
51
|
-
shouldRetryOnError: false,
|
|
52
|
-
onError() {
|
|
53
|
-
navigate('/login')
|
|
54
|
-
},
|
|
55
|
-
},
|
|
56
|
-
)
|
|
57
|
-
|
|
58
|
-
return { data, isLoading }
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export function usePermission(code: string) {
|
|
62
|
-
const { data, isLoading } = usePermissions(code ? [code] : [])
|
|
63
|
-
|
|
64
|
-
if (!code) {
|
|
65
|
-
return {
|
|
66
|
-
accessible: true,
|
|
67
|
-
isValidating: false,
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return {
|
|
72
|
-
accessible: data?.[code] ?? false,
|
|
73
|
-
isValidating: isLoading,
|
|
74
|
-
}
|
|
75
|
-
}
|