Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
C
chatGLM
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
1
Merge Requests
1
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
刘坚-丰林-DEV
chatGLM
Commits
5ea911e3
Commit
5ea911e3
authored
May 09, 2023
by
liuxiaohui
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix create user issues
parent
dd3947a2
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
271 additions
and
106 deletions
+271
-106
appsettings.json
aspnet-core/host/BBM.ChatGLM.HttpApi.Host/appsettings.json
+0
-1
ImportUsersResult.cs
...M.ChatGLM.Application.Contracts/Dtos/ImportUsersResult.cs
+15
-0
Results.cs
...ore/src/BBM.ChatGLM.Application.Contracts/Dtos/Results.cs
+7
-1
IUsersAppService.cs
...BM.ChatGLM.Application.Contracts/User/IUsersAppService.cs
+4
-0
UsersAppService.cs
...-core/src/BBM.ChatGLM.Application/User/UsersAppService.cs
+161
-0
UserController.cs
...ore/src/BBM.ChatGLM.HttpApi/Controllers/UserController.cs
+2
-98
index.tsx
react/src/pages/UserManage/index.tsx
+22
-4
userModal.tsx
react/src/pages/UserManage/userModal.tsx
+58
-0
api.ts
react/src/services/chatGLM/api.ts
+2
-2
No files found.
aspnet-core/host/BBM.ChatGLM.HttpApi.Host/appsettings.json
View file @
5ea911e3
...
...
@@ -39,7 +39,6 @@
},
"Redis"
:
{
"Configuration"
:
"yg-redis-dev-wan.redis.rds.aliyuncs.com:6379,password=YG@redis!dev2022123,defaultDatabase=5"
},
"Jwt"
:
{
"Audience"
:
"BBM.ChatGLM"
,
...
...
aspnet-core/src/BBM.ChatGLM.Application.Contracts/Dtos/ImportUsersResult.cs
0 → 100644
View file @
5ea911e3
using
System
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Text
;
using
System.Threading.Tasks
;
namespace
BBM.ChatGLM.Dtos
{
public
class
ImportUsersResult
{
public
List
<
Dtos
.
Results
>
Results
{
get
;
set
;
}
public
int
FailNum
{
get
;
set
;
}
public
int
SuccessNum
{
get
;
set
;
}
}
}
aspnet-core/src/BBM.ChatGLM.Application.Contracts/Dtos/Results.cs
View file @
5ea911e3
...
...
@@ -8,7 +8,13 @@ namespace BBM.ChatGLM.Dtos
{
public
class
Results
{
public
int
?
SuccessNum
{
get
;
set
;
}
=
0
;
public
string
userName
{
get
;
set
;
}
public
string
phone
{
get
;
set
;
}
public
string
role
{
get
;
set
;
}
public
string
state
{
get
;
set
;
}
public
string
failureReason
{
get
;
set
;
}
public
int
?
SuccessNum
{
get
;
set
;
}
=
0
;
public
int
?
FailNum
{
get
;
set
;
}
=
0
;
}
}
aspnet-core/src/BBM.ChatGLM.Application.Contracts/User/IUsersAppService.cs
View file @
5ea911e3
using
BBM.ChatGLM.Dtos
;
using
Microsoft.AspNetCore.Http
;
using
Microsoft.AspNetCore.Mvc
;
using
System
;
using
System.Collections.Generic
;
using
System.Linq
;
...
...
@@ -17,5 +19,7 @@ namespace BBM.ChatGLM.User
Task
<
PagedResultDto
<
UserDto
>>
PageAsync
(
UserPageInput
input
);
Task
<
List
<
string
>>
GetRolesAsync
();
Task
<
string
>
GetTokenAsync
();
Task
<
ImportUsersResult
>
CreateUsersByExcel
([
FromForm
]
IFormFile
file
);
}
}
aspnet-core/src/BBM.ChatGLM.Application/User/UsersAppService.cs
View file @
5ea911e3
using
BBM.ChatGLM.Dtos
;
using
Lion.AbpPro.BasicManagement.Roles
;
using
Lion.AbpPro.BasicManagement.Users
;
using
Microsoft.AspNetCore.Http
;
using
Microsoft.AspNetCore.Mvc
;
using
NetTopologySuite.Mathematics
;
using
OfficeOpenXml
;
using
OfficeOpenXml.FormulaParsing.Excel.Functions.Logical
;
using
System.ComponentModel.DataAnnotations
;
using
System.Text.Json
;
using
System.Text.RegularExpressions
;
using
Volo.Abp
;
using
Volo.Abp.Application.Dtos
;
using
Volo.Abp.Identity
;
...
...
@@ -120,5 +125,161 @@ namespace BBM.ChatGLM.User
throw
new
BusinessException
(
"BBM.ChatGLM:100012"
);
}
}
[
Authorize
(
ChatGLMPermissions
.
UsersManagement
.
Create
)]
public
async
Task
<
ImportUsersResult
>
CreateUsersByExcel
([
FromForm
]
IFormFile
file
)
{
/**
* [FromForm]
* 操作步骤
* 1、React中,使用antd的Upload组件来上传Excel表格数据,并且在上传之前需要将表格数据转换成FormData。
* 2、在ASP.NET中,建立一个Controller用于接收上传的文件,并且使用[HttpPost]属性来指定使用POST方法接收请求。
* 3、在Controller中,使用IFormFile接口来接收上传的Excel文件,然后使用EPPlus等工具来读取Excel文件数据
* 4、将读取到的Excel数据进行处理,例如存储到数据库中或者进行数据分析等操作
*/
List
<
Dtos
.
Results
>
results
=
new
List
<
Dtos
.
Results
>();
Dtos
.
Results
xiangying
=
new
Dtos
.
Results
();
var
failNum
=
0
;
if
(
file
==
null
)
{
xiangying
=
FailReason
(
""
,
""
,
""
,
""
,
"Excel文件为空"
);
results
.
Add
(
xiangying
);
return
new
ImportUsersResult
{
Results
=
new
List
<
Dtos
.
Results
>
{
},
FailNum
=
0
,
SuccessNum
=
0
};
}
string
directoryPath
=
Environment
.
CurrentDirectory
+
@"\Excels"
;
if
(!
Directory
.
Exists
(
directoryPath
))
Directory
.
CreateDirectory
(
directoryPath
);
var
filePath
=
Path
.
Combine
(
directoryPath
,
file
.
FileName
);
using
(
var
stream
=
new
FileStream
(
filePath
,
FileMode
.
Create
))
{
await
file
.
CopyToAsync
(
stream
);
}
using
(
var
package
=
new
ExcelPackage
(
new
FileInfo
(
filePath
)))
{
var
worksheet
=
package
.
Workbook
.
Worksheets
[
"sheet1"
];
var
totalRows
=
worksheet
.
Dimension
.
Rows
;
var
row
=
2
;
var
userName
=
""
;
var
phoneNumber
=
""
;
var
userRole
=
""
;
while
(
row
<=
totalRows
)
{
try
{
userName
=
worksheet
.
Cells
[
row
,
1
].
Value
?.
ToString
().
Replace
(
" "
,
""
)
??
""
;
phoneNumber
=
worksheet
.
Cells
[
row
,
2
].
Value
?.
ToString
().
Replace
(
" "
,
""
)
??
""
;
userRole
=
worksheet
.
Cells
[
row
,
3
].
Value
?.
ToString
().
Replace
(
" "
,
""
)
??
""
;
userName
=
Regex
.
Replace
(
userName
,
@"\s"
,
""
);
phoneNumber
=
Regex
.
Replace
(
phoneNumber
,
@"\s"
,
""
);
userRole
=
Regex
.
Replace
(
userRole
,
@"\s"
,
""
);
if
(
string
.
IsNullOrEmpty
(
userName
))
{
failNum
++;
xiangying
=
FailReason
(
userName
,
phoneNumber
,
userRole
,
"失败"
,
"用户名不正确"
);
}
else
if
(
userName
.
Length
>
20
)
{
failNum
++;
xiangying
=
FailReason
(
userName
,
phoneNumber
,
userRole
,
"失败"
,
"用户名超出长度限制"
);
}
else
if
(!
Regex
.
IsMatch
(
userName
,
@"^[\u4e00-\u9fa5a-zA-Z]+$"
))
{
failNum
++;
xiangying
=
FailReason
(
userName
,
phoneNumber
,
userRole
,
"失败"
,
"用户名包含特殊符号"
);
}
else
if
(
string
.
IsNullOrEmpty
(
phoneNumber
))
{
failNum
++;
xiangying
=
FailReason
(
userName
,
phoneNumber
,
userRole
,
"失败"
,
"手机号码不正确"
);
}
else
if
(!
Regex
.
IsMatch
(
phoneNumber
,
@"^(133|153|189|180|181|177|173|199|174|141
|139|138|137|136|135|134|159|158|157|150|151|152|147|188|187|182|183|184|178|198
|130|131|132|146|156|155|166|186|185|145|175|176
|170|171
|123)\d{8}$"
))
{
failNum
++;
xiangying
=
FailReason
(
userName
,
phoneNumber
,
userRole
,
"失败"
,
"手机号码格式不正确"
);
}
else
if
(
phoneNumber
.
Length
>
11
)
{
failNum
++;
xiangying
=
FailReason
(
userName
,
phoneNumber
,
userRole
,
"失败"
,
"手机号码超出长度限制"
);
}
else
if
(
userRole
!=
"普通用户"
&&
userRole
!=
"管理员"
)
{
failNum
++;
xiangying
=
FailReason
(
userName
,
phoneNumber
,
userRole
,
"失败"
,
"角色输入不正确"
);
}
else
{
var
password
=
"Zs."
+
phoneNumber
.
Substring
(
phoneNumber
.
Length
-
6
);
if
(
userRole
==
"管理员"
)
{
userRole
=
"admin"
;
}
UserCreateInput
userInput
=
new
UserCreateInput
();
userInput
.
Name
=
userName
;
userInput
.
UserName
=
userName
;
userInput
.
Password
=
password
;
userInput
.
Role
=
userRole
;
userInput
.
IsActive
=
true
;
var
res
=
await
CreateAsync
(
userInput
);
xiangying
=
FailReason
(
userName
,
phoneNumber
,
userRole
,
"成功"
,
""
);
}
}
catch
(
Exception
ex
)
{
failNum
++;
xiangying
=
FailReason
(
userName
,
phoneNumber
,
userRole
,
"失败"
,
"已存在当前用户,重复添加失败"
);
}
finally
{
row
++;
results
.
Add
(
xiangying
);
}
}
return
new
ImportUsersResult
{
Results
=
results
,
FailNum
=
failNum
,
SuccessNum
=
(
totalRows
-
1
)
-
failNum
};
}
}
public
Dtos
.
Results
FailReason
(
string
userName
,
string
phone
,
string
role
,
string
state
,
string
reason
)
{
Dtos
.
Results
results
=
new
Dtos
.
Results
();
results
.
userName
=
userName
;
results
.
phone
=
phone
;
results
.
role
=
role
;
results
.
state
=
state
;
results
.
failureReason
=
reason
;
return
results
;
}
}
}
aspnet-core/src/BBM.ChatGLM.HttpApi/Controllers/UserController.cs
View file @
5ea911e3
...
...
@@ -66,105 +66,9 @@ namespace BBM.ChatGLM.Controllers
}
[
HttpPost
(
"excelFile"
)]
public
async
Task
<
I
ActionResult
>
Upload
Excel
([
FromForm
]
IFormFile
file
)
public
async
Task
<
I
mportUsersResult
>
CreateUsersBy
Excel
([
FromForm
]
IFormFile
file
)
{
/**
* [FromForm]
* 操作步骤
* 1、React中,使用antd的Upload组件来上传Excel表格数据,并且在上传之前需要将表格数据转换成FormData。
* 2、在ASP.NET中,建立一个Controller用于接收上传的文件,并且使用[HttpPost]属性来指定使用POST方法接收请求。
* 3、在Controller中,使用IFormFile接口来接收上传的Excel文件,然后使用EPPlus等工具来读取Excel文件数据
* 4、将读取到的Excel数据进行处理,例如存储到数据库中或者进行数据分析等操作
*/
Dtos
.
Results
xiangying
=
new
Dtos
.
Results
();
var
failNum
=
0
;
if
(
file
==
null
)
return
BadRequest
(
"Excel文件为空"
);
string
directoryPath
=
Environment
.
CurrentDirectory
+
@"\Excels"
;
if
(!
Directory
.
Exists
(
directoryPath
))
Directory
.
CreateDirectory
(
directoryPath
);
var
filePath
=
Path
.
Combine
(
directoryPath
,
file
.
FileName
);
using
(
var
stream
=
new
FileStream
(
filePath
,
FileMode
.
Create
))
{
await
file
.
CopyToAsync
(
stream
);
}
using
(
var
package
=
new
ExcelPackage
(
new
FileInfo
(
filePath
)))
{
var
worksheet
=
package
.
Workbook
.
Worksheets
[
"sheet1"
];
var
totalRows
=
worksheet
.
Dimension
.
Rows
;
var
row
=
2
;
var
userName
=
""
;
var
phoneNumber
=
""
;
var
userRole
=
""
;
while
(
row
<=
totalRows
)
{
try
{
userName
=
worksheet
.
Cells
[
row
,
1
].
Value
?.
ToString
()
??
""
;
phoneNumber
=
worksheet
.
Cells
[
row
,
2
].
Value
?.
ToString
()
??
""
;
userRole
=
worksheet
.
Cells
[
row
,
3
].
Value
?.
ToString
()
??
""
;
if
(
userName
==
""
||
phoneNumber
==
""
||
userName
.
Length
>
50
||
userRole
==
""
||
(
userRole
!=
"普通用户"
&&
userRole
!=
"管理员"
))
{
failNum
++;
}
else
{
if
(!
Regex
.
IsMatch
(
phoneNumber
,
@"^(133|153|189|180|181|177|173|199|174|141
|139|138|137|136|135|134|159|158|157|150|151|152|147|188|187|182|183|184|178|198
|130|131|132|146|156|155|166|186|185|145|175|176
|170|171
|123)\d{8}$"
))
{
failNum
++;
}
else
{
var
password
=
"Zs"
+
phoneNumber
.
Substring
(
phoneNumber
.
Length
-
6
);
if
(
userRole
==
"管理员"
)
{
userRole
=
"admin"
;
}
UserCreateInput
userInput
=
new
UserCreateInput
();
userInput
.
Name
=
userName
;
userInput
.
UserName
=
userName
;
userInput
.
Password
=
password
;
userInput
.
Role
=
userRole
;
userInput
.
IsActive
=
true
;
await
_usersAppService
.
CreateAsync
(
userInput
);
continue
;
}
}
}
catch
(
Exception
ex
)
{
failNum
++;
}
finally
{
row
++;
}
}
xiangying
.
SuccessNum
=
(
totalRows
-
1
)
-
failNum
;
xiangying
.
FailNum
=
failNum
;
package
.
Dispose
();
}
return
Ok
(
xiangying
);
return
await
_usersAppService
.
CreateUsersByExcel
(
file
);
}
}
...
...
react/src/pages/UserManage/index.tsx
View file @
5ea911e3
...
...
@@ -21,7 +21,20 @@ import styles from './index.less';
import
{
Exclamtion
}
from
'@/components/Icons/Icons'
;
import
{
LoadingOutlined
}
from
'@ant-design/icons'
;
import
UserModal
from
'./userModal'
;
interface
IUserResult
{
userName
:
string
;
role
:
string
;
state
:
string
;
phone
:
string
;
failureReason
:
string
}
export
interface
ICreateUserResult
{
results
:
IUserResult
[],
failNum
:
number
,
successNum
:
number
,
}
const
{
Item
}
=
Form
;
const
{
Password
}
=
Input
;
...
...
@@ -59,6 +72,8 @@ const UserManage = () => {
const
[
uploadButtonDisable
,
setUploadButtonDisable
]
=
useState
(
false
);
const
[
accountForm
]
=
Form
.
useForm
();
const
[
resetPasswordForm
]
=
Form
.
useForm
();
const
[
isModalOpen
,
setIsModalOpen
]
=
useState
(
false
);
const
[
users
,
setUsers
]
=
useState
<
ICreateUserResult
>
();
useEffect
(()
=>
{
getRole
().
then
((
res
)
=>
{
...
...
@@ -284,9 +299,12 @@ const UserManage = () => {
const
handleUpload
=
(
file
)
=>
{
setUploadButtonDisable
(
true
);
postExcelFile
(
file
).
then
(
res
=>
{
postExcelFile
(
file
).
then
(
data
=>
{
setUploadButtonDisable
(
false
);
message
.
success
(
`批量添加用户: 成功人数:
${
res
.
successNum
}
失败人数:
${
res
.
failNum
}
人`
);
setUsers
(
data
);
setTimeout
(()
=>
{
setIsModalOpen
(
true
);
},
100
)
})
};
...
...
@@ -294,7 +312,6 @@ const UserManage = () => {
postDowload
();
}
return
(
<
PageContainer
>
<
Modal
...
...
@@ -473,7 +490,7 @@ const UserManage = () => {
disabled=
{
uploadButtonDisable
}
showUploadList=
{
false
}
>
{
uploadButtonDisable
?
<
Button
><
Loading
/></
Button
>
:
<
Button
icon=
{
<
UploadOutlined
/>
}
>
Excel表格添加账号
</
Button
>
}
{
uploadButtonDisable
?
<
Button
color=
'white'
><
Loading
/></
Button
>
:
<
Button
icon=
{
<
UploadOutlined
/>
}
>
Excel表格添加账号
</
Button
>
}
</
Upload
>,
<
Button
key=
"button"
...
...
@@ -488,6 +505,7 @@ const UserManage = () => {
</
Button
>
]
}
/>
<
UserModal
isModalOpen=
{
isModalOpen
}
data=
{
users
}
onClose=
{
()
=>
{
setIsModalOpen
(
false
)
}
}
></
UserModal
>
</
PageContainer
>
);
};
...
...
react/src/pages/UserManage/userModal.tsx
0 → 100644
View file @
5ea911e3
import
{
Modal
,
Row
,
Table
,
Tag
,
Col
}
from
'antd'
;
import
{
ICreateUserResult
}
from
'.'
;
const
UserModal
=
(
props
:
{
data
?:
ICreateUserResult
,
isModalOpen
:
boolean
,
onClose
:
()
=>
void
})
=>
{
const
{
data
,
isModalOpen
,
onClose
}
=
props
;
const
columns
=
[
{
title
:
'用户名'
,
dataIndex
:
'userName'
,
key
:
'userName'
,
},
{
title
:
'手机号码'
,
dataIndex
:
'phone'
,
key
:
'phone'
,
},
{
title
:
'用户角色'
,
dataIndex
:
'role'
,
key
:
'role'
,
},
{
title
:
'状态'
,
dataIndex
:
'state'
,
key
:
'state'
,
render
:
(
_
,
record
:
any
)
=>
{
let
color
=
record
?.
state
===
'失败'
?
'volcano'
:
'green'
;
return
<
Tag
color=
{
color
}
>
{
record
?.
state
}
</
Tag
>;
}
},
{
title
:
'原因'
,
dataIndex
:
'failureReason'
,
key
:
'failureReason'
,
},
];
return
(
<>
{
data
&&
<
Row
>
<
Modal
title=
"导入结果"
width=
{
'50vw'
}
open=
{
isModalOpen
}
onCancel=
{
onClose
}
onOk=
{
onClose
}
>
<
Row
>
<
Col
span=
{
24
}
>
共导入用户
<
Tag
style=
{
{
margin
:
'0 4px'
}
}
>
{
data
.
successNum
+
data
.
failNum
}
</
Tag
>
个。 成功
<
Tag
style=
{
{
margin
:
'0 4px'
}
}
color=
'green'
>
{
data
.
successNum
}
</
Tag
>
个
,失败
<
Tag
style=
{
{
margin
:
'0 4px'
}
}
color=
'volcano'
>
{
data
.
failNum
}
</
Tag
>
个。
</
Col
>
</
Row
>
<
br
></
br
>
<
Table
columns=
{
columns
}
dataSource=
{
data
.
results
}
pagination=
{
false
}
/>
</
Modal
>
</
Row
>
}
</>
);
};
export
default
UserModal
;
\ No newline at end of file
react/src/services/chatGLM/api.ts
View file @
5ea911e3
...
...
@@ -22,13 +22,13 @@ request.interceptors.request.use((url, options) => {
authHeader
=
{
Authorization
:
`Bearer
${
token
||
''
}
`
,
headers
:{
'Content-Type'
:
'multipart/form-data'
},
__tenant
:
'3a0a
90fe-9a0d-70f4-200d-a80a41fb61
95'
,
__tenant
:
'3a0a
d79d-bf4e-e9ec-4315-b9021cfacd
95'
,
};
}
else
{
authHeader
=
{
Authorization
:
`Bearer
${
token
||
''
}
`
,
'Content-Type'
:
'application/json'
,
__tenant
:
'3a0a
90fe-9a0d-70f4-200d-a80a41fb61
95'
,
__tenant
:
'3a0a
d79d-bf4e-e9ec-4315-b9021cfacd
95'
,
};
}
return
{
...
...
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