Commit 283bf7be authored by 涂伟's avatar 涂伟

feat: '运维新增用户导入导出'

parent 36469bf1
/* eslint-disable no-unused-expressions */
/* eslint-disable eqeqeq */
import React, { useState, useEffect, useRef } from 'react';
import React, { useState, useEffect, useRef, useMemo } from 'react';
import {
Tree,
Table,
......@@ -19,6 +19,7 @@ import {
Form,
Radio,
Pagination,
Upload
} from 'antd';
import {
UserOutlined,
......@@ -45,6 +46,7 @@ import {
MessageOutlined,
} from '@ant-design/icons';
import PageContainer from '@/components/BasePageContainer';
import { encipher } from '@wisdom-utils/utils/lib/helpers';
import voca from 'voca';
import zhCN from 'antd/es/locale/zh_CN';
import {
......@@ -72,6 +74,10 @@ import {
SetGroupManager,
ChangeSMSState,
AddUserAppBindWhiteList,
ExportUserData,
ImportAccountData,
GetPasswordRegularization,
SysConfiguration
} from '@/services/userManage/api';
import { AddUserAuthSetting, GetUserAuthSet } from '@/services/database/api';
import TreeComponents from '@/components/ExpendableTree';
......@@ -181,6 +187,80 @@ const UserManage = () => {
const [currentPage, setCurrentPage] = useState(1);
const [treeDataTotal, setTreeDataTotal] = useState();
const [totalSearch, setTotalSearch] = useState(0);
const [importAccountVisible, setImportAccountVisible] = useState(false);
const [passwordLevel, setPasswordLevel] = useState(''); // 密码等级
const [rules, setRules] = useState();
const [btnDisabled, setBtnDisabled] = useState(true);
const [pasType, setPasType] = useState('');
const [importUserForm] = Form.useForm(); // 添加用户
const getPasswordRule = () => {
GetPasswordRegularization().then(res => {
if (res.code === 0) {
setRules(res.data);
}
});
};
const passwordType = () => {
SysConfiguration().then(res => {
if (res.code === 0) {
setPasType(res.data);
}
});
};
// 密码强度验证
const changeValue = changedFields => {
if (changedFields[0].name[0] === 'password') {
// console.log(changedFields[0].value);
checkStrong(changedFields[0].value);
const regex = /^(?=.*[a-zA-Z])(?=.*\d)[\w]{6,16}$/; // 调整后的正则表达式,不包含空白字符
console.log(regex.test(changedFields[0].value), 'regex.test(changedFields[0].value')
if (regex.test(changedFields[0].value)) {
setBtnDisabled(false)
} else {
setBtnDisabled(true)
}
// console.log(checkStrong(changedFields[0].value));
}
};
const checkStrong = sValue => {
let modes = 0;
// 正则表达式验证符合要求的
if (sValue.length < 1) return modes;
if (/\d/.test(sValue)) modes++; // 数字
if (/[a-z]/.test(sValue)) modes++; // 小写
if (/[A-Z]/.test(sValue)) modes++; // 大写
if (/[_\W]/.test(sValue)) modes++; // 特殊字符
console.log(modes, 'modes');
// 逻辑处理
// eslint-disable-next-line default-case
switch (modes) {
case 1:
setPasswordLevel('弱');
break;
case 2:
if (sValue.length > 8) {
setPasswordLevel('中');
} else {
setPasswordLevel('弱');
}
break;
case 3:
if (sValue.length > 8) {
setPasswordLevel('强');
} else {
setPasswordLevel('中');
}
break;
case 4:
setPasswordLevel('强');
break;
}
};
// 用户表列名
const columns = [
{
......@@ -364,7 +444,7 @@ const UserManage = () => {
>
<SafetyOutlined
style={{ fontSize: '16px', color: record.whitelist === 0 ? '#e86060' : '#1890FF' }}
// style={{ fontSize: '16px', color: '#1890FF' }}
// style={{ fontSize: '16px', color: '#1890FF' }}
/>
</Popconfirm>
</Tooltip>
......@@ -472,6 +552,8 @@ const UserManage = () => {
setSiteList(res.data.map(item => ({ value: item.GroupId, label: item.GroupName })));
}
});
getPasswordRule()
passwordType()
updateTrees();
return () => {
......@@ -857,6 +939,33 @@ const UserManage = () => {
}
};
/** ***其他操作*** */
// 导出用户
const exportRoles = async () => {
// menuID
// searchWord
// pageSize
// currentPage
console.log(menuID, 'menuIDmenuIDmenuID');
ExportUserData({
groupId: menuID ? menuID : 0,
key: searchWord,
isModel: false,
}).then(res => {
// window.open(`${window.origin}/${res.data}`)
window.open(`${window.origin}/${res.data}`)
console.log(res, 'resssssssssssssssssss');
})
}
// 导入用户
const importRoles = () => {
console.log('66666666666666666');
setImportAccountVisible(true)
}
/** ***用户批量操作****** */
// 关联角色
const relateRoles = () => {
......@@ -1466,6 +1575,72 @@ const UserManage = () => {
</Menu>
);
// 校验文件名字不为空
const filenameVerification = (file, special) => {
// 文件名含有特殊字符 提示不能上传 {+,:/?#[]@!$&\\*+;=}
// 规则对象(flag)
let flag = !special ? new RegExp('[`~!@#$^&*=|{}\':;\',\\[\\]/?~!@#¥&*——|{}【】‘;:”“\'。,、?]') : new RegExp('[`~!@#$^&*=|{}\':;\',\\[\\]?~!@#¥&*——|{}【】‘;:”“\'。,、?]');
if (flag.test(file.name)) {
return {
type: 'error',
content: `文件名格式错误,请检查文件名是否含有特殊字符${'~!@#$^&*=|{}\':;\',\\[\\]/?~!@#¥&*——|{}【】‘;:”“\'。,、?'}`,
};
}
return {
type: 'success',
content: `上传成功!`,
};
}
const uploadProps = {
name: 'file',
action: `${window.origin}/PandaOMS/OMS/UserCenter/ImportAccountData?password=${encipher(importUserForm.getFieldValue('password'), pasType ? pasType : '').toUpperCase()}`,
// headers: {
// authorization: 'authorization-text',
// },
// fileList: [],
showUploadList: false,
onChange: ({ file, fileList, event }) => {
console.log(file, 'filefilefilefilefile');
if (!file.size && file.status !== 'removed') {
return message.error('上传文件为空,禁止上传!')
}
// 检验名字,名字不通过不允许显示
if (filenameVerification(file).type === 'error') return false;
// 返回的链接在file.response内;不设置url,预览图表不可点击
if (file.status === 'done' && file.response.code === 0) {
// file.url = `${window.origin}/PandaWorkFlow/WorkFlow/AccountManage/DownloadFiles?filePath=${file.response.data}`
// file.sourcePath = file.response.data;
message.success(file.response.data)
setImportAccountVisible(false)
} else if (file.status === 'done' && file.response.code !== 0) {
file.status = 'error';
message.error(file.response.msg)
}
// if (file.status === 'done') {
// onChange(fileList.map(v => v.sourcePath).join(','))
// }
},
};
// 其他操作
const otherButtonMenu = (
<Menu>
{/* <Upload {...props}> */}
<Menu.Item key="11" onClick={importRoles} icon={<IdcardOutlined />}>
批量导入角色
</Menu.Item>
{/* </Upload> */}
{/* <Menu.Item key="11" onClick={importRoles} icon={<IdcardOutlined />}>
批量导入角色
</Menu.Item> */}
<Menu.Item key="22" onClick={exportRoles} icon={<ApartmentOutlined />}>
批量导出角色
</Menu.Item>
</Menu>
);
const kee = () => {
setUserVisible(false);
};
......@@ -1615,6 +1790,12 @@ const UserManage = () => {
重置
</Button>
<Dropdown overlay={otherButtonMenu}>
<Button type="primary" style={{ marginRight: '10px' }}>
其他操作 <DownOutlined />
</Button>
</Dropdown>
<Dropdown overlay={userButtonMenu} disabled={multiOperate}>
<Button type={multiOperateButtonType}>
用户批量操作 <DownOutlined />
......@@ -1841,6 +2022,82 @@ const UserManage = () => {
onCancel={() => setAuthUserVisible(false)}
/> */}
</div>
<Modal
title="确认密码"
visible={importAccountVisible}
// onOk={multiDelete ? submitDeleteUsers : submitDeleteUser}
maskClosable={false}
destroyOnClose
onCancel={() => {
setImportAccountVisible(false);
}}
afterClose={() => {
importUserForm.resetFields();
setPasswordLevel('');
}}
okText="确认"
cancelText="取消"
footer={[
<Button key="back" onClick={() => setImportAccountVisible(false)} style={{ 'marginRight': '5px' }}>
取消
</Button>,
<Upload {...uploadProps}>
<Button key="submit"
type="primary"
// loading={loading}
// onClick={handleOk}
disabled={btnDisabled}
>
确认
</Button>
</Upload>,
]}
>
<div className={styles.modalContent}>
<Form form={importUserForm} labelCol={{ span: 4 }} onFieldsChange={changeValue}>
<div className={styles.formBox}>
<Form.Item
hasFeedback
name="password"
label="账号密码"
rules={[
{
pattern: rules ? rules.regex : `/^(?=.*[a-zA-Z])(?=.*d)[wS]{6,16}$/`,
message: rules ? rules.tip : '长度6-16位,必须包含数字与字母',
},
{
pattern: /^(?!.*(?:SELECT|UPDATE|INSERT|AND|OR|'|"|;|--|\\)).*$/,
message: '当前密码存在sql注入风险,请重新输入', // 防止sql注入
},
{ required: true },
]}
>
<Input.Password
placeholder={rules ? rules.tip : '请输入账号密码长度6~16位,必须包含数字与字母'}
maxLength="16"
onCopy={e => {
e.preventDefault();
}}
onPaste={e => {
// 禁止粘贴
e.preventDefault();
}}
/>
</Form.Item>
<div
style={{ right: '70px' }}
className={classnames(styles.tipsText, {
[styles.tipsRed]: passwordLevel === '弱',
[styles.tipsOrange]: passwordLevel === '中',
[styles.tipsGreen]: passwordLevel === '强',
})}
>
{passwordLevel}
</div>
</div>
</Form>
</div>
</Modal>
</PageContainer>
// <DraggleLayout
// containerWidth={550}
......
......@@ -414,4 +414,39 @@
}
.titleSearch {
color: #f50;
}
.modalContent {
width: 100%;
height: 100%;
.ant-form-item-feedback-icon {
margin-left: 10px;
}
.formBox {
position: relative;
.ant-input-password-icon {
margin-top: 6px;
}
.tipsText {
position: absolute;
right: 40px;
top: 7px;
z-index: 11;
}
.tipsGreen {
color: limegreen;
}
.tipsRed {
color: red;
}
.tipsOrange {
color: coral;
}
}
}
\ No newline at end of file
......@@ -201,5 +201,12 @@ export const SysConfiguration = params =>
// 是否加入白名单
export const AddUserAppBindWhiteList = params =>
get(`/PandaOMS/OMS/AddUserAppBindWhiteList`, params);
// 导出用户
export const ExportUserData = params => get(`${PUBLISH_SERVICE}/UserCenter/ExportUserData`, params);
// 导入用户
export const ImportAccountData = params =>
post(`${PUBLISH_SERVICE}/UserCenter/ImportAccountData`, params);
// export const DeleteOUNew = params =>
// get(`${PUBLISH_SERVICE}/UserCenter/DeleteOU`, params)
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