Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com
159 lines
3.2 KiB
TypeScript
159 lines
3.2 KiB
TypeScript
import { Provide } from "@midwayjs/core";
|
|
import { InjectRepository } from "@midwayjs/sequelize";
|
|
import SysMenu from "../entity/sysMenu.entity";
|
|
|
|
@Provide()
|
|
export class MenuService {
|
|
@InjectRepository(SysMenu)
|
|
menuModel!: typeof SysMenu;
|
|
|
|
async getMenuTree(): Promise<any> {
|
|
const menus = await this.menuModel.findAll({
|
|
order: [["sort_order", "ASC"], ["id", "ASC"]],
|
|
});
|
|
|
|
const tree = this.buildMenuTree(menus.map(menu => menu.toJSON()));
|
|
|
|
return {
|
|
code: 200,
|
|
message: "获取菜单树成功",
|
|
data: tree,
|
|
};
|
|
}
|
|
|
|
async create(data: any): Promise<any> {
|
|
const {
|
|
parentId,
|
|
menuName,
|
|
menuPath,
|
|
component,
|
|
icon,
|
|
sortOrder = 0,
|
|
menuType = 2,
|
|
permission,
|
|
visible = 1,
|
|
} = data;
|
|
|
|
if (!menuName) {
|
|
return {
|
|
code: 400,
|
|
message: "菜单名称不能为空",
|
|
data: null,
|
|
};
|
|
}
|
|
|
|
const menu = await this.menuModel.create({
|
|
parentId,
|
|
menuName,
|
|
menuPath,
|
|
component,
|
|
icon,
|
|
sortOrder,
|
|
menuType,
|
|
permission,
|
|
visible,
|
|
});
|
|
|
|
return {
|
|
code: 200,
|
|
message: "创建菜单成功",
|
|
data: menu,
|
|
};
|
|
}
|
|
|
|
async update(id: string, data: any): Promise<any> {
|
|
const menu = await this.menuModel.findByPk(Number(id));
|
|
|
|
if (!menu) {
|
|
return {
|
|
code: 404,
|
|
message: "菜单不存在",
|
|
data: null,
|
|
};
|
|
}
|
|
|
|
const updateData: any = {};
|
|
if (data.parentId !== undefined) updateData.parentId = data.parentId;
|
|
if (data.menuName !== undefined) updateData.menuName = data.menuName;
|
|
if (data.menuPath !== undefined) updateData.menuPath = data.menuPath;
|
|
if (data.component !== undefined) updateData.component = data.component;
|
|
if (data.icon !== undefined) updateData.icon = data.icon;
|
|
if (data.sortOrder !== undefined) updateData.sortOrder = data.sortOrder;
|
|
if (data.menuType !== undefined) updateData.menuType = data.menuType;
|
|
if (data.permission !== undefined) updateData.permission = data.permission;
|
|
if (data.visible !== undefined) updateData.visible = data.visible;
|
|
|
|
await menu.update(updateData);
|
|
|
|
return {
|
|
code: 200,
|
|
message: "更新菜单成功",
|
|
data: menu,
|
|
};
|
|
}
|
|
|
|
async remove(id: string): Promise<any> {
|
|
const menu = await this.menuModel.findByPk(Number(id));
|
|
|
|
if (!menu) {
|
|
return {
|
|
code: 404,
|
|
message: "菜单不存在",
|
|
data: null,
|
|
};
|
|
}
|
|
|
|
const childCount = await this.menuModel.count({
|
|
where: { parentId: Number(id) },
|
|
});
|
|
|
|
if (childCount > 0) {
|
|
return {
|
|
code: 400,
|
|
message: "存在子菜单,无法删除",
|
|
data: null,
|
|
};
|
|
}
|
|
|
|
await menu.destroy();
|
|
|
|
return {
|
|
code: 200,
|
|
message: "删除菜单成功",
|
|
data: null,
|
|
};
|
|
}
|
|
|
|
private buildMenuTree(menus: any[]): any[] {
|
|
const map = new Map<number, any>();
|
|
const tree: any[] = [];
|
|
|
|
for (const menu of menus) {
|
|
map.set(menu.id, {
|
|
id: menu.id,
|
|
parentId: menu.parentId,
|
|
menuName: menu.menuName,
|
|
menuPath: menu.menuPath,
|
|
component: menu.component,
|
|
icon: menu.icon,
|
|
sortOrder: menu.sortOrder,
|
|
menuType: menu.menuType,
|
|
permission: menu.permission,
|
|
visible: menu.visible,
|
|
children: [],
|
|
});
|
|
}
|
|
|
|
for (const menu of menus) {
|
|
const node = map.get(menu.id)!;
|
|
if (menu.parentId && map.has(menu.parentId)) {
|
|
map.get(menu.parentId)!.children.push(node);
|
|
} else {
|
|
tree.push(node);
|
|
}
|
|
}
|
|
|
|
return tree;
|
|
}
|
|
}
|