init: UserBaseFront (frontend)

This commit is contained in:
chenxing
2026-08-10 14:41:13 +08:00
commit eea881b616
174 changed files with 32833 additions and 0 deletions
@@ -0,0 +1,114 @@
<template>
<UserForm v-model="visible" :initForm="detailData" :groupOptions="groupOptions" :isEdit="true"
:loading="submitting" @submit="handleSubmit" @cancel="visible = false" />
</template>
<script setup lang="ts">
import { ref } from "vue";
import UserForm from "./UserForm.vue";
/* ---------- 对外暴露 ---------- */
const visible = ref(false);
const groupOptions = ref<any[]>([]);
// 编辑模式:当前编辑的用户 ID
const currentId = ref<number | null>(null);
// 编辑模式:回填数据(来自当前行,辅以 roles[] 拆分到 userType/role)
const detailData = ref<Record<string, any>>({});
// 成功后回调
let onSuccessCallback: (() => void) | null = null;
// useForm 托管提交——currentId 是 ref,闭包内 .value 在 sendForm 时取当前值
const { form, loading: submitting, send: sendForm, onSuccess, onError } = useForm(
(dto) => Apis.SysUser.edit({ pathParams: { id: currentId.value }, data: dto }),
{ initialForm: { id: null, account: '', realName: '', password: '', confirmPassword: '', idcard: '', phone: '', phone2: '', gender: 0, groupId: undefined, userType: [], role: undefined }, resetAfterSubmiting: true }
);
onSuccess(() => {
Message.success('编辑用户成功!');
visible.value = false;
onSuccessCallback?.();
});
onError((event) => {
Message.error(event?.error?.message || '编辑失败');
});
/* ---------- 打开编辑弹窗 ---------- */
/**
* @param row - 当前行数据(来自 SysUser.list 接口返回的 SysUserVo)
* @param groups - 所在组下拉(拍平的组织树)
* @param onSuccess - 编辑成功后的回调
*/
function open(row: any, groups: any[], onSuccess?: () => void) {
if (!row?.id) {
Message.error('用户 ID 不存在');
return;
}
currentId.value = row.id;
groupOptions.value = groups || [];
detailData.value = buildInitForm(row);
onSuccessCallback = onSuccess || null;
visible.value = true;
}
/* ---------- 把行数据映射成表单回填数据 ---------- */
function buildInitForm(row: any) {
const roles: number[] = Array.isArray(row.roles) ? row.roles : [];
// 用户身份(业务身份)= 1..7;角色属性(具体角色)= 1..3
const userType = roles.filter(r => r >= 1 && r <= 7);
const role = roles.filter(r => r >= 1 && r <= 3).slice(-1)[0];
return {
id: row.id,
account: row.account || '',
realName: row.realName || '',
idcard: row.idcard || '',
phone: row.phone || '',
groupId: row.groupId,
password: '',
confirmPassword: '',
phone2: '',
gender: 0,
userType,
role,
};
}
/* ---------- 提交:由 useForm 接管 loading 与异常处理 ---------- */
async function handleSubmit(formData: Record<string, any>) {
if (!currentId.value) return;
form.value = buildPayload(formData, currentId.value);
await sendForm();
}
/**
* 把表单字段映射成 SysUserRequest:
* - 只提交后端 SysUserRequest 里声明的字段
* - "用户身份"(userType checkbox) + "角色属性"(role select) 合并为 roles[](去重)
* - 编辑时密码留空表示不修改,所以密码字段不传
*/
function buildPayload(formData: Record<string, any>, id: number) {
const roleSet = new Set<number>();
(formData.userType || []).forEach((v: any) => roleSet.add(Number(v)));
if (formData.role != null && formData.role !== '') roleSet.add(Number(formData.role));
const payload: any = {
id,
account: formData.account,
realName: formData.realName,
idcard: formData.idcard || undefined,
phone: formData.phone,
groupId: formData.groupId,
roles: Array.from(roleSet),
};
// 编辑时若填写了密码才提交(密码为空表示不修改)
if (formData.password) {
payload.password = formData.password;
payload.confirmPassword = formData.confirmPassword;
}
return payload;
}
defineExpose({ open, visible });
</script>