forked from UKSOURCE/cms.hailearning.edu.vn
first commit
This commit is contained in:
185
models/menuHeader.js
Normal file
185
models/menuHeader.js
Normal file
@@ -0,0 +1,185 @@
|
||||
const mongoose = require('mongoose');
|
||||
|
||||
const MenuSchema = new mongoose.Schema({
|
||||
menuid: { type: String, required: true, unique: true }, // ID tùy chỉnh
|
||||
parent: { type: String, default: null }, // ID menu cha
|
||||
title: { type: String, required: true }, // Tên hiển thị
|
||||
url: { type: String, default: '' }, // Đường dẫn
|
||||
order: { type: Number, default: 0 }, // Thứ tự hiển thị
|
||||
type: { type: String, enum: ['static', 'page', 'level'], default: 'static' }, // Loại menu
|
||||
fetch: { type: Boolean, default: false }, // Có fetch programme không
|
||||
isActive: { type: Boolean, default: true } // Trạng thái hoạt động của menu
|
||||
}, { timestamps: false });
|
||||
|
||||
// Index để tối ưu query
|
||||
MenuSchema.index({ parent: 1, order: 1 });
|
||||
MenuSchema.index({ type: 1 });
|
||||
|
||||
// Method để lấy menu tree
|
||||
MenuSchema.statics.getMenuTree = async function () {
|
||||
try {
|
||||
const allMenus = await this.find().sort({ order: 1 }).lean();
|
||||
|
||||
const menuMap = new Map();
|
||||
const rootMenus = [];
|
||||
|
||||
// Đưa tất cả menus vào map và xử lý URL dựa trên isActive
|
||||
allMenus.forEach(menu => {
|
||||
const activeUrl = menu.isActive === false ? '/maintenance/' : menu.url;
|
||||
menuMap.set(menu.menuid, {
|
||||
...menu,
|
||||
url: activeUrl, // Sử dụng URL đã được xử lý
|
||||
children: []
|
||||
});
|
||||
});
|
||||
|
||||
// Xây dựng tree structure
|
||||
allMenus.forEach(menu => {
|
||||
const menuObj = menuMap.get(menu.menuid);
|
||||
|
||||
if (!menu.parent) {
|
||||
rootMenus.push(menuObj);
|
||||
} else {
|
||||
const parent = menuMap.get(menu.parent);
|
||||
if (parent) {
|
||||
parent.children.push(menuObj);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return rootMenus;
|
||||
} catch (error) {
|
||||
console.error('Error building menu tree:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
// Method để lấy menu tree với programmes
|
||||
MenuSchema.statics.getMenuTreeWithProgrammes = async function () {
|
||||
try {
|
||||
const menuTree = await this.getMenuTree();
|
||||
|
||||
// Thêm programmes cho các menu level
|
||||
for (const menu of menuTree) {
|
||||
await this.addProgrammesToMenu(menu);
|
||||
}
|
||||
|
||||
return menuTree;
|
||||
} catch (error) {
|
||||
console.error('Error building menu tree with programmes:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
// Method để thêm programmes vào menu
|
||||
MenuSchema.statics.addProgrammesToMenu = async function (menuItem) {
|
||||
try {
|
||||
if (menuItem.type === 'level' && menuItem.fetch) {
|
||||
const programmes = await this.getProgrammesByMenuId(menuItem.menuid);
|
||||
menuItem.programmes = programmes;
|
||||
}
|
||||
|
||||
if (menuItem.children && menuItem.children.length > 0) {
|
||||
for (const child of menuItem.children) {
|
||||
await this.addProgrammesToMenu(child);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error adding programmes to menu:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
// Method để lấy programmes theo menu ID
|
||||
MenuSchema.statics.getProgrammesByMenuId = async function (menuId) {
|
||||
try {
|
||||
const Programme = require('./programme');
|
||||
const Level = require('./level');
|
||||
|
||||
// Sử dụng trực tiếp menuId làm levelType vì menuid đã được đặt đúng khi tạo
|
||||
const levelType = menuId;
|
||||
|
||||
const level = await Level.findOne({ type: levelType });
|
||||
if (!level) return [];
|
||||
|
||||
const programmes = await Programme.find({ level: level._id })
|
||||
.select('name code level_type')
|
||||
.sort({ name: 1 })
|
||||
.lean();
|
||||
|
||||
return programmes;
|
||||
} catch (error) {
|
||||
console.error('Error getting programmes by menu ID:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
// Method để tạo menu mới
|
||||
MenuSchema.statics.createMenu = async function (menuData) {
|
||||
try {
|
||||
const menu = new this(menuData);
|
||||
await menu.save();
|
||||
return menu;
|
||||
} catch (error) {
|
||||
console.error('Error creating menu:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
// Method để cập nhật menu
|
||||
MenuSchema.statics.updateMenu = async function (menuId, updateData) {
|
||||
try {
|
||||
const menu = await this.findOneAndUpdate({ menuid: menuId }, updateData, { new: true });
|
||||
return menu;
|
||||
} catch (error) {
|
||||
console.error('Error updating menu:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
// Method để xóa menu
|
||||
MenuSchema.statics.deleteMenu = async function (menuId) {
|
||||
try {
|
||||
// Xóa tất cả children trước
|
||||
await this.deleteMany({ parent: menuId });
|
||||
// Sau đó xóa menu chính
|
||||
const result = await this.findOneAndDelete({ menuid: menuId });
|
||||
return result;
|
||||
} catch (error) {
|
||||
console.error('Error deleting menu:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
// Method để sắp xếp lại order
|
||||
MenuSchema.statics.reorderMenus = async function (parentId, menuIds) {
|
||||
try {
|
||||
const updates = menuIds.map((menuId, index) => ({
|
||||
updateOne: {
|
||||
filter: { menuid: menuId },
|
||||
update: { order: index }
|
||||
}
|
||||
}));
|
||||
|
||||
await this.bulkWrite(updates);
|
||||
console.log('Menus reordered successfully');
|
||||
} catch (error) {
|
||||
console.error('Error reordering menus:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
// Method để lấy URL dựa trên trạng thái isActive
|
||||
MenuSchema.methods.getActiveUrl = function () {
|
||||
if (this.isActive === false) {
|
||||
return '/maintenance/';
|
||||
}
|
||||
return this.url;
|
||||
};
|
||||
|
||||
// Method để kiểm tra trạng thái hoạt động
|
||||
MenuSchema.methods.isMenuActive = function () {
|
||||
return this.isActive !== false;
|
||||
};
|
||||
|
||||
module.exports = mongoose.model('MenuHeader', MenuSchema);
|
||||
Reference in New Issue
Block a user