refactor: 分页响应数据结构调整

This commit is contained in:
Ray.Hao
2026-02-12 21:01:48 +08:00
parent c09ce3e4a8
commit 9480b426dc
45 changed files with 1013 additions and 1026 deletions

View File

@@ -823,9 +823,9 @@ function handleNextClick() {
function handleQuery() {
loading.value = true;
GeneratorAPI.getTablePage(queryParams)
.then((res) => {
pageData.value = res.data;
total.value = res.page?.total ?? 0;
.then((data) => {
pageData.value = data.list;
total.value = data.total ?? 0;
})
.finally(() => {
loading.value = false;
@@ -1071,18 +1071,16 @@ async function writeFile(dirHandle: any, filePath: string, content: string) {
const folderSegments = parts;
const targetDir = await ensureDir(dirHandle, folderSegments, true);
// @ts-ignore
let fileHandle;
try {
// @ts-ignore
fileHandle = await targetDir.getFileHandle(fileName, { create: true });
} catch (err: any) {
if (err?.name === "TypeMismatchError") {
// 存在同名目录(或其它类型冲突),为安全起见不自动删除
throw err;
} else {
const fileHandle = await targetDir.getFileHandle(fileName, { create: true }).then(
(handle: any) => handle,
(err: any) => {
if (err?.name === "TypeMismatchError") {
// 存在同名目录(或其它类型冲突),为安全起见不自动删除
throw err;
}
throw err;
}
}
);
// @ts-ignore
const writable = await fileHandle.createWritable();
await writable.write(content ?? "");
@@ -1190,41 +1188,43 @@ const writeGeneratedCode = async () => {
while (queue.length) {
const item = queue.shift()!;
try {
const root = resolveRootForItem(item);
const relativePath = stripProjectRoot(`${item.path}/${item.fileName}`);
writeProgress.current = relativePath;
if (overwriteMode.value === "ifChanged") {
// 简单差异:已有文件内容与待写内容相同则跳过
// @ts-ignore
const targetRoot = root === "frontend" ? frontendDirHandle.value : backendDirHandle.value;
const existsSame = await isSameFile(targetRoot, relativePath, item.content || "");
if (existsSame) {
// 视作成功但不处理
writeProgress.done++;
writeProgress.percent = Math.round((writeProgress.done / writeProgress.total) * 100);
continue;
await (async () => {
const root = resolveRootForItem(item);
const relativePath = stripProjectRoot(`${item.path}/${item.fileName}`);
writeProgress.current = relativePath;
if (overwriteMode.value === "ifChanged") {
// 简单差异:已有文件内容与待写内容相同则跳过
// @ts-ignore
const targetRoot =
root === "frontend" ? frontendDirHandle.value : backendDirHandle.value;
const existsSame = await isSameFile(targetRoot, relativePath, item.content || "");
if (existsSame) {
return;
}
}
}
if (overwriteMode.value === "skip") {
// @ts-ignore
const targetRoot = root === "frontend" ? frontendDirHandle.value : backendDirHandle.value;
const exists = await pathExists(targetRoot, relativePath);
if (exists) {
writeProgress.done++;
writeProgress.percent = Math.round((writeProgress.done / writeProgress.total) * 100);
continue;
if (overwriteMode.value === "skip") {
// @ts-ignore
const targetRoot =
root === "frontend" ? frontendDirHandle.value : backendDirHandle.value;
const exists = await pathExists(targetRoot, relativePath);
if (exists) {
return;
}
}
}
if (root === "frontend") {
await writeFile(frontendDirHandle.value, relativePath, item.content || "");
frontCount++;
} else {
await writeFile(backendDirHandle.value, relativePath, item.content || "");
backCount++;
}
} catch (err) {
console.error("写入失败:", item.path, err);
failed.push(item.path);
if (root === "frontend") {
await writeFile(frontendDirHandle.value, relativePath, item.content || "");
frontCount++;
} else {
await writeFile(backendDirHandle.value, relativePath, item.content || "");
backCount++;
}
})().then(
() => {},
(err) => {
console.error("写入失败:", item.path, err);
failed.push(item.path);
}
);
} finally {
writeProgress.done++;
writeProgress.percent = Math.round((writeProgress.done / writeProgress.total) * 100);

View File

@@ -99,13 +99,9 @@ const stateArr = ref<OptionItem[]>([
// 初始化选项数据
const initOptions = async () => {
try {
const [dept, roles] = await Promise.all([DeptAPI.getOptions(), RoleAPI.getOptions()]);
deptArr.value = dept;
roleArr.value = roles;
} catch (error) {
console.error("初始化选项失败:", error);
}
const [dept, roles] = await Promise.all([DeptAPI.getOptions(), RoleAPI.getOptions()]);
deptArr.value = dept;
roleArr.value = roles;
};
// ========================= 搜索配置 =========================
@@ -191,9 +187,9 @@ const contentConfig: IContentConfig<UserQueryParams, UserItem> = reactive({
return Promise.resolve();
},
async exportsAction(params: any) {
const res = await UserAPI.getPage(params);
console.log("exportsAction", res.data);
return res.data;
const data = await UserAPI.getPage(params);
console.log("exportsAction", data.list);
return data.list;
},
pk: "id",
toolbar: [
@@ -560,8 +556,8 @@ const handleOperateClick = (data: IObject) => {
ElMessageBox.prompt("请输入用户名" + data.row.username + "」的新密码", "重置密码", {
confirmButtonText: "确定",
cancelButtonText: "取消",
})
.then(({ value }: any) => {
}).then(
({ value }: any) => {
if (!value || value.length < 6) {
ElMessage.warning("密码至少需6位字符,请重新输入");
return false;
@@ -569,8 +565,11 @@ const handleOperateClick = (data: IObject) => {
UserAPI.resetPassword(data.row.id, value).then(() => {
ElMessage.success("密码重置成功,新密码是:" + value);
});
})
.catch(() => {});
},
() => {
// 用户取消
}
);
}
};

View File

@@ -31,9 +31,9 @@ const contentConfig: IContentConfig<UserQueryParams, UserItem> = {
},
async exportsAction(params) {
// 模拟获取到的是全量数据
const res = await UserAPI.getPage(params);
console.log("exportsAction", res.data);
return res.data;
const data = await UserAPI.getPage(params);
console.log("exportsAction", data.list);
return data.list;
},
pk: "id",
toolbar: [

View File

@@ -18,14 +18,10 @@ export const stateArr = ref<OptionItem[]>([
// 初始化逻辑,在 onMounted 钩子中调用
export const initOptions = async () => {
try {
// 使用Promise.all并行请求
const [dept, roles] = await Promise.all([DeptAPI.getOptions(), RoleAPI.getOptions()]);
// 获取部门选项并赋值
deptArr.value = dept;
// 获取角色选项并赋值
roleArr.value = roles;
} catch (error) {
console.error("初始化选项失败:", error);
}
// 使用Promise.all并行请求
const [dept, roles] = await Promise.all([DeptAPI.getOptions(), RoleAPI.getOptions()]);
// 获取部门选项并赋值
deptArr.value = dept;
// 获取角色选项并赋值
roleArr.value = roles;
};

View File

@@ -68,12 +68,8 @@ const contentConfig: IContentConfig<DemoQueryParams, DemoItem> = {
const end = start + pageSize;
return Promise.resolve({
data: list.slice(start, end),
page: {
pageNum,
pageSize,
total: list.length,
},
list: list.slice(start, end),
total: list.length,
});
},
modifyAction(data) {

View File

@@ -169,8 +169,8 @@ const handleOperateClick = (data: IObject) => {
ElMessageBox.prompt("请输入用户名" + data.row.username + "」的新密码", "重置密码", {
confirmButtonText: "确定",
cancelButtonText: "取消",
})
.then(({ value }) => {
}).then(
({ value }) => {
if (!value || value.length < 6) {
ElMessage.warning("密码至少需6位字符,请重新输入");
return false;
@@ -178,8 +178,11 @@ const handleOperateClick = (data: IObject) => {
UserAPI.resetPassword(data.row.id, value).then(() => {
ElMessage.success("密码重置成功,新密码是:" + value);
});
})
.catch(() => {});
},
() => {
// 用户取消
}
);
}
};
const handleOperateClick2 = (data: IOperateData) => {

View File

@@ -218,20 +218,14 @@ const saveDict = async () => {
if (!dictForm.value) return;
saving.value = true;
try {
// dictForm的类型已经是DictItemForm,直接传递
await DictAPI.updateDictItem(DICT_CODE, MALE_ITEM_ID, dictForm.value);
// dictForm的类型已经是DictItemForm,直接传递
await DictAPI.updateDictItem(DICT_CODE, MALE_ITEM_ID, dictForm.value);
// 更新时间
lastUpdateTime.value = useDateFormat(new Date(), "YYYY-MM-DD HH:mm:ss").value;
// 更新时间
lastUpdateTime.value = useDateFormat(new Date(), "YYYY-MM-DD HH:mm:ss").value;
ElMessage.success("保存成功,后端将通过WebSocket通知所有客户端");
} catch (error) {
console.error("保存字典项失败", error);
ElMessage.error("保存失败");
} finally {
saving.value = false;
}
ElMessage.success("保存成功,后端将通过WebSocket通知所有客户端");
saving.value = false;
};
// 组件挂载时加载性别字典

View File

@@ -192,27 +192,28 @@ function getCaptcha() {
* 登录提交
*/
async function handleLoginSubmit() {
// 1. 表单验证
const valid = await loginFormRef.value?.validate().then(
() => true,
() => false
);
if (!valid) return;
loading.value = true;
try {
// 1. 表单验证
const valid = await loginFormRef.value?.validate();
if (!valid) return;
loading.value = true;
// 2. 执行登录
try {
await userStore.login(loginFormData.value);
// 登录成功,跳转到目标页面
const redirectPath = (route.query.redirect as string) || "/";
await router.push(decodeURIComponent(redirectPath));
} catch (error) {
// 登录失败,刷新验证码
getCaptcha();
throw error;
}
} catch (error) {
// 统一错误处理
console.error("登录失败:", error);
await userStore.login(loginFormData.value).then(
async () => {
// 登录成功,跳转到目标页面
const redirectPath = (route.query.redirect as string) || "/";
await router.push(decodeURIComponent(redirectPath));
},
(error) => {
// 登录失败,刷新验证码
getCaptcha();
throw error;
}
);
} finally {
loading.value = false;
}

View File

@@ -586,18 +586,13 @@ const handleFileChange = async (event: Event) => {
const file = target.files ? target.files[0] : null;
if (file) {
// 调用文件上传API
try {
const data = await FileAPI.uploadFile(file);
// 更新用户信息
await UserAPI.updateProfile({
avatar: data.url,
});
// 更新用户头像
userStore.userInfo.avatar = data.url;
} catch (error) {
console.error("头像上传失败:" + error);
ElMessage.error("头像上传失败");
}
const data = await FileAPI.uploadFile(file);
// 更新用户信息
await UserAPI.updateProfile({
avatar: data.url,
});
// 更新用户头像
userStore.userInfo.avatar = data.url;
}
};

View File

@@ -114,7 +114,6 @@ defineOptions({
});
import { onMounted, reactive, ref } from "vue";
import { ElMessage } from "element-plus";
import NoticeAPI from "@/api/system/notice";
import type { NoticeDetail, NoticeItem, NoticeQueryParams } from "@/types/api";
@@ -134,12 +133,9 @@ const noticeDetail = ref<NoticeDetail | null>(null);
async function handleQuery() {
loading.value = true;
try {
const res = await NoticeAPI.getMyNoticePage(queryParams);
pageData.value = res.data;
total.value = res.page?.total ?? 0;
} catch (error) {
ElMessage.error("获取通知列表失败");
console.error("获取我的通知失败", error);
const data = await NoticeAPI.getMyNoticePage(queryParams);
pageData.value = data.list;
total.value = data.total ?? 0;
} finally {
loading.value = false;
}
@@ -152,14 +148,9 @@ function handleResetQuery() {
}
async function handleReadNotice(id: string) {
try {
const data = await NoticeAPI.getDetail(id);
noticeDetail.value = data;
noticeDialogVisible.value = true;
} catch (error) {
ElMessage.error("获取通知详情失败");
console.error("获取通知详情失败", error);
}
const data = await NoticeAPI.getDetail(id);
noticeDetail.value = data;
noticeDialogVisible.value = true;
}
onMounted(() => {

View File

@@ -185,9 +185,9 @@ const rules = reactive({
function fetchData() {
loading.value = true;
ConfigAPI.getPage(queryParams)
.then((res) => {
pageData.value = res.data;
total.value = res.page?.total ?? 0;
.then((data) => {
pageData.value = data.list;
total.value = data.total ?? 0;
})
.finally(() => {
loading.value = false;

View File

@@ -199,9 +199,9 @@ const computedRules = computed(() => {
function fetchData() {
loading.value = true;
DictAPI.getDictItemPage(dictCode.value, queryParams)
.then((res) => {
tableData.value = res.data;
total.value = res.page?.total ?? 0;
.then((data) => {
tableData.value = data.list;
total.value = data.total ?? 0;
})
.finally(() => {
loading.value = false;

View File

@@ -176,9 +176,9 @@ const computedRules = computed(() => {
function fetchData() {
loading.value = true;
DictAPI.getPage(queryParams)
.then((res) => {
tableData.value = res.data;
total.value = res.page?.total ?? 0;
.then((data) => {
tableData.value = data.list;
total.value = data.total ?? 0;
})
.finally(() => {
loading.value = false;

View File

@@ -90,9 +90,9 @@ const pageData = ref<LogItem[]>();
function fetchData() {
loading.value = true;
LogAPI.getPage(queryParams)
.then((res) => {
pageData.value = res.data;
total.value = res.page?.total ?? 0;
.then((data) => {
pageData.value = data.list;
total.value = data.total ?? 0;
})
.finally(() => {
loading.value = false;

View File

@@ -349,9 +349,9 @@ function handleQuery() {
function fetchData() {
loading.value = true;
NoticeAPI.getPage(queryParams)
.then((res) => {
pageData.value = res.data;
total.value = res.page?.total ?? 0;
.then((data) => {
pageData.value = data.list;
total.value = data.total ?? 0;
})
.finally(() => {
loading.value = false;

View File

@@ -47,6 +47,14 @@
<el-table-column label="角色名称" prop="name" min-width="100" />
<el-table-column label="角色编码" prop="code" width="150" />
<el-table-column label="数据权限" align="center" width="140">
<template #default="scope">
<el-tag :type="getDataScopeTagType(scope.row.dataScope)">
{{ getDataScopeLabel(scope.row.dataScope) }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="状态" align="center" width="100">
<template #default="scope">
<el-tag v-if="scope.row.status === 1" type="success">正常</el-tag>
@@ -103,7 +111,7 @@
<el-dialog
v-model="dialog.visible"
:title="dialog.title"
width="500px"
width="600px"
@close="handleCloseDialog"
>
<el-form ref="roleFormRef" :model="formData" :rules="rules" label-width="100px">
@@ -116,14 +124,28 @@
</el-form-item>
<el-form-item label="数据权限" prop="dataScope">
<el-select v-model="formData.dataScope">
<el-select v-model="formData.dataScope" placeholder="请选择数据权限" style="width: 100%">
<el-option :key="1" label="全部数据" :value="1" />
<el-option :key="2" label="部门及子部门数据" :value="2" />
<el-option :key="3" label="本部门数据" :value="3" />
<el-option :key="4" label="本人数据" :value="4" />
<el-option :key="5" label="自定义部门数据" :value="5" />
</el-select>
</el-form-item>
<!-- 自定义部门选择 -->
<el-form-item v-if="formData.dataScope === 5" label="选择部门" prop="deptIds">
<el-tree-select
v-model="formData.deptIds"
:data="deptOptions"
multiple
:render-after-expand="false"
check-strictly
placeholder="请选择部门"
style="width: 100%"
/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-radio-group v-model="formData.status">
<el-radio :value="1">正常</el-radio>
@@ -220,6 +242,7 @@ import { DeviceEnum } from "@/enums/settings";
import RoleAPI from "@/api/system/role";
import type { RoleItem, RoleForm, RoleQueryParams } from "@/types/api";
import MenuAPI from "@/api/system/menu";
import DeptAPI from "@/api/system/dept";
defineOptions({
name: "Role",
@@ -245,6 +268,8 @@ const queryParams = reactive<RoleQueryParams>({
const roleList = ref<RoleItem[]>();
// 菜单权限下拉
const menuPermOptions = ref<OptionItem[]>([]);
// 部门下拉选项
const deptOptions = ref<OptionItem[]>([]);
// 弹窗
const dialog = reactive({
@@ -264,6 +289,7 @@ const rules = reactive({
name: [{ required: true, message: "请输入角色名称", trigger: "blur" }],
code: [{ required: true, message: "请输入角色编码", trigger: "blur" }],
dataScope: [{ required: true, message: "请选择数据权限", trigger: "blur" }],
deptIds: [{ required: true, message: "请选择部门", trigger: "blur" }],
status: [{ required: true, message: "请选择状态", trigger: "blur" }],
});
@@ -280,13 +306,32 @@ const isExpanded = ref(true);
const parentChildLinked = ref(true);
// 数据权限标签
const dataScopeOptions = [
{ value: 1, label: "全部数据", type: "danger" },
{ value: 2, label: "部门及子部门数据", type: "warning" },
{ value: 3, label: "本部门数据", type: "primary" },
{ value: 4, label: "本人数据", type: "info" },
{ value: 5, label: "自定义部门数据", type: "success" },
];
function getDataScopeLabel(value: number): string {
const option = dataScopeOptions.find((item) => item.value === value);
return option ? option.label : "未知";
}
function getDataScopeTagType(value: number): string {
const option = dataScopeOptions.find((item) => item.value === value);
return option ? option.type : "info";
}
// 获取数据
function fetchData() {
loading.value = true;
RoleAPI.getPage(queryParams)
.then((res) => {
roleList.value = res.data;
total.value = res.page?.total ?? 0;
.then((data) => {
roleList.value = data.list;
total.value = data.total ?? 0;
})
.finally(() => {
loading.value = false;
@@ -312,8 +357,13 @@ function handleSelectionChange(selection: any) {
}
// 打开角色弹窗
function handleOpenDialog(roleId?: string) {
async function handleOpenDialog(roleId?: string) {
dialog.visible = true;
// 获取部门下拉选项
if (deptOptions.value.length === 0) {
deptOptions.value = await DeptAPI.getOptions();
}
if (roleId) {
dialog.title = "修改角色";
RoleAPI.getFormData(roleId).then((data) => {
@@ -328,10 +378,16 @@ function handleOpenDialog(roleId?: string) {
function handleSubmit() {
roleFormRef.value.validate((valid: any) => {
if (valid) {
// 如果不是自定义数据权限,清空部门ID列表
const submitData = { ...formData };
if (submitData.dataScope !== 5) {
submitData.deptIds = undefined;
}
loading.value = true;
const roleId = formData.id;
if (roleId) {
RoleAPI.update(roleId, formData)
RoleAPI.update(roleId, submitData)
.then(() => {
ElMessage.success("修改成功");
handleCloseDialog();
@@ -339,7 +395,7 @@ function handleSubmit() {
})
.finally(() => (loading.value = false));
} else {
RoleAPI.create(formData)
RoleAPI.create(submitData)
.then(() => {
ElMessage.success("新增成功");
handleCloseDialog();
@@ -361,6 +417,8 @@ function handleCloseDialog() {
formData.id = undefined;
formData.sort = 1;
formData.status = 1;
formData.dataScope = undefined;
formData.deptIds = undefined;
}
// 删除角色

View File

@@ -491,12 +491,12 @@ function resolvePlanLabel(planId?: number) {
function fetchData() {
loading.value = true;
TenantAPI.getPage(queryParams)
.then((res) => {
pageData.value = res.data.map((item) => ({
.then((data) => {
pageData.value = data.list.map((item) => ({
...item,
planId: item.planId != null ? Number(item.planId) : undefined,
}));
total.value = res.page?.total ?? 0;
total.value = data.total ?? 0;
})
.finally(() => {
loading.value = false;
@@ -881,7 +881,10 @@ function handleCloseDialog() {
// 提交租户表单(新增/编辑)
const handleSubmit = useDebounceFn(async () => {
const valid = await dataFormRef.value?.validate().catch(() => false);
const valid = await dataFormRef.value?.validate().then(
() => true,
() => false
);
if (!valid) return;
loading.value = true;
@@ -922,8 +925,6 @@ const handleSubmit = useDebounceFn(async () => {
handleCloseDialog();
handleResetQuery();
} catch {
ElMessage.error(formData.id != null && String(formData.id) !== "" ? "修改失败" : "新增失败");
} finally {
loading.value = false;
}
@@ -941,8 +942,8 @@ function handleDelete(tenantId?: string) {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(async () => {
}).then(
async () => {
loading.value = true;
try {
await TenantAPI.deleteByIds(tenantIds);
@@ -951,10 +952,11 @@ function handleDelete(tenantId?: string) {
} finally {
loading.value = false;
}
})
.catch(() => {
},
() => {
// 用户取消
});
}
);
}
// 页面初始化
@@ -965,15 +967,11 @@ onMounted(() => {
// 拉取租户套餐选项
async function fetchPlanOptions() {
try {
const options = await TenantPlanAPI.getOptions();
planOptions.value = options.map((item) => ({
...item,
value: item.value != null ? Number(item.value) : item.value,
}));
} catch {
planOptions.value = [];
}
const options = await TenantPlanAPI.getOptions();
planOptions.value = options.map((item) => ({
...item,
value: item.value != null ? Number(item.value) : item.value,
}));
}
</script>

View File

@@ -278,9 +278,9 @@ const menuParentChildLinked = ref(true);
function fetchData() {
loading.value = true;
TenantPlanAPI.getPage(queryParams)
.then((res) => {
pageData.value = res.data;
total.value = res.page?.total ?? 0;
.then((data) => {
pageData.value = data.list;
total.value = data.total ?? 0;
})
.finally(() => {
loading.value = false;
@@ -343,7 +343,10 @@ function handleCloseDialog() {
// 提交新增/编辑
const handleSubmit = useDebounceFn(async () => {
const valid = await dataFormRef.value?.validate().catch(() => false);
const valid = await dataFormRef.value?.validate().then(
() => true,
() => false
);
if (!valid) return;
loading.value = true;

View File

@@ -161,22 +161,17 @@ const handleUpload = async () => {
return;
}
try {
const result = await UserAPI.import("1", importFormData.files[0].raw as File);
if (result.code === ApiCodeEnum.SUCCESS && result.invalidCount === 0) {
ElMessage.success("导入成功,导入数据:" + result.validCount + "条");
emit("import-success");
handleClose();
} else {
ElMessage.error("上传失败");
resultVisible.value = true;
resultData.value = result.messageList;
invalidCount.value = result.invalidCount;
validCount.value = result.validCount;
}
} catch (error: any) {
console.error(error);
ElMessage.error("上传失败:" + error);
const result = await UserAPI.import("1", importFormData.files[0].raw as File);
if (result.code === ApiCodeEnum.SUCCESS && result.invalidCount === 0) {
ElMessage.success("导入成功,导入数据:" + result.validCount + "条");
emit("import-success");
handleClose();
} else {
ElMessage.error("上传失败");
resultVisible.value = true;
resultData.value = result.messageList;
invalidCount.value = result.invalidCount;
validCount.value = result.validCount;
}
};

View File

@@ -351,12 +351,9 @@ const rules = reactive({
async function fetchUserList(): Promise<void> {
loading.value = true;
try {
const res = await UserAPI.getPage(queryParams);
userList.value = res.data;
total.value = res.page?.total ?? 0;
} catch (error) {
ElMessage.error("获取用户列表失败");
console.error("获取用户列表失败:", error);
const data = await UserAPI.getPage(queryParams);
userList.value = data.list;
total.value = data.total ?? 0;
} finally {
loading.value = false;
}
@@ -400,14 +397,14 @@ function handleResetPassword(row: UserItem): void {
.then(({ value }) => {
return UserAPI.resetPassword(row.id, value);
})
.then(() => {
ElMessage.success("密码重置成功");
})
.catch((error) => {
if (error !== "cancel") {
ElMessage.error("密码重置失败");
.then(
() => {
ElMessage.success("密码重置成功");
},
() => {
// 用户取消
}
});
);
}
// ==================== 弹窗操作 ====================
@@ -420,27 +417,17 @@ async function handleOpenDialog(id?: string): Promise<void> {
dialogState.visible = true;
// 并行加载下拉选项数据
try {
[roleOptions.value, deptOptions.value] = await Promise.all([
RoleAPI.getOptions(),
DeptAPI.getOptions(),
]);
} catch (error) {
ElMessage.error("加载选项数据失败");
console.error("加载选项数据失败:", error);
}
[roleOptions.value, deptOptions.value] = await Promise.all([
RoleAPI.getOptions(),
DeptAPI.getOptions(),
]);
// 编辑:加载用户数据
if (id) {
dialogState.title = "修改用户";
dialogState.mode = DialogMode.EDIT;
try {
const data = await UserAPI.getFormData(id);
Object.assign(formData, data);
} catch (error) {
ElMessage.error("加载用户数据失败");
console.error("加载用户数据失败:", error);
}
const data = await UserAPI.getFormData(id);
Object.assign(formData, data);
} else {
// 新增:设置默认值
dialogState.title = "新增用户";
@@ -466,7 +453,10 @@ function handleCloseDialog(): void {
* 提交用户表单(防抖)
*/
const handleSubmit = useDebounceFn(async () => {
const valid = await userFormRef.value?.validate().catch(() => false);
const valid = await userFormRef.value?.validate().then(
() => true,
() => false
);
if (!valid) return;
const userId = formData.id;
@@ -482,9 +472,6 @@ const handleSubmit = useDebounceFn(async () => {
}
handleCloseDialog();
handleResetQuery();
} catch (error) {
ElMessage.error(userId ? "修改用户失败" : "新增用户失败");
console.error("提交用户表单失败:", error);
} finally {
loading.value = false;
}
@@ -519,23 +506,21 @@ function handleDelete(id?: string): void {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(async () => {
}).then(
async () => {
loading.value = true;
try {
await UserAPI.deleteByIds(userIds);
ElMessage.success("删除成功");
handleResetQuery();
} catch (error) {
ElMessage.error("删除失败");
console.error("删除用户失败:", error);
} finally {
loading.value = false;
}
})
.catch(() => {
},
() => {
// 用户取消操作,无需处理
});
}
);
}
// ==================== 导入导出 ====================
@@ -551,14 +536,9 @@ function handleOpenImportDialog(): void {
* 导出用户列表
*/
async function handleExport(): Promise<void> {
try {
const response = await UserAPI.export(queryParams);
downloadFile(response);
ElMessage.success("导出成功");
} catch (error) {
ElMessage.error("导出失败");
console.error("导出用户列表失败:", error);
}
const response = await UserAPI.export(queryParams);
downloadFile(response);
ElMessage.success("导出成功");
}
// ==================== 生命周期 ====================