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.

293 lines
8.6 KiB

10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
  1. const prisma = require("../utils/prisma");
  2. /**
  3. * @typedef {Object} Dept
  4. * @property {number} deptId
  5. * @property {number} parentId
  6. * @property {string} ancestors
  7. * @property {string} deptName
  8. * @property {number} orderNum
  9. * @property {number} status
  10. * @property {number} delFlag
  11. * @property {Date} createdAt
  12. * @property {Date} lastUpdatedAt
  13. */
  14. const Dept = {
  15. writable: [
  16. 'parentId', 'ancestors', 'deptName', 'orderNum', 'status', 'delFlag'
  17. ],
  18. validations: {
  19. deptName: (newValue = '') => {
  20. if (typeof newValue !== 'string' || newValue.length > 255) {
  21. throw new Error('Dept name must be a string and cannot be longer than 255 characters');
  22. }
  23. return newValue;
  24. },
  25. orderNum: (newValue = 0) => {
  26. const num = Number(newValue);
  27. if (isNaN(num)) {
  28. throw new Error('Order num must be a number');
  29. }
  30. return num;
  31. },
  32. status: (newValue = 0) => {
  33. const status = Number(newValue);
  34. if (isNaN(status) || status < 0 || status > 1) {
  35. throw new Error('Status must be a number between 0 and 1');
  36. }
  37. return status;
  38. },
  39. delFlag: (newValue = 0) => {
  40. const flag = Number(newValue);
  41. if (isNaN(flag) || flag < 0 || flag > 1) {
  42. throw new Error('Del flag must be a number between 0 and 1');
  43. }
  44. return flag;
  45. }
  46. },
  47. castColumnValue: function (key, value) {
  48. switch (key) {
  49. case 'status':
  50. case 'delFlag':
  51. return Number(value);
  52. default:
  53. return value;
  54. }
  55. },
  56. create: async function ({ parentId, ancestors, deptName, orderNum, status = 0, delFlag = 0 }) {
  57. try {
  58. const validatedDeptName = this.validations.deptName(deptName);
  59. const validatedOrderNum = this.validations.orderNum(orderNum);
  60. const validatedStatus = this.validations.status(status);
  61. const validatedDelFlag = this.validations.delFlag(delFlag);
  62. const dept = await prisma.dept.create({
  63. data: {
  64. parentId,
  65. ancestors,
  66. deptName: validatedDeptName,
  67. orderNum: validatedOrderNum,
  68. status: validatedStatus,
  69. delFlag: validatedDelFlag,
  70. createdAt: new Date(),
  71. lastUpdatedAt: new Date()
  72. }
  73. });
  74. return { dept, error: null };
  75. } catch (error) {
  76. console.error('FAILED TO CREATE DEPT.', error.message);
  77. return { dept: null, error: error.message };
  78. }
  79. },
  80. // 插入部门数据
  81. insertDept: async function (dept) {
  82. try {
  83. const insertedDept = await prisma.dept.create({
  84. data: {
  85. deptName: dept.deptName,
  86. parentId: dept.parentId || null,
  87. ancestors: dept.ancestors || null,
  88. orderNum: dept.orderNum || 0,
  89. status: dept.status || 0,
  90. delFlag: dept.delFlag || 0,
  91. createdAt: new Date(),
  92. lastUpdatedAt: new Date(),
  93. },
  94. });
  95. return insertedDept;
  96. } catch (error) {
  97. console.error("插入部门数据失败:", error);
  98. throw error;
  99. }
  100. },
  101. update: async function (deptId, updates = {}) {
  102. console.log("更新部门数据:", updates);
  103. try {
  104. // 检查 deptId 是否存在
  105. if (!deptId) throw new Error('没有提供用于查询的deptId');
  106. // 检查 updates 是否为空
  107. if (Object.keys(updates).length === 0) throw new Error('没有提供更新字段');
  108. // 查询当前部门
  109. const currentDept = await prisma.dept.findUnique({ where: { deptId } });
  110. if (!currentDept) throw new Error('不存在该部门');
  111. // 更新 lastUpdatedAt 字段
  112. updates.lastUpdatedAt = new Date();
  113. // 如果 parentId 发生变化,更新 ancestors 字段
  114. if (updates.parentId !== undefined && updates.parentId !== currentDept.parentId) {
  115. const parentId = updates.parentId;
  116. const parentDept = await prisma.dept.findUnique({ where: { deptId: parentId } });
  117. updates.ancestors = parentDept ? `${parentDept.ancestors},${parentId}` : `${parentId}`;
  118. }
  119. console.log("更新前部门数据:", updates);
  120. // 执行更新操作
  121. const updatedDept = await prisma.dept.update({
  122. where: { deptId }, // 使用 deptId 作为查询条件
  123. data: updates, // 更新的字段
  124. });
  125. console.log("更新后部门数据:", updatedDept);
  126. // 返回成功结果
  127. return { success: true, error: null, dept: updatedDept };
  128. } catch (error) {
  129. console.error(error.message);
  130. return { success: false, error: error.message, dept: null };
  131. }
  132. },
  133. get: async function (clause = {}) {
  134. try {
  135. const dept = await prisma.dept.findFirst({ where: clause, select: {
  136. deptId: true, parentId: true, ancestors: true, deptName: true, orderNum: true, status: true, delFlag: true, createdAt: true, lastUpdatedAt: true
  137. } });
  138. return dept ? { dept } : null;
  139. } catch (error) {
  140. console.error(error.message);
  141. return null;
  142. }
  143. },
  144. delete: async function (clause = {}) {
  145. try {
  146. const affectedRows = await prisma.dept.deleteMany({ where: clause });
  147. return affectedRows > 0;
  148. } catch (error) {
  149. console.error(error.message);
  150. return false;
  151. }
  152. },
  153. where: async function (clause = {}, limit = null) {
  154. try {
  155. const depts = await prisma.dept.findMany({
  156. where: clause,
  157. take: limit !== null ? limit : undefined,
  158. select: {
  159. deptId: true, parentId: true, ancestors: true, deptName: true, orderNum: true, status: true, delFlag: true, createdAt: true, lastUpdatedAt: true
  160. }
  161. });
  162. return depts;
  163. } catch (error) {
  164. console.error(error.message);
  165. return [];
  166. }
  167. },
  168. checkDeptNameUnique: async function (dept){
  169. try {
  170. const existingDept = await prisma.dept.findFirst({
  171. where: {
  172. deptName: dept.deptName, // 根据部门名称查询
  173. parentId: dept.parentId, // 排除父id
  174. },
  175. });
  176. // 如果查询到记录,说明部门名称已存在
  177. console.log("existingDept:", existingDept);
  178. return !existingDept;
  179. } catch (error) {
  180. console.error('检查部门名称唯一性失败:', error);
  181. throw error;
  182. }
  183. },
  184. // 检查部门是否包含未停用的子部门
  185. selectNormalChildrenDeptById: async function (deptId) {
  186. try {
  187. // 查询所有祖先部门中包含当前部门的未停用部门
  188. const childrenDepts = await prisma.$queryRaw`
  189. SELECT COUNT(*) as count
  190. FROM sys_dept
  191. WHERE status = 0
  192. AND del_flag = '0'
  193. AND FIND_IN_SET(${deptId}, ancestors)
  194. `;
  195. // 返回未停用的子部门数量
  196. return childrenDepts[0].count;
  197. } catch (error) {
  198. console.error("查询子部门失败:", error);
  199. throw error;
  200. }
  201. },
  202. // 检查部门是否有子部门
  203. hasChildByDeptId: async function (deptId) {
  204. try {
  205. const children = await prisma.dept.findMany({
  206. where: {
  207. parentId: deptId, // 查询当前部门的子部门
  208. delFlag: 0,
  209. },
  210. });
  211. // 如果有子部门,返回 true
  212. return children.length > 0;
  213. } catch (error) {
  214. console.error("检查子部门失败:", error);
  215. throw error;
  216. }
  217. },
  218. // 检查部门是否存在用户
  219. checkDeptExistUser: async function (deptId) {
  220. try {
  221. const users = await prisma.user.findMany({
  222. where: {
  223. deptId: deptId, // 查询当前部门的用户
  224. },
  225. });
  226. // 如果存在用户,返回 true
  227. return users.length > 0;
  228. } catch (error) {
  229. console.error("检查部门用户失败:", error);
  230. throw error;
  231. }
  232. },
  233. /**
  234. * 获取部门树状结构
  235. * @returns {Promise<Array>}
  236. */
  237. getDeptTree:async function () {
  238. try {
  239. // 查询所有部门
  240. const allDepts = await prisma.dept.findMany();
  241. // 构建树状结构
  242. const buildTree = (parentId = null) => {
  243. return allDepts
  244. .filter((dept) => dept.parentId === parentId)
  245. .map((dept) => ({
  246. ...dept,
  247. children: buildTree(dept.deptId), // 递归获取子部门
  248. }));
  249. };
  250. return buildTree();
  251. } catch (error) {
  252. console.error("获取部门树状结构失败:", error);
  253. throw error;
  254. }
  255. },
  256. /**
  257. * 根据父部门 ID 获取子部门列表
  258. * @param {number} parentId - 父部门 ID
  259. * @returns {Promise<Array>}
  260. */
  261. getChildrenByParentId:async function (parentId = null) {
  262. try {
  263. const children = await prisma.dept.findMany({
  264. where: { parentId },
  265. });
  266. return children;
  267. } catch (error) {
  268. console.error("获取子部门列表失败:", error);
  269. throw error;
  270. }
  271. },
  272. };
  273. module.exports = { Dept };