9 changed files with 547 additions and 44 deletions
-
1.gitignore
-
65.idea/inspectionProfiles/Project_Default.xml
-
160server/endpoints/dept.js
-
2server/index.js
-
238server/models/dept.js
-
12server/prisma/migrations/20250222043007_init/migration.sql
-
10server/prisma/migrations/20250224030233_init_test_table/migration.sql
-
98server/prisma/schema.prisma
-
5server/utils/files/index.js
@ -1,6 +1,69 @@ |
|||||
<component name="InspectionProjectProfileManager"> |
<component name="InspectionProjectProfileManager"> |
||||
<profile version="1.0"> |
<profile version="1.0"> |
||||
<option name="myName" value="Project Default" /> |
<option name="myName" value="Project Default" /> |
||||
|
<inspection_tool class="AliAccessStaticViaInstance" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AliArrayNamingShouldHaveBracket" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AliControlFlowStatementWithoutBraces" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AliDeprecation" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AliEqualsAvoidNull" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AliLongLiteralsEndingWithLowercaseL" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AliMissingOverrideAnnotation" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AliWrapperTypeEquality" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaAbstractClassShouldStartWithAbstractNaming" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaAbstractMethodOrInterfaceMethodMustUseJavadoc" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaAvoidApacheBeanUtilsCopy" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaAvoidCallStaticSimpleDateFormat" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaAvoidCommentBehindStatement" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaAvoidComplexCondition" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaAvoidConcurrentCompetitionRandom" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaAvoidDoubleOrFloatEqualCompare" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaAvoidManuallyCreateThread" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaAvoidMissUseOfMathRandom" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaAvoidNegationOperator" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaAvoidNewDateGetTime" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaAvoidPatternCompileInMethod" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaAvoidReturnInFinally" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaAvoidStartWithDollarAndUnderLineNaming" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaAvoidUseTimer" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaBigDecimalAvoidDoubleConstructor" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaBooleanPropertyShouldNotStartWithIs" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaClassCastExceptionWithSubListToArrayList" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaClassCastExceptionWithToArray" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaClassMustHaveAuthor" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaClassNamingShouldBeCamel" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaCollectionInitShouldAssignCapacity" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaCommentsMustBeJavadocFormat" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaConcurrentExceptionWithModifyOriginSubList" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaConstantFieldShouldBeUpperCase" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaCountDownShouldInFinally" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaDontModifyInForeachCircle" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaEnumConstantsMustHaveComment" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaExceptionClassShouldEndWithException" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaIbatisMethodQueryForList" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaLockShouldWithTryFinally" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaLowerCamelCaseVariableNaming" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaMethodReturnWrapperType" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaMethodTooLong" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaPackageNaming" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaPojoMustOverrideToString" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaPojoMustUsePrimitiveField" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaPojoNoDefaultValue" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaRemoveCommentedCode" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaServiceOrDaoClassShouldEndWithImpl" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaSneakyThrowsWithoutExceptionType" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaStringConcat" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaSwitchExpression" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaSwitchStatement" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaTestClassShouldEndWithTestNaming" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaThreadLocalShouldRemove" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaThreadPoolCreation" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaThreadShouldSetName" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaTransactionMustHaveRollback" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaUndefineMagicConstant" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaUnsupportedExceptionWithModifyAsList" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaUseQuietReferenceNotation" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="AlibabaUseRightCaseForDateFormat" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" /> |
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
|
<inspection_tool class="MapOrSetKeyShouldOverrideHashCodeEquals" enabled="true" level="WARNING" enabled_by_default="true" /> |
||||
</profile> |
</profile> |
||||
</component> |
|
||||
|
</component> |
||||
@ -0,0 +1,160 @@ |
|||||
|
const { Dept } = require("../models/dept"); |
||||
|
const { validatedRequest } = require("../utils/middleware/validatedRequest"); |
||||
|
const { |
||||
|
strictMultiUserRoleValid, |
||||
|
ROLES |
||||
|
} = require("../utils/middleware/multiUserProtected"); |
||||
|
function deptEndpoints(app) { |
||||
|
if (!app) return; |
||||
|
|
||||
|
app.get( |
||||
|
"/dept/list", |
||||
|
[validatedRequest, strictMultiUserRoleValid([ROLES.admin])], |
||||
|
async (_request, response) => { |
||||
|
try { |
||||
|
const depts = await Dept.where(); |
||||
|
response.status(200).json({ depts }); |
||||
|
} catch (e) { |
||||
|
console.error(e); |
||||
|
response.sendStatus(500).end(); |
||||
|
} |
||||
|
} |
||||
|
); |
||||
|
|
||||
|
app.post("/dept/add", |
||||
|
[validatedRequest, strictMultiUserRoleValid([ROLES.admin])], |
||||
|
async (request, response) => { |
||||
|
try { |
||||
|
const dept = request.body; // 获取请求体中的部门数据
|
||||
|
// 检查部门名称是否唯一
|
||||
|
const isUnique = await Dept.checkDeptNameUnique(dept); |
||||
|
if (!isUnique) { |
||||
|
return response.status(400).json({ |
||||
|
success: false, |
||||
|
message: `新增部门 '${dept.deptName}' 失败,部门名称已存在`, |
||||
|
}); |
||||
|
}; |
||||
|
// 按照deptId查询父部门
|
||||
|
const parentDept = await Dept.get({ deptId: dept.parentId }); |
||||
|
dept.ancestors = parentDept.dept.ancestors + ',' + dept.parentId; |
||||
|
// 插入部门数据
|
||||
|
const insertedDept = await Dept.insertDept(dept); |
||||
|
// 返回成功响应
|
||||
|
response.status(200).json({ |
||||
|
success: true, |
||||
|
data: insertedDept, |
||||
|
}); |
||||
|
} catch (error) { |
||||
|
// 处理错误
|
||||
|
console.error("添加部门失败:", error); |
||||
|
response.status(500).json({ |
||||
|
success: false, |
||||
|
message: "添加部门失败,服务器内部错误", |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
app.post("/dept/edit", |
||||
|
[validatedRequest, strictMultiUserRoleValid([ROLES.admin])], |
||||
|
async (request, response) => { |
||||
|
try { |
||||
|
const dept = request.body; // 获取请求体中的部门数据
|
||||
|
|
||||
|
// 检查部门名称是否唯一
|
||||
|
const isUnique = await Dept.checkDeptNameUnique(dept); |
||||
|
if (!isUnique) { |
||||
|
return response.status(400).json({ |
||||
|
success: false, |
||||
|
message: `修改部门 '${dept.deptName}' 失败,部门名称已存在`, |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
// 检查上级部门是否是自己
|
||||
|
if (dept.parentId === dept.deptId) { |
||||
|
return response.status(400).json({ |
||||
|
success: false, |
||||
|
message: `修改部门 '${dept.deptName}' 失败,上级部门不能是自己`, |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
// 检查部门是否包含未停用的子部门
|
||||
|
if (dept.status === 1) { |
||||
|
const normalChildrenCount = await Dept.selectNormalChildrenDeptById(dept.deptId); |
||||
|
if (normalChildrenCount > 0) { |
||||
|
return response.status(400).json({ |
||||
|
success: false, |
||||
|
message: "该部门包含未停用的子部门!", |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
// 更新部门数据
|
||||
|
const updatedDept = await Dept.update(dept); |
||||
|
// 返回成功响应
|
||||
|
response.status(200).json({ |
||||
|
success: true, |
||||
|
data: updatedDept, |
||||
|
}); |
||||
|
} catch (error) { |
||||
|
// 处理错误
|
||||
|
console.error("修改部门失败:", error); |
||||
|
response.status(500).json({ |
||||
|
success: false, |
||||
|
message: "修改部门失败,服务器内部错误", |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
// 删除部门的接口
|
||||
|
app.delete("/dept/:deptId", |
||||
|
[validatedRequest, strictMultiUserRoleValid([ROLES.admin])], |
||||
|
async (request, response) => { |
||||
|
try { |
||||
|
const deptId = parseInt(request.params.deptId); // 获取部门 ID
|
||||
|
|
||||
|
// 检查部门是否有子部门
|
||||
|
const hasChild = await Dept.hasChildByDeptId(deptId); |
||||
|
if (hasChild) { |
||||
|
return response.status(400).json({ |
||||
|
success: false, |
||||
|
message: "存在下级部门,不允许删除", |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
// 检查部门是否存在用户
|
||||
|
const hasUser = await Dept.checkDeptExistUser(deptId); |
||||
|
if (hasUser) { |
||||
|
return response.status(400).json({ |
||||
|
success: false, |
||||
|
message: "部门存在用户,不允许删除", |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
// // 检查部门数据权限
|
||||
|
// const hasDataScope = await Dept.checkDeptDataScope(deptId);
|
||||
|
// if (!hasDataScope) {
|
||||
|
// return response.status(403).json({
|
||||
|
// success: false,
|
||||
|
// message: "无权限删除该部门",
|
||||
|
// });
|
||||
|
// }
|
||||
|
|
||||
|
// 删除部门
|
||||
|
const deletedDept = await Dept.deleteDeptById(deptId); |
||||
|
|
||||
|
// 返回成功响应
|
||||
|
response.status(200).json({ |
||||
|
success: true, |
||||
|
data: deletedDept, |
||||
|
}); |
||||
|
} catch (error) { |
||||
|
// 处理错误
|
||||
|
console.error("删除部门失败:", error); |
||||
|
response.status(500).json({ |
||||
|
success: false, |
||||
|
message: "删除部门失败,服务器内部错误", |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
module.exports = { deptEndpoints }; |
||||
@ -0,0 +1,238 @@ |
|||||
|
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; |
||||
|
} |
||||
|
}, |
||||
|
}; |
||||
|
|
||||
|
module.exports = { Dept }; |
||||
@ -0,0 +1,12 @@ |
|||||
|
-- CreateTable |
||||
|
CREATE TABLE "dept" ( |
||||
|
"deptId" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, |
||||
|
"parentId" INTEGER, |
||||
|
"ancestors" TEXT, |
||||
|
"deptName" TEXT, |
||||
|
"orderNum" INTEGER, |
||||
|
"status" INTEGER NOT NULL DEFAULT 0, |
||||
|
"delFlag" INTEGER NOT NULL DEFAULT 0, |
||||
|
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, |
||||
|
"lastUpdatedAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP |
||||
|
); |
||||
@ -0,0 +1,10 @@ |
|||||
|
-- CreateTable |
||||
|
CREATE TABLE "dept_users" ( |
||||
|
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, |
||||
|
"deptId" INTEGER NOT NULL, |
||||
|
"userId" INTEGER NOT NULL, |
||||
|
"createdAt" DATETIME DEFAULT CURRENT_TIMESTAMP, |
||||
|
"updatedAt" DATETIME DEFAULT CURRENT_TIMESTAMP, |
||||
|
CONSTRAINT "dept_users_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, |
||||
|
CONSTRAINT "dept_users_deptId_fkey" FOREIGN KEY ("deptId") REFERENCES "dept" ("deptId") ON DELETE CASCADE ON UPDATE NO ACTION |
||||
|
); |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue