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.

320 lines
9.7 KiB

1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year 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. softDelete: async function (deptId) {
  154. try {
  155. // 检查 deptId 是否存在
  156. if (!deptId) throw new Error('没有提供用于查询的deptId');
  157. // 查询当前组织机构
  158. const currentDept = await prisma.dept.findUnique({ where: { deptId } });
  159. if (!currentDept) throw new Error('不存在该组织机构');
  160. // 执行逻辑删除操作
  161. const updatedDept = await prisma.dept.update({
  162. where: { deptId }, // 使用 deptId 作为查询条件
  163. data: {
  164. delFlag: 1, // 标记为已删除
  165. lastUpdatedAt: new Date(), // 更新最后修改时间
  166. },
  167. });
  168. console.log("逻辑删除后的组织机构数据:", updatedDept);
  169. // 返回成功结果
  170. return { success: true, error: null, dept: updatedDept };
  171. } catch (error) {
  172. console.error(error.message);
  173. return { success: false, error: error.message, dept: null };
  174. }
  175. },
  176. where: async function (clause = {}, limit = null) {
  177. try {
  178. const depts = await prisma.dept.findMany({
  179. where: clause,
  180. take: limit !== null ? limit : undefined,
  181. select: {
  182. deptId: true, parentId: true, ancestors: true, deptName: true, orderNum: true, status: true, delFlag: true, createdAt: true, lastUpdatedAt: true
  183. }
  184. });
  185. return depts;
  186. } catch (error) {
  187. console.error(error.message);
  188. return [];
  189. }
  190. },
  191. checkDeptNameUnique: async function (dept){
  192. try {
  193. const existingDept = await prisma.dept.findFirst({
  194. where: {
  195. deptName: dept.deptName, // 根据组织机构名称查询
  196. parentId: dept.parentId, // 排除父id
  197. },
  198. });
  199. // 如果查询到记录,说明组织机构名称已存在
  200. console.log("existingDept:", existingDept);
  201. return !existingDept;
  202. } catch (error) {
  203. console.error('检查组织机构名称唯一性失败:', error);
  204. throw error;
  205. }
  206. },
  207. // 检查组织机构是否包含未停用的子组织机构
  208. selectNormalChildrenDeptById: async function (deptId) {
  209. try {
  210. // 查询所有祖先组织机构中包含当前组织机构的未停用组织机构
  211. const childrenDepts = await prisma.$queryRaw`
  212. SELECT COUNT(*) as count
  213. FROM sys_dept
  214. WHERE status = 0
  215. AND del_flag = '0'
  216. AND FIND_IN_SET(${deptId}, ancestors)
  217. `;
  218. // 返回未停用的子组织机构数量
  219. return childrenDepts[0].count;
  220. } catch (error) {
  221. console.error("查询子组织机构失败:", error);
  222. throw error;
  223. }
  224. },
  225. // 检查组织机构是否有子组织机构
  226. hasChildByDeptId: async function (deptId) {
  227. try {
  228. const children = await prisma.dept.findMany({
  229. where: {
  230. parentId: deptId, // 查询当前组织机构的子组织机构
  231. delFlag: 0,
  232. },
  233. });
  234. // 如果有子组织机构,返回 true
  235. return children.length > 0;
  236. } catch (error) {
  237. console.error("检查子组织机构失败:", error);
  238. throw error;
  239. }
  240. },
  241. // 检查组织机构是否存在用户
  242. checkDeptExistUser: async function (deptId) {
  243. try {
  244. const deptUsers = await prisma.dept_users.findMany({
  245. where: {
  246. deptId: deptId, // 查询当前组织机构的用户
  247. },
  248. });
  249. // 如果存在用户,返回 true
  250. return deptUsers.length > 0;
  251. } catch (error) {
  252. console.error("检查组织机构用户失败:", error);
  253. throw error;
  254. }
  255. },
  256. /**
  257. * 获取组织机构树状结构
  258. * @returns {Promise<Array>}
  259. */
  260. getDeptTree:async function () {
  261. try {
  262. // 查询所有组织机构
  263. const allDepts = await prisma.dept.findMany();
  264. // 构建树状结构
  265. const buildTree = (parentId = null) => {
  266. return allDepts
  267. .filter((dept) => dept.parentId === parentId)
  268. .map((dept) => ({
  269. ...dept,
  270. children: buildTree(dept.deptId), // 递归获取子组织机构
  271. }));
  272. };
  273. return buildTree();
  274. } catch (error) {
  275. console.error("获取组织机构树状结构失败:", error);
  276. throw error;
  277. }
  278. },
  279. /**
  280. * 根据父组织机构 ID 获取子组织机构列表
  281. * @param {number} parentId - 父组织机构 ID
  282. * @returns {Promise<Array>}
  283. */
  284. getChildrenByParentId:async function (parentId = null) {
  285. try {
  286. const children = await prisma.dept.findMany({
  287. where: { parentId },
  288. });
  289. return children;
  290. } catch (error) {
  291. console.error("获取子组织机构列表失败:", error);
  292. throw error;
  293. }
  294. },
  295. };
  296. module.exports = { Dept };