payment_tender.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  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. updateData.push({
  79. id: parseInt(pf),
  80. had_tender: 1,
  81. });
  82. }
  83. }
  84. await transaction.updateRows(this.ctx.service.paymentFolder.tableName, updateData);
  85. // 同时生成固定的报表表单
  86. await this.ctx.service.paymentTenderRpt.setConstRpt(transaction, result.insertId, uid);
  87. await transaction.commit();
  88. } catch (err) {
  89. await transaction.rollback();
  90. throw err;
  91. }
  92. }
  93. async deleteTender(id) {
  94. const transaction = await this.db.beginTransaction();
  95. try {
  96. const tenderInfo = await this.getDataById(id);
  97. if (!tenderInfo) {
  98. throw '标段不存在';
  99. }
  100. if (tenderInfo.uid !== this.ctx.session.sessionUser.accountId && !this.ctx.session.sessionUser.is_admin) {
  101. throw '您没有权限删除此标段';
  102. }
  103. const had_detail = await this.ctx.service.paymentDetail.haveDetail2Tender(id);
  104. if (had_detail) {
  105. throw '请先删除所有报表表单详情';
  106. }
  107. const folderInfo = await this.ctx.service.paymentFolder.getDataById(tenderInfo.folder_id);
  108. if (!folderInfo) {
  109. throw '文件夹不存在';
  110. }
  111. // 判断folderInfo下是否还存在tender,不存在则把had_tender为0,并判断父节点是否需要也为0
  112. const leafTenderCount = await transaction.count(this.tableName, { folder_id: folderInfo.id });
  113. if (leafTenderCount === 1) {
  114. const updateDatas = [{
  115. id: folderInfo.id,
  116. had_tender: 0,
  117. }];
  118. if (folderInfo.parent_path) {
  119. const parentFolderIds = folderInfo.parent_path.split('-').reverse();
  120. for (const pfid of parentFolderIds) {
  121. const parentFolderId = parseInt(pfid);
  122. const leafFolderCount = await transaction.count(this.ctx.service.paymentFolder.tableName, { parent_id: parentFolderId, had_tender: 1 });
  123. if (leafFolderCount === 1) {
  124. updateDatas.push({
  125. id: parentFolderId,
  126. had_tender: 0,
  127. });
  128. } else {
  129. break;
  130. }
  131. }
  132. }
  133. await transaction.updateRows(this.ctx.service.paymentFolder.tableName, updateDatas);
  134. }
  135. await transaction.delete(this.ctx.service.paymentTenderRpt.tableName, { tender_id: id });
  136. await transaction.delete(this.ctx.service.paymentShenpiAudit.tableName, { tid: id });
  137. await transaction.delete(this.tableName, { id });
  138. await transaction.commit();
  139. } catch (err) {
  140. await transaction.rollback();
  141. throw err;
  142. }
  143. }
  144. // async getChildrenByParentId(parentId, transaction = null) {
  145. // const list = await this.getAllDataByCondition({ where: { parent_id: parentId } });
  146. // }
  147. async doCheckTender(id) {
  148. return await this.service.paymentTender.getDataById(id);
  149. }
  150. async bindSp(tids) {
  151. const noSpTenderList = await this.getNoSpList(this.ctx.session.sessionProject.id);
  152. const noSpFolderList = await this.ctx.service.paymentFolder.getNoSpList(this.ctx.session.sessionProject.id);
  153. const transaction = await this.db.beginTransaction();
  154. try {
  155. const hadSpTenderList = await this.getNoSpList(this.ctx.session.sessionProject.id, false);
  156. if (tids.length === noSpTenderList.length && hadSpTenderList.length === 0) {
  157. // 一次性迁移所有可以不用复制folder数据,也不用调整tender数据,直接更新spid
  158. await transaction.update(this.tableName, { spid: this.ctx.subProject.id }, { where: { pid: this.ctx.session.sessionProject.id } });
  159. await transaction.update(this.ctx.service.paymentFolder.tableName, { spid: this.ctx.subProject.id }, { where: { pid: this.ctx.session.sessionProject.id } });
  160. } else {
  161. const hadSpTenderIds = hadSpTenderList.map(item => item.id);
  162. // tids里过滤掉hadSpTenderIds存在的值
  163. const filterTids = tids.filter(item => !hadSpTenderIds.includes(item));
  164. if (filterTids.length > 0) {
  165. const folderList = await this.ctx.service.paymentFolder.getAllDataByCondition({ where: { spid: this.ctx.subProject.id } });
  166. // 需要复制一份folder数据,且比对folderList,如果存在则不复制,且可能需要调整id,parent_id,parent_path, order值
  167. const allNotExistFolderIds = [];
  168. for (const tid of filterTids) {
  169. const tender = this._.find(noSpTenderList, { id: tid });
  170. if (tender) {
  171. const parentFolder = this._.find(noSpFolderList, { folder_id: tender.folder_id });
  172. if (parentFolder) {
  173. const spParentFolder = this._.find(folderList, { folder_id: tender.folder_id });
  174. if (!spParentFolder) allNotExistFolderIds.push(tender.folder_id);
  175. const parentPathArray = parentFolder.parent_path ? this._.map(parentFolder.parent_path.split('-'), this._.toInteger) : [];
  176. if (parentPathArray.length > 0) {
  177. for (const id of parentPathArray) {
  178. const spFolder = this._.find(folderList, { folder_id: id });
  179. if (!spFolder && !this._.includes(allNotExistFolderIds, id)) {
  180. allNotExistFolderIds.push(id);
  181. }
  182. }
  183. }
  184. }
  185. }
  186. }
  187. const newFolderList = [];
  188. if (allNotExistFolderIds.length > 0) {
  189. const allNotExistFolderList = this._.orderBy(this._.filter(noSpFolderList, item => this._.includes(allNotExistFolderIds, item.folder_id)), ['in_time'], ['asc']);
  190. for (const f of allNotExistFolderList) {
  191. newFolderList.push({
  192. id: this.uuid.v4(),
  193. pid: this.ctx.session.sessionProject.id,
  194. spid: this.ctx.subProject.id,
  195. uid: f.uid,
  196. name: f.name,
  197. folder_id: f.folder_id,
  198. parent_id: f.parent_id,
  199. parent_path: f.parent_path,
  200. level: f.level,
  201. order: f.order,
  202. is_leaf: f.is_leaf,
  203. had_tender: f.had_tender,
  204. in_time: f.in_time,
  205. });
  206. }
  207. }
  208. await transaction.update(this.tableName, { spid: this.ctx.subProject.id }, { where: { id: filterTids } });
  209. if (newFolderList.length > 0) await transaction.insert(this.ctx.service.paymentFolder.tableName, newFolderList);
  210. }
  211. }
  212. // 权限也要迁移至本子项目
  213. const ppAudits = await this.ctx.service.paymentPermissionAudit.getAllDataByCondition({ where: { pid: this.ctx.session.sessionProject.id } });
  214. for (const audit of ppAudits) {
  215. if (audit.uid) {
  216. const spAudit = await this.ctx.service.subProjPermission.getDataByCondition({ spid: this.ctx.subProject.id, uid: audit.uid });
  217. const payment_permission = [1];
  218. const one_pp = audit.permission_json ? JSON.parse(audit.permission_json) : null;
  219. if (one_pp) {
  220. if (one_pp.admin) payment_permission.push(2);
  221. if (one_pp.view_all) payment_permission.push(3);
  222. }
  223. const new_payment_permission = payment_permission.join(',');
  224. console.log(spAudit, new_payment_permission);
  225. if (spAudit && spAudit.payment_permission !== new_payment_permission) {
  226. await transaction.update(this.ctx.service.subProjPermission.tableName, { id: spAudit.id, payment_permission: new_payment_permission });
  227. } else if (!spAudit) {
  228. const a = await this.ctx.service.projectAccount.getDataById(audit.uid);
  229. if (a) {
  230. 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 };
  231. await transaction.insert(this.ctx.service.subProjPermission.tableName, sp_permission);
  232. }
  233. }
  234. }
  235. }
  236. await transaction.commit();
  237. } catch (err) {
  238. await transaction.rollback();
  239. throw err;
  240. }
  241. return true;
  242. }
  243. }
  244. return paymentTender;
  245. };