Commit 5ea911e3 authored by liuxiaohui's avatar liuxiaohui

fix create user issues

parent dd3947a2
......@@ -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",
......
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; }
}
}
......@@ -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;
}
}
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);
}
}
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;
}
}
}
......@@ -66,105 +66,9 @@ namespace BBM.ChatGLM.Controllers
}
[HttpPost("excelFile")]
public async Task<IActionResult> UploadExcel([FromForm] IFormFile file)
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数据进行处理,例如存储到数据库中或者进行数据分析等操作
*/
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);
}
}
......
......@@ -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>
);
};
......
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}>
共导入用户&nbsp;<Tag style={{ margin:'0 4px' }}>{data.successNum + data.failNum}</Tag>个。 成功<Tag style={{ margin:'0 4px' }} color='green'>{data.successNum}</Tag>&nbsp;,失败<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
......@@ -22,13 +22,13 @@ request.interceptors.request.use((url, options) => {
authHeader= {
Authorization: `Bearer ${token || ''}`,
headers:{'Content-Type': 'multipart/form-data'},
__tenant: '3a0a90fe-9a0d-70f4-200d-a80a41fb6195',
__tenant: '3a0ad79d-bf4e-e9ec-4315-b9021cfacd95',
};
}else{
authHeader= {
Authorization: `Bearer ${token || ''}`,
'Content-Type': 'application/json',
__tenant: '3a0a90fe-9a0d-70f4-200d-a80a41fb6195',
__tenant: '3a0ad79d-bf4e-e9ec-4315-b9021cfacd95',
};
}
return {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment