Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
J
jinfa-admin
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
project
jinfa-admin
Commits
a3d015fe
Commit
a3d015fe
authored
Aug 17, 2020
by
前端-许佳敏
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
用户管理
parent
060069e7
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
177 additions
and
59 deletions
+177
-59
authConfig.ts
config/routes/authConfig.ts
+3
-1
package.json
package.json
+1
-0
index.less
src/components/DetailPage/index.less
+1
-1
index.tsx
src/components/TabTree/index.tsx
+9
-1
regExp.ts
src/constants/regExp.ts
+20
-0
useHttpRequest.ts
src/hooks/useHttpRequest.ts
+1
-1
index.tsx
src/pages/authConfig/userSystem/index.tsx
+1
-1
index.ts
src/pages/authConfig/userSystem/schema/index.ts
+25
-2
userDetail.tsx
src/pages/authConfig/userSystem/userDetail.tsx
+80
-50
index.ts
src/utils/index.ts
+35
-0
request.ts
src/utils/request.ts
+1
-2
No files found.
config/routes/authConfig.ts
View file @
a3d015fe
...
...
@@ -29,7 +29,8 @@ export default {
path
:
'/authConfig/userSystem/userDetail'
,
name
:
'userSystem'
,
component
:
'@/pages/authConfig/userSystem/userDetail'
,
hideInMenu
:
true
hideInMenu
:
true
,
hidePageHeader
:
true
},
],
}
\ No newline at end of file
package.json
View file @
a3d015fe
...
...
@@ -7,6 +7,7 @@
"scripts:build-yxc"
:
"node scripts/run http://yxc-web-demo.shushangyun.com/api"
,
"start"
:
"yarn api && yarn scripts:build && umi dev"
,
"build"
:
"yarn api && yarn scripts:build && umi build"
,
"build:yxc"
:
"yarn api && yarn scripts:build-yxc && umi build"
,
"build:dev"
:
"pm2 start scripts/devServer.js"
,
"build:analyze"
:
"ANALYZE=1 umi build"
,
"postinstall"
:
"umi generate tmp"
,
...
...
src/components/DetailPage/index.less
View file @
a3d015fe
.common_detail_page {
margin: -24px;
//
margin: -24px;
.common_header {
display: flex;
...
...
src/components/TabTree/index.tsx
View file @
a3d015fe
import
React
,
{
useState
,
ReactText
,
useImperativeHandle
,
useEffect
,
useRef
}
from
'react'
import
{
Tree
,
Space
,
Tooltip
,
Button
}
from
'antd'
import
{
findItemAndDelete
,
findTreeKeys
}
from
'@/utils'
import
{
findItemAndDelete
,
findTreeKeys
,
treeReduction
,
getParentTreeTitles
}
from
'@/utils'
import
'./index.less'
import
deepClone
from
'clone'
import
{
TreeProps
}
from
'antd/lib/tree'
...
...
@@ -17,6 +17,7 @@ export interface TabTreeActions {
setExpandedKeys
:
(
keys
:
ReactText
[])
=>
void
,
setSelectKey
:
(
key
:
ReactText
)
=>
void
setSelectKeys
:
(
keys
:
ReactText
[])
=>
void
getParentPath
:
(
id
:
ReactText
)
=>
string
}
export
interface
toolsRenderProps
{
...
...
@@ -63,6 +64,7 @@ export const createTreeActions = () => {
setSelectKey
(){},
setSelectKeys
(){},
setExpandedKeys
(){},
getParentPath
(
id
){
return
''
},
}
return
actions
}
...
...
@@ -163,6 +165,8 @@ const TabTree:React.FC<TabTreeProps> = (props) => {
checkedKeys
,
[]
);
console
.
log
(
treeReduction
(
treeData
))
useEffect
(()
=>
{
if
(
getMenuSelectData
)
{
getMenuSelectData
().
then
(
res
=>
{
...
...
@@ -193,6 +197,10 @@ const TabTree:React.FC<TabTreeProps> = (props) => {
selfActions
.
setSelectKey
=
(
key
:
ReactText
)
=>
{
setSelectKey
(
key
)
}
selfActions
.
getParentPath
=
(
id
:
ReactText
)
=>
{
return
getParentTreeTitles
(
treeData
,
id
)
}
}
const
batchSelect
=
(
items
:
any
[])
=>
{
...
...
src/constants/regExp.ts
0 → 100644
View file @
a3d015fe
/*
* @Author: LeeJiancong
* @Date: 2020-07-22 09:54:50
* @LastEditors: LeeJiancong
* @LastEditTime: 2020-07-30 19:28:23
*/
/**
* 正则表达式集合
*/
export
const
PATTERN_MAPS
=
{
// 8-20位, 大小写字幕 + 数字组合
password
:
/^
(?=
.*
[
a-z
])(?=
.*
[
A-Z
])[
a-zA-Z
\d]{8,20}
$/
,
email
:
/^
[\w
-
]
+
(\.[\w
-
]
+
)
*@
[\w
-
]
+
(\.[\w
-
]
+
)
+$/
,
phone
:
/^1
[
3|4|5|6|7|8|9
][
0-9
]{9}
$/
,
smsCode
:
/^
\d{6}
$/
,
money
:
/^
\d
*
(?:\.\d{0,2})?
$/
,
weight
:
/^
\d
*
(?:\.\d{0,3})?
$/
,
}
\ No newline at end of file
src/hooks/useHttpRequest.ts
View file @
a3d015fe
...
...
@@ -23,7 +23,7 @@ export function useHttpRequest<T>(api: (params?, config?) => Promise<T>, config?
setLoading
(
true
)
api
(
params
).
then
((
res
:
any
)
=>
{
setData
(
res
.
data
)
if
(
config
&&
config
.
back
)
{
if
(
res
.
code
===
1000
&&
config
&&
config
.
back
)
{
setTimeout
(()
=>
{
goBack
()
},
1000
)
...
...
src/pages/authConfig/userSystem/index.tsx
View file @
a3d015fe
...
...
@@ -94,7 +94,7 @@ const UserSystem: React.FC<{}> = () => {
dataIndex
:
'option'
,
align
:
'center'
,
render
:
(
text
:
any
,
record
:
any
)
=>
{
return
record
.
stat
e
===
0
&&
(
return
record
.
stat
us
===
0
&&
(
<>
<
Popconfirm
title=
"确定要执行这个操作?"
...
...
src/pages/authConfig/userSystem/schema/index.ts
View file @
a3d015fe
import
{
ISchema
}
from
'@formily/antd'
;
import
{
PATTERN_MAPS
}
from
'@/constants/regExp'
;
export
const
UserDetailSchema
:
ISchema
=
{
type
:
'object'
,
...
...
@@ -21,6 +22,12 @@ export const UserDetailSchema:ISchema = {
password
:
{
type
:
'password'
,
title
:
'登录密码'
,
"x-rules"
:
[
{
pattern
:
PATTERN_MAPS
.
password
,
message
:
'请输入由大小写字母和数字组成的8位密码'
}
],
required
:
true
},
name
:
{
...
...
@@ -36,6 +43,12 @@ export const UserDetailSchema:ISchema = {
phone
:
{
type
:
'number'
,
title
:
'手机号'
,
"x-rules"
:
[
{
pattern
:
PATTERN_MAPS
.
phone
,
message
:
'请输入正确的手机号'
}
],
required
:
true
},
idCardNo
:
{
...
...
@@ -44,13 +57,19 @@ export const UserDetailSchema:ISchema = {
},
email
:
{
type
:
'string'
,
title
:
'邮箱'
title
:
'邮箱'
,
"x-rules"
:
[
{
pattern
:
PATTERN_MAPS
.
email
,
message
:
'请输入正确的邮箱'
}
]
},
jobTitle
:
{
type
:
'string'
,
title
:
'职位'
},
org
Id
:
{
org
Name
:
{
type
:
'string'
,
title
:
'所属组织机构'
,
required
:
true
,
...
...
@@ -59,6 +78,10 @@ export const UserDetailSchema:ISchema = {
addonAfter
:
"{{connectCategory}}"
},
},
orgId
:
{
type
:
'string'
,
visible
:
false
},
memberRoleIds
:
{
required
:
true
,
type
:
'array:string'
,
...
...
src/pages/authConfig/userSystem/userDetail.tsx
View file @
a3d015fe
import
React
,
{
useRef
,
useState
,
useEffect
}
from
'react'
;
import
{
Button
,
Modal
,
Tag
,
Row
,
Col
}
from
'antd'
;
import
{
Form
,
FormItem
,
createFormActions
}
from
'@formily/antd'
import
{
Form
,
FormItem
,
createFormActions
,
FormButtonGroup
,
Submit
}
from
'@formily/antd'
import
{
Input
}
from
'@formily/antd-components'
import
{
PlusOutlined
,
LinkOutlined
}
from
'@ant-design/icons'
;
import
{
StandardTable
}
from
'god'
...
...
@@ -14,7 +14,10 @@ import { UserDetailSchema } from './schema';
import
'./index.less'
import
ModalTable
from
'@/components/ModalTable'
;
import
{
useRowSelectionTable
}
from
'@/hooks/useRowSelectionTable'
;
import
{
findItemAndDelete
}
from
'@/utils'
;
import
{
findItemAndDelete
,
omit
}
from
'@/utils'
;
import
TabTree
,
{
useTreeActions
}
from
'@/components/TabTree'
;
import
{
useTreeTabs
}
from
'@/hooks/useTreeTabs'
;
import
{
useHttpRequest
}
from
'@/hooks/useHttpRequest'
;
// 定义选择的行数据的类型
type
Item
=
any
...
...
@@ -26,9 +29,15 @@ const titleRender = (title) => {
return
''
}
const
fetchOriginTreeData
=
async
(
params
?)
=>
{
// 平台后台树
const
res
=
await
PublicApi
.
getMemberOrgTree
()
return
res
}
const
userActions
=
createFormActions
()
const
AddUser
:
React
.
FC
<
{}
>
=
()
=>
{
const
[
originVisible
,
setOriginVisible
]
=
useState
(
false
)
const
checkBoxRef
=
useRef
<
any
[]
>
([])
const
[
roleVisible
,
setRoleVisible
]
=
useState
(
false
)
const
[
selectedRowKeys
,
setSelectedRowKeys
]
=
useState
<
Array
<
string
>>
([])
...
...
@@ -36,28 +45,33 @@ const AddUser: React.FC<{}> = () => {
const
[
formData
,
setFormData
]
=
useState
<
any
>
(
null
)
const
{
id
,
pageStatus
}
=
usePageStatus
()
const
[
roleSelection
,
roleSelectCtl
]
=
useRowSelectionTable
()
const
originTreeActions
=
useTreeActions
()
const
[
originSelectNode
,
setOriginSelectNode
]
=
useState
<
any
>
()
const
{
data
,
loading
,
err
,
run
}
=
useHttpRequest
(
id
?
PublicApi
.
postMemberUserUpdate
:
PublicApi
.
postMemberUserAdd
)
const
{
treeData
:
originTreeData
,
}
=
useTreeTabs
({
fetchMenuData
:
fetchOriginTreeData
,
})
useEffect
(()
=>
{
if
(
id
)
{
// PublicApi.getMiddlegroundUserDetailsById({
// userId: id
// }).then(res => {
// const { data } = res
// setFormData(data)
// setSelectRow(data.roles)
// })
PublicApi
.
getMemberUserGet
({
userId
:
id
}).
then
(
async
res
=>
{
const
{
data
}
=
res
setFormData
(
data
)
})
}
},
[])
const
onFinish
=
async
(
values
:
any
)
=>
{
if
(
values
.
roles
)
{
delete
values
.
roles
}
let
value
=
{
...
values
}
const
fn
=
id
?
PublicApi
.
postMemberUserUpdate
:
PublicApi
.
postMemberUserAdd
values
.
memberRoleIds
=
values
.
memberRoleIds
.
map
(
v
=>
v
.
id
)
const
omitValue
=
omit
(
values
,
[
'orgName'
])
const
params
=
id
?
{
...
v
alue
,
i
d
:
Number
(
id
)
}
:
v
alue
await
f
n
(
params
)
...
omitV
alue
,
userI
d
:
Number
(
id
)
}
:
omitV
alue
await
ru
n
(
params
)
history
.
goBack
(
-
1
)
};
...
...
@@ -99,19 +113,45 @@ const AddUser: React.FC<{}> = () => {
const
handleCloseTag
=
(
removedTag
:
any
)
=>
{
};
const
handleOrigin
=
()
=>
{
setOriginVisible
(
false
)
if
(
originSelectNode
?.
id
){
userActions
.
setFieldValue
(
'orgName'
,
originTreeActions
.
getParentPath
(
originSelectNode
.
id
))
userActions
.
setFieldValue
(
'orgId'
,
originSelectNode
.
id
)
}
}
const
handleAddRole
=
()
=>
{
setRoleVisible
(
true
);
}
const
connectCategory
=
<
div
className=
'connectBtn'
><
LinkOutlined
style=
{
{
marginRight
:
4
}
}
/>
关联
</
div
>
const
handlePlateformSelect
=
(
key
,
node
)
=>
{
setOriginSelectNode
({
id
:
key
*
1
,
name
:
node
.
_title
})
}
const
openOriginTree
=
()
=>
{
setOriginVisible
(
true
)
}
const
connectCategory
=
<
div
className=
'connectBtn'
onClick=
{
openOriginTree
}
><
LinkOutlined
style=
{
{
marginRight
:
4
}
}
/>
关联
</
div
>
const
addRoles
=
<
Button
block
onClick=
{
()
=>
setRoleVisible
(
true
)
}
>
添加角色
</
Button
>
return
(
<
DetailPage
title=
{
titleRender
(
pageStatus
)
}
>
<
div
className=
"common-wrapper user-system"
>
<
NiceForm
onSubmit=
{
onFinish
}
schema=
{
UserDetailSchema
}
initialValues=
{
formData
}
actions=
{
userActions
}
effects=
{
(
$
,
{
setFieldState
})
=>
{
$
(
'onFormInit'
).
subscribe
(()
=>
{
if
(
id
)
{
setFieldState
(
'password'
,
state
=>
{
state
.
visible
=
false
})
}
})
}
}
expressionScope=
{
{
connectCategory
,
addRoles
,
...
...
@@ -120,7 +160,12 @@ const AddUser: React.FC<{}> = () => {
roleSelectCtl
.
setSelectedRowKeys
(
findItemAndDelete
(
roleSelectCtl
.
selectedRowKeys
,
id
))
}
}
}
/>
>
<
FormButtonGroup
offset=
{
6
}
>
<
Button
htmlType=
'submit'
type=
'primary'
loading=
{
loading
}
>
提交
</
Button
>
<
Button
>
取消
</
Button
>
</
FormButtonGroup
>
</
NiceForm
>
<
ModalTable
modalTitle=
'选择角色'
visible=
{
roleVisible
}
...
...
@@ -151,40 +196,25 @@ const AddUser: React.FC<{}> = () => {
}
}
/>
{
/* <Modal
title="选择角色"
visible={roleVisible}
onOk={handleSelectOk}
onCancel={handleSelectCancel}
<
Modal
title=
"选择组织机构"
visible=
{
originVisible
}
onOk=
{
handleOrigin
}
onCancel=
{
()
=>
setOriginVisible
(
false
)
}
okText=
"确认"
cancelText=
"取消"
getContainer=
'#root'
// destroyOnClose={true}
>
<StandardTable
columns={columns}
currentRef={ref}
rowSelection={rowSelection}
fetchTableData={(params:any) => fetchUserList(params)}
tableProps={{ rowKey: 'id' }}
formilyProps={{
layouts: {
order: 3
},
ctx: {
schema: {
type: 'object',
properties: {
name: {
type: 'Search',
"x-component-props": {
placeholder: '请输入角色名称'
}
}
}
}
}
}}
<
TabTree
fetchData
=
{
params
=
>
fetchOriginTreeData(params)}
treeData=
{
originTreeData
}
handleSelect=
{
(
key
,
node
)
=>
handlePlateformSelect
(
key
,
node
)
}
actions=
{
originTreeActions
}
customKey="id"
/
>
</Modal>
*/
}
</
Modal
>
</
div
>
</
DetailPage
>
...
...
src/utils/index.ts
View file @
a3d015fe
...
...
@@ -174,6 +174,41 @@ export const findTreeKeys = (arr: any[], keyword?: string) => {
return
results
}
// 树形结构降为一维对象处理
export
const
treeReduction
=
(
data
:
any
[])
=>
{
const
hashMaps
=
{}
const
selfData
:
any
[]
=
deepClone
(
data
)
while
(
selfData
.
length
>
0
)
{
const
useItem
=
selfData
.
shift
()
// 存在子集
if
(
useItem
.
children
&&
useItem
.
children
.
length
>
0
)
{
useItem
.
children
=
useItem
.
children
.
map
(
v
=>
{
v
.
parentId
=
useItem
.
id
return
v
})
selfData
.
push
(...
useItem
.
children
)
}
hashMaps
[
useItem
.
id
]
=
useItem
}
return
hashMaps
}
// 获取某一节点的title路径
export
const
getParentTreeTitles
=
(
dataSouce
,
key
)
=>
{
const
hashMaps
=
treeReduction
(
dataSouce
)
let
targetKey
=
key
let
targetPath
=
''
while
(
targetKey
!==
''
)
{
const
title
=
hashMaps
[
targetKey
].
title
targetPath
=
targetPath
===
''
?
title
:
`
${
title
}
-
${
targetPath
}
`
targetKey
=
hashMaps
[
targetKey
].
parentId
||
''
}
return
targetPath
}
// 数组通过某个key进行去重合并, 并返回一个新数组
export
const
mergeArrByKey
=
(
preArr
:
any
[],
nextArr
:
any
[],
target
?:
string
)
=>
{
const
mergeArr
=
preArr
.
concat
(
nextArr
)
...
...
src/utils/request.ts
View file @
a3d015fe
...
...
@@ -90,13 +90,12 @@ class ApiRequest {
baseRequest
<
IRequestSuccess
<
T
>>
(
url
,
options
).
then
(
res
=>
{
// 登录验证
if
(
res
.
code
===
1101
)
{
message
.
error
(
res
.
message
)
if
(
isDev
)
{
return
;
}
removeAuth
()
history
.
replace
(
'/login'
)
message
.
error
(
res
.
message
)
return
false
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment