修改功能

This commit is contained in:
chenxing
2026-08-17 16:41:08 +08:00
parent 85619785f6
commit b96bbc9a62
5 changed files with 279 additions and 111 deletions
+78 -61
View File
@@ -45,14 +45,9 @@
</Col>
</Row>
<!-- 第 4 行:手机号码2 / 性别 -->
<!-- 第 4 行:性别 -->
<Row>
<Col span="12">
<FormItem label="手机号码2:">
<Input v-model="form.phone2" placeholder="请输入手机号码" />
</FormItem>
</Col>
<Col span="12">
<Col span="24">
<FormItem label="性别:">
<RadioGroup v-model="form.gender">
<Radio :label="0">女</Radio>
@@ -62,12 +57,12 @@
</Col>
</Row>
<!-- 第 5 行:所在组(整行) -->
<Row>
<!-- 第 5 行:所在组(只读)(仅编辑展示,显示用户全部所属组;不提交) -->
<Row v-if="isEdit">
<Col span="24">
<FormItem label="所在组:" prop="groupId">
<Select v-model="form.groupId" placeholder="请选择所在组" filterable transfer>
<Option v-for="g in groupOptions" :key="g.id" :value="g.id" :label="g.name" />
<FormItem label="所在组(只读):">
<Select :value="userGroupIds" multiple disabled transfer class="group-readonly">
<Option v-for="g in userGroups" :key="g.id" :value="g.id" :label="g.name" />
</Select>
</FormItem>
</Col>
@@ -86,16 +81,18 @@
</Col>
</Row>
<!-- 第 7 行:角色属性(整行) -->
<!-- 第 7 行:角色属性(业务角色多选,可编辑;来自角色授权页) -->
<Row>
<Col span="24">
<FormItem label="角色属性:" prop="role">
<Select v-model="form.role" placeholder="请选择" clearable transfer style="width: 220px">
<Option v-for="r in roleOptions" :key="r.value" :value="r.value" :label="r.label" />
<FormItem label="角色属性:">
<Select v-model="form.appRoles" multiple filterable clearable transfer
placeholder="可选择业务角色(来自角色授权)">
<Option v-for="r in roleOptions" :key="r.id" :value="r.id" :label="r.name" />
</Select>
</FormItem>
</Col>
</Row>
</Form>
<template #footer>
@@ -106,18 +103,20 @@
</template>
<script setup lang="ts">
import { computed, reactive, watch } from "vue";
import { computed, reactive, ref, watch } from "vue";
/* ---------- Props / Emits ---------- */
const props = withDefaults(defineProps<{
modelValue: boolean;
initForm?: Record<string, any>;
groupOptions?: any[];
userGroups?: { id: number; name: string }[];
roleOptions?: { id: number; name: string }[];
isEdit?: boolean;
loading?: boolean;
}>(), {
initForm: () => ({}),
groupOptions: () => [],
userGroups: () => [],
roleOptions: () => [],
isEdit: false,
loading: false,
});
@@ -140,11 +139,9 @@ const defaultForm = (): Record<string, any> => ({
confirmPassword: '',
idcard: '',
phone: '',
phone2: '',
gender: 0,
groupId: undefined as number | undefined,
userType: [] as number[],
role: undefined as number | undefined,
appRoles: [] as number[],
});
const form = reactive(defaultForm());
@@ -158,6 +155,9 @@ watch(() => props.initForm, (val) => {
}
}, { immediate: true, deep: true });
// 所在组(只读) 多选值:用户全部所属组的 ID 列表
const userGroupIds = computed(() => (props.userGroups || []).map(g => g.id));
/* ---------- 用户身份(业务身份多选)---------- */
const userTypeOptions = [
{ value: 1, label: '管理员' },
@@ -169,74 +169,80 @@ const userTypeOptions = [
{ value: 7, label: '工作号' },
];
/* ---------- 角色属性(具体角色单选,固定枚举)---------- */
const roleOptions = [
{ value: 1, label: '超级管理员' },
{ value: 2, label: '学校管理员' },
{ value: 3, label: '普通用户' },
];
/* ---------- 校验规则 ---------- */
// 自定义确认密码校验
// 自定义确认密码校验:新增必填且必须与密码一致;编辑时两者皆空表示不修改,任一非空则必须一致
const validateConfirmPassword = (rule: any, value: string, callback: any) => {
const pwd = form.password || '';
const conf = value || '';
if (!props.isEdit) {
// 新增:必填 + 必须与密码一致
if (!value) {
callback(new Error('请再次输入密码'));
} else if (value !== form.password) {
callback(new Error('两次输入的密码不一致'));
} else {
callback();
}
} else {
// 编辑:留空表示不修改密码;非空时必须与密码一致
if (value && value !== form.password) {
callback(new Error('两次输入的密码不一致'));
} else {
callback();
}
if (!conf) return callback(new Error('请再次输入密码'));
if (conf !== pwd) return callback(new Error('两次输入的密码不一致'));
return callback();
}
// 编辑:都为空 -> 不修改密码,放行
if (!pwd && !conf) return callback();
// 修改密码时两次输入必须同时填写且一致
if (!pwd || !conf) return callback(new Error('修改密码时两次输入必须一致'));
if (pwd !== conf) return callback(new Error('两次输入的密码不一致'));
callback();
};
// 自定义密码校验(编辑时可留空)
// 自定义密码校验:新增必填(>=6位);编辑可留空,留空表示不修改
const validatePassword = (rule: any, value: string, callback: any) => {
if (!props.isEdit && !value) {
callback(new Error('请输入密码'));
} else if (value && value.length < 6) {
callback(new Error('密码长度不能少于 6 位'));
const pwd = value || '';
if (!props.isEdit) {
if (!pwd) return callback(new Error('请输入密码'));
if (pwd.length < 6) return callback(new Error('密码长度不能少于 6 位'));
return callback();
}
if (!pwd) return callback();
if (pwd.length < 6) return callback(new Error('密码长度不能少于 6 位'));
callback();
};
// 用户名格式校验:新增时强制仅数字/字母;编辑时账号只读不可改,跳过格式校验
const validateAccount = (rule: any, value: string, callback: any) => {
if (props.isEdit) {
callback();
return;
}
if (value && !/^[A-Za-z0-9]+$/.test(value)) {
callback(new Error('用户名只能由数字或字母组成'));
} else {
callback();
}
};
const rules = {
// 密码红五星号仅新增显示;校验规则随 isEdit 变化
const rules = computed(() => ({
account: [
{ required: true, message: '请输入用户名', trigger: 'blur' },
{ min: 3, max: 30, message: '用户名长度 3-30 位', trigger: 'blur' },
{ validator: validateAccount, trigger: 'blur' },
],
realName: [
{ required: true, message: '请输入真实姓名', trigger: 'blur' },
],
password: [{ validator: validatePassword, trigger: 'blur' }],
confirmPassword: [{ validator: validateConfirmPassword, trigger: 'blur' }],
password: [{ required: !props.isEdit, validator: validatePassword, trigger: 'blur' }],
confirmPassword: [{ required: !props.isEdit, validator: validateConfirmPassword, trigger: 'blur' }],
phone: [
{ required: true, message: '请输入手机号码', trigger: 'blur' },
{ pattern: /^1\d{10}$/, message: '请输入正确的手机号', trigger: 'blur' },
],
groupId: [
{ required: true, type: 'number' as const, message: '请选择所在组', trigger: 'change' },
],
userType: [
{ required: true, type: 'array' as const, min: 1, message: '请选择至少一个用户身份', trigger: 'change' },
],
role: [
{ required: true, type: 'number' as const, message: '请选择角色属性', trigger: 'change' },
],
};
}));
/* ---------- 提交 ---------- */
const formRef = ref();
// 密码变化时,若已填确认密码则重新校验确认密码,保持一致性提示
watch(() => form.password, () => {
if (form.confirmPassword) {
formRef.value?.validateField('confirmPassword');
}
});
async function handleSubmit() {
try {
await formRef.value?.validate();
@@ -292,4 +298,15 @@ function onVisibleChange(val: boolean) {
flex-wrap: wrap;
gap: 0 18px;
}
/* 所在组(只读):保留 disabled(防止误删标签),但去掉灰底灰字,显示为正常白底深色 */
.user-form :deep(.group-readonly.ivu-select-disabled .ivu-select-selection) {
background-color: #fff;
color: #515a6e;
cursor: default;
}
.user-form :deep(.group-readonly.ivu-select-disabled .ivu-select-arrow) {
display: none;
}
</style>