Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
C
center-book
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
EzijingWeb
center-book
Commits
9b39dd3e
提交
9b39dd3e
authored
7月 20, 2026
作者:
王鹏飞
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
refactor(admin): migrate access admin module
上级
c36c6000
显示空白字符变更
内嵌
并排
正在显示
12 个修改的文件
包含
864 行增加
和
789 行删除
+864
-789
access-admin-report.md
.superpowers/sdd/access-admin-report.md
+57
-0
api.ts
apps/admin/src/modules/access/admin/api.ts
+102
-0
AdminFormDrawer.tsx
...n/src/modules/access/admin/components/AdminFormDrawer.tsx
+116
-0
DeleteAdminModal.tsx
.../src/modules/access/admin/components/DeleteAdminModal.tsx
+32
-0
PasswordDrawer.tsx
...in/src/modules/access/admin/components/PasswordDrawer.tsx
+79
-0
query.ts
apps/admin/src/modules/access/admin/query.ts
+38
-0
routes.tsx
apps/admin/src/modules/access/admin/routes.tsx
+10
-0
useAdminList.ts
apps/admin/src/modules/access/admin/useAdminList.ts
+136
-0
AdminListView.tsx
apps/admin/src/modules/access/admin/views/AdminListView.tsx
+292
-0
routes.tsx
apps/admin/src/modules/access/routes.tsx
+2
-2
index.jsx
apps/admin/src/pages/jurisdiction/admin/index.jsx
+0
-659
request.js
apps/admin/src/pages/jurisdiction/admin/request.js
+0
-128
没有找到文件。
.superpowers/sdd/access-admin-report.md
0 → 100644
浏览文件 @
9b39dd3e
# access/admin migration report
## Status
Migrated
`/jurisdiction/admin`
from
`pages/jurisdiction/admin`
to the module-owned
`modules/access/admin`
boundary. The active access route now lazy-loads the new
module route and view, and the replaced legacy page/request files were removed
after a successful pre-delete production build.
## Preserved contract
-
List API remains
`POST /user/user/getList`
through
`utils/request.js`
with a
`qs.stringify`
body containing
`page`
,
`page_size`
, and active filters.
-
Role options remain
`POST /user/role/getAllList`
with
`{ type: 1 }`
.
-
Add, detail, edit, delete, status, and password endpoints are unchanged.
-
Existing success/error messages and false-return behavior are retained in the
module API adapter.
-
Filters remain administrator name, phone, role, and validity range. Date
values are sent as local-day
`start_time`
/
`end_time`
second timestamps.
-
Pagination remains 1/10 initially with 10/20/30/40 page-size choices.
-
All eight columns are retained in order, including the status switch and the
edit/password/delete operation column.
-
Permissions remain exact, including the existing
`/jurisdiction/role/add`
permission for the administrator Add button.
-
Add/edit, password, and delete flows remain module-private components with the
original field validation and confirmation copy.
-
Successful mutations refresh the current page without filters, matching the
legacy direct
`init()`
calls; failed mutations do not refresh.
## Architecture
-
`api.ts`
owns the legacy request protocol and awaits responses before reading
the response body.
-
`query.ts`
owns filter-to-request mapping.
-
`useAdminList.ts`
owns controlled list/filter/pagination/loading/error state,
retry, and stale-response protection.
-
`views/AdminListView.tsx`
owns permissions, operations, role loading, and
AppList composition.
-
`components/`
owns the add/edit drawer, password drawer, and delete modal.
-
`routes.tsx`
owns the leaf route without changing the public URL.
## Verification
-
Focused oxlint and oxfmt checks pass for
`modules/access/admin`
.
-
`pnpm test`
passed all 11 global Node tests.
-
Post-delete
`pnpm build`
passed with only the existing formula-editor and
large-chunk warnings.
-
`pnpm exec tsc --noEmit`
reports no access/admin diagnostics; unrelated
existing/concurrent diagnostics remain elsewhere in the workspace.
## Concerns
-
No API/query/Hook tests were added, per the updated task instruction.
-
Deprecated
`src/routes/routes.jsx`
and
`src/config/component.js`
still contain
the legacy page path as inactive metadata. They are outside the authorized
scope; the active
`src/app/routes.tsx -> modules/access/routes.tsx`
chain and
production build use the new module.
apps/admin/src/modules/access/admin/api.ts
0 → 100644
浏览文件 @
9b39dd3e
import
{
message
}
from
"antd"
;
// @ts-expect-error The legacy workspace does not install the qs declaration package.
import
qs
from
"qs"
;
import
request
from
"@/utils/request.js"
;
import
type
{
AdminQuery
}
from
"./query"
;
export
interface
AdminRow
{
id
:
number
;
real_name
?:
string
;
tel
?:
string
;
role_id
?:
number
;
role_name
?:
string
;
status
?:
number
|
string
;
validity
?:
string
;
create_time
?:
string
;
}
export
interface
RoleOption
{
id
:
number
;
name
:
string
;
type
?:
number
;
}
export
interface
AdminListResult
{
rows
:
AdminRow
[];
total
:
number
;
}
type
ApiParams
=
Record
<
string
,
unknown
>
;
async
function
getPayload
<
T
>
(
url
:
string
,
params
:
ApiParams
):
Promise
<
T
|
false
>
{
try
{
const
response
=
await
request
.
post
(
url
,
qs
.
stringify
(
params
));
const
body
=
response
.
data
as
{
code
?:
number
;
data
?:
T
;
message
?:
string
};
const
code
=
body
?.
code
??
0
;
const
data
=
(
body
?.
data
??
[])
as
T
;
const
text
=
body
?.
message
??
"数据获取失败!"
;
if
(
code
===
200
)
return
data
;
message
.
error
(
text
);
return
false
;
}
catch
{
return
false
;
}
}
async
function
mutate
(
url
:
string
,
params
:
ApiParams
):
Promise
<
boolean
>
{
try
{
const
response
=
await
request
.
post
(
url
,
qs
.
stringify
(
params
));
const
body
=
response
.
data
as
{
code
?:
number
;
message
?:
string
};
const
code
=
body
?.
code
??
0
;
const
text
=
body
?.
message
??
"数据获取失败!"
;
if
(
code
===
200
)
{
message
.
success
(
text
);
return
true
;
}
message
.
error
(
text
);
return
false
;
}
catch
{
return
false
;
}
}
export
async
function
getAdminList
(
params
:
AdminQuery
):
Promise
<
AdminListResult
|
false
>
{
const
data
=
await
getPayload
<
{
list
?:
AdminRow
[];
total
?:
number
}
>
(
"/user/user/getList"
,
{
...
params
,
});
if
(
data
===
false
)
return
false
;
return
{
rows
:
data
.
list
??
[],
total
:
data
.
total
??
0
};
}
export
function
getRoleOptions
()
{
return
getPayload
<
RoleOption
[]
>
(
"/user/role/getAllList"
,
{
type
:
1
});
}
export
function
getAdminInfo
(
id
:
number
)
{
return
getPayload
<
AdminRow
>
(
"/user/user/getInfoById"
,
{
id
});
}
export
function
addAdmin
(
params
:
ApiParams
)
{
return
mutate
(
"/user/user/add"
,
params
);
}
export
function
editAdmin
(
params
:
ApiParams
)
{
return
mutate
(
"/user/user/edit"
,
params
);
}
export
function
deleteAdmin
(
id
:
number
)
{
return
mutate
(
"/user/user/del"
,
{
id
});
}
export
function
changeAdminStatus
(
id
:
number
,
status
:
"0"
|
"1"
)
{
return
mutate
(
"/user/user/changeStatus"
,
{
status
,
id
});
}
export
function
changeAdminPassword
(
params
:
ApiParams
)
{
return
mutate
(
"/user/user/editPass"
,
params
);
}
apps/admin/src/modules/access/admin/components/AdminFormDrawer.tsx
0 → 100644
浏览文件 @
9b39dd3e
import
{
Button
,
DatePicker
,
Drawer
,
Form
,
Input
,
Select
,
Space
}
from
"antd"
;
import
type
{
Dayjs
}
from
"dayjs"
;
import
{
useEffect
}
from
"react"
;
import
type
{
RoleOption
}
from
"../api"
;
export
interface
AdminFormValues
{
real_name
:
string
;
tel
:
string
;
role_id
:
number
;
validity
:
Dayjs
;
password
?:
string
;
}
interface
AdminFormDrawerProps
{
open
:
boolean
;
isAdd
:
boolean
;
initialAdmin
:
Partial
<
AdminFormValues
>
|
null
;
roles
:
RoleOption
[];
onClose
:
()
=>
void
;
onSubmit
:
(
values
:
AdminFormValues
)
=>
void
|
Promise
<
void
>
;
}
const
passwordPattern
=
/^
((?=
.*
\d)(?=
.*
[
A-Z
])(?=
.*
[
a-z
]))
|
((?=
.*
\d)(?=
.*
[
A-Z
])(?=
.*
[\W
_
]))
|
((?=
.*
\d)(?=
.*
[
a-z
])(?=
.*
[\W
_
]))
|
((?=
.*
[
A-Z
])(?=
.*
[
a-z
])(?=
.*
[\W
_
]))[
a-zA-Z
\d\W
_
]{8,12}
$/
;
export
default
function
AdminFormDrawer
({
open
,
isAdd
,
initialAdmin
,
roles
,
onClose
,
onSubmit
,
}:
AdminFormDrawerProps
)
{
const
[
form
]
=
Form
.
useForm
<
AdminFormValues
>
();
useEffect
(()
=>
{
if
(
!
open
)
{
form
.
resetFields
();
return
;
}
if
(
initialAdmin
)
{
form
.
setFieldsValue
(
initialAdmin
as
unknown
as
AdminFormValues
);
}
},
[
form
,
initialAdmin
,
open
]);
return
(
<
Drawer
placement=
"right"
onClose=
{
onClose
}
open=
{
open
}
mask=
{
false
}
>
<
Form
form=
{
form
}
onFinish=
{
onSubmit
}
labelCol=
{
{
span
:
6
}
}
>
<
Form
.
Item
name=
"real_name"
label=
"管理员名称"
rules=
{
[
{
required
:
true
,
message
:
"请输入管理员名称"
},
{
max
:
30
,
message
:
"最大30字符"
},
]
}
>
<
Input
autoComplete=
"off"
placeholder=
"请输入管理员名称"
/>
</
Form
.
Item
>
<
Form
.
Item
name=
"tel"
label=
"手机号"
rules=
{
[
{
required
:
true
,
message
:
"请输入手机号"
},
{
pattern
:
/^
(?:(?:\+
|00
)
86
)?
1
[
3-9
]\d
{9}$/
,
message
:
"请输入正确格式的手机号"
,
},
]
}
>
<
Input
autoComplete=
"off"
placeholder=
"请输入手机号"
/>
</
Form
.
Item
>
<
Form
.
Item
name=
"role_id"
label=
"角色"
rules=
{
[{
required
:
true
,
message
:
"请选择角色"
}]
}
>
<
Select
placeholder=
"请选择角色"
showSearch
optionFilterProp=
"children"
>
{
roles
.
map
((
role
)
=>
(
<
Select
.
Option
key=
{
role
.
id
}
value=
{
role
.
id
}
>
{
role
.
name
}
</
Select
.
Option
>
))
}
</
Select
>
</
Form
.
Item
>
<
Form
.
Item
name=
"validity"
label=
"有效期"
rules=
{
[{
required
:
true
,
message
:
"请选择有效期"
}]
}
>
<
DatePicker
placeholder=
"请选择有效期"
/>
</
Form
.
Item
>
{
isAdd
?
(
<
Form
.
Item
name=
"password"
label=
"初始密码"
rules=
{
[
{
required
:
true
,
message
:
"请输入密码"
},
{
pattern
:
passwordPattern
,
message
:
"密码至少满足三种格式(大写字母、小写字母、数字、特殊符号), 长度为8~12位字符!"
,
},
]
}
>
<
Input
allowClear
placeholder=
"请输入密码"
autoComplete=
"off"
/>
</
Form
.
Item
>
)
:
null
}
<
Form
.
Item
wrapperCol=
{
{
offset
:
5
,
span
:
16
}
}
style=
{
{
textAlign
:
"center"
}
}
>
<
Space
size=
{
20
}
>
<
Button
onClick=
{
onClose
}
>
取消
</
Button
>
<
Button
type=
"primary"
htmlType=
"submit"
>
提交
</
Button
>
</
Space
>
</
Form
.
Item
>
</
Form
>
</
Drawer
>
);
}
apps/admin/src/modules/access/admin/components/DeleteAdminModal.tsx
0 → 100644
浏览文件 @
9b39dd3e
import
{
Modal
,
Row
,
Space
}
from
"antd"
;
interface
DeleteAdminModalProps
{
open
:
boolean
;
onCancel
:
()
=>
void
;
onConfirm
:
()
=>
void
|
Promise
<
void
>
;
}
export
default
function
DeleteAdminModal
({
open
,
onCancel
,
onConfirm
}:
DeleteAdminModalProps
)
{
return
(
<
Modal
mask=
{
false
}
centered
open=
{
open
}
onOk=
{
onConfirm
}
onCancel=
{
onCancel
}
footer=
{
(
_
,
{
OkBtn
,
CancelBtn
})
=>
(
<
Row
justify=
"center"
className=
"delModal"
style=
{
{
marginBottom
:
"30px"
}
}
>
<
Space
size=
{
20
}
>
<
CancelBtn
/>
<
OkBtn
/>
</
Space
>
</
Row
>
)
}
okText=
"确认"
>
<
p
style=
{
{
textAlign
:
"center"
,
padding
:
"30px 0 18px"
,
fontSize
:
16
}
}
>
管理员将永久删除,是否继续?
</
p
>
</
Modal
>
);
}
apps/admin/src/modules/access/admin/components/PasswordDrawer.tsx
0 → 100644
浏览文件 @
9b39dd3e
import
{
Button
,
Drawer
,
Form
,
Input
,
Space
}
from
"antd"
;
import
{
useEffect
}
from
"react"
;
export
interface
PasswordFormValues
{
password
:
string
;
re_password
:
string
;
}
interface
PasswordDrawerProps
{
open
:
boolean
;
onClose
:
()
=>
void
;
onSubmit
:
(
values
:
PasswordFormValues
)
=>
void
|
Promise
<
void
>
;
}
const
passwordPattern
=
/^
((?=
.*
\d)(?=
.*
[
A-Z
])(?=
.*
[
a-z
]))
|
((?=
.*
\d)(?=
.*
[
A-Z
])(?=
.*
[\W
_
]))
|
((?=
.*
\d)(?=
.*
[
a-z
])(?=
.*
[\W
_
]))
|
((?=
.*
[
A-Z
])(?=
.*
[
a-z
])(?=
.*
[\W
_
]))[
a-zA-Z
\d\W
_
]{8,12}
$/
;
const
passwordMessage
=
"密码至少满足三种格式(大写字母、小写字母、数字、特殊符号), 长度为8~12位字符!"
;
export
default
function
PasswordDrawer
({
open
,
onClose
,
onSubmit
}:
PasswordDrawerProps
)
{
const
[
form
]
=
Form
.
useForm
<
PasswordFormValues
>
();
useEffect
(()
=>
{
if
(
!
open
)
form
.
resetFields
();
},
[
form
,
open
]);
return
(
<
Drawer
mask=
{
false
}
open=
{
open
}
onClose=
{
onClose
}
footer=
{
null
}
>
<
Form
labelCol=
{
{
span
:
6
}
}
form=
{
form
}
wrapperCol=
{
{
span
:
12
}
}
onFinish=
{
onSubmit
}
>
<
Form
.
Item
label=
"新密码"
name=
"password"
wrapperCol=
{
{
span
:
16
}
}
rules=
{
[
{
required
:
true
,
message
:
"请输入新密码"
},
{
pattern
:
passwordPattern
,
message
:
passwordMessage
},
{
validator
(
_
,
value
)
{
if
(
!
value
||
form
.
getFieldValue
(
"re_password"
)
===
value
)
{
form
.
setFields
([{
name
:
"re_password"
,
errors
:
[
""
]
}]);
return
Promise
.
resolve
();
}
form
.
setFields
([{
name
:
"re_password"
,
errors
:
[
"两次输入的密码不一致"
]
}]);
return
Promise
.
reject
();
},
},
]
}
>
<
Input
.
Password
autoComplete=
"off"
placeholder=
"请输入新密码"
/>
</
Form
.
Item
>
<
Form
.
Item
label=
"确认新密码"
name=
"re_password"
wrapperCol=
{
{
span
:
16
}
}
rules=
{
[
{
required
:
true
,
message
:
"请再次输入新密码"
},
{
pattern
:
passwordPattern
,
message
:
passwordMessage
},
{
validator
(
_
,
value
)
{
if
(
!
value
||
form
.
getFieldValue
(
"password"
)
===
value
)
return
Promise
.
resolve
();
return
Promise
.
reject
(
new
Error
(
"两次输入的密码不一致"
));
},
},
]
}
>
<
Input
.
Password
autoComplete=
"off"
placeholder=
"请再次输入新密码"
/>
</
Form
.
Item
>
<
Form
.
Item
wrapperCol=
{
{
offset
:
10
,
span
:
24
}
}
>
<
Space
size=
{
20
}
>
<
Button
onClick=
{
onClose
}
>
取消
</
Button
>
<
Button
type=
"primary"
htmlType=
"submit"
>
提交
</
Button
>
</
Space
>
</
Form
.
Item
>
</
Form
>
</
Drawer
>
);
}
apps/admin/src/modules/access/admin/query.ts
0 → 100644
浏览文件 @
9b39dd3e
import
type
{
Dayjs
}
from
"dayjs"
;
export
interface
AdminFilters
{
real_name
?:
string
;
tel
?:
string
;
role_id
?:
string
|
number
|
null
;
time
?:
[
Dayjs
|
null
,
Dayjs
|
null
]
|
null
;
}
export
interface
AdminQuery
{
page
:
number
;
page_size
:
number
;
real_name
?:
string
;
tel
?:
string
;
role_id
?:
string
|
number
;
start_time
?:
number
;
end_time
?:
number
;
}
interface
BuildAdminQueryInput
{
page
:
number
;
pageSize
:
number
;
filters
:
AdminFilters
;
}
export
function
buildAdminQuery
({
page
,
pageSize
,
filters
}:
BuildAdminQueryInput
):
AdminQuery
{
const
query
:
AdminQuery
=
{
page
,
page_size
:
pageSize
};
if
(
filters
.
real_name
)
query
.
real_name
=
filters
.
real_name
;
if
(
filters
.
tel
)
query
.
tel
=
filters
.
tel
;
if
(
filters
.
role_id
)
query
.
role_id
=
filters
.
role_id
;
if
(
filters
.
time
?.[
0
]
&&
filters
.
time
[
1
])
{
query
.
start_time
=
filters
.
time
[
0
].
startOf
(
"day"
).
unix
();
query
.
end_time
=
filters
.
time
[
1
].
endOf
(
"day"
).
unix
();
}
return
query
;
}
apps/admin/src/modules/access/admin/routes.tsx
0 → 100644
浏览文件 @
9b39dd3e
import
{
Navigate
,
useRoutes
}
from
"react-router"
;
import
AdminListView
from
"./views/AdminListView"
;
export
default
function
AdminRoutes
()
{
return
useRoutes
([
{
index
:
true
,
Component
:
AdminListView
},
{
path
:
"*"
,
element
:
<
Navigate
to=
"/jurisdiction/admin"
/>
},
]);
}
apps/admin/src/modules/access/admin/useAdminList.ts
0 → 100644
浏览文件 @
9b39dd3e
import
{
useCallback
,
useEffect
,
useRef
,
useState
}
from
"react"
;
import
{
getAdminList
,
type
AdminListResult
,
type
AdminRow
}
from
"./api"
;
import
{
buildAdminQuery
,
type
AdminFilters
,
type
AdminQuery
}
from
"./query"
;
const
INITIAL_PAGE
=
1
;
const
INITIAL_PAGE_SIZE
=
10
;
function
isCleared
(
previous
:
AdminFilters
,
next
:
AdminFilters
)
{
const
keys
=
new
Set
([...
Object
.
keys
(
previous
),
...
Object
.
keys
(
next
)])
as
Set
<
keyof
AdminFilters
>
;
return
[...
keys
].
some
((
key
)
=>
previous
[
key
]
!==
next
[
key
]
&&
!
next
[
key
]);
}
export
function
useAdminList
()
{
const
[
filters
,
setFilterState
]
=
useState
<
AdminFilters
>
({});
const
[
appliedFilters
,
setAppliedFilters
]
=
useState
<
AdminFilters
>
({});
const
[
page
,
setPage
]
=
useState
(
INITIAL_PAGE
);
const
[
pageSize
,
setPageSize
]
=
useState
(
INITIAL_PAGE_SIZE
);
const
[
rows
,
setRows
]
=
useState
<
AdminRow
[]
>
([]);
const
[
total
,
setTotal
]
=
useState
(
0
);
const
[
loading
,
setLoading
]
=
useState
(
true
);
const
[
error
,
setError
]
=
useState
<
Error
|
null
>
(
null
);
const
requestId
=
useRef
(
0
);
const
lastQuery
=
useRef
<
AdminQuery
>
(
buildAdminQuery
({
page
:
INITIAL_PAGE
,
pageSize
:
INITIAL_PAGE_SIZE
,
filters
:
{}
}),
);
const
load
=
useCallback
(
async
(
query
:
AdminQuery
)
=>
{
const
currentRequest
=
++
requestId
.
current
;
lastQuery
.
current
=
query
;
setLoading
(
true
);
setError
(
null
);
try
{
const
result
:
AdminListResult
|
false
=
await
getAdminList
(
query
);
if
(
currentRequest
!==
requestId
.
current
)
return
;
if
(
result
===
false
)
{
setError
(
new
Error
(
"数据获取失败!"
));
return
;
}
setRows
(
result
.
rows
);
setTotal
(
result
.
total
);
}
catch
(
reason
)
{
if
(
currentRequest
===
requestId
.
current
)
{
setError
(
reason
instanceof
Error
?
reason
:
new
Error
(
"数据获取失败!"
));
}
}
finally
{
if
(
currentRequest
===
requestId
.
current
)
setLoading
(
false
);
}
},
[]);
const
loadFor
=
useCallback
(
(
nextPage
:
number
,
nextPageSize
:
number
,
nextFilters
:
AdminFilters
)
=>
load
(
buildAdminQuery
({
page
:
nextPage
,
pageSize
:
nextPageSize
,
filters
:
nextFilters
})),
[
load
],
);
useEffect
(()
=>
{
void
load
(
lastQuery
.
current
);
return
()
=>
{
requestId
.
current
+=
1
;
};
},
[
load
]);
const
setFilters
=
useCallback
(
(
nextFilters
:
AdminFilters
)
=>
{
const
shouldReload
=
isCleared
(
filters
,
nextFilters
);
setFilterState
(
nextFilters
);
if
(
shouldReload
)
{
setAppliedFilters
(
nextFilters
);
void
loadFor
(
page
,
pageSize
,
nextFilters
);
}
},
[
filters
,
loadFor
,
page
,
pageSize
],
);
const
search
=
useCallback
(()
=>
{
setAppliedFilters
(
filters
);
setPage
(
INITIAL_PAGE
);
void
loadFor
(
INITIAL_PAGE
,
pageSize
,
filters
);
},
[
filters
,
loadFor
,
pageSize
]);
const
reset
=
useCallback
(()
=>
{
const
emptyFilters
:
AdminFilters
=
{};
setFilterState
(
emptyFilters
);
setAppliedFilters
(
emptyFilters
);
setPage
(
INITIAL_PAGE
);
void
loadFor
(
INITIAL_PAGE
,
pageSize
,
emptyFilters
);
},
[
loadFor
,
pageSize
]);
const
refresh
=
useCallback
(()
=>
{
setAppliedFilters
(
filters
);
void
loadFor
(
page
,
pageSize
,
filters
);
},
[
filters
,
loadFor
,
page
,
pageSize
]);
const
refreshUnfiltered
=
useCallback
(()
=>
{
void
loadFor
(
page
,
pageSize
,
{});
},
[
loadFor
,
page
,
pageSize
]);
const
changePage
=
useCallback
(
(
nextPage
:
number
)
=>
{
setPage
(
nextPage
);
void
loadFor
(
nextPage
,
pageSize
,
appliedFilters
);
},
[
appliedFilters
,
loadFor
,
pageSize
],
);
const
changePageSize
=
useCallback
(
(
nextPageSize
:
number
)
=>
{
setPage
(
INITIAL_PAGE
);
setPageSize
(
nextPageSize
);
void
loadFor
(
INITIAL_PAGE
,
nextPageSize
,
appliedFilters
);
},
[
appliedFilters
,
loadFor
],
);
const
retry
=
useCallback
(()
=>
void
load
(
lastQuery
.
current
),
[
load
]);
return
{
filters
,
setFilters
,
page
,
pageSize
,
rows
,
total
,
loading
,
error
,
search
,
reset
,
refresh
,
refreshUnfiltered
,
changePage
,
changePageSize
,
retry
,
};
}
apps/admin/src/modules/access/admin/views/AdminListView.tsx
0 → 100644
浏览文件 @
9b39dd3e
import
{
Button
,
DatePicker
,
Input
,
Select
,
Space
,
Switch
}
from
"antd"
;
import
type
{
ColumnsType
}
from
"antd/es/table"
;
import
dayjs
from
"dayjs"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
useSelector
}
from
"react-redux"
;
import
{
AppList
,
type
AppListFilterItem
}
from
"@/shared/components/AppList"
;
import
{
addAdmin
,
changeAdminPassword
,
changeAdminStatus
,
deleteAdmin
,
editAdmin
,
getAdminInfo
,
getRoleOptions
,
type
AdminRow
,
type
RoleOption
,
}
from
"../api"
;
import
AdminFormDrawer
,
{
type
AdminFormValues
}
from
"../components/AdminFormDrawer"
;
import
DeleteAdminModal
from
"../components/DeleteAdminModal"
;
import
PasswordDrawer
,
{
type
PasswordFormValues
}
from
"../components/PasswordDrawer"
;
import
type
{
AdminFilters
}
from
"../query"
;
import
{
useAdminList
}
from
"../useAdminList"
;
interface
RootState
{
user
:
{
operationPermissionsList
?:
string
[];
};
}
const
{
RangePicker
}
=
DatePicker
;
export
default
function
AdminListView
()
{
const
list
=
useAdminList
();
const
permissions
=
useSelector
((
state
:
RootState
)
=>
state
.
user
.
operationPermissionsList
??
[]);
const
[
roles
,
setRoles
]
=
useState
<
RoleOption
[]
>
([]);
const
[
selectedId
,
setSelectedId
]
=
useState
<
number
|
null
>
(
null
);
const
[
formOpen
,
setFormOpen
]
=
useState
(
false
);
const
[
isAdd
,
setIsAdd
]
=
useState
(
false
);
const
[
initialAdmin
,
setInitialAdmin
]
=
useState
<
Partial
<
AdminFormValues
>
|
null
>
(
null
);
const
[
passwordOpen
,
setPasswordOpen
]
=
useState
(
false
);
const
[
deleteOpen
,
setDeleteOpen
]
=
useState
(
false
);
useEffect
(()
=>
{
let
active
=
true
;
void
getRoleOptions
().
then
((
result
)
=>
{
if
(
active
&&
result
!==
false
)
setRoles
(
result
);
});
return
()
=>
{
active
=
false
;
};
},
[]);
const
handleEdit
=
async
(
id
:
number
)
=>
{
const
admin
=
await
getAdminInfo
(
id
);
if
(
admin
===
false
)
return
;
setSelectedId
(
id
);
setIsAdd
(
false
);
setInitialAdmin
({
real_name
:
admin
.
real_name
,
tel
:
admin
.
tel
,
role_id
:
admin
.
role_id
,
validity
:
dayjs
(
admin
.
validity
),
});
setFormOpen
(
true
);
};
const
handleFormSubmit
=
async
(
values
:
AdminFormValues
)
=>
{
const
params
=
{
...
values
,
validity
:
dayjs
(
values
.
validity
).
unix
()
};
const
success
=
isAdd
?
await
addAdmin
(
params
)
:
await
editAdmin
({
...
params
,
id
:
selectedId
});
if
(
!
success
)
return
;
list
.
refreshUnfiltered
();
setFormOpen
(
false
);
};
const
handlePasswordSubmit
=
async
({
password
,
re_password
}:
PasswordFormValues
)
=>
{
if
(
selectedId
===
null
)
return
;
const
success
=
await
changeAdminPassword
({
id
:
selectedId
,
password
,
re_password
,
});
if
(
!
success
)
return
;
list
.
refreshUnfiltered
();
setPasswordOpen
(
false
);
};
const
handleDelete
=
async
()
=>
{
if
(
selectedId
===
null
)
return
;
const
success
=
await
deleteAdmin
(
selectedId
);
if
(
success
)
list
.
refreshUnfiltered
();
setDeleteOpen
(
false
);
};
const
handleStatus
=
async
(
checked
:
boolean
,
id
:
number
)
=>
{
const
success
=
await
changeAdminStatus
(
id
,
checked
?
"1"
:
"0"
);
if
(
success
)
list
.
refreshUnfiltered
();
};
const
columns
:
ColumnsType
<
AdminRow
>
=
[
{
title
:
"ID"
,
key
:
"id"
,
dataIndex
:
"id"
,
align
:
"center"
},
{
title
:
"管理员名称"
,
key
:
"real_name"
,
dataIndex
:
"real_name"
,
align
:
"center"
,
},
{
title
:
"手机号"
,
key
:
"tel"
,
dataIndex
:
"tel"
,
align
:
"center"
},
{
title
:
"角色名称"
,
key
:
"role_name"
,
dataIndex
:
"role_name"
,
align
:
"center"
,
},
{
title
:
"状态"
,
key
:
"sort"
,
dataIndex
:
"sort"
,
align
:
"center"
,
render
:
(
_
,
record
)
=>
(
<
Switch
checked=
{
Number
(
record
.
status
)
===
1
}
onChange=
{
(
checked
)
=>
void
handleStatus
(
checked
,
record
.
id
)
}
disabled=
{
!
permissions
.
includes
(
"/jurisdiction/admin/changeStatus"
)
}
/>
),
},
{
title
:
"有效期"
,
key
:
"validity"
,
dataIndex
:
"validity"
,
align
:
"center"
},
{
title
:
"创建时间"
,
key
:
"create_time"
,
dataIndex
:
"create_time"
,
align
:
"center"
,
},
{
title
:
"操作"
,
key
:
"handle"
,
dataIndex
:
"handle"
,
render
:
(
_
,
record
)
=>
(
<
Space
>
{
permissions
.
includes
(
"/jurisdiction/admin/getInfoById"
)
?
(
<
Button
onClick=
{
()
=>
void
handleEdit
(
record
.
id
)
}
>
编辑
</
Button
>
)
:
null
}
{
permissions
.
includes
(
"/jurisdiction/admin/editPass"
)
?
(
<
Button
onClick=
{
()
=>
{
setSelectedId
(
record
.
id
);
setPasswordOpen
(
true
);
}
}
>
修改密码
</
Button
>
)
:
null
}
{
permissions
.
includes
(
"/jurisdiction/admin/del"
)
?
(
<
Button
onClick=
{
()
=>
{
setSelectedId
(
record
.
id
);
setDeleteOpen
(
true
);
}
}
>
删除
</
Button
>
)
:
null
}
</
Space
>
),
},
];
const
filterItems
:
AppListFilterItem
<
AdminFilters
>
[]
=
[
{
name
:
"real_name"
,
label
:
"管理员名称"
,
render
:
(
field
)
=>
(
<
Input
autoComplete=
"off"
allowClear
value=
{
field
.
value
??
""
}
onChange=
{
(
event
)
=>
field
.
onChange
(
event
.
target
.
value
)
}
placeholder=
"请输入管理员名称"
id=
"name"
/>
),
},
{
name
:
"tel"
,
label
:
"手机号"
,
render
:
(
field
)
=>
(
<
Input
autoComplete=
"off"
allowClear
value=
{
field
.
value
??
""
}
onChange=
{
(
event
)
=>
field
.
onChange
(
event
.
target
.
value
)
}
placeholder=
"请输入手机号"
id=
"phone"
/>
),
},
{
name
:
"role_id"
,
label
:
"角色"
,
render
:
(
field
)
=>
(
<
Select
placeholder=
"请选择角色"
allowClear
style=
{
{
width
:
"200px"
}
}
value=
{
field
.
value
}
onChange=
{
field
.
onChange
}
options=
{
roles
.
map
((
role
)
=>
({
label
:
role
.
name
,
value
:
role
.
id
}))
}
/>
),
},
{
name
:
"time"
,
label
:
"有效期"
,
render
:
(
field
)
=>
(
<
RangePicker
value=
{
field
.
value
}
onChange=
{
(
value
)
=>
field
.
onChange
(
value
)
}
allowClear
id=
"createTime"
/>
),
},
];
const
toolbar
=
permissions
.
includes
(
"/jurisdiction/role/add"
)
?
(
<
Button
type=
"primary"
ghost
onClick=
{
()
=>
{
setSelectedId
(
null
);
setInitialAdmin
(
null
);
setIsAdd
(
true
);
setFormOpen
(
true
);
}
}
>
添加
</
Button
>
)
:
undefined
;
return
(
<>
<
AppList
<
AdminRow
,
AdminFilters
>
rowKey="id"
columns=
{
columns
}
data=
{
{
rows
:
list
.
rows
,
total
:
list
.
total
,
loading
:
list
.
loading
,
error
:
list
.
error
,
}
}
filters=
{
{
value
:
list
.
filters
,
items
:
filterItems
,
onChange
:
list
.
setFilters
,
onSearch
:
list
.
search
,
onReset
:
list
.
reset
,
onRefresh
:
list
.
refresh
,
}
}
pagination=
{
{
page
:
list
.
page
,
pageSize
:
list
.
pageSize
,
pageSizeOptions
:
[
10
,
20
,
30
,
40
],
onChange
:
list
.
changePage
,
onPageSizeChange
:
list
.
changePageSize
,
}
}
toolbar=
{
toolbar
}
onRetry=
{
list
.
retry
}
/
>
<
AdminFormDrawer
open=
{
formOpen
}
isAdd=
{
isAdd
}
initialAdmin=
{
initialAdmin
}
roles=
{
roles
}
onClose=
{
()
=>
setFormOpen
(
false
)
}
onSubmit=
{
handleFormSubmit
}
/>
<
PasswordDrawer
open=
{
passwordOpen
}
onClose=
{
()
=>
setPasswordOpen
(
false
)
}
onSubmit=
{
handlePasswordSubmit
}
/>
<
DeleteAdminModal
open=
{
deleteOpen
}
onCancel=
{
()
=>
setDeleteOpen
(
false
)
}
onConfirm=
{
handleDelete
}
/>
</>
);
}
apps/admin/src/modules/access/routes.tsx
浏览文件 @
9b39dd3e
...
@@ -3,7 +3,7 @@ import { Navigate, useRoutes } from "react-router";
...
@@ -3,7 +3,7 @@ import { Navigate, useRoutes } from "react-router";
import
ModuleBoundary
from
"@/app/ModuleBoundary"
;
import
ModuleBoundary
from
"@/app/ModuleBoundary"
;
const
AccessLayout
=
lazy
(()
=>
import
(
"@/pages/jurisdiction/index"
));
const
AccessLayout
=
lazy
(()
=>
import
(
"@/pages/jurisdiction/index"
));
const
Admin
=
lazy
(()
=>
import
(
"@/pages/jurisdiction/admin/index
"
));
const
Admin
Routes
=
lazy
(()
=>
import
(
"./admin/routes
"
));
const
Role
=
lazy
(()
=>
import
(
"@/pages/jurisdiction/role/index"
));
const
Role
=
lazy
(()
=>
import
(
"@/pages/jurisdiction/role/index"
));
export
default
function
AccessRoutes
()
{
export
default
function
AccessRoutes
()
{
...
@@ -12,7 +12,7 @@ export default function AccessRoutes() {
...
@@ -12,7 +12,7 @@ export default function AccessRoutes() {
Component
:
AccessLayout
,
Component
:
AccessLayout
,
children
:
[
children
:
[
{
index
:
true
,
element
:
<
Navigate
to=
"/jurisdiction/role"
/>
},
{
index
:
true
,
element
:
<
Navigate
to=
"/jurisdiction/role"
/>
},
{
path
:
"admin
"
,
Component
:
Admin
},
{
path
:
"admin
/*"
,
Component
:
AdminRoutes
},
{
path
:
"role"
,
Component
:
Role
},
{
path
:
"role"
,
Component
:
Role
},
],
],
},
},
...
...
apps/admin/src/pages/jurisdiction/admin/index.jsx
deleted
100644 → 0
浏览文件 @
c36c6000
import
React
,
{
useEffect
,
useState
,
useRef
}
from
"react"
;
import
{
Table
,
Input
,
Button
,
Row
,
Col
,
Space
,
DatePicker
,
Pagination
,
Drawer
,
Form
,
Modal
,
Switch
,
Select
,
Image
,
}
from
"antd"
;
import
{
useNavigate
}
from
"react-router"
;
const
{
RangePicker
}
=
DatePicker
;
import
PaginationCom
from
"@/common/Pagination"
;
import
{
getList1
,
addRole
,
infoRole
,
editRole
,
changeStatus
,
delRole
,
editPass
}
from
"./request"
;
import
{
getAllList
}
from
"../role/request"
;
import
reload
from
"@/assets/images/icon/reload.png"
;
import
reset
from
"@/assets/images/icon/reset.png"
;
import
filter
from
"@/assets/images/icon/filter.png"
;
import
add
from
"@/assets/images/icon/add.png"
;
import
dayjs
from
"dayjs"
;
import
TableCom
from
"@/common/TableCom/index"
;
import
{
useSelector
}
from
"react-redux"
;
const
Administrator
=
()
=>
{
const
[
data
,
setData
]
=
useState
([]);
const
navigate
=
useNavigate
();
const
[
page_size
,
setpage_size
]
=
useState
(
10
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
[
total
,
setTotal
]
=
useState
(
0
);
const
[
loading
,
setLoading
]
=
useState
(
true
);
const
[
showModal
,
setshowModal
]
=
useState
(
false
);
const
[
isAdd
,
setIsAdd
]
=
useState
(
false
);
const
[
delMoadal
,
setDelModal
]
=
useState
(
false
);
const
[
passwordModal
,
setPasswordModal
]
=
useState
(
false
);
const
[
form
]
=
Form
.
useForm
();
const
[
form2
]
=
Form
.
useForm
();
const
[
id
,
setId
]
=
useState
(
0
);
const
flag
=
useRef
(
true
);
// 获取操作权限
const
{
operationPermissionsList
}
=
useSelector
((
state
)
=>
state
.
user
);
// 角色列表
const
[
roleList
,
setRoleList
]
=
useState
([]);
const
[
initialValues
,
setinitialValues
]
=
useState
({
real_name
:
""
,
tel
:
""
,
role_id
:
""
,
validity
:
""
,
password
:
""
,
});
const
[
filterObj
,
setfilterObj
]
=
useState
({
real_name
:
""
,
tel
:
""
,
role_id
:
null
,
start_time
:
""
,
end_time
:
""
,
});
const
[
dateVal
,
setDateVal
]
=
useState
([]);
// 过滤
const
handleFilter
=
(
flag
,
val
)
=>
{
if
(
flag
==
"startandend"
)
{
let
val2
=
val
||
[];
filterObj
[
"start_time"
]
=
parseInt
(
new
Date
(
dayjs
(
val2
[
0
]).
format
(
"YYYY-MM-DD"
)
+
" 00:00:00"
).
getTime
()
/
1000
,
);
const
endDate
=
new
Date
(
dayjs
(
val2
[
1
])).
getDate
();
const
endTime
=
parseInt
(
new
Date
(
dayjs
(
val2
[
1
]).
format
(
"YYYY-MM-"
)
+
endDate
+
" 23:59:59"
).
getTime
()
/
1000
,
);
filterObj
[
"end_time"
]
=
endTime
;
setDateVal
(
val
);
if
(
!
val2
.
length
)
{
delete
filterObj
[
"start_time"
];
delete
filterObj
[
"end_time"
];
}
}
else
{
filterObj
[
flag
]
=
val
;
}
for
(
const
key
in
filterObj
)
{
if
(
!
filterObj
[
key
])
{
delete
filterObj
[
key
];
}
}
setfilterObj
({
...
filterObj
});
if
(
!
val
)
init
(
filterObj
);
};
// 重置
const
handleReset
=
()
=>
{
setfilterObj
({
real_name
:
""
,
tel
:
""
,
role_id
:
""
});
setDateVal
([]);
init
();
};
const
init
=
async
(
obj
=
{})
=>
{
setLoading
(
true
);
const
{
total
,
list
}
=
await
getList1
({
page
,
page_size
,
...
obj
});
setTotal
(
total
);
setData
(
list
);
setLoading
(
false
);
};
const
handleEdit
=
async
(
id
)
=>
{
console
.
log
(
"handleEdit id"
,
id
);
const
data
=
await
infoRole
({
id
});
let
{
validity
}
=
data
;
setIsAdd
(
false
);
setshowModal
(
true
);
setId
(
id
);
form
.
setFieldsValue
({
...
data
,
validity
:
dayjs
(
validity
)
});
};
const
onClose
=
()
=>
{
setshowModal
(
false
);
};
const
submitForm
=
async
(
obj
)
=>
{
let
bool
;
let
{
validity
}
=
obj
;
if
(
isAdd
)
{
bool
=
await
addRole
({
...
obj
,
validity
:
dayjs
(
validity
).
unix
(),
});
}
else
{
bool
=
await
editRole
({
...
obj
,
id
,
validity
:
dayjs
(
validity
).
unix
()
});
}
if
(
!
bool
)
return
;
init
();
setshowModal
(
false
);
};
const
delSuccess
=
async
(
id
)
=>
{
console
.
log
(
"id"
,
id
);
const
bool
=
await
delRole
({
id
});
console
.
log
(
"bool"
,
bool
);
bool
&&
init
();
setDelModal
(
false
);
};
const
handleStatus
=
async
(
status
,
id
)
=>
{
const
bool
=
await
changeStatus
({
status
:
status
?
"1"
:
"0"
,
id
});
bool
&&
init
();
};
const
passwordSuccess
=
async
(
obj
)
=>
{
let
{
password
:
pass
,
re_password
:
repass
}
=
obj
;
const
bool
=
await
editPass
({
id
,
password
:
pass
,
re_password
:
repass
});
if
(
!
bool
)
return
;
init
();
setPasswordModal
(
false
);
};
// 获取角色
const
RoleList
=
async
()
=>
{
const
res
=
await
getAllList
({
type
:
1
});
setRoleList
(
res
);
};
useEffect
(()
=>
{
// if(!flag.current){
RoleList
();
// }else{
// flag.current=false
// }
},
[]);
useEffect
(()
=>
{
if
(
!
passwordModal
)
{
form2
.
setFieldsValue
({
password
:
""
,
re_password
:
""
,
});
}
},
[
passwordModal
]);
const
columns
=
[
{
title
:
"ID"
,
key
:
"id"
,
dataIndex
:
"id"
,
align
:
"center"
,
},
{
title
:
"管理员名称"
,
key
:
"real_name"
,
dataIndex
:
"real_name"
,
align
:
"center"
,
},
{
title
:
"手机号"
,
key
:
"tel"
,
dataIndex
:
"tel"
,
align
:
"center"
,
},
{
title
:
"角色名称"
,
key
:
"role_name"
,
dataIndex
:
"role_name"
,
align
:
"center"
,
},
{
title
:
"状态"
,
key
:
"sort"
,
dataIndex
:
"sort"
,
render
(
_
,
{
status
,
id
})
{
return
(
<
Switch
defaultChecked=
{
status
}
onChange=
{
(
ev
)
=>
handleStatus
(
ev
,
id
)
}
disabled=
{
!
operationPermissionsList
.
includes
(
"/jurisdiction/admin/changeStatus"
)
}
/>
);
},
align
:
"center"
,
},
{
title
:
"有效期"
,
key
:
"validity"
,
align
:
"center"
,
dataIndex
:
"validity"
,
},
{
title
:
"创建时间"
,
key
:
"create_time"
,
align
:
"center"
,
dataIndex
:
"create_time"
,
},
{
title
:
"操作"
,
key
:
"handle"
,
dataIndex
:
"handle"
,
render
:
(
_
,
record
)
=>
{
return
(
<
Space
>
{
operationPermissionsList
.
includes
(
"/jurisdiction/admin/getInfoById"
)
&&
(
<
Button
onClick=
{
()
=>
handleEdit
(
record
.
id
)
}
>
编辑
</
Button
>
)
}
{
operationPermissionsList
.
includes
(
"/jurisdiction/admin/editPass"
)
&&
(
<
Button
onClick=
{
()
=>
{
setId
(
record
.
id
);
setPasswordModal
(
true
);
}
}
>
修改密码
</
Button
>
)
}
{
operationPermissionsList
.
includes
(
"/jurisdiction/admin/del"
)
&&
(
<
Button
onClick=
{
()
=>
{
setId
(
record
.
id
);
setDelModal
(
true
);
}
}
>
删除
</
Button
>
)
}
</
Space
>
);
},
},
];
useEffect
(()
=>
{
if
(
!
showModal
)
{
form
.
setFieldsValue
({
real_name
:
""
,
tel
:
""
,
role_id
:
null
,
validity
:
""
,
password
:
""
,
});
form
.
resetFields
();
}
},
[
showModal
]);
return
(
<
div
>
<
Row
justify=
{
"space-between"
}
>
<
Col
className=
"form-devices-inline"
>
<
Form
layout=
"inline"
>
<
Form
.
Item
label=
"管理员名称"
>
<
Input
autoComplete=
"off"
allowClear
value=
{
filterObj
.
real_name
}
onChange=
{
(
ev
)
=>
handleFilter
(
"real_name"
,
ev
.
target
.
value
)
}
placeholder=
"请输入管理员名称"
id=
"name"
></
Input
>
</
Form
.
Item
>
<
Form
.
Item
label=
"手机号"
>
<
Input
autoComplete=
"off"
allowClear
value=
{
filterObj
.
tel
}
onChange=
{
(
ev
)
=>
handleFilter
(
"tel"
,
ev
.
target
.
value
)
}
placeholder=
"请输入手机号"
id=
"phone"
></
Input
>
</
Form
.
Item
>
<
Form
.
Item
label=
"角色"
rules=
{
[{
required
:
true
,
message
:
"请选择角色"
}]
}
>
<
Select
placeholder=
"请选择角色"
allowClear
style=
{
{
width
:
"200px"
}
}
>
{
roleList
.
length
&&
roleList
.
map
((
item
)
=>
(
<
Select
.
Option
key=
{
item
.
id
}
value=
{
item
.
id
}
>
{
item
.
name
}
</
Select
.
Option
>
))
}
</
Select
>
</
Form
.
Item
>
<
Form
.
Item
label=
"有效期"
>
<
RangePicker
value=
{
dateVal
}
onChange=
{
(
ev
)
=>
handleFilter
(
"startandend"
,
ev
)
}
allowClear
id=
"createTime"
></
RangePicker
>
</
Form
.
Item
>
<
Space
>
<
Button
type=
"primary"
ghost
icon=
{
<
span
style=
{
{
display
:
"inline-block"
,
width
:
"11px"
,
height
:
"10px"
,
pointerEvents
:
"none"
,
}
}
>
<
Image
src=
{
reset
}
/>
</
span
>
}
onClick=
{
handleReset
}
>
重置
</
Button
>
<
Button
type=
"primary"
icon=
{
<
span
style=
{
{
display
:
"inline-block"
,
width
:
"13px"
,
height
:
"12px"
,
pointerEvents
:
"none"
,
}
}
>
<
Image
src=
{
filter
}
/>
</
span
>
}
ghost
onClick=
{
()
=>
{
setPage
(
1
);
Object
.
values
(
filterObj
).
some
((
item
)
=>
item
)
?
init
(
filterObj
)
:
init
();
}
}
>
筛选
</
Button
>
<
Button
type=
"primary"
ghost
icon=
{
<
span
style=
{
{
display
:
"inline-block"
,
width
:
"10px"
,
height
:
"12px"
,
pointerEvents
:
"none"
,
}
}
>
<
Image
src=
{
reload
}
/>
</
span
>
}
onClick=
{
()
=>
Object
.
values
(
filterObj
).
some
((
item
)
=>
item
)
?
init
(
filterObj
)
:
init
()
}
>
刷新
</
Button
>
{
/* <Button
type='primary'
ghost
icon={
<span
style={{
display: 'inline-block',
width: '13px',
height: '12px',
pointerEvents: 'none',
}}
>
<Image src={add} />
</span>
}
onClick={() => {
setIsAdd(true);
setshowModal(true);
}}
>
添加
</Button> */
}
</
Space
>
</
Form
>
</
Col
>
<
Col
>
<
Space
>
{
operationPermissionsList
.
includes
(
"/jurisdiction/role/add"
)
&&
(
<
Button
type=
"primary"
ghost
icon=
{
<
span
style=
{
{
display
:
"inline-block"
,
width
:
"13px"
,
height
:
"12px"
,
pointerEvents
:
"none"
,
}
}
>
<
Image
src=
{
add
}
/>
</
span
>
}
onClick=
{
()
=>
{
setIsAdd
(
true
);
setshowModal
(
true
);
}
}
>
添加
</
Button
>
)
}
</
Space
>
</
Col
>
</
Row
>
<
br
/>
{
TableCom
({
columns
,
loading
,
data
})
}
<
Modal
mask=
{
false
}
centered
open=
{
delMoadal
}
onOk=
{
()
=>
delSuccess
(
id
)
}
onCancel=
{
()
=>
setDelModal
(
false
)
}
footer=
{
(
_
,
{
OkBtn
,
CancelBtn
})
=>
{
return
(
<
Row
justify=
{
"center"
}
className=
"delModal"
style=
{
{
marginBottom
:
"30px"
}
}
>
<
Space
size=
{
20
}
>
<
CancelBtn
/>
<
OkBtn
/>
</
Space
>
</
Row
>
);
}
}
okText=
"确认"
>
<
p
style=
{
{
textAlign
:
"center"
,
padding
:
"30px 0 18px"
,
fontSize
:
16
}
}
>
管理员将永久删除,是否继续?
</
p
>
</
Modal
>
<
Drawer
mask=
{
false
}
centered
open=
{
passwordModal
}
onCancel=
{
()
=>
setPasswordModal
(
false
)
}
onClose=
{
()
=>
setPasswordModal
(
false
)
}
footer=
{
null
}
okText=
"提交"
>
<
Form
labelCol=
{
{
span
:
6
}
}
form=
{
form2
}
wrapperCol=
{
{
span
:
12
}
}
onFinish=
{
passwordSuccess
}
>
<
Form
.
Item
label=
"新密码"
name=
"password"
wrapperCol=
{
{
span
:
16
}
}
rules=
{
[
{
required
:
true
,
message
:
"请输入新密码"
},
{
pattern
:
/^
((?=
.*
\d)(?=
.*
[
A-Z
])(?=
.*
[
a-z
]))
|
((?=
.*
\d)(?=
.*
[
A-Z
])(?=
.*
[\W
_
]))
|
((?=
.*
\d)(?=
.*
[
a-z
])(?=
.*
[\W
_
]))
|
((?=
.*
[
A-Z
])(?=
.*
[
a-z
])(?=
.*
[\W
_
]))[
a-zA-Z
\d\W
_
]
{8,12}$/
,
message
:
"密码至少满足三种格式(大写字母、小写字母、数字、特殊符号), 长度为8~12位字符!"
,
trigger
:
[
"change"
,
"blur"
],
},
{
validator
(
_
,
value
)
{
if
(
!
value
||
form2
.
getFieldValue
(
"re_password"
)
===
value
)
{
form2
.
setFields
([{
name
:
"re_password"
,
errors
:
[
""
]
}]);
return
Promise
.
resolve
();
}
form2
.
setFields
([{
name
:
"re_password"
,
errors
:
[
"两次输入的密码不一致"
]
}]);
return
Promise
.
reject
();
},
},
]
}
// validateStatus='error' // 设置为 'error' 显示错误样式
>
<
Input
.
Password
autoComplete=
"off"
placeholder=
"请输入新密码"
></
Input
.
Password
>
</
Form
.
Item
>
<
Form
.
Item
label=
"确认新密码"
name=
"re_password"
wrapperCol=
{
{
span
:
16
}
}
rules=
{
[
{
required
:
true
,
message
:
"请再次输入新密码"
},
{
pattern
:
/^
((?=
.*
\d)(?=
.*
[
A-Z
])(?=
.*
[
a-z
]))
|
((?=
.*
\d)(?=
.*
[
A-Z
])(?=
.*
[\W
_
]))
|
((?=
.*
\d)(?=
.*
[
a-z
])(?=
.*
[\W
_
]))
|
((?=
.*
[
A-Z
])(?=
.*
[
a-z
])(?=
.*
[\W
_
]))[
a-zA-Z
\d\W
_
]
{8,12}$/
,
message
:
"密码至少满足三种格式(大写字母、小写字母、数字、特殊符号), 长度为8~12位字符!"
,
trigger
:
[
"change"
,
"blur"
],
},
{
validator
(
_
,
value
)
{
if
(
!
value
||
form2
.
getFieldValue
(
"password"
)
===
value
)
{
return
Promise
.
resolve
();
}
return
Promise
.
reject
(
new
Error
(
"两次输入的密码不一致"
));
},
},
]
}
>
<
Input
.
Password
autoComplete=
"off"
placeholder=
"请再次输入新密码"
></
Input
.
Password
>
</
Form
.
Item
>
<
Form
.
Item
wrapperCol=
{
{
offset
:
10
,
span
:
24
}
}
>
<
Space
size=
{
20
}
>
<
Button
onClick=
{
()
=>
setPasswordModal
(
false
)
}
>
取消
</
Button
>
<
Button
type=
"primary"
htmlType=
"submit"
>
提交
</
Button
>
</
Space
>
</
Form
.
Item
>
</
Form
>
</
Drawer
>
<
br
/>
<
PaginationCom
total=
{
total
}
page_size=
{
page_size
}
setpage_size=
{
setpage_size
}
page=
{
page
}
setPage=
{
setPage
}
init=
{
init
}
filterObj=
{
filterObj
}
/>
<
Drawer
placement=
"right"
onClose=
{
onClose
}
open=
{
showModal
}
mask=
{
false
}
>
<
Form
form=
{
form
}
onFinish=
{
submitForm
}
labelCol=
{
{
span
:
6
}
}
>
<
Form
.
Item
name=
"real_name"
label=
"管理员名称"
rules=
{
[
{
required
:
true
,
message
:
"请输入管理员名称"
},
{
max
:
30
,
message
:
"最大30字符"
},
]
}
>
<
Input
autoComplete=
"off"
placeholder=
"请输入管理员名称"
></
Input
>
</
Form
.
Item
>
<
Form
.
Item
name=
"tel"
label=
"手机号"
rules=
{
[
{
required
:
true
,
message
:
"请输入手机号"
},
{
pattern
:
/^
(?:(?:\+
|00
)
86
)?
1
[
3-9
]\d
{9}$/
,
message
:
"请输入正确格式的手机号"
,
trigger
:
"blur"
,
},
]
}
>
<
Input
autoComplete=
"off"
placeholder=
"请输入手机号"
></
Input
>
</
Form
.
Item
>
<
Form
.
Item
name=
"role_id"
label=
"角色"
rules=
{
[{
required
:
true
,
message
:
"请选择角色"
}]
}
>
{
/* <Select placeholder='请选择角色'>
{roleList
.reduce((acc, item) => {
if (item.type === 1 && !acc.some((el) => el.type === 1)) {
acc.push(item);
}
if (item.type === 2 && !acc.some((el) => el.type === 2)) {
acc.push(item);
}
return acc;
}, [])
.map((item) => (
<Select.Option key={item.id} value={item.id}>
{item.type === 1 ? '管理员' : '老师'}
</Select.Option>
))}
</Select> */
}
<
Select
placeholder=
"请选择角色"
showSearch
optionFilterProp=
"children"
autoComplete=
"off"
>
{
roleList
.
length
&&
roleList
.
map
((
item
)
=>
(
<
Select
.
Option
key=
{
item
.
id
}
value=
{
item
.
id
}
>
{
item
.
name
}
</
Select
.
Option
>
))
}
</
Select
>
</
Form
.
Item
>
<
Form
.
Item
name=
"validity"
label=
"有效期"
rules=
{
[{
required
:
true
,
message
:
"请选择有效期"
}]
}
>
<
DatePicker
placeholder=
"请选择有效期"
></
DatePicker
>
</
Form
.
Item
>
{
isAdd
&&
(
<
Form
.
Item
name=
"password"
label=
"初始密码"
rules=
{
[
{
required
:
true
,
message
:
"请输入密码"
},
{
pattern
:
/^
((?=
.*
\d)(?=
.*
[
A-Z
])(?=
.*
[
a-z
]))
|
((?=
.*
\d)(?=
.*
[
A-Z
])(?=
.*
[\W
_
]))
|
((?=
.*
\d)(?=
.*
[
a-z
])(?=
.*
[\W
_
]))
|
((?=
.*
[
A-Z
])(?=
.*
[
a-z
])(?=
.*
[\W
_
]))[
a-zA-Z
\d\W
_
]
{8,12}$/
,
message
:
"密码至少满足三种格式(大写字母、小写字母、数字、特殊符号), 长度为8~12位字符!"
,
trigger
:
[
"change"
,
"blur"
],
},
]
}
>
<
Input
allowClear
placeholder=
"请输入密码"
autoComplete=
"off"
/>
{
/* <Input.Password
allowClear
placeholder='请输入密码'
autoComplete='new-password'
autoFill='off'
data-autocomplete='off'
style={{ MozAppearance: 'textfield' }}
name={Math.random().toString(36).substring(2)} // 假设这个值是每次都会重新生成的随机字符串
inputProps={{
autocomplete: 'new-password',
style: { WebkitTextSecurity: 'disc'}
, }} /> */
}
</
Form
.
Item
>
)
}
<
Form
.
Item
wrapperCol=
{
{
offset
:
5
,
span
:
16
}
}
style=
{
{
textAlign
:
"center"
}
}
>
<
Space
size=
{
20
}
>
<
Button
onClick=
{
()
=>
setshowModal
(
false
)
}
>
取消
</
Button
>
<
Button
type=
"primary"
htmlType=
"submit"
>
提交
</
Button
>
</
Space
>
</
Form
.
Item
>
</
Form
>
</
Drawer
>
</
div
>
);
};
export
default
Administrator
;
apps/admin/src/pages/jurisdiction/admin/request.js
deleted
100644 → 0
浏览文件 @
c36c6000
import
axios
from
"@/utils/request.js"
;
import
qs
from
"qs"
;
import
{
get
}
from
"lodash-es"
;
import
{
message
}
from
"antd"
;
// 管理员列表
const
getList1
=
async
(
obj
)
=>
{
try
{
const
res
=
await
axios
.
post
(
"/user/user/getList"
,
qs
.
stringify
(
obj
));
const
code
=
get
(
res
,
"data.code"
,
0
);
const
data
=
get
(
res
,
"data.data"
,
[]);
const
msg
=
get
(
res
,
"data.message"
,
"数据获取失败!"
);
if
(
code
===
200
)
{
return
data
;
}
else
{
message
.
error
(
msg
);
return
false
;
}
}
catch
(
error
)
{
return
false
;
}
};
// 添加
const
addRole
=
async
(
obj
)
=>
{
try
{
const
res
=
await
axios
.
post
(
"/user/user/add"
,
qs
.
stringify
(
obj
));
const
code
=
get
(
res
,
"data.code"
,
0
);
const
data
=
get
(
res
,
"data.data"
,
[]);
const
msg
=
get
(
res
,
"data.message"
,
"数据获取失败!"
);
if
(
code
===
200
)
{
message
.
success
(
msg
);
return
true
;
}
else
{
message
.
error
(
msg
);
return
false
;
}
}
catch
(
error
)
{
return
false
;
}
};
// 详情
const
infoRole
=
async
(
obj
)
=>
{
try
{
const
res
=
await
axios
.
post
(
"/user/user/getInfoById"
,
qs
.
stringify
(
obj
));
const
code
=
get
(
res
,
"data.code"
,
0
);
const
data
=
get
(
res
,
"data.data"
,
[]);
const
msg
=
get
(
res
,
"data.message"
,
"数据获取失败!"
);
if
(
code
===
200
)
{
return
data
;
}
else
{
message
.
error
(
msg
);
return
false
;
}
}
catch
(
error
)
{
return
false
;
}
};
// 修改
const
editRole
=
async
(
obj
)
=>
{
try
{
const
res
=
await
axios
.
post
(
"/user/user/edit"
,
qs
.
stringify
(
obj
));
const
code
=
get
(
res
,
"data.code"
,
0
);
const
data
=
get
(
res
,
"data.data"
,
[]);
const
msg
=
get
(
res
,
"data.message"
,
"数据获取失败!"
);
if
(
code
===
200
)
{
message
.
success
(
msg
);
return
true
;
}
else
{
message
.
error
(
msg
);
return
false
;
}
}
catch
(
error
)
{
return
false
;
}
};
// 删除
const
delRole
=
async
(
obj
)
=>
{
try
{
const
res
=
await
axios
.
post
(
"/user/user/del"
,
qs
.
stringify
(
obj
));
const
code
=
get
(
res
,
"data.code"
,
0
);
const
data
=
get
(
res
,
"data.data"
,
[]);
const
msg
=
get
(
res
,
"data.message"
,
"数据获取失败!"
);
if
(
code
===
200
)
{
message
.
success
(
msg
);
return
true
;
}
else
{
message
.
error
(
msg
);
return
false
;
}
}
catch
(
error
)
{
return
false
;
}
};
const
changeStatus
=
async
(
obj
)
=>
{
try
{
const
res
=
await
axios
.
post
(
"/user/user/changeStatus"
,
qs
.
stringify
(
obj
));
const
code
=
get
(
res
,
"data.code"
,
0
);
const
data
=
get
(
res
,
"data.data"
,
[]);
const
msg
=
get
(
res
,
"data.message"
,
"数据获取失败!"
);
if
(
code
===
200
)
{
message
.
success
(
msg
);
return
true
;
}
else
{
message
.
error
(
msg
);
return
false
;
}
}
catch
(
error
)
{
return
false
;
}
};
// 修改密码
const
editPass
=
async
(
obj
)
=>
{
try
{
const
res
=
await
axios
.
post
(
"/user/user/editPass"
,
qs
.
stringify
(
obj
));
const
code
=
get
(
res
,
"data.code"
,
0
);
const
data
=
get
(
res
,
"data.data"
,
[]);
const
msg
=
get
(
res
,
"data.message"
,
"数据获取失败!"
);
if
(
code
===
200
)
{
message
.
success
(
msg
);
return
true
;
}
else
{
message
.
error
(
msg
);
return
false
;
}
}
catch
(
error
)
{
return
false
;
}
};
export
{
getList1
,
addRole
,
infoRole
,
editRole
,
changeStatus
,
delRole
,
editPass
};
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论