You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

279 lines
8.0 KiB

const prisma = require("../utils/prisma");
/**
* @typedef {Object} Dept
* @property {number} deptId
* @property {number} parentId
* @property {string} ancestors
* @property {string} deptName
* @property {number} orderNum
* @property {number} status
* @property {number} delFlag
* @property {Date} createdAt
* @property {Date} lastUpdatedAt
*/
const Dept = {
writable: [
'parentId', 'ancestors', 'deptName', 'orderNum', 'status', 'delFlag'
],
validations: {
deptName: (newValue = '') => {
if (typeof newValue !== 'string' || newValue.length > 255) {
throw new Error('Dept name must be a string and cannot be longer than 255 characters');
}
return newValue;
},
orderNum: (newValue = 0) => {
const num = Number(newValue);
if (isNaN(num)) {
throw new Error('Order num must be a number');
}
return num;
},
status: (newValue = 0) => {
const status = Number(newValue);
if (isNaN(status) || status < 0 || status > 1) {
throw new Error('Status must be a number between 0 and 1');
}
return status;
},
delFlag: (newValue = 0) => {
const flag = Number(newValue);
if (isNaN(flag) || flag < 0 || flag > 1) {
throw new Error('Del flag must be a number between 0 and 1');
}
return flag;
}
},
castColumnValue: function (key, value) {
switch (key) {
case 'status':
case 'delFlag':
return Number(value);
default:
return value;
}
},
create: async function ({ parentId, ancestors, deptName, orderNum, status = 0, delFlag = 0 }) {
try {
const validatedDeptName = this.validations.deptName(deptName);
const validatedOrderNum = this.validations.orderNum(orderNum);
const validatedStatus = this.validations.status(status);
const validatedDelFlag = this.validations.delFlag(delFlag);
const dept = await prisma.dept.create({
data: {
parentId,
ancestors,
deptName: validatedDeptName,
orderNum: validatedOrderNum,
status: validatedStatus,
delFlag: validatedDelFlag,
createdAt: new Date(),
lastUpdatedAt: new Date()
}
});
return { dept, error: null };
} catch (error) {
console.error('FAILED TO CREATE DEPT.', error.message);
return { dept: null, error: error.message };
}
},
// 插入部门数据
insertDept: async function (dept) {
try {
const insertedDept = await prisma.dept.create({
data: {
deptName: dept.deptName,
parentId: dept.parentId || null,
ancestors: dept.ancestors || null,
orderNum: dept.orderNum || 0,
status: dept.status || 0,
delFlag: dept.delFlag || 0,
createdAt: new Date(),
lastUpdatedAt: new Date(),
},
});
return insertedDept;
} catch (error) {
console.error("插入部门数据失败:", error);
throw error;
}
},
update: async function (deptId, updates = {}) {
try {
if (!deptId) throw new Error('No dept id provided for update');
const currentDept = await prisma.dept.findUnique({ where: { deptId } });
if (!currentDept) throw new Error('Dept not found');
Object.entries(updates).forEach(([key, value]) => {
if (this.writable.includes(key)) {
if (Object.prototype.hasOwnProperty.call(this.validations, key)) {
updates[key] = this.validations[key](this.castColumnValue(key, value));
} else {
updates[key] = this.castColumnValue(key, value);
}
}
});
updates.lastUpdatedAt = new Date();
const updatedDept = await prisma.dept.update({ where: { deptId }, data: updates });
return { success: true, error: null, dept: updatedDept };
} catch (error) {
console.error(error.message);
return { success: false, error: error.message, dept: null };
}
},
get: async function (clause = {}) {
try {
const dept = await prisma.dept.findFirst({ where: clause, select: {
deptId: true, parentId: true, ancestors: true, deptName: true, orderNum: true, status: true, delFlag: true, createdAt: true, lastUpdatedAt: true
} });
return dept ? { dept } : null;
} catch (error) {
console.error(error.message);
return null;
}
},
delete: async function (clause = {}) {
try {
const affectedRows = await prisma.dept.deleteMany({ where: clause });
return affectedRows > 0;
} catch (error) {
console.error(error.message);
return false;
}
},
where: async function (clause = {}, limit = null) {
try {
const depts = await prisma.dept.findMany({
where: clause,
take: limit !== null ? limit : undefined,
select: {
deptId: true, parentId: true, ancestors: true, deptName: true, orderNum: true, status: true, delFlag: true, createdAt: true, lastUpdatedAt: true
}
});
return depts;
} catch (error) {
console.error(error.message);
return [];
}
},
checkDeptNameUnique: async function (dept){
try {
const existingDept = await prisma.dept.findFirst({
where: {
deptName: dept.deptName, // 根据部门名称查询
parentId: dept.parentId, // 排除父id
},
});
// 如果查询到记录,说明部门名称已存在
return !existingDept;
} catch (error) {
console.error('检查部门名称唯一性失败:', error);
throw error;
}
},
// 检查部门是否包含未停用的子部门
selectNormalChildrenDeptById: async function (deptId) {
try {
// 查询所有祖先部门中包含当前部门的未停用部门
const childrenDepts = await prisma.$queryRaw`
SELECT COUNT(*) as count
FROM sys_dept
WHERE status = 0
AND del_flag = '0'
AND FIND_IN_SET(${deptId}, ancestors)
`;
// 返回未停用的子部门数量
return childrenDepts[0].count;
} catch (error) {
console.error("查询子部门失败:", error);
throw error;
}
},
// 检查部门是否有子部门
hasChildByDeptId: async function (deptId) {
try {
const children = await prisma.dept.findMany({
where: {
parentId: deptId, // 查询当前部门的子部门
delFlag: 0,
},
});
// 如果有子部门,返回 true
return children.length > 0;
} catch (error) {
console.error("检查子部门失败:", error);
throw error;
}
},
// 检查部门是否存在用户
checkDeptExistUser: async function (deptId) {
try {
const users = await prisma.user.findMany({
where: {
deptId: deptId, // 查询当前部门的用户
},
});
// 如果存在用户,返回 true
return users.length > 0;
} catch (error) {
console.error("检查部门用户失败:", error);
throw error;
}
},
/**
* 获取部门树状结构
* @returns {Promise<Array>}
*/
getDeptTree:async function () {
try {
// 查询所有部门
const allDepts = await prisma.dept.findMany();
// 构建树状结构
const buildTree = (parentId = null) => {
return allDepts
.filter((dept) => dept.parentId === parentId)
.map((dept) => ({
...dept,
children: buildTree(dept.deptId), // 递归获取子部门
}));
};
return buildTree();
} catch (error) {
console.error("获取部门树状结构失败:", error);
throw error;
}
},
/**
* 根据父部门 ID 获取子部门列表
* @param {number} parentId - 父部门 ID
* @returns {Promise<Array>}
*/
getChildrenByParentId:async function (parentId = null) {
try {
const children = await prisma.dept.findMany({
where: { parentId },
});
return children;
} catch (error) {
console.error("获取子部门列表失败:", error);
throw error;
}
},
};
module.exports = { Dept };