merge 合并dev
This commit is contained in:
commit
63d07864f7
@ -18,6 +18,8 @@ VITE_APP_POWERJOB_ADMIN = 'http://localhost:7700/'
|
||||
|
||||
VITE_APP_PORT = 80
|
||||
|
||||
# 接口加密功能开关(如需关闭 后端也必须对应关闭)
|
||||
VITE_APP_ENCRYPT = true
|
||||
# 接口加密传输 RSA 公钥与后端解密私钥对应 如更换需前后端一同更换
|
||||
VITE_APP_RSA_PUBLIC_KEY = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdHnzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ=='
|
||||
# 接口响应解密 RSA 私钥与后端加密公钥对应 如更换需前后端一同更换
|
||||
|
@ -21,6 +21,8 @@ VITE_BUILD_COMPRESS = gzip
|
||||
|
||||
VITE_APP_PORT = 80
|
||||
|
||||
# 接口加密功能开关(如需关闭 后端也必须对应关闭)
|
||||
VITE_APP_ENCRYPT = true
|
||||
# 接口加密传输 RSA 公钥与后端解密私钥对应 如更换需前后端一同更换
|
||||
VITE_APP_RSA_PUBLIC_KEY = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdHnzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ=='
|
||||
# 接口响应解密 RSA 私钥与后端加密公钥对应 如更换需前后端一同更换
|
||||
|
@ -38,6 +38,7 @@
|
||||
"file-saver": "2.0.5",
|
||||
"fuse.js": "7.0.0",
|
||||
"highlight.js": "11.9.0",
|
||||
"image-conversion": "^2.1.1",
|
||||
"js-cookie": "3.0.5",
|
||||
"jsencrypt": "3.3.2",
|
||||
"moddle": "6.2.3",
|
||||
@ -76,10 +77,10 @@
|
||||
"eslint": "8.56.0",
|
||||
"eslint-config-prettier": "9.1.0",
|
||||
"eslint-define-config": "2.1.0",
|
||||
"eslint-plugin-import": "2.29.1",
|
||||
"eslint-plugin-node": "11.1.0",
|
||||
"eslint-plugin-prettier": "5.1.3",
|
||||
"eslint-plugin-promise": "6.1.1",
|
||||
"eslint-plugin-node": "11.1.0",
|
||||
"eslint-plugin-import": "2.29.1",
|
||||
"eslint-plugin-vue": "9.20.1",
|
||||
"fast-glob": "3.3.2",
|
||||
"husky": "8.0.3",
|
||||
|
@ -50,12 +50,13 @@ const values = computed(() => {
|
||||
const unmatch = computed(() => {
|
||||
if (props.options?.length == 0 || props.value === '' || props.value === null || typeof props.value === 'undefined') return false;
|
||||
// 传入值为非数组
|
||||
let unmatch = false; // 添加一个标志来判断是否有未匹配项
|
||||
values.value.forEach((item) => {
|
||||
if (!props.options.some((v) => v.value === item)) {
|
||||
return true; // 如果有未匹配项,将标志设置为true
|
||||
unmatch = true; // 如果有未匹配项,将标志设置为true
|
||||
}
|
||||
});
|
||||
return false; // 返回标志的值
|
||||
return unmatch; // 返回标志的值
|
||||
});
|
||||
|
||||
const unmatchArray = computed(() => {
|
||||
|
@ -44,6 +44,7 @@ import { listByIds, delOss } from '@/api/system/oss';
|
||||
import { OssVO } from '@/api/system/oss/types';
|
||||
import { propTypes } from '@/utils/propTypes';
|
||||
import { globalHeaders } from '@/utils/request';
|
||||
import { compressAccurately } from 'image-conversion';
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
@ -60,7 +61,14 @@ const props = defineProps({
|
||||
isShowTip: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
// 是否支持压缩,默认否
|
||||
compressSupport: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 压缩目标大小,单位KB。默认300KB以上文件才压缩,并压缩至300KB以内
|
||||
compressTargetSize: propTypes.number.def(300)
|
||||
});
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
@ -138,8 +146,16 @@ const handleBeforeUpload = (file: any) => {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
proxy?.$modal.loading('正在上传图片,请稍候...');
|
||||
number.value++;
|
||||
|
||||
//压缩图片,开启压缩并且大于指定的压缩大小时才压缩
|
||||
if (props.compressSupport && file.size / 1024 > props.compressTargetSize) {
|
||||
proxy?.$modal.loading('正在上传图片,请稍候...');
|
||||
number.value++;
|
||||
return compressAccurately(file, props.compressTargetSize);
|
||||
} else {
|
||||
proxy?.$modal.loading('正在上传图片,请稍候...');
|
||||
number.value++;
|
||||
}
|
||||
};
|
||||
|
||||
// 文件个数超出
|
||||
|
@ -36,7 +36,7 @@
|
||||
:data="roleList"
|
||||
:loading="loading"
|
||||
:row-config="{ keyField: 'roleId' }"
|
||||
:checkbox-config="{ reserve: true, checkRowKeys: defaultSelectRoleIds }"
|
||||
:checkbox-config="{ reserve: true, checkRowKeys: roleIds }"
|
||||
highlight-current-row
|
||||
@checkbox-all="handleCheckboxAll"
|
||||
@checkbox-change="handleCheckboxChange"
|
||||
@ -63,41 +63,42 @@
|
||||
v-model:total="total"
|
||||
v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="pageList"
|
||||
@pagination="getList"
|
||||
/>
|
||||
</el-card>
|
||||
<template #footer>
|
||||
<el-button @click="close">取消</el-button>
|
||||
<el-button @click="roleDialog.closeDialog">取消</el-button>
|
||||
<el-button type="primary" @click="confirm">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
<script setup name="Role" lang="ts">
|
||||
import { listRole } from '@/api/system/role';
|
||||
import { RoleVO, RoleQuery } from '@/api/system/role/types';
|
||||
import { VxeTableInstance } from 'vxe-table';
|
||||
import useDialog from '@/hooks/useDialog';
|
||||
import api from '@/api/system/role';
|
||||
interface PropType {
|
||||
modelValue?: RoleVO[] | RoleVO | undefined;
|
||||
multiple?: boolean;
|
||||
data?: string | number | (string | number)[];
|
||||
modelValue?: RoleVO[];
|
||||
}
|
||||
const prop = withDefaults(defineProps<PropType>(), {
|
||||
multiple: true,
|
||||
modelValue: undefined,
|
||||
data: undefined
|
||||
modelValue: () => []
|
||||
});
|
||||
const emit = defineEmits(['update:modelValue', 'confirmCallBack']);
|
||||
const emit = defineEmits(['update:modelValue']);
|
||||
|
||||
const router = useRouter();
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { sys_normal_disable } = toRefs<any>(proxy?.useDict('sys_normal_disable'));
|
||||
|
||||
const roleIds = computed(() => prop.modelValue.map((item) => item.roleId as string));
|
||||
|
||||
const roleList = ref<RoleVO[]>();
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true);
|
||||
const ids = ref<Array<string | number>>([]);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
const dateRange = ref<[DateModelType, DateModelType]>(['', '']);
|
||||
const selectRoleList = ref<RoleVO[]>([]);
|
||||
@ -116,46 +117,22 @@ const queryParams = ref<RoleQuery>({
|
||||
roleKey: '',
|
||||
status: ''
|
||||
});
|
||||
|
||||
const defaultSelectRoleIds = computed(() => computedIds(prop.data));
|
||||
|
||||
const confirm = () => {
|
||||
emit('update:modelValue', selectRoleList.value);
|
||||
emit('confirmCallBack', selectRoleList.value);
|
||||
emit('update:modelValue', [...selectRoleList.value]);
|
||||
roleDialog.closeDialog();
|
||||
};
|
||||
|
||||
const computedIds = (data) => {
|
||||
if (data instanceof Array) {
|
||||
return [...data];
|
||||
} else if (typeof data === 'string') {
|
||||
return data.split(',');
|
||||
} else if (typeof data === 'number') {
|
||||
return [data];
|
||||
} else {
|
||||
console.warn('<RoleSelect> The data type of data should be array or string or number, but I received other');
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 查询角色列表
|
||||
*/
|
||||
const getList = () => {
|
||||
loading.value = true;
|
||||
api.listRole(proxy?.addDateRange(queryParams.value, dateRange.value)).then((res) => {
|
||||
listRole(proxy?.addDateRange(queryParams.value, dateRange.value)).then((res) => {
|
||||
roleList.value = res.rows;
|
||||
total.value = res.total;
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
const pageList = async () => {
|
||||
await getList();
|
||||
const roles = roleList.value.filter((item) => {
|
||||
return selectRoleList.value.some((role) => role.roleId === item.roleId);
|
||||
});
|
||||
await tableRef.value.setCheckboxRow(roles, true);
|
||||
};
|
||||
|
||||
/**
|
||||
* 搜索按钮操作
|
||||
*/
|
||||
@ -172,10 +149,6 @@ const resetQuery = () => {
|
||||
};
|
||||
|
||||
const handleCheckboxChange = (checked) => {
|
||||
if (!prop.multiple && checked.checked) {
|
||||
tableRef.value.setCheckboxRow(selectRoleList.value, false);
|
||||
selectRoleList.value = [];
|
||||
}
|
||||
const row = checked.row;
|
||||
if (checked.checked) {
|
||||
selectRoleList.value.push(row);
|
||||
@ -208,43 +181,19 @@ const handleCloseTag = (user: RoleVO) => {
|
||||
tableRef.value?.setCheckboxRow(rows, false);
|
||||
selectRoleList.value.splice(index, 1);
|
||||
};
|
||||
/**
|
||||
* 初始化选中数据
|
||||
*/
|
||||
const initSelectRole = async () => {
|
||||
if (defaultSelectRoleIds.value.length > 0) {
|
||||
const { data } = await api.optionSelect(defaultSelectRoleIds.value);
|
||||
selectRoleList.value = data;
|
||||
const users = roleList.value.filter((item) => {
|
||||
return defaultSelectRoleIds.value.includes(String(item.roleId));
|
||||
});
|
||||
await nextTick(() => {
|
||||
tableRef.value.setCheckboxRow(users, true);
|
||||
});
|
||||
}
|
||||
};
|
||||
const close = () => {
|
||||
roleDialog.closeDialog();
|
||||
};
|
||||
watch(
|
||||
() => roleDialog.visible.value,
|
||||
(newValue: boolean) => {
|
||||
if (newValue) {
|
||||
initSelectRole();
|
||||
} else {
|
||||
tableRef.value.clearCheckboxReserve();
|
||||
tableRef.value.clearCheckboxRow();
|
||||
resetQuery();
|
||||
selectRoleList.value = [];
|
||||
}
|
||||
}
|
||||
() => prop.modelValue,
|
||||
(newVal, oldValue) => {
|
||||
Object.assign(selectRoleList.value, newVal);
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
onMounted(() => {
|
||||
getList(); // 初始化列表数据
|
||||
});
|
||||
|
||||
defineExpose({
|
||||
open: roleDialog.openDialog,
|
||||
close: roleDialog.closeDialog
|
||||
});
|
||||
</script>
|
||||
|
||||
onMounted(() => {
|
||||
getList();
|
||||
});
|
||||
</script>
|
@ -47,7 +47,7 @@
|
||||
</transition>
|
||||
|
||||
<el-card shadow="hover">
|
||||
<template v-if="prop.multiple" #header>
|
||||
<template #header>
|
||||
<el-tag v-for="user in selectUserList" :key="user.userId" closable style="margin: 2px" @close="handleCloseTag(user)">
|
||||
{{ user.userName }}
|
||||
</el-tag>
|
||||
@ -60,8 +60,9 @@
|
||||
show-overflow
|
||||
:data="userList"
|
||||
:loading="loading"
|
||||
:row-config="{ keyField: 'userId', isHover: true }"
|
||||
:checkbox-config="{ reserve: true, trigger: 'row', highlight: true, showHeader: prop.multiple }"
|
||||
:row-config="{ keyField: 'userId' }"
|
||||
:checkbox-config="{ reserve: true, checkRowKeys: userIds }"
|
||||
highlight-current-row
|
||||
@checkbox-all="handleCheckboxAll"
|
||||
@checkbox-change="handleCheckboxChange"
|
||||
>
|
||||
@ -89,14 +90,14 @@
|
||||
v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
:total="total"
|
||||
@pagination="pageList"
|
||||
@pagination="getList"
|
||||
/>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<template #footer>
|
||||
<el-button @click="close">取消</el-button>
|
||||
<el-button @click="userDialog.closeDialog">取消</el-button>
|
||||
<el-button type="primary" @click="confirm">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
@ -111,20 +112,18 @@ import { VxeTableInstance } from 'vxe-table';
|
||||
import useDialog from '@/hooks/useDialog';
|
||||
|
||||
interface PropType {
|
||||
modelValue?: UserVO[] | UserVO | undefined;
|
||||
multiple?: boolean;
|
||||
data?: string | number | (string | number)[];
|
||||
modelValue?: UserVO[];
|
||||
}
|
||||
const prop = withDefaults(defineProps<PropType>(), {
|
||||
multiple: true,
|
||||
modelValue: undefined,
|
||||
data: undefined
|
||||
modelValue: () => []
|
||||
});
|
||||
const emit = defineEmits(['update:modelValue', 'confirmCallBack']);
|
||||
const emit = defineEmits(['update:modelValue']);
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { sys_normal_disable } = toRefs<any>(proxy?.useDict('sys_normal_disable'));
|
||||
|
||||
const userIds = computed(() => prop.modelValue.map((item) => item.userId as string));
|
||||
|
||||
const userList = ref<UserVO[]>();
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true);
|
||||
@ -152,8 +151,11 @@ const queryParams = ref<UserQuery>({
|
||||
roleId: ''
|
||||
});
|
||||
|
||||
const defaultSelectUserIds = computed(() => computedIds(prop.data));
|
||||
|
||||
/** 通过条件过滤节点 */
|
||||
const filterNode = (value: string, data: any) => {
|
||||
if (!value) return true;
|
||||
return data.label.indexOf(value) !== -1;
|
||||
};
|
||||
/** 根据名称筛选部门树 */
|
||||
watchEffect(
|
||||
() => {
|
||||
@ -165,30 +167,10 @@ watchEffect(
|
||||
);
|
||||
|
||||
const confirm = () => {
|
||||
emit('update:modelValue', selectUserList.value);
|
||||
emit('confirmCallBack', selectUserList.value);
|
||||
emit('update:modelValue', [...selectUserList.value]);
|
||||
userDialog.closeDialog();
|
||||
};
|
||||
|
||||
const computedIds = (data) => {
|
||||
if (data instanceof Array) {
|
||||
return [...data];
|
||||
} else if (typeof data === 'string') {
|
||||
return data.split(',');
|
||||
} else if (typeof data === 'number') {
|
||||
return [data];
|
||||
} else {
|
||||
console.warn('<UserSelect> The data type of data should be array or string or number, but I received other');
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
/** 通过条件过滤节点 */
|
||||
const filterNode = (value: string, data: any) => {
|
||||
if (!value) return true;
|
||||
return data.label.indexOf(value) !== -1;
|
||||
};
|
||||
|
||||
/** 查询部门下拉树结构 */
|
||||
const getTreeSelect = async () => {
|
||||
const res = await api.deptTreeSelect();
|
||||
@ -204,14 +186,6 @@ const getList = async () => {
|
||||
total.value = res.total;
|
||||
};
|
||||
|
||||
const pageList = async () => {
|
||||
await getList();
|
||||
const users = userList.value.filter((item) => {
|
||||
return selectUserList.value.some((user) => user.userId === item.userId);
|
||||
});
|
||||
await tableRef.value.setCheckboxRow(users, true);
|
||||
};
|
||||
|
||||
/** 节点单击事件 */
|
||||
const handleNodeClick = (data: DeptVO) => {
|
||||
queryParams.value.deptId = data.id;
|
||||
@ -234,10 +208,6 @@ const resetQuery = () => {
|
||||
};
|
||||
|
||||
const handleCheckboxChange = (checked) => {
|
||||
if (!prop.multiple && checked.checked) {
|
||||
tableRef.value.setCheckboxRow(selectUserList.value, false);
|
||||
selectUserList.value = [];
|
||||
}
|
||||
const row = checked.row;
|
||||
if (checked.checked) {
|
||||
selectUserList.value.push(row);
|
||||
@ -264,46 +234,22 @@ const handleCheckboxAll = (checked) => {
|
||||
|
||||
const handleCloseTag = (user: UserVO) => {
|
||||
const userId = user.userId;
|
||||
// 使用split删除用户
|
||||
const index = selectUserList.value.findIndex((item) => item.userId === userId);
|
||||
const rows = selectUserList.value[index];
|
||||
tableRef.value?.setCheckboxRow(rows, false);
|
||||
selectUserList.value.splice(index, 1);
|
||||
};
|
||||
|
||||
const initSelectUser = async () => {
|
||||
if (defaultSelectUserIds.value.length > 0) {
|
||||
const { data } = await api.optionSelect(defaultSelectUserIds.value);
|
||||
selectUserList.value = data;
|
||||
const users = userList.value.filter((item) => {
|
||||
return defaultSelectUserIds.value.includes(String(item.userId));
|
||||
});
|
||||
await nextTick(() => {
|
||||
tableRef.value.setCheckboxRow(users, true);
|
||||
});
|
||||
}
|
||||
};
|
||||
const close = () => {
|
||||
userDialog.closeDialog();
|
||||
};
|
||||
|
||||
watch(
|
||||
() => userDialog.visible.value,
|
||||
(newValue: boolean) => {
|
||||
if (newValue) {
|
||||
initSelectUser();
|
||||
} else {
|
||||
tableRef.value.clearCheckboxReserve();
|
||||
tableRef.value.clearCheckboxRow();
|
||||
resetQuery();
|
||||
selectUserList.value = [];
|
||||
}
|
||||
}
|
||||
() => prop.modelValue,
|
||||
(newVal, oldValue) => {
|
||||
Object.assign(selectUserList.value, newVal);
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
getTreeSelect(); // 初始化部门数据
|
||||
getList(); // 初始化列表数据
|
||||
getTreeSelect();
|
||||
getList();
|
||||
});
|
||||
|
||||
defineExpose({
|
||||
@ -312,4 +258,4 @@ defineExpose({
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
<style lang="scss" scoped></style>
|
@ -2,18 +2,15 @@ import { Ref } from 'vue';
|
||||
|
||||
interface Options {
|
||||
title?: string;
|
||||
visible?: boolean;
|
||||
}
|
||||
|
||||
interface Return {
|
||||
title: Ref<string>;
|
||||
visible: Ref<boolean>;
|
||||
|
||||
openDialog: () => void;
|
||||
closeDialog: () => void;
|
||||
}
|
||||
export default (ops?: Options): Return => {
|
||||
const visible = ref(ops.visible !== undefined ? ops.visible : false);
|
||||
const visible = ref(false);
|
||||
const title = ref(ops.title || '');
|
||||
|
||||
const openDialog = () => {
|
||||
@ -31,4 +28,4 @@ export default (ops?: Options): Return => {
|
||||
openDialog,
|
||||
closeDialog
|
||||
};
|
||||
};
|
||||
};
|
@ -38,6 +38,10 @@ VXETable.config({
|
||||
zIndex: 999999
|
||||
});
|
||||
|
||||
// 修改 el-dialog 默认点击遮照为不关闭
|
||||
import { ElDialog } from 'element-plus';
|
||||
ElDialog.props.closeOnClickModal.default = false;
|
||||
|
||||
const app = createApp(App);
|
||||
|
||||
app.use(HighLight);
|
||||
|
1
src/types/env.d.ts
vendored
1
src/types/env.d.ts
vendored
@ -14,6 +14,7 @@ interface ImportMetaEnv {
|
||||
VITE_APP_MONITRO_ADMIN: string;
|
||||
VITE_APP_POWERJOB_ADMIN: string;
|
||||
VITE_APP_ENV: string;
|
||||
VITE_APP_ENCRYPT: string
|
||||
VITE_APP_RSA_PUBLIC_KEY: string;
|
||||
VITE_APP_RSA_PRIVATE_KEY: string;
|
||||
VITE_APP_CLIENT_ID: string;
|
||||
|
@ -76,12 +76,14 @@ service.interceptors.request.use(
|
||||
}
|
||||
}
|
||||
}
|
||||
// 当开启参数加密
|
||||
if (isEncrypt && (config.method === 'post' || config.method === 'put')) {
|
||||
// 生成一个 AES 密钥
|
||||
const aesKey = generateAesKey();
|
||||
config.headers[encryptHeader] = encrypt(encryptBase64(aesKey));
|
||||
config.data = typeof config.data === 'object' ? encryptWithAes(JSON.stringify(config.data), aesKey) : encryptWithAes(config.data, aesKey);
|
||||
if (import.meta.env.VITE_APP_ENCRYPT === 'true') {
|
||||
// 当开启参数加密
|
||||
if (isEncrypt && (config.method === 'post' || config.method === 'put')) {
|
||||
// 生成一个 AES 密钥
|
||||
const aesKey = generateAesKey();
|
||||
config.headers[encryptHeader] = encrypt(encryptBase64(aesKey));
|
||||
config.data = typeof config.data === 'object' ? encryptWithAes(JSON.stringify(config.data), aesKey) : encryptWithAes(config.data, aesKey);
|
||||
}
|
||||
}
|
||||
// FormData数据去请求头Content-Type
|
||||
if (config.data instanceof FormData) {
|
||||
@ -97,19 +99,21 @@ service.interceptors.request.use(
|
||||
// 响应拦截器
|
||||
service.interceptors.response.use(
|
||||
(res: AxiosResponse) => {
|
||||
// 加密后的 AES 秘钥
|
||||
const keyStr = res.headers[encryptHeader];
|
||||
// 加密
|
||||
if (keyStr != null && keyStr != '') {
|
||||
const data = res.data;
|
||||
// 请求体 AES 解密
|
||||
const base64Str = decrypt(keyStr);
|
||||
// base64 解码 得到请求头的 AES 秘钥
|
||||
const aesKey = decryptBase64(base64Str.toString());
|
||||
// aesKey 解码 data
|
||||
const decryptData = decryptWithAes(data, aesKey);
|
||||
// 将结果 (得到的是 JSON 字符串) 转为 JSON
|
||||
res.data = JSON.parse(decryptData);
|
||||
if (import.meta.env.VITE_APP_ENCRYPT === 'true') {
|
||||
// 加密后的 AES 秘钥
|
||||
const keyStr = res.headers[encryptHeader];
|
||||
// 加密
|
||||
if (keyStr != null && keyStr != '') {
|
||||
const data = res.data;
|
||||
// 请求体 AES 解密
|
||||
const base64Str = decrypt(keyStr);
|
||||
// base64 解码 得到请求头的 AES 秘钥
|
||||
const aesKey = decryptBase64(base64Str.toString());
|
||||
// aesKey 解码 data
|
||||
const decryptData = decryptWithAes(data, aesKey);
|
||||
// 将结果 (得到的是 JSON 字符串) 转为 JSON
|
||||
res.data = JSON.parse(decryptData);
|
||||
}
|
||||
}
|
||||
// 未设置状态码则默认成功状态
|
||||
const code = res.data.code || HttpStatus.SUCCESS;
|
||||
|
@ -91,7 +91,8 @@ const registerRules: ElFormRules = {
|
||||
],
|
||||
password: [
|
||||
{ required: true, trigger: 'blur', message: '请输入您的密码' },
|
||||
{ min: 5, max: 20, message: '用户密码长度必须介于 5 和 20 之间', trigger: 'blur' }
|
||||
{ min: 5, max: 20, message: '用户密码长度必须介于 5 和 20 之间', trigger: 'blur' },
|
||||
{ pattern: /^[^<>"'|\\]+$/, message: "不能包含非法字符:< > \" ' \\\ |", trigger: "blur" }
|
||||
],
|
||||
confirmPassword: [
|
||||
{ required: true, trigger: 'blur', message: '请再次输入您的密码' },
|
||||
|
@ -197,11 +197,10 @@ const getList = async () => {
|
||||
loading.value = false;
|
||||
showTable.value = true;
|
||||
};
|
||||
function checkFileSuffix(fileSuffix: string[]) {
|
||||
let arr = ['png', 'jpg', 'jpeg'];
|
||||
return arr.some((type) => {
|
||||
return fileSuffix.indexOf(type) > -1;
|
||||
});
|
||||
function checkFileSuffix(fileSuffix: string | string[]) {
|
||||
const arr = [".png", ".jpg", ".jpeg"];
|
||||
const suffixArray = Array.isArray(fileSuffix) ? fileSuffix : [fileSuffix];
|
||||
return suffixArray.some(suffix => arr.includes(suffix.toLowerCase()));
|
||||
}
|
||||
/** 取消按钮 */
|
||||
function cancel() {
|
||||
|
@ -59,6 +59,7 @@ import { RoleVO } from '@/api/system/role/types';
|
||||
import { getAuthRole, updateAuthRole } from '@/api/system/user';
|
||||
import { UserForm } from '@/api/system/user/types';
|
||||
import { RouteLocationNormalized } from 'vue-router';
|
||||
import { parseTime } from "@/utils/ruoyi";
|
||||
|
||||
const route = useRoute();
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
@ -395,7 +395,8 @@ const initData: PageData<UserForm, UserQuery> = {
|
||||
max: 20,
|
||||
message: '用户密码长度必须介于 5 和 20 之间',
|
||||
trigger: 'blur'
|
||||
}
|
||||
},
|
||||
{ pattern: /^[^<>"'|\\]+$/, message: "不能包含非法字符:< > \" ' \\\ |", trigger: "blur" }
|
||||
],
|
||||
email: [
|
||||
{
|
||||
@ -504,7 +505,12 @@ const handleResetPwd = async (row: UserVO) => {
|
||||
cancelButtonText: '取消',
|
||||
closeOnClickModal: false,
|
||||
inputPattern: /^.{5,20}$/,
|
||||
inputErrorMessage: '用户密码长度必须介于 5 和 20 之间'
|
||||
inputErrorMessage: '用户密码长度必须介于 5 和 20 之间',
|
||||
inputValidator: (value) => {
|
||||
if (/<|>|"|'|\||\\/.test(value)) {
|
||||
return "不能包含非法字符:< > \" ' \\\ |"
|
||||
}
|
||||
}
|
||||
})
|
||||
);
|
||||
if (!err && res) {
|
||||
|
@ -44,7 +44,8 @@ const rules = ref({
|
||||
max: 20,
|
||||
message: '长度在 6 到 20 个字符',
|
||||
trigger: 'blur'
|
||||
}
|
||||
},
|
||||
{ pattern: /^[^<>"'|\\]+$/, message: "不能包含非法字符:< > \" ' \\\ |", trigger: "blur" }
|
||||
],
|
||||
confirmPassword: [
|
||||
{ required: true, message: '确认密码不能为空', trigger: 'blur' },
|
||||
|
Loading…
x
Reference in New Issue
Block a user