批量导入用户
This commit is contained in:
parent
98a15550c0
commit
5822a3b08c
|
|
@ -37,4 +37,11 @@ export const GetRoleDpList = () =>
|
|||
request({
|
||||
url: `/pub/role-dp-list`,
|
||||
method: 'get',
|
||||
})
|
||||
|
||||
export const PostUserImport = (data: any) =>
|
||||
request({
|
||||
url: `/user/import`,
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
|
|
@ -21,11 +21,14 @@
|
|||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
>button {
|
||||
margin-right: 22px;
|
||||
}
|
||||
|
||||
.userBtnsDel {
|
||||
background-color: #3A1457;
|
||||
box-shadow: none;
|
||||
color: white;
|
||||
margin-left: 22px;
|
||||
|
||||
&:hover {
|
||||
background-color: lighten(#3A1457, 5%) !important;
|
||||
|
|
|
|||
|
|
@ -2,11 +2,16 @@ import styles from '@/page/Home/User/index.module.scss'
|
|||
import { useEffect, useState } from "react";
|
||||
import Operation from '@/components/Operation';
|
||||
import { Button, Input, Table, Pagination, Modal, message, Select } from "antd";
|
||||
import { SearchOutlined } from '@ant-design/icons';
|
||||
import { GetUserList, PostUser, PutUser, DeleteUser, PutUserPwd, GetRoleDpList } from '@/api/Home/User';
|
||||
import { ExclamationCircleFilled, SearchOutlined } from '@ant-design/icons';
|
||||
import { GetUserList, PostUser, PutUser, DeleteUser, PutUserPwd, GetRoleDpList, PostUserImport } from '@/api/Home/User';
|
||||
import * as CryptoJS from 'crypto-js';
|
||||
import ImageUrl from '@/utils/package/imageUrl';
|
||||
import { storage } from '@/utils';
|
||||
const { Column } = Table
|
||||
const { confirm } = Modal;
|
||||
const { exec } = require('child_process');
|
||||
const fs = require('fs').promises;
|
||||
const setting = await JSON.parse(storage.getItem('setting') as string)
|
||||
const User: React.FC = () => {
|
||||
const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
|
||||
const [isCreateUser, setIsCreateUser] = useState(false);
|
||||
|
|
@ -27,6 +32,7 @@ const User: React.FC = () => {
|
|||
UserName: ""
|
||||
})
|
||||
const [changeUserPawModal, setChangeUserPawModal] = useState(false)
|
||||
const [changeImportModal, setChangeImportModal] = useState(false)
|
||||
const [changeUserPawFrom, setChangeUserPawFrom] = useState({
|
||||
Pwd: "",
|
||||
newPwd: '',
|
||||
|
|
@ -72,6 +78,41 @@ const User: React.FC = () => {
|
|||
}
|
||||
})
|
||||
}
|
||||
const fileUpLoad = async (data: { url: string, content: string, fileName: string }): Promise<void> => {
|
||||
try {
|
||||
const response = await fetch(data.url);
|
||||
const arrayBuffer = await response.arrayBuffer();
|
||||
const buffer = Buffer.from(arrayBuffer);
|
||||
await fs.writeFile(`${setting.shareFilesPath}\\${data.fileName}`, buffer, {});
|
||||
setChangeImportModal(false)
|
||||
confirm({
|
||||
title: '提示',
|
||||
icon: <ExclamationCircleFilled />,
|
||||
content: data.content,
|
||||
centered: true,
|
||||
okText: '打开文件夹',
|
||||
cancelText: '关闭',
|
||||
async onOk() {
|
||||
await fs.access(setting.shareFilesPath, fs.constants.F_OK);
|
||||
if (process.platform === 'win32') {
|
||||
exec(`explorer "${setting.shareFilesPath}"`);
|
||||
} else if (process.platform === 'darwin') {
|
||||
exec(`open "${setting.shareFilesPath}"`);
|
||||
}
|
||||
},
|
||||
onCancel() {
|
||||
}
|
||||
})
|
||||
} catch (error: any) {
|
||||
if (error.code === 'ENOENT') {
|
||||
message.error('文件夹不存在!')
|
||||
return
|
||||
} else {
|
||||
message.error(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={styles.user}>
|
||||
|
|
@ -100,6 +141,13 @@ const User: React.FC = () => {
|
|||
className='m-ant-btn'>
|
||||
添加用户
|
||||
</Button>
|
||||
<Button type="primary"
|
||||
onClick={() => {
|
||||
setChangeImportModal(true)
|
||||
}}
|
||||
className='m-ant-btn'>
|
||||
批量导入用户
|
||||
</Button>
|
||||
<Button type="primary"
|
||||
icon={<img src={ImageUrl.icon21} alt="" />}
|
||||
className={styles.userBtnsDel}
|
||||
|
|
@ -400,6 +448,67 @@ const User: React.FC = () => {
|
|||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
<Modal title='批量导入用户' open={changeImportModal} onCancel={() => setChangeImportModal(false)} footer={null} centered width={'300px'}>
|
||||
<div>
|
||||
<div>
|
||||
<Button type="primary" className='m-ant-btn' style={{ width: '100%', marginBottom: '10px' }}
|
||||
onClick={async () => {
|
||||
await fileUpLoad({
|
||||
url: 'https://wgshare.oss-cn-chengdu.aliyuncs.com/%E7%94%A8%E6%88%B7%E6%89%B9%E9%87%8F%E5%AF%BC%E5%85%A5%E6%A8%A1%E6%9D%BF%E8%A1%A8.xlsx',
|
||||
content: `下载导入模板成功!文件已保存至:${setting.shareFilesPath}`,
|
||||
fileName: `用户批量导入模板表_${+new Date()}.xlsx`
|
||||
})
|
||||
}}
|
||||
>
|
||||
下载导入模版
|
||||
</Button>
|
||||
</div>
|
||||
<div>
|
||||
<Button type="primary" className='m-ant-btn' style={{ width: '100%' }}
|
||||
onClick={() => {
|
||||
const file = document.createElement("input") as any;
|
||||
file.type = "file";
|
||||
file.accept = ".xls,.xlsx";
|
||||
file.onchange = async () => {
|
||||
const fileInfo = file.files[0];
|
||||
const formData = new FormData();
|
||||
formData.append("file", fileInfo);
|
||||
await PostUserImport(formData).then(res => {
|
||||
if (res.code === 200) {
|
||||
if (res.data.item1) {
|
||||
message.success('导入成功')
|
||||
if (list.pageIndex === 1) {
|
||||
getUserList()
|
||||
} else {
|
||||
setList({
|
||||
...list,
|
||||
pageIndex: 1
|
||||
})
|
||||
}
|
||||
} else {
|
||||
if (res.data.item2) {
|
||||
const fileName = res.data.item2.split('/').pop().split('?')[0];
|
||||
fileUpLoad({
|
||||
url: res.data.item2,
|
||||
content: `导入模板失败!失败文件已保存至:${setting.shareFilesPath}`,
|
||||
fileName
|
||||
})
|
||||
} else {
|
||||
message.error('导入失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
setChangeImportModal(false)
|
||||
};
|
||||
file.click();
|
||||
}}
|
||||
>
|
||||
选择导入文件
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue