😎1、优化登录是获取系统配置 2、优化前端表单修改记录组件 3、优化前端表单效验 4、优化组织结构新增和更新逻辑
This commit is contained in:
parent
53a68874dc
commit
085c8c8dba
@ -47,7 +47,7 @@
|
|||||||
<PackageReference Include="NewLife.Redis" Version="6.3.2025.1001" />
|
<PackageReference Include="NewLife.Redis" Version="6.3.2025.1001" />
|
||||||
<PackageReference Include="Novell.Directory.Ldap.NETStandard" Version="4.0.0" />
|
<PackageReference Include="Novell.Directory.Ldap.NETStandard" Version="4.0.0" />
|
||||||
<PackageReference Include="OnceMi.AspNetCore.OSS" Version="1.2.0" />
|
<PackageReference Include="OnceMi.AspNetCore.OSS" Version="1.2.0" />
|
||||||
<PackageReference Include="QRCoder" Version="1.6.0" />
|
<PackageReference Include="QRCoder" Version="1.7.0" />
|
||||||
<PackageReference Include="RabbitMQ.Client" Version="7.1.2" />
|
<PackageReference Include="RabbitMQ.Client" Version="7.1.2" />
|
||||||
<PackageReference Include="SixLabors.ImageSharp.Web" Version="3.2.0" />
|
<PackageReference Include="SixLabors.ImageSharp.Web" Version="3.2.0" />
|
||||||
<PackageReference Include="SKIT.FlurlHttpClient.Wechat.Api" Version="3.12.0" />
|
<PackageReference Include="SKIT.FlurlHttpClient.Wechat.Api" Version="3.12.0" />
|
||||||
|
|||||||
@ -119,7 +119,7 @@ public class SysOrgService : IDynamicApiController, ITransient
|
|||||||
if (!_userManager.SuperAdmin && input.Pid == 0)
|
if (!_userManager.SuperAdmin && input.Pid == 0)
|
||||||
throw Oops.Oh(ErrorCodeEnum.D2009);
|
throw Oops.Oh(ErrorCodeEnum.D2009);
|
||||||
|
|
||||||
if (await _sysOrgRep.IsAnyAsync(u => u.Name == input.Name && u.Code == input.Code))
|
if (await _sysOrgRep.IsAnyAsync(u => u.Name == input.Name || u.Code == input.Code))
|
||||||
throw Oops.Oh(ErrorCodeEnum.D2002);
|
throw Oops.Oh(ErrorCodeEnum.D2002);
|
||||||
|
|
||||||
if (!_userManager.SuperAdmin && input.Pid != 0)
|
if (!_userManager.SuperAdmin && input.Pid != 0)
|
||||||
@ -189,7 +189,7 @@ public class SysOrgService : IDynamicApiController, ITransient
|
|||||||
if (input.Id == input.Pid)
|
if (input.Id == input.Pid)
|
||||||
throw Oops.Oh(ErrorCodeEnum.D2001);
|
throw Oops.Oh(ErrorCodeEnum.D2001);
|
||||||
|
|
||||||
if (await _sysOrgRep.IsAnyAsync(u => u.Name == input.Name && u.Code == input.Code && u.Id != input.Id))
|
if (await _sysOrgRep.IsAnyAsync(u => (u.Name == input.Name || u.Code == input.Code) && u.Id != input.Id))
|
||||||
throw Oops.Oh(ErrorCodeEnum.D2002);
|
throw Oops.Oh(ErrorCodeEnum.D2002);
|
||||||
|
|
||||||
// 父Id不能为自己的子节点
|
// 父Id不能为自己的子节点
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
"name": "admin.net.pro",
|
"name": "admin.net.pro",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "2.4.33",
|
"version": "2.4.33",
|
||||||
"lastBuildTime": "2025.10.08",
|
"lastBuildTime": "2025.10.10",
|
||||||
"description": "Admin.NET 站在巨人肩膀上的 .NET 通用权限开发框架",
|
"description": "Admin.NET 站在巨人肩膀上的 .NET 通用权限开发框架",
|
||||||
"author": "zuohuaijun",
|
"author": "zuohuaijun",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@ -49,7 +49,7 @@
|
|||||||
"jsplumb": "^2.15.6",
|
"jsplumb": "^2.15.6",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"magic-string": "^0.30.19",
|
"magic-string": "^0.30.19",
|
||||||
"md-editor-v3": "^6.0.1",
|
"md-editor-v3": "^6.1.0",
|
||||||
"mitt": "^3.0.1",
|
"mitt": "^3.0.1",
|
||||||
"monaco-editor": "^0.54.0",
|
"monaco-editor": "^0.54.0",
|
||||||
"mqtt": "^5.14.0",
|
"mqtt": "^5.14.0",
|
||||||
@ -82,7 +82,7 @@
|
|||||||
"vue-signature-pad": "^3.0.2",
|
"vue-signature-pad": "^3.0.2",
|
||||||
"vue3-tree-org": "^4.2.2",
|
"vue3-tree-org": "^4.2.2",
|
||||||
"vxe-pc-ui": "^4.9.41",
|
"vxe-pc-ui": "^4.9.41",
|
||||||
"vxe-table": "^4.16.20",
|
"vxe-table": "^4.16.21",
|
||||||
"xe-utils": "^3.7.9",
|
"xe-utils": "^3.7.9",
|
||||||
"xlsx-js-style": "^1.2.0"
|
"xlsx-js-style": "^1.2.0"
|
||||||
},
|
},
|
||||||
@ -90,7 +90,7 @@
|
|||||||
"@iconify/vue": "^5.0.0",
|
"@iconify/vue": "^5.0.0",
|
||||||
"@plugin-web-update-notification/vite": "^2.0.2",
|
"@plugin-web-update-notification/vite": "^2.0.2",
|
||||||
"@types/lodash-es": "^4.17.12",
|
"@types/lodash-es": "^4.17.12",
|
||||||
"@types/node": "^22.18.8",
|
"@types/node": "^22.18.9",
|
||||||
"@types/nprogress": "^0.2.3",
|
"@types/nprogress": "^0.2.3",
|
||||||
"@types/sortablejs": "^1.15.8",
|
"@types/sortablejs": "^1.15.8",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.46.0",
|
"@typescript-eslint/eslint-plugin": "^8.46.0",
|
||||||
|
|||||||
@ -1,14 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-popover placement="bottom" width="300" trigger="hover">
|
<el-popover placement="bottom" width="300" trigger="hover">
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<el-text type="primary" class="cursor-pointer">
|
<el-text type="primary" class="cursor-default">
|
||||||
<el-icon><ele-InfoFilled /></el-icon>{{ t('message.list.detail') }}
|
<el-icon><ele-InfoFilled /></el-icon>{{ t('message.list.detail') }}
|
||||||
</el-text>
|
</el-text>
|
||||||
</template>
|
</template>
|
||||||
<el-descriptions direction="vertical" :column="2" border>
|
<el-descriptions direction="vertical" :column="2" border>
|
||||||
<el-descriptions-item width="140">
|
<el-descriptions-item width="140">
|
||||||
<template #label>
|
<template #label>
|
||||||
<el-text>
|
<el-text truncated class="one-line">
|
||||||
<el-icon><ele-UserFilled /></el-icon>{{ t('message.list.creator') }}
|
<el-icon><ele-UserFilled /></el-icon>{{ t('message.list.creator') }}
|
||||||
</el-text>
|
</el-text>
|
||||||
</template>
|
</template>
|
||||||
@ -16,7 +16,7 @@
|
|||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item>
|
<el-descriptions-item>
|
||||||
<template #label>
|
<template #label>
|
||||||
<el-text>
|
<el-text truncated class="one-line">
|
||||||
<el-icon><ele-Calendar /></el-icon>{{ t('message.list.createTime') }}
|
<el-icon><ele-Calendar /></el-icon>{{ t('message.list.createTime') }}
|
||||||
</el-text>
|
</el-text>
|
||||||
</template>
|
</template>
|
||||||
@ -24,7 +24,7 @@
|
|||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item>
|
<el-descriptions-item>
|
||||||
<template #label>
|
<template #label>
|
||||||
<el-text>
|
<el-text truncated class="one-line">
|
||||||
<el-icon><ele-UserFilled /></el-icon>{{ t('message.list.modifier') }}
|
<el-icon><ele-UserFilled /></el-icon>{{ t('message.list.modifier') }}
|
||||||
</el-text>
|
</el-text>
|
||||||
</template>
|
</template>
|
||||||
@ -32,7 +32,7 @@
|
|||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item>
|
<el-descriptions-item>
|
||||||
<template #label>
|
<template #label>
|
||||||
<el-text>
|
<el-text truncated class="one-line">
|
||||||
<el-icon><ele-Calendar /></el-icon>{{ t('message.list.modifyTime') }}
|
<el-icon><ele-Calendar /></el-icon>{{ t('message.list.modifyTime') }}
|
||||||
</el-text>
|
</el-text>
|
||||||
</template>
|
</template>
|
||||||
@ -41,7 +41,7 @@
|
|||||||
|
|
||||||
<el-descriptions-item>
|
<el-descriptions-item>
|
||||||
<template #label>
|
<template #label>
|
||||||
<el-text>
|
<el-text truncated class="one-line">
|
||||||
<el-icon><ele-OfficeBuilding /></el-icon>{{ t('message.list.organizationName') }}
|
<el-icon><ele-OfficeBuilding /></el-icon>{{ t('message.list.organizationName') }}
|
||||||
</el-text>
|
</el-text>
|
||||||
</template>
|
</template>
|
||||||
@ -49,7 +49,7 @@
|
|||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item>
|
<el-descriptions-item>
|
||||||
<template #label>
|
<template #label>
|
||||||
<el-text>
|
<el-text truncated class="one-line">
|
||||||
<el-icon><ele-School /></el-icon>{{ t('message.list.tenantName') }}
|
<el-icon><ele-School /></el-icon>{{ t('message.list.tenantName') }}
|
||||||
</el-text>
|
</el-text>
|
||||||
</template>
|
</template>
|
||||||
@ -58,7 +58,7 @@
|
|||||||
|
|
||||||
<el-descriptions-item v-if="'remark' in props.data">
|
<el-descriptions-item v-if="'remark' in props.data">
|
||||||
<template #label>
|
<template #label>
|
||||||
<el-text>
|
<el-text truncated class="one-line">
|
||||||
<el-icon><ele-Tickets /></el-icon>{{ t('message.list.remark') }}
|
<el-icon><ele-Tickets /></el-icon>{{ t('message.list.remark') }}
|
||||||
</el-text>
|
</el-text>
|
||||||
</template>
|
</template>
|
||||||
@ -76,3 +76,13 @@ const props = defineProps<{
|
|||||||
data: ModifyRecord;
|
data: ModifyRecord;
|
||||||
}>();
|
}>();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.one-line {
|
||||||
|
width: 120px;
|
||||||
|
display: inline-block;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import type { FormItemRule } from 'element-plus';
|
import type { FormItemRule } from 'element-plus';
|
||||||
import { ElMessage } from 'element-plus';
|
import { ElMessage } from 'element-plus';
|
||||||
|
import { nextTick, Ref, watch } from 'vue';
|
||||||
|
|
||||||
const TRIGGER_INPUT: FormItemRule['trigger'] = 'change';
|
const TRIGGER_INPUT: FormItemRule['trigger'] = 'change';
|
||||||
const TRIGGER_BLUR: FormItemRule['trigger'] = 'blur';
|
const TRIGGER_BLUR: FormItemRule['trigger'] = 'blur';
|
||||||
@ -17,6 +18,27 @@ export function useFormRulePresets() {
|
|||||||
trigger,
|
trigger,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const validatorIf = (shouldError: () => boolean, formRef?: Ref<any>, label: string = '此项') => {
|
||||||
|
let field = '';
|
||||||
|
watch(
|
||||||
|
() => shouldError(),
|
||||||
|
() => nextTick(() => formRef?.value?.validateField(field).catch(() => {})),
|
||||||
|
{ immediate: false, deep: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
validator: (_: any, __: any, callback: (error?: Error) => void) => {
|
||||||
|
field = _.field;
|
||||||
|
if (shouldError()) {
|
||||||
|
callback(new Error(`${label}为必填`));
|
||||||
|
} else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
trigger: ['blur', 'change'] as const,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
const maxLen = (len: number, label = '此项', trigger = TRIGGER_INPUT): FormItemRule => ({
|
const maxLen = (len: number, label = '此项', trigger = TRIGGER_INPUT): FormItemRule => ({
|
||||||
max: len,
|
max: len,
|
||||||
message: `${label}长度不能超过 ${len} 个字符`,
|
message: `${label}长度不能超过 ${len} 个字符`,
|
||||||
@ -373,6 +395,7 @@ export function useFormRulePresets() {
|
|||||||
return {
|
return {
|
||||||
required,
|
required,
|
||||||
requiredIf,
|
requiredIf,
|
||||||
|
validatorIf,
|
||||||
maxLen,
|
maxLen,
|
||||||
minLen,
|
minLen,
|
||||||
pattern,
|
pattern,
|
||||||
|
|||||||
@ -95,6 +95,7 @@ import { initBackEndControlRoutes } from '/@/router/backEnd';
|
|||||||
import { Local, Session } from '/@/utils/storage';
|
import { Local, Session } from '/@/utils/storage';
|
||||||
import { formatAxis } from '/@/utils/formatTime';
|
import { formatAxis } from '/@/utils/formatTime';
|
||||||
import { NextLoading } from '/@/utils/loading';
|
import { NextLoading } from '/@/utils/loading';
|
||||||
|
import { loadSysInfo } from '/@/utils/sysInfo';
|
||||||
import { sm2 } from 'sm-crypto-v2';
|
import { sm2 } from 'sm-crypto-v2';
|
||||||
import { useRoutesList } from '/@/stores/routesList';
|
import { useRoutesList } from '/@/stores/routesList';
|
||||||
import { useThemeConfig } from '/@/stores/themeConfig';
|
import { useThemeConfig } from '/@/stores/themeConfig';
|
||||||
@ -161,11 +162,9 @@ onMounted(async () => {
|
|||||||
const accessToken = route.query.token;
|
const accessToken = route.query.token;
|
||||||
if (accessToken) await saveTokenAndInitRoutes(accessToken);
|
if (accessToken) await saveTokenAndInitRoutes(accessToken);
|
||||||
|
|
||||||
// 若系统配置为空则刷新页面
|
// 若系统配置为空则获取系统配置
|
||||||
if (themeConfig.value.captcha == undefined) {
|
if (themeConfig.value.captcha == undefined) {
|
||||||
setTimeout(() => {
|
await loadSysInfo(Local.get('tid') ?? 0);
|
||||||
window.location.reload();
|
|
||||||
}, 1000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取登录配置
|
// 获取登录配置
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user