BookSystem/frontend/src/modules/admin/views/permissions/permission-crud.ts
jayhgq 9586c7467a feat: 菜单管理添加排序功能
- Permission 模型新增 sort 字段
- 后端 API 按 sort 升序排列树形菜单
- 前端菜单管理页面增加排序列
- 初始数据添加排序号
- 修复 GET /permissions/{id} 详情接口 bug

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-20 08:33:51 +00:00

189 lines
5.5 KiB
TypeScript

import type { CreateCrudOptions } from "@fast-crud/fast-crud";
import dayjs from "dayjs";
import { ElMessage } from "element-plus";
import { http } from "@/modules/admin/api/http";
import { toSearchParams } from "@/modules/admin/utils/list-query";
export type PermissionRow = {
id: number;
name: string;
code: string;
parentid: number;
route?: string | null;
description?: string | null;
sort: number;
createtime: string;
updatetime: string;
children?: PermissionRow[];
};
export const createPermissionCrudOptions: CreateCrudOptions<PermissionRow> = () => {
return {
crudOptions: {
pagination: { show: false },
search: {
show: true,
options: {
layout: 'inline',
},
expand: false,
},
tree: {
enable: true,
childrenKey: "children",
parentKey: "parentid",
hasChildField: "children",
},
request: {
transformQuery: ({ form }) =>
toSearchParams(form as Record<string, unknown>, ["name", "code"]),
pageRequest: async (_query) => {
const { data } = await http.get<PermissionRow[]>("/permissions/tree");
return data;
},
transformRes: ({ res }) => {
const records = Array.isArray(res) ? res : [];
return {
currentPage: 1,
pageSize: Math.max(records.length, 1),
total: records.length,
records,
};
},
addRequest: async ({ form }) => {
await http.post("/permissions/", form);
ElMessage.success({ message: "添加成功", duration: 5000 });
},
editRequest: async ({ form, row }) => {
if (!row) return;
await http.put(`/permissions/${row.id}`, form);
ElMessage.success({ message: "修改成功", duration: 5000 });
},
delRequest: async ({ row }) => {
if (!row) return;
await http.delete(`/permissions/${row.id}`);
ElMessage.success({ message: "删除成功", duration: 5000 });
},
onSuccess: ({ action }: { action: string }) => {
if (action === "add") {
ElMessage.success({ message: "添加成功", duration: 5000 });
} else if (action === "edit") {
ElMessage.success({ message: "修改成功", duration: 5000 });
}
},
onError: (error: any) => {
let message = "操作失败";
if (error.response?.data) {
const data = error.response.data;
if (data.message) {
message = data.message;
} else if (data.detail) {
message = typeof data.detail === "string" ? data.detail : "操作失败";
}
}
ElMessage.error({ message, duration: 5000 });
},
},
table: {
remove: {
showSuccessNotification: false,
},
},
rowHandle: {
buttons: {
edit: { text: "编辑" },
remove: { text: "删除" },
},
},
columns: {
id: {
title: "ID",
key: "id",
type: "number",
column: { width: 70 },
form: { show: false },
},
name: {
title: "名称",
key: "name",
type: "text",
search: { show: true },
form: {
rules: [{ required: true, message: "必填" }],
},
},
code: {
title: "编码",
key: "code",
type: "text",
search: { show: true },
form: {
rules: [{ required: true, message: "必填" }],
},
},
parentid: {
title: "父级ID",
key: "parentid",
type: "number",
form: {
value: 0,
rules: [{ required: true, message: "必填" }],
},
},
description: {
title: "描述",
key: "description",
type: "textarea",
column: { show: false },
},
route: {
title: "路由",
key: "route",
type: "text",
column: { width: 200 },
form: {
placeholder: "如:/admin/users",
},
},
sort: {
title: "排序",
key: "sort",
type: "number",
column: { width: 80, align: "center" },
form: {
value: 0,
rules: [{ required: true, message: "必填" }],
helper: "数字越小,排序越靠前",
},
},
createtime: {
title: "创建时间",
key: "createtime",
type: "text",
form: { show: false },
column: { width: 170 },
valueBuilder({ value, row, key }) {
if (!row || value == null) return;
(row as Record<string, unknown>)[key as string] = dayjs(value).format(
"YYYY-MM-DD HH:mm:ss",
);
},
},
updatetime: {
title: "更新时间",
key: "updatetime",
type: "text",
form: { show: false },
column: { width: 170 },
valueBuilder({ value, row, key }) {
if (!row || value == null) return;
(row as Record<string, unknown>)[key as string] = dayjs(value).format(
"YYYY-MM-DD HH:mm:ss",
);
},
},
},
},
};
};