payment_tender.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. 'use strict';
  2. /**
  3. * 决策大屏用户查看权限-数据模型
  4. *
  5. * @author ellisran
  6. * @date 2021/09/23
  7. * @version
  8. */
  9. const accountGroup = require('../const/account_group').group;
  10. const paymentConst = require('../const/payment');
  11. const auditConst = require('../const/audit').stage;
  12. module.exports = app => {
  13. class paymentTender extends app.BaseService {
  14. constructor(ctx) {
  15. super(ctx);
  16. this.tableName = 'payment_tender';
  17. }
  18. async getList(uid, auditPermission) {
  19. if (auditPermission.view_all) {
  20. const sql1 = 'SELECT pt.*, pa.name as user_name FROM ?? as pt LEFT JOIN ?? as pa ON pt.`uid` = pa.`id` WHERE pt.`pid` = ? AND pt.`spid` = ?';
  21. const params1 = [this.tableName, this.ctx.service.projectAccount.tableName, this.ctx.session.sessionProject.id, this.ctx.subProject.id];
  22. return await this.db.query(sql1, params1);
  23. }
  24. const typeValues = [];
  25. const modes = this.ctx.subProject.payment_setting ? JSON.parse(this.ctx.subProject.payment_setting) : this._.cloneDeep(paymentConst.setting_modes);
  26. for (const m in paymentConst.setting_modes) {
  27. if (!modes[m]) modes[m] = this._.cloneDeep(paymentConst.setting_modes[m]);
  28. if (modes[m].checked) {
  29. typeValues.push(modes[m].value);
  30. }
  31. }
  32. if (typeValues.length === 0) {
  33. return -1;
  34. }
  35. const sql = 'SELECT pt.*, pa.name as user_name FROM ?? as pt LEFT JOIN ?? as pa ON pt.`uid` = pa.`id` WHERE pid = ? AND spid = ? AND (pt.`uid` = ? ' +
  36. 'OR pt.`id` in (SELECT pr.`tender_id` FROM ?? as pr WHERE pr.`uid` = ? AND pr.`type` IN (' + this.ctx.helper.getInArrStrSqlFilter(typeValues) + '))' +
  37. 'OR pt.`id` in (SELECT pd.`tender_id` FROM ?? as pd WHERE pd.`uid` = ?)' +
  38. 'OR pt.`id` in (SELECT pda.`tender_id` FROM ?? as pda LEFT JOIN ?? as pd ON pda.`tender_id` = pd.`tender_id` ' +
  39. 'WHERE pd.`status` != ' + auditConst.status.uncheck + ' AND pda.`aid` = ?)' +
  40. 'OR pt.`id` in (SELECT pra.`tender_id` FROM ?? as pra LEFT JOIN ?? as pd ON pra.`tender_id` = pd.`tender_id` ' +
  41. 'WHERE pd.`status` != ' + auditConst.status.uncheck + ' AND pd.`status` !=' + auditConst.status.checkNo + ' AND pra.`uid` = ?))';
  42. const params = [this.tableName, this.ctx.service.projectAccount.tableName, this.ctx.session.sessionProject.id, this.ctx.subProject.id, uid,
  43. this.ctx.service.paymentTenderRpt.tableName, uid,
  44. this.ctx.service.paymentDetail.tableName, uid,
  45. this.ctx.service.paymentDetailAudit.tableName, this.ctx.service.paymentDetail.tableName, uid,
  46. this.ctx.service.paymentRptAudit.tableName, this.ctx.service.paymentDetail.tableName, uid];
  47. return await this.db.query(sql, params);
  48. }
  49. async getNoSpList(pid, spIsNull = true) {
  50. const spSql = spIsNull ? ' AND pt.`spid` = ?' : ' AND pt.`spid` != ?';
  51. const sql1 = 'SELECT pt.*, pa.name as user_name FROM ?? as pt LEFT JOIN ?? as pa ON pt.`uid` = pa.`id` WHERE pt.`pid` = ?' + spSql;
  52. const params1 = [this.tableName, this.ctx.service.projectAccount.tableName, pid, ''];
  53. return await this.db.query(sql1, params1);
  54. }
  55. async addTender(projectId, uid, folderId, name) {
  56. const transaction = await this.db.beginTransaction();
  57. try {
  58. const folderInfo = await this.ctx.service.paymentFolder.getDataById(folderId);
  59. if (!folderInfo || folderInfo.is_leaf === 0) {
  60. throw '文件夹不存在或存在子目录不能新建标段';
  61. }
  62. const insertData = {
  63. pid: projectId,
  64. spid: this.ctx.subProject.id,
  65. uid,
  66. name,
  67. folder_id: folderId,
  68. in_time: new Date(),
  69. };
  70. const result = await transaction.insert(this.tableName, insertData);
  71. const updateData = [
  72. { id: folderInfo.id, had_tender: 1 },
  73. ];
  74. // 更新父节点had_tender值
  75. if (folderInfo.parent_path) {
  76. const parentFolderIds = folderInfo.parent_path.split('-');
  77. for (const pf of parentFolderIds) {
  78. const pfInfo = await this.ctx.service.paymentFolder.getDataByCondition({ spid: this.ctx.subProject.id, folder_id: parseInt(pf) });
  79. updateData.push({
  80. id: pfInfo.id,
  81. had_tender: 1,
  82. });
  83. }
  84. }
  85. await transaction.updateRows(this.ctx.service.paymentFolder.tableName, updateData);
  86. // 同时生成固定的报表表单
  87. await this.ctx.service.paymentTenderRpt.setConstRpt(transaction, result.insertId, uid);
  88. await transaction.commit();
  89. } catch (err) {
  90. await transaction.rollback();
  91. throw err;
  92. }
  93. }
  94. async deleteTender(id) {
  95. const transaction = await this.db.beginTransaction();
  96. try {
  97. const tenderInfo = await this.getDataById(id);
  98. if (!tenderInfo) {
  99. throw '标段不存在';
  100. }
  101. if (tenderInfo.uid !== this.ctx.session.sessionUser.accountId && !this.ctx.session.sessionUser.is_admin) {
  102. throw '您没有权限删除此标段';
  103. }
  104. const had_detail = await this.ctx.service.paymentDetail.haveDetail2Tender(id);
  105. if (had_detail) {
  106. throw '请先删除所有报表表单详情';
  107. }
  108. const folderInfo = await this.ctx.service.paymentFolder.getDataById(tenderInfo.folder_id);
  109. if (!folderInfo) {
  110. throw '文件夹不存在';
  111. }
  112. // 判断folderInfo下是否还存在tender,不存在则把had_tender为0,并判断父节点是否需要也为0
  113. const leafTenderCount = await transaction.count(this.tableName, { folder_id: folderInfo.id });
  114. if (leafTenderCount === 1) {
  115. const updateDatas = [{
  116. id: folderInfo.id,
  117. had_tender: 0,
  118. }];
  119. if (folderInfo.parent_path) {
  120. const parentFolderIds = folderInfo.parent_path.split('-').reverse();
  121. for (const pfid of parentFolderIds) {
  122. const parentFolderId = parseInt(pfid);
  123. const leafFolderCount = await transaction.count(this.ctx.service.paymentFolder.tableName, { spid: this.ctx.subProject.id, parent_id: parentFolderId, had_tender: 1 });
  124. if (leafFolderCount === 1) {
  125. const pfInfo = await this.ctx.service.paymentFolder.getDataByCondition({ spid: this.ctx.subProject.id, folder_id: parseInt(parentFolderId) });
  126. updateDatas.push({
  127. id: pfInfo.id,
  128. had_tender: 0,
  129. });
  130. } else {
  131. break;
  132. }
  133. }
  134. }
  135. await transaction.updateRows(this.ctx.service.paymentFolder.tableName, updateDatas);
  136. }
  137. await transaction.delete(this.ctx.service.paymentTenderRpt.tableName, { tender_id: id });
  138. await transaction.delete(this.ctx.service.paymentShenpiAudit.tableName, { tid: id });
  139. await transaction.delete(this.tableName, { id });
  140. await transaction.commit();
  141. } catch (err) {
  142. await transaction.rollback();
  143. throw err;
  144. }
  145. }
  146. // async getChildrenByParentId(parentId, transaction = null) {
  147. // const list = await this.getAllDataByCondition({ where: { parent_id: parentId } });
  148. // }
  149. async doCheckTender(id) {
  150. return await this.service.paymentTender.getDataById(id);
  151. }
  152. async bindSp(tids) {
  153. const noSpTenderList = await this.getNoSpList(this.ctx.session.sessionProject.id);
  154. const noSpFolderList = await this.ctx.service.paymentFolder.getNoSpList(this.ctx.session.sessionProject.id);
  155. const transaction = await this.db.beginTransaction();
  156. try {
  157. const hadSpTenderList = await this.getNoSpList(this.ctx.session.sessionProject.id, false);
  158. if (tids.length === noSpTenderList.length && hadSpTenderList.length === 0) {
  159. // 一次性迁移所有可以不用复制folder数据,也不用调整tender数据,直接更新spid
  160. await transaction.update(this.tableName, { spid: this.ctx.subProject.id }, { where: { pid: this.ctx.session.sessionProject.id } });
  161. await transaction.update(this.ctx.service.paymentFolder.tableName, { spid: this.ctx.subProject.id }, { where: { pid: this.ctx.session.sessionProject.id } });
  162. } else {
  163. const hadSpTenderIds = hadSpTenderList.map(item => item.id);
  164. // tids里过滤掉hadSpTenderIds存在的值
  165. const filterTids = tids.filter(item => !hadSpTenderIds.includes(item));
  166. if (filterTids.length > 0) {
  167. const folderList = await this.ctx.service.paymentFolder.getAllDataByCondition({ where: { spid: this.ctx.subProject.id } });
  168. // 需要复制一份folder数据,且比对folderList,如果存在则不复制,且可能需要调整id,parent_id,parent_path, order值
  169. const allNotExistFolderIds = [];
  170. for (const tid of filterTids) {
  171. const tender = this._.find(noSpTenderList, { id: tid });
  172. if (tender) {
  173. const parentFolder = this._.find(noSpFolderList, { folder_id: tender.folder_id });
  174. if (parentFolder) {
  175. const spParentFolder = this._.find(folderList, { folder_id: tender.folder_id });
  176. if (!spParentFolder) allNotExistFolderIds.push(tender.folder_id);
  177. const parentPathArray = parentFolder.parent_path ? this._.map(parentFolder.parent_path.split('-'), this._.toInteger) : [];
  178. if (parentPathArray.length > 0) {
  179. for (const id of parentPathArray) {
  180. const spFolder = this._.find(folderList, { folder_id: id });
  181. if (!spFolder && !this._.includes(allNotExistFolderIds, id)) {
  182. allNotExistFolderIds.push(id);
  183. }
  184. }
  185. }
  186. }
  187. }
  188. }
  189. const newFolderList = [];
  190. if (allNotExistFolderIds.length > 0) {
  191. const allNotExistFolderList = this._.orderBy(this._.filter(noSpFolderList, item => this._.includes(allNotExistFolderIds, item.folder_id)), ['in_time'], ['asc']);
  192. for (const f of allNotExistFolderList) {
  193. newFolderList.push({
  194. id: this.uuid.v4(),
  195. pid: this.ctx.session.sessionProject.id,
  196. spid: this.ctx.subProject.id,
  197. uid: f.uid,
  198. name: f.name,
  199. folder_id: f.folder_id,
  200. parent_id: f.parent_id,
  201. parent_path: f.parent_path,
  202. level: f.level,
  203. order: f.order,
  204. is_leaf: f.is_leaf,
  205. had_tender: f.had_tender,
  206. in_time: f.in_time,
  207. });
  208. }
  209. }
  210. await transaction.update(this.tableName, { spid: this.ctx.subProject.id }, { where: { id: filterTids } });
  211. if (newFolderList.length > 0) await transaction.insert(this.ctx.service.paymentFolder.tableName, newFolderList);
  212. }
  213. }
  214. // 权限也要迁移至本子项目
  215. const ppAudits = await this.ctx.service.paymentPermissionAudit.getAllDataByCondition({ where: { pid: this.ctx.session.sessionProject.id } });
  216. for (const audit of ppAudits) {
  217. if (audit.uid) {
  218. const spAudit = await this.ctx.service.subProjPermission.getDataByCondition({ spid: this.ctx.subProject.id, uid: audit.uid });
  219. const payment_permission = [1];
  220. const one_pp = audit.permission_json ? JSON.parse(audit.permission_json) : null;
  221. if (one_pp) {
  222. if (one_pp.admin) payment_permission.push(2);
  223. if (one_pp.view_all) payment_permission.push(3);
  224. }
  225. const new_payment_permission = payment_permission.join(',');
  226. console.log(spAudit, new_payment_permission);
  227. if (spAudit && spAudit.payment_permission !== new_payment_permission) {
  228. await transaction.update(this.ctx.service.subProjPermission.tableName, { id: spAudit.id, payment_permission: new_payment_permission });
  229. } else if (!spAudit) {
  230. const a = await this.ctx.service.projectAccount.getDataById(audit.uid);
  231. if (a) {
  232. const sp_permission = { id: this.uuid.v4(), spid: this.ctx.subProject.id, pid: this.ctx.session.sessionProject.id, uid: audit.uid, self_category_level: a.self_category_level, payment_permission: new_payment_permission };
  233. await transaction.insert(this.ctx.service.subProjPermission.tableName, sp_permission);
  234. }
  235. }
  236. }
  237. }
  238. await transaction.commit();
  239. } catch (err) {
  240. await transaction.rollback();
  241. throw err;
  242. }
  243. return true;
  244. }
  245. }
  246. return paymentTender;
  247. };