Browse Source

Merge branch 'dev' of http://192.168.1.41:3000/maixinrong/Calculation into dev

Tony Kang 3 months ago
parent
commit
00b53d4094
100 changed files with 2172 additions and 1102 deletions
  1. 1 0
      app/base/base_bills_service.js
  2. 6 7
      app/base/base_controller.js
  3. 104 0
      app/const/sp_page_show.js
  4. 6 4
      app/const/spread.js
  5. 5 7
      app/controller/budget_controller.js
  6. 2 5
      app/controller/change_controller.js
  7. 5 5
      app/controller/construction_controller.js
  8. 7 7
      app/controller/contract_controller.js
  9. 7 7
      app/controller/dashboard_controller.js
  10. 1 1
      app/controller/datacollect_controller.js
  11. 1 1
      app/controller/file_controller.js
  12. 107 107
      app/controller/financial_controller.js
  13. 7 7
      app/controller/material_controller.js
  14. 1 1
      app/controller/measure_controller.js
  15. 2 1
      app/controller/pay_controller.js
  16. 44 56
      app/controller/payment_controller.js
  17. 6 6
      app/controller/report_controller.js
  18. 30 4
      app/controller/sub_proj_controller.js
  19. 31 20
      app/controller/sub_proj_setting_controller.js
  20. 6 1
      app/controller/tender_controller.js
  21. 76 9
      app/controller/wap_controller.js
  22. 42 0
      app/lib/rm/change.js
  23. 29 0
      app/lib/rm/material.js
  24. 36 0
      app/lib/rpt_data_analysis.js
  25. 3 9
      app/middleware/budget_check.js
  26. 1 1
      app/middleware/construction_check.js
  27. 10 2
      app/middleware/contract_check.js
  28. 3 2
      app/middleware/financial_check.js
  29. 2 2
      app/middleware/financial_pay_check.js
  30. 1 1
      app/middleware/material_check.js
  31. 1 1
      app/middleware/payment_detail_check.js
  32. 8 8
      app/middleware/payment_tender_check.js
  33. 0 56
      app/middleware/session_auth.js
  34. 63 6
      app/middleware/sub_project_check.js
  35. 3 2
      app/middleware/tender_check.js
  36. 459 460
      app/public/js/change_revise.js
  37. 5 4
      app/public/js/contract_detail.js
  38. 1 1
      app/public/js/contract_index.js
  39. 1 1
      app/public/js/contract_tender.js
  40. 17 1
      app/public/js/filing_manage.js
  41. 6 5
      app/public/js/ledger.js
  42. 5 5
      app/public/js/payment_detail.js
  43. 3 3
      app/public/js/payment_detail_audit.js
  44. 10 10
      app/public/js/payment_index.js
  45. 7 7
      app/public/js/payment_list.js
  46. 9 9
      app/public/js/payment_process.js
  47. 1 1
      app/public/js/payment_setting.js
  48. 94 23
      app/public/js/setting_manage.js
  49. 4 1
      app/public/js/shares/export_excel.js
  50. 1 1
      app/public/js/shenpi.js
  51. 5 1
      app/public/js/sp_data.js
  52. 3 2
      app/public/js/sp_progress.js
  53. 2 1
      app/public/js/sp_push.js
  54. 29 1
      app/public/js/sp_setting_permission.js
  55. 15 0
      app/public/js/spreadjs_rela/spreadjs_zh.js
  56. 54 5
      app/public/js/stage.js
  57. 1 1
      app/public/js/stage_gather.js
  58. 19 5
      app/public/js/sub_project.js
  59. 48 49
      app/router.js
  60. 4 2
      app/service/budget.js
  61. 1 1
      app/service/change_apply_audit.js
  62. 1 0
      app/service/change_ledger.js
  63. 1 1
      app/service/change_plan_audit.js
  64. 1 1
      app/service/change_project_audit.js
  65. 1 1
      app/service/contract.js
  66. 1 1
      app/service/contract_att.js
  67. 49 20
      app/service/contract_audit.js
  68. 1 1
      app/service/contract_pay_att.js
  69. 3 3
      app/service/filing.js
  70. 1 1
      app/service/financial_pay.js
  71. 54 9
      app/service/financial_pay_tender_audit.js
  72. 1 1
      app/service/payment_detail.js
  73. 1 1
      app/service/payment_detail_att.js
  74. 2 6
      app/service/payment_detail_audit.js
  75. 47 11
      app/service/payment_folder.js
  76. 1 1
      app/service/payment_permission_audit.js
  77. 107 6
      app/service/payment_tender.js
  78. 1 1
      app/service/payment_tender_rpt.js
  79. 5 5
      app/service/project_account.js
  80. 48 0
      app/service/report.js
  81. 85 0
      app/service/report_memory.js
  82. 1 1
      app/service/stage_audit.js
  83. 232 9
      app/service/sub_proj_permission.js
  84. 14 14
      app/service/sub_project.js
  85. 11 2
      app/service/tender.js
  86. 0 2
      app/view/change/addlist.ejs
  87. 4 8
      app/view/change/information_modal.ejs
  88. 0 11
      app/view/change/revise.ejs
  89. 0 2
      app/view/change/revise_modal.ejs
  90. 1 1
      app/view/contract/detail.ejs
  91. 16 18
      app/view/contract/modal.ejs
  92. 10 10
      app/view/dashboard/index.ejs
  93. 1 0
      app/view/file/file.ejs
  94. 2 0
      app/view/file/manage.ejs
  95. 1 1
      app/view/financial/transfer_tender_modal.ejs
  96. 1 1
      app/view/ledger/explode.ejs
  97. 1 1
      app/view/ledger/explode_modal.ejs
  98. 3 3
      app/view/measure/stage.ejs
  99. 2 2
      app/view/payment/detail.ejs
  100. 0 0
      app/view/payment/index.ejs

+ 1 - 0
app/base/base_bills_service.js

@@ -673,6 +673,7 @@ class BaseBillsSerivce extends TreeService {
                     check_calc: 1,
                     dgn_qty1: d.dgn_qty1,
                     dgn_qty2: d.dgn_qty2,
+                    features: d.features || '',
                 };
                 for (const c of d.children) {
                     c.ledger_pid = newBills.ledger_id;

+ 6 - 7
app/base/base_controller.js

@@ -33,12 +33,12 @@ class BaseController extends Controller {
                     ctx.menu = menuList.budget;
                 }
             }
-            menuList.datacollect.display = ctx.session && ctx.session.sessionProject ? ctx.session.sessionProject.showDataCollect : false;
-            menuList.file.display = ctx.session && ctx.session.sessionProject ? ctx.session.sessionProject.page_show.openFile : false;
-            // menuList.construction.display = ctx.session && ctx.session.sessionProject ? ctx.session.sessionProject.page_show.openConstruction : false;
-            menuList.contract.display = ctx.session && ctx.session.sessionProject ? ctx.session.sessionProject.page_show.openContract : false;
-            menuList.financial.display = ctx.session && ctx.session.sessionProject ? ctx.session.sessionProject.page_show.openFinancial : false;
-            menuList.budget.display = ctx.session && ctx.session.sessionProject ? ctx.session.sessionProject.showBudget : false;
+            menuList.datacollect.display = ctx.subProject.showDataCollect || false;
+            menuList.file.display = ctx.subProject.page_show.openFile || false;
+            menuList.contract.display = ctx.subProject.page_show.openContract || false;
+            menuList.financial.display = ctx.subProject.page_show.openFinancial || false;
+            menuList.budget.display = ctx.subProject.page_show.openBudget || false;
+            menuList.payment.display = ctx.subProject.page_show.openPayment || false;
             for (const index in menuList) {
                 const im = menuList[index];
                 if (!im.url) {
@@ -54,7 +54,6 @@ class BaseController extends Controller {
                 }
             }
         } else {
-            menuList.payment.display = ctx.session && ctx.session.sessionProject ? ctx.session.sessionProject.showPayment : false;
             menuList.management.display = ctx.session && ctx.session.sessionProject ? ctx.session.sessionProject.page_show.openManagement : false;
         }
         ctx.menuList = menuList;

+ 104 - 0
app/const/sp_page_show.js

@@ -0,0 +1,104 @@
+'use strict';
+
+/**
+ * 前台页面展示相关
+ *
+ * @author Ellisran
+ * @date
+ * @version
+ */
+
+//  { title: '打开项目管理系统', name: 'openManagement', value: pageStatus.show, type: 'checkbox' },
+const pageStatus = {
+    show: 1,
+    hide: 0,
+};
+// 模块管理开关
+const managerPageControl = [
+    { title: '决策大屏', name: 'openDataCollect', value: pageStatus.show, type: 'checkbox', tip: '开启后,前台配置用户权限后方可显示' },
+    { title: '合同管理', name: 'openContract', value: pageStatus.show, type: 'checkbox' },
+    { title: '资料归集', name: 'openFile', value: pageStatus.show, type: 'checkbox' },
+    { title: '动态投资', name: 'openBudget', value: pageStatus.show, type: 'checkbox', tip: '开启后,前台配置用户权限后方可显示' },
+    { title: '支付审批', name: 'openPayment', value: pageStatus.show, type: 'checkbox', tip: '开启后,前台配置用户权限后方可显示' },
+    { title: '资金监管', name: 'openFinancial', value: pageStatus.show, type: 'checkbox' },
+];
+// 标段功能开关
+const tenderPageControl = [
+    { title: '部位台帐', name: 'bwtz', value: pageStatus.show, type: 'checkbox', tip: '「部位台帐」显示在「0号台帐」以及「各期计量」侧栏菜单中', tipClass: '' },
+    { title: '其他台账', name: 'stageExtra', value: pageStatus.show, type: 'checkbox' },
+    { title: '合同支付独立审批', name: 'phasePay', value: pageStatus.show, type: 'checkbox' },
+    { title: '投资进度', name: 'xxjd', value: pageStatus.show, type: 'checkbox' },
+    { title: '材料调差', name: 'openMaterial', value: pageStatus.show, type: 'checkbox' },
+    { title: '过程结算', name: 'openSettle', value: pageStatus.show, type: 'checkbox' },
+    { title: '施工日志', name: 'openTenderContract', value: pageStatus.show, type: 'checkbox' },
+    { title: '合同管理', name: 'openTenderContract', value: pageStatus.show, type: 'checkbox' },
+];
+// 报表相关开关
+const reportPageControl = [
+    { title: '关闭报表「导出PDF」', name: 'closeExportPdf', value: pageStatus.show, type: 'checkbox' },
+    { title: '关闭报表「导出Excel」', name: 'closeExportExcel', value: pageStatus.show, type: 'checkbox' },
+    { title: '关闭报表「水印」', name: 'closeWatermark', value: pageStatus.show, type: 'checkbox', tip: '审批未通过的计量期,报表将显示水印「审批未通过」', tipClass: '' },
+    { title: '关闭「定制报表」默认加载报表功能', name: 'closeShowAllCustomized', value: pageStatus.show, type: 'checkbox', tip: '关闭后,定制报表将默认不显示(用户定制选择除外)', tipClass: '' },
+    { title: '开启报表「跨标段批量签名」', name: 'openSign', value: pageStatus.show, type: 'checkbox' },
+    { title: '开启个人「签字」功能', name: 'individualSign', value: pageStatus.show, type: 'checkbox', tip: '签字仅可选择当前人账号,管理员账号可选择所有人', tipClass: '' },
+    { title: '开启签名「网证通电子签名」', name: 'openNetCaSign', value: pageStatus.show, type: 'checkbox' },
+    { title: '开启文本「签字」', name: 'isTextSignature', value: pageStatus.show, type: 'checkbox', tip: '开启后,所有签名将以文字代替图片', tipClass: '' },
+    { title: '开启「报表数据预设」', name: 'isPreset', value: pageStatus.show, type: 'checkbox', tip: '', tipClass: '' },
+    { title: '开启「审批完成过滤」', name: 'isOnlyChecked', value: pageStatus.show, type: 'checkbox', tip: '关闭后,「工程变更」将包含未上报、审批中等全部状态的数据,影响 开启「报表数据预设」', tipClass: '' },
+    { title: '开启「归档时不生成签字和签章」', name: 'closeArchiveSignature', value: pageStatus.show, type: 'checkbox', tip: '开启后,归档时所有报表的签名(名、章、文本等)都不显示', tipClass: '' },
+];
+// 功能设置页name名列表,功能设置需要设置的name必须添加到这个列表中,否则有可能清空数据
+const settingNameArray = (function(controlArr){
+    const result = [];
+    controlArr.forEach(control => {
+        const key = control.map(x => { return x.name; });
+        result.push(...key);
+    });
+})([managerPageControl, tenderPageControl]);
+
+
+// 设置默认值,同步前台的const/page_show.js文件
+const defaultSetting = {
+    bwtz: 0,
+    xxjd: 0,
+    openMaterial: 1,
+    stageExtra: 1,
+    phasePay: 0,
+    closeExportPdf: 0,
+    closeExportExcel: 0,
+    closeWatermark: 0,
+    closeShowAllCustomized: 0,
+    openSign: 0,
+    individualSign: 0,
+    openNetCaSign: 0,
+    isTextSignature: 0,
+    openChangeRevise: 1,
+    openMaterialTax: 0,
+    addDataCollect: 1,
+    closeWapYfSf: 0,
+    close1stStageCheckDealParam: 0,
+    openManagement: 0,
+    isPreset: 0,
+    isOnlyChecked: 1,
+    closeArchiveSignature: 0,
+    openSettle: 0,
+    openContractExpr: 0,
+    openMultiStageCalc: 0,
+    maxMultiStageCount: 5,
+    openDataCollect: 1,
+    openFile: 1,
+    openBudget: 1,
+    openPayment: 1,
+    openConstruction: 1,
+    openMaterialStageRepeat: 0,
+    openContract: 1,
+    openFinancial: 1,
+};
+
+module.exports = {
+    pageStatus,
+    managerPageControl,
+    tenderPageControl,
+    defaultSetting,
+    settingNameArray,
+};

+ 6 - 4
app/const/spread.js

@@ -540,7 +540,7 @@ const BaseSpreadColSetting = {
             position: [{title: '位置', colSpan: '1', rowSpan: '2', field: 'position', hAlign: 0, width: 60, formatter: '@'}],
             tz_calc: [
                 {title: '台账数量|设计量', colSpan: '5|1', rowSpan: '1|1', field: 'sgfh_qty', hAlign: 2, width: 100, type: 'Number'},
-                {title: '|设计量公式', colSpan: '|1', rowSpan: '|1', field: 'sgfh_expr', hAlign: 2, width: 100},
+                {title: '|设计量公式', colSpan: '|1', rowSpan: '|1', field: 'sgfh_expr', hAlign: 0, width: 100},
                 {title: '|设计错漏增减', colSpan: '|1', rowSpan: '|1', field: 'sjcl_qty', hAlign: 2, width: 100, type: 'Number'},
                 {title: '|其他错漏增减', colSpan: '|1', rowSpan: '|1', field: 'qtcl_qty', hAlign: 2, width: 100, type: 'Number'},
                 {title: '|小计', colSpan: '|1', rowSpan: '|1', field: 'quantity', hAlign: 2, width: 60, type: 'Number', readOnly: true},
@@ -616,7 +616,8 @@ const BaseSpreadColSetting = {
             real_qty: [{title: '现场实际数量', colSpan: '1', rowSpan: '2', field: 'real_qty', hAlign: 2, width: 60, type: 'Number'}],
             estimate_qty: [{title: '预计变更数量', colSpan: '1', rowSpan: '2', field: 'estimate_qty', hAlign: 2, width: 60, type: 'Number', readOnly: true}],
             cur_calc: [
-                {title: '本期计量|合同', colSpan: '4|1', rowSpan: '1|1', field: 'contract_qty', hAlign: 2, width: 60, type: 'Number'},
+                {title: '本期计量|合同', colSpan: '5|1', rowSpan: '1|1', field: 'contract_qty', hAlign: 2, width: 60, type: 'Number'},
+                {title: '|合同公式', colSpan: '|1', rowSpan: '|1', field: 'contract_expr', hAlign: 0, width: 100},
                 {title: '|数量变更', colSpan: '|1', rowSpan: '|1', field: 'qc_qty', hAlign: 2, width: 80, type: 'Number'},
                 {title: '|不计价', colSpan: '|1', rowSpan: '|1', field: 'qc_minus_qty', hAlign: 2, width: 60, type: 'Number'},
                 {title: '|完成', colSpan: '|1', rowSpan: '|1', field: 'gather_qty', hAlign: 2, width: 60, type: 'Number', readOnly: true},
@@ -677,7 +678,7 @@ const BaseSpreadColSetting = {
             position: [{title: '位置', colSpan: '1', rowSpan: '2', field: 'position', hAlign: 0, width: 60, formatter: '@'}],
             tz_calc: [
                 {title: '台账数量|设计量', colSpan: '5|1', rowSpan: '1|1', field: 'sgfh_qty', hAlign: 2, width: 100, type: 'Number'},
-                {title: '|设计量公式', colSpan: '|1', rowSpan: '|1', field: 'sgfh_expr', hAlign: 2, width: 100},
+                {title: '|设计量公式', colSpan: '|1', rowSpan: '|1', field: 'sgfh_expr', hAlign: 0, width: 100},
                 {title: '|设计错漏增减', colSpan: '|1', rowSpan: '|1', field: 'sjcl_qty', hAlign: 2, width: 100, type: 'Number'},
                 {title: '|其他错漏增减', colSpan: '|1', rowSpan: '|1', field: 'qtcl_qty', hAlign: 2, width: 100, type: 'Number'},
                 {title: '|小计', colSpan: '|1', rowSpan: '|1', field: 'quantity', hAlign: 2, width: 60, type: 'Number', readOnly: true},
@@ -753,7 +754,8 @@ const BaseSpreadColSetting = {
             estimate_qty: [{title: '预计变更数量', colSpan: '1', rowSpan: '2', field: 'estimate_qty', hAlign: 2, width: 60, type: 'Number', readOnly: true}],
             tz_calc: [{title: '台账数量', colSpan: '1', rowSpan: '2', field: 'sgfh_qty', hAlign: 2, width: 60, type: 'Number', aliasFormat: '{%s}数量'}],
             cur_calc: [
-                {title: '本期计量|合同', colSpan: '4|1', rowSpan: '1|1', field: 'contract_qty', hAlign: 2, width: 60, type: 'Number'},
+                {title: '本期计量|合同', colSpan: '5|1', rowSpan: '1|1', field: 'contract_qty', hAlign: 2, width: 60, type: 'Number'},
+                {title: '|合同公式', colSpan: '|1', rowSpan: '|1', field: 'contract_expr', hAlign: 0, width: 100},
                 {title: '|数量变更', colSpan: '|1', rowSpan: '|1', field: 'qc_qty', hAlign: 2, width: 80, type: 'Number'},
                 {title: '|不计价', colSpan: '|1', rowSpan: '|1', field: 'qc_minus_qty', hAlign: 2, width: 60, type: 'Number'},
                 {title: '|完成', colSpan: '|1', rowSpan: '|1', field: 'gather_qty', hAlign: 2, width: 60, type: 'Number', readOnly: true},

+ 5 - 7
app/controller/budget_controller.js

@@ -27,9 +27,7 @@ module.exports = app => {
          */
         async list(ctx) {
             try {
-                if (!ctx.session.sessionProject.showBudget) {
-                    throw '该功能已关闭或无法查看';
-                }
+                if (!ctx.subProject.page_show.openBudget) throw '该功能已关闭或无法查看';
                 const renderData = {
                     jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.budget.list),
                     auditConst,
@@ -47,6 +45,7 @@ module.exports = app => {
                 renderData.categoryData = await this.ctx.service.category.getAllCategory(ctx.subProject);
                 await this.layout('budget/list.ejs', renderData, 'budget/list_modal.ejs');
             } catch (err) {
+                console.log(err);
                 ctx.log(err);
                 ctx.session.postError = err.toString();
                 ctx.redirect(this.menu.menu.dashboard.url);
@@ -87,11 +86,10 @@ module.exports = app => {
                     jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.budget.compare),
                     auditConst,
                 };
-                const relaTenderId = ctx.helper._.map(ctx.budget.rela_tender.split(','), ctx.helper._.toInteger);
                 const tenderList = await ctx.service.tender.getList4Select('stage');
-                renderData.tenderList = relaTenderId.length > 0 ? tenderList.filter(x => {
-                    return relaTenderId.indexOf(x.id) >= 0;
-                }) : tenderList;
+                renderData.tenderList = tenderList.filter(x => {
+                    return !x.filter_budger;
+                });
                 renderData.tenderList = renderData.tenderList.map(y => {
                     return { id: y.id, name: y.name, lastStageOrder: y.lastStage.order, lastStageStatus: auditConst.stage.statusString[y.lastStage.status], category: y.category };
                 });

+ 2 - 5
app/controller/change_controller.js

@@ -927,9 +927,9 @@ module.exports = app => {
                 const readySettle = await ctx.service.settle.getReadySettle(ctx.tender.id);
                 if (data.from === 'revise') await ctx.service.change.checkSettleUpdate(ctx.tender.id, readySettle);
                 const ledgerData = await ctx.service.ledger.getData(ctx.tender.id);
-                const changeLedgerData = !ctx.session.sessionProject.page_show.openChangeRevise ? [] : (lastRevise && lastRevise.status !== audit.revise.status.checked && data.from !== 'revise' ? [] : await ctx.service.changeLedger.getData(ctx.tender.id));
+                const changeLedgerData = lastRevise && lastRevise.status !== audit.revise.status.checked && data.from !== 'revise' ? [] : await ctx.service.changeLedger.getData(ctx.tender.id);
                 const posData = await ctx.service.pos.getPosData({ tid: ctx.tender.id });
-                const changePosData = !ctx.session.sessionProject.page_show.openChangeRevise ? [] : (lastRevise && lastRevise.status !== audit.revise.status.checked && data.from !== 'revise' ? [] : await ctx.service.changePos.getPosData({ tid: ctx.tender.id }));
+                const changePosData = lastRevise && lastRevise.status !== audit.revise.status.checked && data.from !== 'revise' ? [] : await ctx.service.changePos.getPosData({ tid: ctx.tender.id });
                 const dealBills = await ctx.service.dealBills.getAllDataByCondition({ where: { tender_id: ctx.tender.id } });
                 // const settleStatus = ctx.service.settle.settleStatus;
                 const settleBills = readySettle ? await this.ctx.service.settleBills.getAllDataByCondition({ where: { settle_id: readySettle.id } }) : [];
@@ -1794,9 +1794,6 @@ module.exports = app => {
         async updateRevise(ctx) {
             try {
                 if (!ctx.tender.data) throw '标段数据错误';
-                if (!ctx.session.sessionProject.page_show.openChangeRevise) {
-                    throw '该功能已关闭';
-                }
                 const data = JSON.parse(ctx.request.body.data);
                 if (!data.postType || !data.postData) throw '数据错误';
                 const responseData = { err: 0, msg: '', data: {} };

+ 5 - 5
app/controller/construction_controller.js

@@ -234,7 +234,7 @@ module.exports = app => {
                 const responseData = {
                     err: 0, msg: '', data: null,
                 };
-                const id = parseInt(ctx.params.id);
+                const id = parseInt(ctx.params.lid);
                 if (!id) throw '参数有误';
                 const logInfo = await ctx.service.constructionLog.getDataById(id);
                 if (!logInfo) throw '该日志不存在';
@@ -251,7 +251,7 @@ module.exports = app => {
 
         async logInfo(ctx) {
             try {
-                const id = parseInt(ctx.params.id);
+                const id = parseInt(ctx.params.lid);
                 if (!id) throw '参数有误';
                 const logInfo = await ctx.service.constructionLog.getDataById(id);
                 if (!logInfo) throw '该日志不存在';
@@ -298,7 +298,7 @@ module.exports = app => {
 
         async logSave(ctx) {
             try {
-                const id = parseInt(ctx.params.id);
+                const id = parseInt(ctx.params.lid);
                 if (!id) throw '参数有误';
                 const logInfo = await ctx.service.constructionLog.getDataById(id);
                 if (!logInfo) throw '该日志不存在';
@@ -370,7 +370,7 @@ module.exports = app => {
             };
             let stream;
             try {
-                const id = parseInt(ctx.params.id);
+                const id = parseInt(ctx.params.lid);
                 if (!id) throw '参数有误';
                 const logInfo = await ctx.service.constructionLog.getDataById(id);
                 if (!logInfo) throw '该日志不存在';
@@ -482,7 +482,7 @@ module.exports = app => {
                 data: '',
             };
             try {
-                const id = parseInt(ctx.params.id);
+                const id = parseInt(ctx.params.lid);
                 if (!id) throw '参数有误';
                 const logInfo = await ctx.service.constructionLog.getDataById(id);
                 if (!logInfo) throw '该日志不存在';

+ 7 - 7
app/controller/contract_controller.js

@@ -27,7 +27,7 @@ module.exports = app => {
          */
         async index(ctx) {
             try {
-                if (!ctx.session.sessionProject.page_show.openContract) {
+                if (!ctx.subProject.page_show.openContract) {
                     throw '该功能已关闭或无法查看';
                 }
                 const renderData = {
@@ -76,7 +76,7 @@ module.exports = app => {
          */
         async tender(ctx) {
             try {
-                if (!ctx.session.sessionProject.page_show.openContract) {
+                if (!ctx.subProject.page_show.openContract) {
                     throw '该功能已关闭或无法查看';
                 }
                 // 获取用户新建标段权利
@@ -169,7 +169,7 @@ module.exports = app => {
                         // 判断用户是单个还是数组
                         uids = data.id instanceof Array ? data.id : [data.id];
                         // 判断该用户的组是否已加入到表中,已加入则提示无需添加
-                        auditList = await ctx.service.contractAudit.getAllDataByCondition({ where: options });
+                        auditList = await ctx.service.contractAudit.getList(options);
                         const addAidList = ctx.helper._.difference(uids, ctx.helper._.map(auditList, 'uid'));
                         if (addAidList.length === 0) {
                             throw '用户已存在成员管理中,无需重复添加';
@@ -181,16 +181,16 @@ module.exports = app => {
                     case 'del-audit':
                         uids = data.id instanceof Array ? data.id : [data.id];
                         const cloneOptions = ctx.helper._.cloneDeep(options);
-                        cloneOptions.id = uids;
-                        auditList = await ctx.service.contractAudit.getAllDataByCondition({ where: cloneOptions });
+                        cloneOptions.uid = uids;
+                        auditList = options.spid ? await ctx.service.subProjPermission.getContractAuditList(options.spid, uids) : await ctx.service.contractAudit.getAllDataByCondition({ where: cloneOptions });
                         if (auditList.length !== uids.length) {
                             throw '该用户已不存在成员管理中,移除失败';
                         }
-                        await ctx.service.contractAudit.delAudit(uids);
+                        await ctx.service.contractAudit.delAudit(options, ctx.helper._.map(auditList, 'id'));
                         responseData.data = await ctx.service.contractAudit.getList(options);
                         break;
                     case 'save-permission':
-                        result = await ctx.service.contractAudit.updatePermission(data.updateData);
+                        result = await ctx.service.contractAudit.updatePermission(options, data.updateData);
                         if (!result) {
                             throw '修改权限失败';
                         }

+ 7 - 7
app/controller/dashboard_controller.js

@@ -32,14 +32,14 @@ module.exports = app => {
             const auditStages = await ctx.service.stageAudit.getAuditStage(ctx.session.sessionUser.accountId);
             const auditChanges = await ctx.service.changeAudit.getAuditChange(ctx.session.sessionUser.accountId);
             const auditRevise = await ctx.service.reviseAudit.getAuditRevise(ctx.session.sessionUser.accountId);
-            const auditMaterial = ctx.session.sessionProject.page_show.openMaterial ? await ctx.service.materialAudit.getAuditMaterial(ctx.session.sessionUser.accountId) : [];
+            const auditMaterial = ctx.subProject.page_show.openMaterial ? await ctx.service.materialAudit.getAuditMaterial(ctx.session.sessionUser.accountId) : [];
             const auditAdvance = await ctx.service.advanceAudit.getAuditAdvance(ctx.session.sessionUser.accountId);
             const auditChangeProject = ctx.subProject.page_show.openChangeProject ? await ctx.service.changeProjectAudit.getAuditChangeProject(ctx.session.sessionUser.accountId) : [];
             const auditChangeApply = ctx.subProject.page_show.openChangeApply ? await ctx.service.changeApplyAudit.getAuditChangeApply(ctx.session.sessionUser.accountId) : [];
             const auditChangePlan = ctx.subProject.page_show.openChangePlan ? await ctx.service.changePlanAudit.getAuditChangePlan(ctx.session.sessionUser.accountId) : [];
-            const auditPayments = ctx.session.sessionProject.page_show.openPayment ? await ctx.service.paymentDetailAudit.getAuditPayment(ctx.session.sessionUser.accountId) : [];
+            const auditPayments = ctx.subProject.page_show.openPayment ? await ctx.service.paymentDetailAudit.getAuditPayment(ctx.session.sessionUser.accountId) : [];
             const auditStageAss = await ctx.service.stageAuditAss.getAuditStageAss(ctx.session.sessionUser.accountId);
-            const auditFinancials = ctx.session.sessionProject.page_show.openFinancial ? await ctx.service.financialPayAudit.getAuditFinancial(ctx.session.sessionUser.accountId) : [];
+            const auditFinancials = ctx.subProject.page_show.openFinancial ? await ctx.service.financialPayAudit.getAuditFinancial(ctx.session.sessionUser.accountId) : [];
             const pa = await ctx.service.projectAccount.getDataById(ctx.session.sessionUser.accountId);
             const noticeList = await ctx.service.noticePush.getNotice(ctx.session.sessionProject.id, pa.id);
             const projectData = await ctx.service.project.getDataById(ctx.session.sessionProject.id);
@@ -67,8 +67,8 @@ module.exports = app => {
             if (ctx.subProject.page_show.openChangeProject) shenpi_count.push({ count: await ctx.service.changeProjectAudit.getCountByChecked(ctx.session.sessionUser.accountId), name: '变更立项' });
             if (ctx.subProject.page_show.openChangeApply) shenpi_count.push({ count: await ctx.service.changeApplyAudit.getCountByChecked(ctx.session.sessionUser.accountId), name: '变更申请' });
             if (ctx.subProject.page_show.openChangePlan) shenpi_count.push({ count: await ctx.service.changePlanAudit.getCountByChecked(ctx.session.sessionUser.accountId), name: '变更方案' });
-            if (ctx.session.sessionProject.page_show.openMaterial) shenpi_count.push({ count: await ctx.service.materialAudit.getCountByChecked(ctx.session.sessionUser.accountId), name: '材料调差' });
-            if (ctx.session.sessionProject.page_show.openFinancial) shenpi_count.push({ count: await ctx.service.financialPayAudit.getCountByChecked(ctx.session.sessionUser.accountId), name: '资金支付' });
+            if (ctx.subProject.page_show.openMaterial) shenpi_count.push({ count: await ctx.service.materialAudit.getCountByChecked(ctx.session.sessionUser.accountId), name: '材料调差' });
+            if (ctx.subProject.page_show.openFinancial) shenpi_count.push({ count: await ctx.service.financialPayAudit.getCountByChecked(ctx.session.sessionUser.accountId), name: '资金支付' });
             // shenpi_count.push({ count: await ctx.service.advanceAudit.getCountByChecked(ctx.session.sessionUser.accountId), name: '预付款' });
             const total_count = ctx.app._.sumBy(shenpi_count, 'count');
             const shenpi_lastime = [
@@ -80,8 +80,8 @@ module.exports = app => {
                 ctx.subProject.page_show.openChangeProject ? await ctx.service.changeProjectAudit.getLastEndTimeByChecked(ctx.session.sessionUser.accountId) : null,
                 ctx.subProject.page_show.openChangeApply ? await ctx.service.changeApplyAudit.getLastEndTimeByChecked(ctx.session.sessionUser.accountId) : null,
                 ctx.subProject.page_show.openChangePlan ? await ctx.service.changePlanAudit.getLastEndTimeByChecked(ctx.session.sessionUser.accountId) : null,
-                ctx.session.sessionProject.page_show.openMaterial ? await ctx.service.materialAudit.getLastEndTimeByChecked(ctx.session.sessionUser.accountId) : null,
-                ctx.session.sessionProject.page_show.openFinancial ? await ctx.service.financialPayAudit.getLastEndTimeByChecked(ctx.session.sessionUser.accountId) : null,
+                ctx.subProject.page_show.openMaterial ? await ctx.service.materialAudit.getLastEndTimeByChecked(ctx.session.sessionUser.accountId) : null,
+                ctx.subProject.page_show.openFinancial ? await ctx.service.financialPayAudit.getLastEndTimeByChecked(ctx.session.sessionUser.accountId) : null,
             ];
             const last_time = ctx.app._.max(shenpi_lastime);
             // console.log(ctx.app._.max(shenpi_lastime), ctx.helper.calcDayNum(last_time));

+ 1 - 1
app/controller/datacollect_controller.js

@@ -47,7 +47,7 @@ module.exports = app => {
          */
         async index(ctx) {
             try {
-                if (!ctx.session.sessionProject.showDataCollect) {
+                if (!ctx.subProject.showDataCollect) {
                     throw '该功能已关闭或无法查看';
                 }
                 // 获取标段审批信息

+ 1 - 1
app/controller/file_controller.js

@@ -31,7 +31,7 @@ module.exports = app => {
          */
         async index(ctx) {
             try {
-                if (!ctx.session.sessionProject.page_show.openFile) {
+                if (!ctx.subProject.page_show.openFile) {
                     throw '该功能已关闭或无法查看';
                 }
                 const renderData = {

+ 107 - 107
app/controller/financial_controller.js

@@ -26,102 +26,102 @@ module.exports = app => {
          * @param {Object} ctx - egg全局页面
          * @return {void}
          */
-        async index(ctx) {
-            try {
-                if (!ctx.subProject.page_show.openFinancial) {
-                    throw '该功能已关闭或无法查看';
-                }
-                const renderData = {
-                    jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.financial.index),
-                    auditConst,
-                };
-                renderData.projectList = await ctx.service.subProject.getSubProjectByFinancial(ctx.session.sessionProject.id, ctx.session.sessionUser.accountId, ctx.session.sessionUser.is_admin);
-                const accountList = await ctx.service.projectAccount.getAllSubProjectAccount(ctx.subProject);
-                for (const proj of renderData.projectList) {
-                    const financialPermission = await ctx.service.financialAudit.getPermission(proj.id, ctx.session.sessionUser.accountId);
-                    if (financialPermission.transfer_show) {
-                        proj.toUrl = 'transfer';
-                    } else if (financialPermission.pay_show) {
-                        proj.toUrl = 'pay';
-                    } else if (!financialPermission.transfer_show && !financialPermission.pay_show) {
-                        proj.toUrl = 'transfer';
-                    }
-                }
-                renderData.accountList = accountList;
-                const unitList = await ctx.service.constructionUnit.getAllDataByCondition({where: {pid: ctx.session.sessionProject.id}});
-                renderData.accountGroup = unitList.map(item => {
-                    const groupList = accountList.filter(item1 => item1.company === item.name);
-                    return { groupName: item.name, groupList };
-                }).filter(x => { return x.groupList.length > 0; });
-                // renderData.permissionConst = ctx.service.subProjPermission.PermissionConst;
-                renderData.categoryData = await this.ctx.service.category.getAllCategory(ctx.subProject);
-                renderData.companys = await this.ctx.service.constructionUnit.getAllDataByCondition({where: {pid: ctx.session.sessionProject.id}});
-                // renderData.templates = await this.ctx.service.filingTemplateList.getAllTemplate(ctx.session.sessionProject.id);
-                await this.layout('financial/index.ejs', renderData, 'financial/modal.ejs');
-            } catch (err) {
-                ctx.log(err);
-                ctx.session.postError = err.toString();
-                ctx.redirect(this.menu.menu.dashboard.url);
-            }
-        }
+        // async index(ctx) {
+        //     try {
+        //         if (!ctx.subProject.page_show.openFinancial) {
+        //             throw '该功能已关闭或无法查看';
+        //         }
+        //         const renderData = {
+        //             jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.financial.index),
+        //             auditConst,
+        //         };
+        //         renderData.projectList = await ctx.service.subProject.getSubProjectByFinancial(ctx.session.sessionProject.id, ctx.session.sessionUser.accountId, ctx.session.sessionUser.is_admin);
+        //         const accountList = await ctx.service.projectAccount.getAllSubProjectAccount(ctx.subProject);
+        //         for (const proj of renderData.projectList) {
+        //             const financialPermission = await ctx.service.financialAudit.getPermission(proj.id, ctx.session.sessionUser.accountId);
+        //             if (financialPermission.transfer_show) {
+        //                 proj.toUrl = 'transfer';
+        //             } else if (financialPermission.pay_show) {
+        //                 proj.toUrl = 'pay';
+        //             } else if (!financialPermission.transfer_show && !financialPermission.pay_show) {
+        //                 proj.toUrl = 'transfer';
+        //             }
+        //         }
+        //         renderData.accountList = accountList;
+        //         const unitList = await ctx.service.constructionUnit.getAllDataByCondition({where: {pid: ctx.session.sessionProject.id}});
+        //         renderData.accountGroup = unitList.map(item => {
+        //             const groupList = accountList.filter(item1 => item1.company === item.name);
+        //             return { groupName: item.name, groupList };
+        //         }).filter(x => { return x.groupList.length > 0; });
+        //         // renderData.permissionConst = ctx.service.subProjPermission.PermissionConst;
+        //         renderData.categoryData = await this.ctx.service.category.getAllCategory(ctx.subProject);
+        //         renderData.companys = await this.ctx.service.constructionUnit.getAllDataByCondition({where: {pid: ctx.session.sessionProject.id}});
+        //         // renderData.templates = await this.ctx.service.filingTemplateList.getAllTemplate(ctx.session.sessionProject.id);
+        //         await this.layout('financial/index.ejs', renderData, 'financial/modal.ejs');
+        //     } catch (err) {
+        //         ctx.log(err);
+        //         ctx.session.postError = err.toString();
+        //         ctx.redirect(this.menu.menu.dashboard.url);
+        //     }
+        // }
 
-        async auditSave(ctx) {
-            try {
-                if (ctx.session.sessionUser.is_admin === 0) throw '没有设置权限';
-                const responseData = {
-                    err: 0, msg: '', data: null,
-                };
-                const data = JSON.parse(ctx.request.body.data);
-                if (!data.type) {
-                    throw '提交数据错误';
-                }
-                let uids;
-                let result = false;
-                let auditList = [];
-                switch (data.type) {
-                    case 'add-audit':
-                        // 判断用户是单个还是数组
-                        uids = data.id instanceof Array ? data.id : [data.id];
-                        // 判断该用户的组是否已加入到表中,已加入则提示无需添加
-                        auditList = await ctx.service.financialAudit.getAllDataByCondition({ where: { spid: ctx.subProject.id } });
-                        const addAidList = ctx.helper._.difference(uids, ctx.helper._.map(auditList, 'uid'));
-                        if (addAidList.length === 0) {
-                            throw '用户已存在成员管理中,无需重复添加';
-                        }
-                        const accountList = await ctx.service.projectAccount.getAllDataByCondition({ where: { id: addAidList } });
-                        await ctx.service.financialAudit.saveAudits(ctx.subProject.id, accountList);
-                        responseData.data = await ctx.service.financialAudit.getList(ctx.subProject.id);
-                        break;
-                    case 'del-audit':
-                        uids = data.id instanceof Array ? data.id : [data.id];
-                        auditList = await ctx.service.financialAudit.getAllDataByCondition({ where: { spid: ctx.subProject.id, id: uids } });
-                        if (auditList.length !== uids.length) {
-                            throw '该用户已不存在成员管理中,移除失败';
-                        }
-                        await ctx.service.financialAudit.delAudit(uids);
-                        responseData.data = await ctx.service.financialAudit.getList(ctx.subProject.id);
-                        break;
-                    case 'save-permission':
-                        result = await ctx.service.financialAudit.updatePermission(data.updateData);
-                        if (!result) {
-                            throw '修改权限失败';
-                        }
-                        break;
-                    case 'list':
-                        responseData.data = await ctx.service.financialAudit.getList(ctx.subProject.id);
-                        break;
-                    default: throw '参数有误';
-                }
-                ctx.body = responseData;
-            } catch (err) {
-                this.log(err);
-                ctx.body = { err: 1, msg: err.toString(), data: null };
-            }
-        }
+        // async auditSave(ctx) {
+        //     try {
+        //         if (ctx.session.sessionUser.is_admin === 0) throw '没有设置权限';
+        //         const responseData = {
+        //             err: 0, msg: '', data: null,
+        //         };
+        //         const data = JSON.parse(ctx.request.body.data);
+        //         if (!data.type) {
+        //             throw '提交数据错误';
+        //         }
+        //         let uids;
+        //         let result = false;
+        //         let auditList = [];
+        //         switch (data.type) {
+        //             case 'add-audit':
+        //                 // 判断用户是单个还是数组
+        //                 uids = data.id instanceof Array ? data.id : [data.id];
+        //                 // 判断该用户的组是否已加入到表中,已加入则提示无需添加
+        //                 auditList = await ctx.service.financialAudit.getAllDataByCondition({ where: { spid: ctx.subProject.id } });
+        //                 const addAidList = ctx.helper._.difference(uids, ctx.helper._.map(auditList, 'uid'));
+        //                 if (addAidList.length === 0) {
+        //                     throw '用户已存在成员管理中,无需重复添加';
+        //                 }
+        //                 const accountList = await ctx.service.projectAccount.getAllDataByCondition({ where: { id: addAidList } });
+        //                 await ctx.service.financialAudit.saveAudits(ctx.subProject.id, accountList);
+        //                 responseData.data = await ctx.service.financialAudit.getList(ctx.subProject.id);
+        //                 break;
+        //             case 'del-audit':
+        //                 uids = data.id instanceof Array ? data.id : [data.id];
+        //                 auditList = await ctx.service.financialAudit.getAllDataByCondition({ where: { spid: ctx.subProject.id, id: uids } });
+        //                 if (auditList.length !== uids.length) {
+        //                     throw '该用户已不存在成员管理中,移除失败';
+        //                 }
+        //                 await ctx.service.financialAudit.delAudit(uids);
+        //                 responseData.data = await ctx.service.financialAudit.getList(ctx.subProject.id);
+        //                 break;
+        //             case 'save-permission':
+        //                 result = await ctx.service.financialAudit.updatePermission(data.updateData);
+        //                 if (!result) {
+        //                     throw '修改权限失败';
+        //                 }
+        //                 break;
+        //             case 'list':
+        //                 responseData.data = await ctx.service.financialAudit.getList(ctx.subProject.id);
+        //                 break;
+        //             default: throw '参数有误';
+        //         }
+        //         ctx.body = responseData;
+        //     } catch (err) {
+        //         this.log(err);
+        //         ctx.body = { err: 1, msg: err.toString(), data: null };
+        //     }
+        // }
 
         async transfer(ctx) {
             try {
-                const financialPermission = await ctx.service.financialAudit.getPermission(ctx.subProject.id, ctx.session.sessionUser.accountId);
+                const financialPermission = await ctx.service.subProjPermission.getFinancailPermission(ctx.subProject.permission.fund_trans_permission, ctx.subProject.permission.fund_pay_permission);
                 if (!financialPermission.transfer_show) {
                     throw '没有查看权限';
                 }
@@ -144,7 +144,7 @@ module.exports = app => {
 
         async transferAdd(ctx) {
             try {
-                const financialPermission = await ctx.service.financialAudit.getPermission(ctx.subProject.id, ctx.session.sessionUser.accountId);
+                const financialPermission = await ctx.service.subProjPermission.getFinancailPermission(ctx.subProject.permission.fund_trans_permission, ctx.subProject.permission.fund_pay_permission);
                 if (!financialPermission.transfer_add) {
                     throw '没有添加权限';
                 }
@@ -167,17 +167,17 @@ module.exports = app => {
 
         async transferTender(ctx) {
             try {
-                const financialPermission = await ctx.service.financialAudit.getPermission(ctx.subProject.id, ctx.session.sessionUser.accountId);
+                const financialPermission = await ctx.service.subProjPermission.getFinancailPermission(ctx.subProject.permission.fund_trans_permission, ctx.subProject.permission.fund_pay_permission);
                 if (!financialPermission.transfer_show) {
                     throw '没有查看权限';
                 }
-                const trid = ctx.params.id;
+                const trid = ctx.params.trid;
                 const transferInfo = await ctx.service.financialTransfer.getDataById(trid);
                 if (!transferInfo) {
                     throw '该资金划拨信息不存在';
                 }
                 const transferTenderList = await ctx.service.financialTransferTender.getList(trid);
-                const tenders = await ctx.service.tender.getAllDataByCondition({ where: { spid: ctx.subProject.id } });
+                const tenders = await ctx.service.tender.getAllDataByCondition({ where: { spid: ctx.subProject.id, filter_fund: 0 } });
                 for (const tt of transferTenderList) {
                     const tenderIndex = ctx.helper._.findIndex(tenders, { id: tt.tid });
                     if (tenderIndex !== -1) {
@@ -249,11 +249,11 @@ module.exports = app => {
 
         async transferTenderUpdate(ctx) {
             try {
-                const financialPermission = await ctx.service.financialAudit.getPermission(ctx.subProject.id, ctx.session.sessionUser.accountId);
+                const financialPermission = await ctx.service.subProjPermission.getFinancailPermission(ctx.subProject.permission.fund_trans_permission, ctx.subProject.permission.fund_pay_permission);
                 if (!financialPermission.transfer_add) {
                     throw '没有权限';
                 }
-                const trid = ctx.params.id;
+                const trid = ctx.params.trid;
                 const transferInfo = await ctx.service.financialTransfer.getDataById(trid);
                 if (!transferInfo) {
                     throw '该资金划拨信息不存在';
@@ -295,12 +295,12 @@ module.exports = app => {
         async transferUploadFile(ctx) {
             let stream;
             try {
-                const financialPermission = await ctx.service.financialAudit.getPermission(ctx.subProject.id, ctx.session.sessionUser.accountId);
+                const financialPermission = await ctx.service.subProjPermission.getFinancailPermission(ctx.subProject.permission.fund_trans_permission, ctx.subProject.permission.fund_pay_permission);
                 if (!financialPermission.transfer_file) {
                     throw '没有权限';
                 }
                 const responseData = { err: 0, msg: '', data: {} };
-                const id = ctx.params.id;
+                const id = ctx.params.trid;
                 if (!id) throw '参数有误';
                 const parts = this.ctx.multipart({
                     autoFields: true,
@@ -358,7 +358,7 @@ module.exports = app => {
          */
         async transferDeleteFile(ctx) {
             try {
-                const id = ctx.params.id;
+                const id = ctx.params.trid;
                 const responseData = { err: 0, msg: '', data: {} };
                 const data = JSON.parse(ctx.request.body.data);
                 const fileInfo = await ctx.service.financialTransferAtt.getDataById(data.id);
@@ -426,13 +426,13 @@ module.exports = app => {
         async transferTenderUploadFile(ctx) {
             let stream;
             try {
-                const financialPermission = await ctx.service.financialAudit.getPermission(ctx.subProject.id, ctx.session.sessionUser.accountId);
+                const financialPermission = await ctx.service.subProjPermission.getFinancailPermission(ctx.subProject.permission.fund_trans_permission, ctx.subProject.permission.fund_pay_permission);
                 if (!financialPermission.transfer_file) {
                     throw '没有权限';
                 }
                 const responseData = { err: 0, msg: '', data: {} };
                 const trid = ctx.params.trid;
-                const id = ctx.params.id;
+                const id = ctx.params.ttid;
                 if (!id) throw '参数有误';
                 const parts = this.ctx.multipart({
                     autoFields: true,
@@ -491,7 +491,7 @@ module.exports = app => {
          */
         async transferTenderDeleteFile(ctx) {
             try {
-                const id = ctx.params.id;
+                const id = ctx.params.ttid;
                 const responseData = { err: 0, msg: '', data: {} };
                 const data = JSON.parse(ctx.request.body.data);
                 const fileInfo = await ctx.service.financialTransferTenderAtt.getDataById(data.id);
@@ -588,7 +588,7 @@ module.exports = app => {
         // }
 
         async _filterPay(ctx, status = 0, tid = null, used = null) {
-            const financialPermission = await ctx.service.financialAudit.getPermission(ctx.subProject.id, ctx.session.sessionUser.accountId);
+            const financialPermission = await ctx.service.subProjPermission.getFinancailPermission(ctx.subProject.permission.fund_trans_permission, ctx.subProject.permission.fund_pay_permission);
             if (!financialPermission.pay_show) {
                 throw '没有查看权限';
             }
@@ -596,7 +596,7 @@ module.exports = app => {
             const fptAuditTids = ctx.helper._.map(fptAudits, 'tid');
             const fptReportTids = ctx.helper._.map(ctx.helper._.filter(fptAudits, { is_report: 1 }), 'tid');
             const filterTids = tid === null ? (ctx.session.sessionUser.is_admin ? null : fptAuditTids) : [tid];
-            const tenderCondition = { spid: ctx.subProject.id };
+            const tenderCondition = { spid: ctx.subProject.id, filter_fund: 0 };
             let hadTender = false;
             if (ctx.session.sessionUser.is_admin) {
                 hadTender = true;
@@ -1045,7 +1045,7 @@ module.exports = app => {
 
         async summary(ctx) {
             try {
-                const financialPermission = await ctx.service.financialAudit.getPermission(ctx.subProject.id, ctx.session.sessionUser.accountId);
+                const financialPermission = await ctx.service.subProjPermission.getFinancailPermission(ctx.subProject.permission.fund_trans_permission, ctx.subProject.permission.fund_pay_permission);
                 if (!financialPermission.transfer_show && !financialPermission.pay_show) {
                     throw '没有查看权限';
                 }

+ 7 - 7
app/controller/material_controller.js

@@ -46,7 +46,7 @@ module.exports = app => {
          */
         async index(ctx) {
             try {
-                if (!ctx.session.sessionProject.page_show.openMaterial) {
+                if (!ctx.subProject.page_show.openMaterial) {
                     throw '该功能已关闭';
                 }
                 // 列展示
@@ -95,7 +95,7 @@ module.exports = app => {
                             await ctx.service.material.defaultUpdate({ id: s.id, final_auditor_str });
                         }
                     }
-                    if (!ctx.session.sessionProject.page_show.openMaterialStageRepeat) {
+                    if (!ctx.subProject.page_show.openMaterialStageRepeat) {
                         const materialStageList = s.stage_id.split(',');
                         for (const ms of materialStageList) {
                             const index = stages.findIndex(function(item) {
@@ -143,7 +143,7 @@ module.exports = app => {
          */
         async materialAuditors(ctx) {
             try {
-                if (!ctx.session.sessionProject.page_show.openMaterial) {
+                if (!ctx.subProject.page_show.openMaterial) {
                     throw '该功能已关闭';
                 }
                 const order = JSON.parse(ctx.request.body.data).order;
@@ -165,7 +165,7 @@ module.exports = app => {
          */
         async save(ctx) {
             try {
-                if (!ctx.session.sessionProject.page_show.openMaterial) {
+                if (!ctx.subProject.page_show.openMaterial) {
                     throw '该功能已关闭';
                 }
                 const data = {
@@ -197,7 +197,7 @@ module.exports = app => {
          */
         async saveData(ctx) {
             try {
-                if (!ctx.session.sessionProject.page_show.openMaterial) {
+                if (!ctx.subProject.page_show.openMaterial) {
                     throw '该功能已关闭';
                 }
                 const data = JSON.parse(ctx.request.body.data);
@@ -226,7 +226,7 @@ module.exports = app => {
          */
         async add(ctx) {
             try {
-                if (!ctx.session.sessionProject.page_show.openMaterial) {
+                if (!ctx.subProject.page_show.openMaterial) {
                     throw '该功能已关闭';
                 }
                 if (ctx.session.sessionUser.accountId !== ctx.tender.data.user_id) {
@@ -266,7 +266,7 @@ module.exports = app => {
          */
         async delete(ctx) {
             try {
-                if (!ctx.session.sessionProject.page_show.openMaterial) {
+                if (!ctx.subProject.page_show.openMaterial) {
                     throw '该功能已关闭';
                 }
                 const material_id = ctx.request.body.material_id;

+ 1 - 1
app/controller/measure_controller.js

@@ -111,7 +111,7 @@ module.exports = app => {
                 const stages = await ctx.service.stage.getAllDataByCondition({ where: { tid: ctx.tender.id }});
                 const unCompleteStageCount = stages.filter(s => { return s.status !== auditConst.status.checked; }).length;
                 if (unCompleteStageCount.length > 0) {
-                    if (ctx.session.sessionProject.page_show.openMultiStageCalc) {
+                    if (ctx.subProject.page_show.openMultiStageCalc) {
                         if (unCompleteStageCount >= ctx.session.sessionProject.page_show.maxMultiStageCount)
                             throw `最多只可同时进行${ctx.session.sessionProject.page_show.maxMultiStageCount}期计量`;
                     } else {

+ 2 - 1
app/controller/pay_controller.js

@@ -87,7 +87,7 @@ module.exports = app => {
 
         async del(ctx) {
             try {
-                if (!ctx.session.sessionUser.is_admin && ctx.request.body.confirm !== '确认删除本期') throw '请输入文本确认删除本期';
+                // if (!ctx.session.sessionUser.is_admin && ctx.request.body.confirm !== '确认删除本期') throw '请输入文本确认删除本期';
                 const phase_id = ctx.request.body.phase_id;
                 const phasePay = await ctx.service.phasePay.getDataById(phase_id);
                 if (!phasePay) throw '删除的期不存在,请刷新页面';
@@ -102,6 +102,7 @@ module.exports = app => {
                 ctx.redirect('/tender/' + ctx.tender.id + '/pay');
             } catch (err) {
                 ctx.log(err);
+                ctx.postError(err, '删除期失败');
                 ctx.redirect('/tender/' + ctx.tender.id + '/pay');
             }
         }

+ 44 - 56
app/controller/payment_controller.js

@@ -31,10 +31,10 @@ module.exports = app => {
          */
         async index(ctx) {
             try {
-                if (!ctx.session.sessionProject.showPayment) {
+                if (!ctx.subProject.showPayment) {
                     throw '该功能已关闭或无法查看';
                 }
-                const auditPermission = await this.ctx.service.paymentPermissionAudit.getOnePermission(ctx.session.sessionUser.is_admin, ctx.session.sessionUser.accountId);
+                const auditPermission = await ctx.service.subProjPermission.getPaymentPermission(ctx.subProject.permission.payment_permission);
                 if (!auditPermission) {
                     throw '权限不足';
                 }
@@ -46,12 +46,9 @@ module.exports = app => {
                 };
                 if (ctx.session.sessionUser.is_admin) {
                     const projectId = ctx.session.sessionProject.id;
-                    const permissionAudits = await ctx.service.paymentPermissionAudit.getList(projectId);
+                    const permissionAudits = await ctx.service.subProjPermission.getPaymentAuditList(ctx.subProject.id);
                     // 获取所有项目参与者
-                    const accountList = await ctx.service.projectAccount.getAllDataByCondition({
-                        where: { project_id: ctx.session.sessionProject.id, enable: 1 },
-                        columns: ['id', 'name', 'company', 'role', 'enable', 'is_admin', 'account_group', 'mobile'],
-                    });
+                    const accountList = await ctx.service.projectAccount.getAllSubProjectAccount(ctx.subProject);
                     const unitList = await ctx.service.constructionUnit.getAllDataByCondition({ where: { pid: projectId } });
                     const accountGroupList = unitList.map(item => {
                         const groupList = accountList.filter(item1 => item1.company === item.name);
@@ -64,7 +61,12 @@ module.exports = app => {
                     renderData.permissionAudits = permissionAudits;
                     renderData.accountList = accountList;
                     renderData.accountGroup = accountGroupList;
+                    // 整理未分类的支付审批标段
+                    const noSpFolderList = await ctx.service.paymentFolder.getNoSpList(ctx.session.sessionProject.id);
+                    renderData.noSpFolderList = ctx.helper._.orderBy(noSpFolderList, ['in_time'], ['asc']);
                 }
+                const noSpTenderList = await ctx.service.paymentTender.getNoSpList(ctx.session.sessionProject.id);
+                renderData.noSpTenderList = ctx.helper._.orderBy(noSpTenderList, ['in_time'], ['asc']);
                 await this.layout('payment/index.ejs', renderData, 'payment/modal.ejs');
             } catch (err) {
                 console.log(err);
@@ -78,7 +80,7 @@ module.exports = app => {
             const responseData = {
                 err: 0, msg: '', data: {},
             };
-            const auditPermission = await this.ctx.service.paymentPermissionAudit.getOnePermission(ctx.session.sessionUser.is_admin, ctx.session.sessionUser.accountId);
+            const auditPermission = await ctx.service.subProjPermission.getPaymentPermission(ctx.subProject.permission.payment_permission);
             if (!auditPermission) {
                 throw '权限不足';
             }
@@ -99,7 +101,7 @@ module.exports = app => {
 
         async permissionSave(ctx) {
             try {
-                if (!ctx.session.sessionProject.showPayment) {
+                if (!ctx.subProject.showPayment) {
                     throw '该功能已关闭或无法查看';
                 }
                 if (ctx.session.sessionUser.is_admin === 0) throw '没有设置权限';
@@ -120,30 +122,33 @@ module.exports = app => {
                         // 判断用户是单个还是数组
                         uids = data.id instanceof Array ? data.id : [data.id];
                         // 判断该用户的组是否已加入到表中,已加入则提示无需添加
-                        auditList = await ctx.service.paymentPermissionAudit.getAllDataByCondition({ where: { pid: projectId, uid: uids } });
+                        auditList = await ctx.service.subProjPermission.getPaymentAuditList(ctx.subProject.id, uids);
                         const addAidList = ctx.helper._.difference(uids, ctx.helper._.map(auditList, 'uid'));
                         if (addAidList.length === 0) {
                             throw '用户已存在权限中,无需重复添加';
                         }
-                        const accountList = await ctx.service.projectAccount.getAllDataByCondition({ where: { id: addAidList } });
-                        await ctx.service.paymentPermissionAudit.saveAudits(projectId, accountList);
-                        responseData.data = await ctx.service.paymentPermissionAudit.getList(projectId);
+                        // const accountList = await ctx.service.projectAccount.getAllDataByCondition({ where: { id: addAidList } });
+                        await ctx.service.subProjPermission.savePaymentPermissionAudits(ctx.subProject.id, addAidList, 'add');
+                        responseData.data = await ctx.service.subProjPermission.getPaymentAuditList(ctx.subProject.id);
                         break;
                     case 'del-audit':
                         uids = data.id instanceof Array ? data.id : [data.id];
-                        auditList = await ctx.service.paymentPermissionAudit.getAllDataByCondition({ where: { id: uids } });
+                        auditList = await ctx.service.subProjPermission.getPaymentAuditList(ctx.subProject.id, uids);
                         if (auditList.length !== uids.length) {
                             throw '该用户已不存在权限中,移除失败';
                         }
-                        await ctx.service.paymentPermissionAudit.delAudit(uids);
-                        responseData.data = await ctx.service.paymentPermissionAudit.getList(projectId);
+                        await ctx.service.subProjPermission.savePaymentPermissionAudits(ctx.subProject.id, uids, 'del');
+                        responseData.data = await ctx.service.subProjPermission.getPaymentAuditList(ctx.subProject.id);
                         break;
                     case 'save-permission-one':
-                        result = await ctx.service.paymentPermissionAudit.updateOnePermission(data.updateData);
+                        result = await ctx.service.subProjPermission.updateOnePaymentPermission(ctx.subProject.id, data.updateData);
                         if (!result) {
                             throw '修改权限失败';
                         }
                         break;
+                    case 'bind-sp':
+                        result = await ctx.service.paymentTender.bindSp(data.tids);
+                        break;
                     // case 'save-permission-all':
                     //     result = await ctx.service.paymentPermissionAudit.updateAllPermission(projectId, data.permission_type, data.value);
                     //     if (!result) {
@@ -163,7 +168,7 @@ module.exports = app => {
 
         async paymentInfoSave(ctx) {
             try {
-                if (!ctx.session.sessionProject.showPayment) {
+                if (!ctx.subProject.showPayment) {
                     throw '该功能已关闭或无法查看';
                 }
                 const data = JSON.parse(ctx.request.body.data);
@@ -183,11 +188,11 @@ module.exports = app => {
 
         async save(ctx) {
             try {
-                if (!ctx.session.sessionProject.showPayment) {
+                if (!ctx.subProject.showPayment) {
                     throw '该功能已关闭或无法查看';
                 }
                 const projectId = ctx.session.sessionProject.id;
-                const auditPermission = await this.ctx.service.paymentPermissionAudit.getOnePermission(ctx.session.sessionUser.is_admin, ctx.session.sessionUser.accountId);
+                const auditPermission = await ctx.service.subProjPermission.getPaymentPermission(ctx.subProject.permission.payment_permission);
                 if (!auditPermission) {
                     throw '权限不足';
                 }
@@ -246,8 +251,7 @@ module.exports = app => {
                         if (!ctx.session.sessionUser.is_admin) {
                             throw '您无权操作';
                         }
-                        const projectInfo = await ctx.service.project.getDataById(ctx.session.sessionProject.id);
-                        const modes = projectInfo.payment_setting ? JSON.parse(projectInfo.payment_setting) : ctx.helper._.cloneDeep(paymentConst.setting_modes);
+                        const modes = ctx.subProject.payment_setting ? JSON.parse(ctx.subProject.payment_setting) : ctx.helper._.cloneDeep(paymentConst.setting_modes);
                         const checked = data.checked;
                         if (modes[data.mode_type]) {
                             const detailCount = await ctx.service.paymentDetail.getCountByPidType(ctx.session.sessionProject.id, modes[data.mode_type].value);
@@ -265,7 +269,7 @@ module.exports = app => {
                         } else {
                             throw '该模块不存在';
                         }
-                        await ctx.service.project.defaultUpdate({ id: ctx.session.sessionProject.id, payment_setting: JSON.stringify(modes) });
+                        await ctx.service.subProject.defaultUpdate({ id: ctx.subProject.id, payment_setting: JSON.stringify(modes) });
                         break;
                     case 'info':
                         await ctx.service.paymentTenderInfo.saveTenderInfo(data.postData.id, data.postData.info);
@@ -290,8 +294,7 @@ module.exports = app => {
                 if (!ctx.session.sessionUser.is_admin) {
                     throw '您无权打开此页';
                 }
-                const projectInfo = await ctx.service.project.getDataById(ctx.session.sessionProject.id);
-                const modes = projectInfo.payment_setting ? JSON.parse(projectInfo.payment_setting) : ctx.helper._.cloneDeep(paymentConst.setting_modes);
+                const modes = ctx.subProject.payment_setting ? JSON.parse(ctx.subProject.payment_setting) : ctx.helper._.cloneDeep(paymentConst.setting_modes);
                 for (const m in modes) {
                     const detailCount = await ctx.service.paymentDetail.getCountByPidType(ctx.session.sessionProject.id, modes[m].value);
                     modes[m].can_check = !detailCount;
@@ -306,7 +309,7 @@ module.exports = app => {
                 console.log(err);
                 this.log(err);
                 ctx.session.postError = err.toString();
-                ctx.redirect('/payment');
+                ctx.redirect(`/sp/${ctx.subProject.id}/payment`);
             }
         }
 
@@ -431,7 +434,7 @@ module.exports = app => {
                     moment,
                     whiteList: ctx.app.config.multipart.whitelist,
                     uidList,
-                    preUrl: '/payment/' + ctx.paymentTender.id + '/detail/' + ctx.detail.id,
+                    preUrl: '/sp/' + ctx.subProject.id + '/payment/' + ctx.paymentTender.id + '/detail/' + ctx.detail.id,
                     OSS_PATH: ctx.app.config.fujianOssPath,
                 };
                 renderData.nextDetail = await ctx.service.paymentDetail.getDataByCondition({ tr_id: ctx.trInfo.id, order: ctx.detail.order + 1 });
@@ -503,10 +506,7 @@ module.exports = app => {
                 if ((ctx.detail.status === auditConst.status.uncheck || ctx.detail.status === auditConst.status.checkNo) && ctx.session.sessionUser.accountId === ctx.detail.uid) {
                     // data.accountGroup = accountGroup;
                     // 获取所有项目参与者
-                    const accountList = await ctx.service.projectAccount.getAllDataByCondition({
-                        where: { project_id: ctx.session.sessionProject.id, enable: 1 },
-                        columns: ['id', 'name', 'company', 'role', 'enable', 'is_admin', 'account_group', 'mobile'],
-                    });
+                    const accountList = await ctx.service.projectAccount.getAllSubProjectAccount(ctx.subProject);
                     renderData.accountList = accountList;
                     const unitList = await ctx.service.constructionUnit.getAllDataByCondition({ where: { pid: ctx.session.sessionProject.id } });
                     const accountGroupList = unitList.map(item => {
@@ -521,7 +521,7 @@ module.exports = app => {
                 this.log(err);
                 ctx.session.postError = err.toString();
                 if (ctx.detail.tender_id && ctx.detail.tr_id) {
-                    ctx.redirect('/payment' + ctx.detail.tender_id + '/list/' + ctx.detail.tr_id);
+                    ctx.redirect('/sp/' + ctx.subProject.id + '/payment' + ctx.detail.tender_id + '/list/' + ctx.detail.tr_id);
                 }
                 ctx.redirect(this.menu.menu.dashboard.url);
             }
@@ -626,7 +626,7 @@ module.exports = app => {
                 if (!result) {
                     throw '删除报表表单详情失败,请重试';
                 }
-                ctx.redirect('/payment/' + ctx.paymentTender.id + '/list/' + detailInfo.tr_id);
+                ctx.redirect('/sp/' + ctx.subProject.id + '/payment/' + ctx.paymentTender.id + '/list/' + detailInfo.tr_id);
             } catch (err) {
                 this.log(err);
                 ctx.session.postError = err.toString();
@@ -714,10 +714,7 @@ module.exports = app => {
                 //     }
                 // }
                 // 获取所有项目参与者
-                const accountList = await ctx.service.projectAccount.getAllDataByCondition({
-                    where: { project_id: ctx.session.sessionProject.id, enable: 1 },
-                    columns: ['id', 'name', 'company', 'role', 'enable', 'is_admin', 'account_group', 'mobile'],
-                });
+                const accountList = await ctx.service.projectAccount.getAllSubProjectAccount(ctx.subProject);
                 const unitList = await ctx.service.constructionUnit.getAllDataByCondition({ where: { pid: ctx.session.sessionProject.id } });
                 const accountGroupList = unitList.map(item => {
                     const groupList = accountList.filter(item1 => item1.company === item.name);
@@ -738,7 +735,7 @@ module.exports = app => {
                 console.log(err);
                 this.log(err);
                 ctx.session.postError = err.toString();
-                ctx.redirect(this.request && this.request.headers && this.request.headers.referer ? this.request.headers.referer : '/payment');
+                ctx.redirect(this.request && this.request.headers && this.request.headers.referer ? this.request.headers.referer : '/sp/' + ctx.subProject.id + '/payment');
             }
         }
 
@@ -803,10 +800,7 @@ module.exports = app => {
 
                 // 获取列表
                 const trDetailList = await ctx.service.paymentDetail.getValidDetails(trInfo.id);
-                const accountList = await ctx.service.projectAccount.getAllDataByCondition({
-                    where: { project_id: ctx.session.sessionProject.id, enable: 1 },
-                    columns: ['id', 'name', 'company', 'role', 'enable', 'is_admin', 'account_group', 'mobile'],
-                });
+                const accountList = await ctx.service.projectAccount.getAllSubProjectAccount(ctx.subProject);
                 if (trDetailList.length > 0) {
                     for (const s of trDetailList) {
                         // s.curAuditor = null;
@@ -831,7 +825,7 @@ module.exports = app => {
                     accountGroup: [],
                     accountList: [],
                     paymentConst,
-                    preUrl: '/payment/' + ctx.paymentTender.id + '/list/' + trInfo.id,
+                    preUrl: '/sp/' + ctx.subProject.id + '/payment/' + ctx.paymentTender.id + '/list/' + trInfo.id,
                     categoryData,
                     tenderInfo,
                 };
@@ -905,10 +899,7 @@ module.exports = app => {
                     }
                     if (renderData.rptMsg) {
                         // 获取所有项目参与者
-                        const accountList = await ctx.service.projectAccount.getAllDataByCondition({
-                            where: { project_id: ctx.session.sessionProject.id, enable: 1 },
-                            columns: ['id', 'name', 'company', 'role', 'enable', 'is_admin', 'account_group', 'mobile'],
-                        });
+                        const accountList = await ctx.service.projectAccount.getAllSubProjectAccount(ctx.subProject);
                         const unitList = await ctx.service.constructionUnit.getAllDataByCondition({ where: { pid: ctx.session.sessionProject.id } });
                         const accountGroupList = unitList.map(item => {
                             const groupList = accountList.filter(item1 => item1.company === item.name);
@@ -923,7 +914,7 @@ module.exports = app => {
                 console.log(err);
                 this.log(err);
                 ctx.session.postError = err.toString();
-                ctx.redirect(this.request && this.request.headers && this.request.headers.referer ? this.request.headers.referer : '/payment');
+                ctx.redirect(this.request && this.request.headers && this.request.headers.referer ? this.request.headers.referer : '/sp/' + ctx.subProject.id + '/payment');
             }
         }
 
@@ -1075,7 +1066,7 @@ module.exports = app => {
                     fileData.orginpath = ctx.app.config.fujianOssPath + filepath;
                     delete fileData.filepath;
                     if (!ctx.helper.canPreview(fileData.fileext)) {
-                        fileData.filepath = `/payment/${original_data.tender_id}/detail/${original_data.td_id}/file/${fileData.id}/download`;
+                        fileData.filepath = `/sp/${ctx.subProject.id}/payment/${original_data.tender_id}/detail/${original_data.td_id}/file/${fileData.id}/download`;
                     } else {
                         fileData.filepath = ctx.app.config.fujianOssPath + filepath;
                         fileData.viewpath = ctx.app.config.fujianOssPath + filepath;
@@ -1191,7 +1182,7 @@ module.exports = app => {
                     moment,
                     whiteList: ctx.app.config.multipart.whitelist,
                     uidList,
-                    preUrl: '/payment/' + ctx.paymentTender.id + '/detail/' + ctx.detail.id,
+                    preUrl: '/sp/' + ctx.subProject.id + '/payment/' + ctx.paymentTender.id + '/detail/' + ctx.detail.id,
                     OSS_PATH: ctx.app.config.fujianOssPath,
                     stdBills,
                 };
@@ -1200,10 +1191,7 @@ module.exports = app => {
                 renderData.content = content;
                 if ((ctx.detail.status === auditConst.status.uncheck || ctx.detail.status === auditConst.status.checkNo) && ctx.session.sessionUser.accountId === ctx.detail.uid) {
                     // 获取所有项目参与者
-                    const accountList = await ctx.service.projectAccount.getAllDataByCondition({
-                        where: { project_id: ctx.session.sessionProject.id, enable: 1 },
-                        columns: ['id', 'name', 'company', 'role', 'enable', 'is_admin', 'account_group', 'mobile'],
-                    });
+                    const accountList = await ctx.service.projectAccount.getAllSubProjectAccount(ctx.subProject);
                     renderData.accountList = accountList;
                     const unitList = await ctx.service.constructionUnit.getAllDataByCondition({ where: { pid: ctx.session.sessionProject.id } });
                     const accountGroupList = unitList.map(item => {
@@ -1217,7 +1205,7 @@ module.exports = app => {
                 this.log(err);
                 this.ctx.postError(err, '读取安全生产费错误');
                 if (ctx.detail.tender_id && ctx.detail.tr_id) {
-                    ctx.redirect('/payment' + ctx.detail.tender_id + '/list');
+                    ctx.redirect('/sp/' + ctx.subProject.id + '/payment' + ctx.detail.tender_id + '/list');
                 } else {
                     ctx.redirect(this.menu.menu.dashboard.url);
                 }
@@ -1237,7 +1225,7 @@ module.exports = app => {
                 this.log(err);
                 this.ctx.postError(err, '读取安全生产费错误');
                 if (ctx.detail.tender_id && ctx.detail.tr_id) {
-                    ctx.redirect('/payment' + ctx.detail.tender_id + '/list');
+                    ctx.redirect('/sp/' + ctx.subProject.id + '/payment' + ctx.detail.tender_id + '/list');
                 } else {
                     ctx.redirect(this.menu.menu.dashboard.url);
                 }

+ 6 - 6
app/controller/report_controller.js

@@ -237,7 +237,7 @@ module.exports = app => {
                 }
                 // let prjAccList = await ctx.service.projectAccount.getAllAccountByProjectId(tender.data.project_id);
                 // prjAccList = prjAccList.filter(pa => pa.enable !== 0);
-                let prjAccList = await ctx.service.projectAccount.getAllSubProjectAccount(ctx.subProject);
+                let prjAccList = await ctx.service.projectAccount.getAllSubProjectAccount(ctx.subProject, ['id', 'name', 'company', 'role', 'enable', 'is_admin', 'account_group', 'mobile', 'company_id', 'account', 'telephone', 'permission', 'sign_path', 'stamp_path']);
                 const roleList = await ctx.service.signatureRole.getSignatureRolesByTenderId(tender.id);
                 const usedList = await ctx.service.signatureUsed.getSignatureUsedByTenderId(tender.id);
 
@@ -416,7 +416,7 @@ module.exports = app => {
                 pageShow.showArchive = 0;
                 // pageShow.closeWatermark = 1;
                 pageShow.closeShowAllCustomized = 0;
-                const tenderId = ctx.params.id;
+                const tenderId = ctx.params.pid;
                 const paymentDetail_id = ctx.params.did;
                 // 支付审批: ctx.params.did 是 zh_payment_detail表的id, 通过这个did在 zh_payment_detail_audit表里找审核信息(td_id = ctx.params.did)
                 //          没有计量期的概念!!!
@@ -431,7 +431,7 @@ module.exports = app => {
                 const archiveList = [];
                 // let prjAccList = await ctx.service.projectAccount.getAllAccountByProjectId(tender.pid);
                 // prjAccList = prjAccList.filter(pa => pa.enable !== 0);
-                let prjAccList = await ctx.service.projectAccount.getAllSubProjectAccount(ctx.subProject);
+                let prjAccList = await ctx.service.projectAccount.getAllSubProjectAccount(ctx.subProject, ['id', 'name', 'company', 'role', 'enable', 'is_admin', 'account_group', 'mobile', 'company_id', 'account', 'telephone', 'permission', 'sign_path', 'stamp_path']);
                 const roleList = await ctx.service.signatureRole.getSignatureRolesByTenderId(tender.id);
                 const usedList = await ctx.service.signatureUsed.getSignatureUsedByTenderId(tender.id);
                 // 根据需求,如果开启了‘开启个人「签字」’功能,则只能是本身用户签名,管理员例外
@@ -446,7 +446,7 @@ module.exports = app => {
                     prjAccList = newAccList;
                 }
                 // 分类列表 todo 支付审批 目前没有所属子项目,自定义分类暂无法按所属子项目取值
-                const categoryData = await this.ctx.service.category.getAllCategory(this.ctx.session.sessionProject.id);
+                const categoryData = await this.ctx.service.category.getAllCategory(this.ctx.subProject.id);
                 // 获取用户权限
                 const accountInfo = await this.ctx.service.projectAccount.getDataById(this.ctx.session.sessionUser.accountId);
                 // const userPermission = accountInfo !== undefined && accountInfo.permission !== '' ? JSON.parse(accountInfo.permission) : null;
@@ -582,7 +582,7 @@ module.exports = app => {
                 const archiveList = [];
                 // let prjAccList = await ctx.service.projectAccount.getAllAccountByProjectId(pid);
                 // prjAccList = prjAccList.filter(pa => pa.enable !== 0);
-                let prjAccList = await ctx.service.projectAccount.getAllSubProjectAccount(ctx.subProject);
+                let prjAccList = await ctx.service.projectAccount.getAllSubProjectAccount(ctx.subProject, ['id', 'name', 'company', 'role', 'enable', 'is_admin', 'account_group', 'mobile', 'company_id', 'account', 'telephone', 'permission', 'sign_path', 'stamp_path']);
                 const roleList = [];
                 const usedList = [];
                 // 根据需求,如果开启了‘开启个人「签字」’功能,则只能是本身用户签名,管理员例外
@@ -798,7 +798,7 @@ module.exports = app => {
 
                 // let prjAccList = await ctx.service.projectAccount.getAllAccountByProjectId(pid);
                 // prjAccList = prjAccList.filter(pa => pa.enable !== 0);
-                let prjAccList = await ctx.service.projectAccount.getAllSubProjectAccount(ctx.subProject);
+                let prjAccList = await ctx.service.projectAccount.getAllSubProjectAccount(ctx.subProject, ['id', 'name', 'company', 'role', 'enable', 'is_admin', 'account_group', 'mobile', 'company_id', 'account', 'telephone', 'permission', 'sign_path', 'stamp_path']);
                 const roleList = [];
                 const usedList = await ctx.service.signatureUsed.getSignatureUsedByTenderId(tenderId);
                 // 根据需求,如果开启了‘开启个人「签字」’功能,则只能是本身用户签名,管理员例外

+ 30 - 4
app/controller/sub_proj_controller.js

@@ -15,6 +15,14 @@ const path = require('path');
 module.exports = app => {
     class SubProjController extends app.BaseController {
 
+        async _loadCount(projectList){
+            for (const p of projectList) {
+                p.tender_count = await this.ctx.service.tender.count({ spid: p.id });
+                p.contract_count = await this.ctx.service.contract.count({ spid: p.id });
+                p.file_count = await this.ctx.service.file.count({ spid: p.id, is_deleted: 0 });
+            }
+        }
+
         /**
          * 概算投资
          *
@@ -29,6 +37,7 @@ module.exports = app => {
                 };
                 renderData.budgetStd = await ctx.service.budgetStd.getDataByProjectId(ctx.session.sessionProject.id);
                 renderData.projectList = await ctx.service.subProject.getSubProject(ctx.session.sessionProject.id, ctx.session.sessionUser.accountId, ctx.session.sessionUser.is_admin);
+                await this._loadCount(renderData.projectList);
                 renderData.tenderList = await ctx.service.tender.getManageTenderList(ctx.session.sessionProject.id);
                 const accountList = await ctx.service.projectAccount.getAllDataByCondition({
                     columns: ['id', 'name', 'company', 'role', 'enable', 'is_admin', 'account_group', 'mobile'],
@@ -45,7 +54,6 @@ module.exports = app => {
                 renderData.templates = await this.ctx.service.filingTemplateList.getAllTemplate(ctx.session.sessionProject.id);
                 await this.layout('sub_proj/index.ejs', renderData, 'sub_proj/modal.ejs');
             } catch (err) {
-                console.log(err);
                 ctx.log(err);
                 ctx.session.postError = err.toString();
                 ctx.redirect(this.menu.menu.dashboard.url);
@@ -57,6 +65,7 @@ module.exports = app => {
                 const data = JSON.parse(ctx.request.body.data);
                 if (!data.name || data.name.length > 100) throw '文件夹名称有误';
                 const result = await ctx.service.subProject.addFolder(data);
+                await this._loadCount(result);
                 ctx.body = { err: 0, msg: '', data: result };
             } catch (err) {
                 ctx.log(err);
@@ -69,6 +78,7 @@ module.exports = app => {
                 const data = JSON.parse(ctx.request.body.data);
                 if (!data.name || data.name.length > 100) throw '项目名称有误';
                 const result = await ctx.service.subProject.addSubProject(data);
+                await this._loadCount(result);
                 ctx.body = { err: 0, msg: '', data: result };
             } catch (err) {
                 ctx.log(err);
@@ -81,6 +91,7 @@ module.exports = app => {
                 const data = JSON.parse(ctx.request.body.data);
                 if (!data.drag_id || !data.drop_id) throw '提交数据错误';
                 const result = await ctx.service.subProject.dragTo(data);
+                await this._loadCount(result);
                 ctx.body = { err: 0, msg: '', data: result };
             } catch (err) {
                 ctx.log(err);
@@ -93,6 +104,7 @@ module.exports = app => {
                 const data = JSON.parse(ctx.request.body.data);
                 if (!data.id || !data.type) throw '提交数据错误';
                 const result = await ctx.service.subProject.move(data);
+                await this._loadCount(result);
                 ctx.body = { err: 0, msg: '', data: result };
             } catch (err) {
                 ctx.log(err);
@@ -205,6 +217,12 @@ module.exports = app => {
             }
         }
 
+        _checkInfoEditPermission() {
+            if (this.ctx.subProject.permission.info_permission.indexOf(this.ctx.service.subProjPermission.PermissionConst.info.edit.value) < 0) {
+                throw '暂无权编辑项目概况信息';
+            }
+        }
+
         async info(ctx) {
             try {
                 const info = await this.ctx.service.subProjInfo.getInfo(ctx.subProject.id);
@@ -215,6 +233,7 @@ module.exports = app => {
                 const renderData = {
                     info,
                     jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.subProject.info),
+                    readOnly: ctx.subProject.permission.info_permission.indexOf(ctx.service.subProjPermission.PermissionConst.info.edit.value) < 0,
                 };
                 await this.layout('sub_proj/info.ejs', renderData);
             } catch (err) {
@@ -228,6 +247,7 @@ module.exports = app => {
                 const renderData = {
                     info,
                     jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.subProject.data),
+                    readOnly: ctx.subProject.permission.info_permission.indexOf(ctx.service.subProjPermission.PermissionConst.info.edit.value) < 0,
                 };
                 await this.layout('sub_proj/data_index.ejs', renderData);
             } catch (err) {
@@ -237,6 +257,7 @@ module.exports = app => {
 
         async saveInfo(ctx) {
             try {
+                this._checkInfoEditPermission();
                 const data = JSON.parse(ctx.request.body.data);
                 const result = await ctx.service.subProjInfo.saveInfo(ctx.subProject.id, data);
                 ctx.body = { err: 0, msg: '', data: result };
@@ -251,6 +272,7 @@ module.exports = app => {
                 const renderData = {
                     jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.subProject.progress),
                     fileReferenceList,
+                    readOnly: ctx.subProject.permission.info_permission.indexOf(ctx.service.subProjPermission.PermissionConst.info.edit.value) < 0,
                 };
                 await this.layout('sub_proj/progress.ejs', renderData, 'sub_proj/progress_modal.ejs');
             } catch (err) {
@@ -312,6 +334,7 @@ module.exports = app => {
 
         async progressUpdate(ctx) {
             try {
+                this._checkInfoEditPermission();
                 const data = JSON.parse(ctx.request.body.data);
                 if (!data.postType || !data.postData) throw '数据错误';
                 const responseData = { err: 0, msg: '', data: {} };
@@ -336,7 +359,7 @@ module.exports = app => {
                 }
                 ctx.body = responseData;
             } catch (err) {
-                this.log(err);
+                ctx.log(err);
                 ctx.body = this.ajaxErrorBody(err, '数据错误');
             }
         }
@@ -345,6 +368,7 @@ module.exports = app => {
             try {
                 const renderData = {
                     jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.subProject.push),
+                    readOnly: ctx.subProject.permission.info_permission.indexOf(ctx.service.subProjPermission.PermissionConst.info.edit.value) < 0,
                 };
                 await this.layout('sub_proj/push.ejs', renderData, 'sub_proj/push_modal.ejs');
             } catch (err) {
@@ -354,11 +378,12 @@ module.exports = app => {
 
         async pushUpdate(ctx) {
             try {
+                this._checkInfoEditPermission();
                 const data = JSON.parse(ctx.request.body.data);
                 const result = await ctx.service.subProjPush.updateDatas(data);
                 ctx.body = { err: 0, msg: '', data: result };
             } catch (error) {
-                ctx.helper.log(error);
+                ctx.log(error);
                 ctx.body = this.ajaxErrorBody(error, '提交数据失败,请重试');
             }
         }
@@ -423,7 +448,7 @@ module.exports = app => {
                 const result = await ctx.service.subProjFile.delFiles(data);
                 ctx.body = { err: 0, msg: '', data: result };
             } catch(error) {
-                this.log(error);
+                ctx.log(error);
                 ctx.ajaxErrorBody(error, '删除附件失败');
             }
         }
@@ -446,6 +471,7 @@ module.exports = app => {
                 await ctx.service.projectColSet.setProjectColSet(ctx.subProject.project_id, ctx.subProject.id, colType, colSet);
                 ctx.redirect(ctx.request.header.referer);
             } catch (err) {
+                ctx.log(err);
                 ctx.redirect(ctx.request.header.referer);
             }
         }

+ 31 - 20
app/controller/sub_proj_setting_controller.js

@@ -64,7 +64,7 @@ module.exports = app => {
                 };
                 await this.layout('sp_setting/category.ejs', renderData, 'sp_setting/category_modal.ejs');
             } catch (error) {
-                console.log(error);
+                ctx.log(error);
                 ctx.redirect(`/sp/${ctx.subProject.id}/dashboard`);
             }
         }
@@ -89,7 +89,7 @@ module.exports = app => {
                 responseData.data = await ctx.service.category.addCategory(ctx.subProject, data.name, settingConst.cType.key.dropDown);
                 ctx.body = responseData;
             } catch (err) {
-                this.log(err);
+                ctx.log(err);
                 ctx.body = {err: 1, msg: err.toString(), data: null};
             }
         }
@@ -124,7 +124,7 @@ module.exports = app => {
 
                 ctx.body = responseData;
             } catch (err) {
-                this.log(err);
+                ctx.log(err);
                 ctx.body = {err: 1, msg: err.toString(), data: null};
             }
         }
@@ -145,7 +145,7 @@ module.exports = app => {
 
                 ctx.body = responseData;
             } catch (err) {
-                this.log(err);
+                ctx.log(err);
                 ctx.body = {err: 1, msg: err instanceof String ? err : '提交数据失败', data: null};
             }
         }
@@ -171,7 +171,7 @@ module.exports = app => {
 
                 ctx.body = responseData;
             } catch (err) {
-                this.log(err);
+                ctx.log(err);
                 ctx.body = {err: 1, msg: err.toString(), data: null};
             }
         }
@@ -193,7 +193,7 @@ module.exports = app => {
                 responseData.data = await ctx.service.category.getAllCategory(ctx.subProject);
                 ctx.body = responseData;
             } catch (err) {
-                this.log(err);
+                ctx.log(err);
                 ctx.body = {err: 1, msg: err.toString(), data: null};
             }
         }
@@ -224,7 +224,7 @@ module.exports = app => {
                 };
                 const total = await ctx.service.projectAccount.getSubProjectAccountCount(ctx.subProject, filter);
                 const subProjectAccountList = await ctx.service.projectAccount.getSubProjectAccountListWithPermission(ctx.subProject, filter);
-                const subProjectAllAccountList = filter.company || filter.keyword ? await ctx.service.projectAccount.getSubProjectAccountListWithPermission(ctx.subProject) : subProjectAccountList;
+                const subProjectAllAccountList = await ctx.service.projectAccount.getSubProjecAllAccountListWithPermission(ctx.subProject);
                 const subProjectUnitList = unitList.map(item => {
                     const users = subProjectAllAccountList.filter(item1 => item1.company === item.name);
                     return { name: item.name, users };
@@ -261,7 +261,7 @@ module.exports = app => {
                 };
                 await this.layout('sp_setting/user.ejs', renderData, 'sp_setting/user_modal.ejs');
             } catch (error) {
-                console.log(error);
+                ctx.log(error);
                 ctx.redirect(`/sp/${ctx.subProject.id}/dashboard`);
             }
         }
@@ -292,8 +292,11 @@ module.exports = app => {
                     const groupList = accountList.filter(item1 => item1.company === item.name);
                     return { id: item.id, name: item.name, groupList };
                 }).filter(x => { return x.groupList.length > 0; });
+                const relaBlock = ctx.service.subProjPermission.getRelaPermissionBlock(ctx.query.ptype);
                 const renderData = {
                     ptype: ctx.query.ptype,
+                    ptypeStr: relaBlock ? relaBlock.name : '',
+                    ptypeHint: relaBlock && relaBlock.hint ? relaBlock.hint : '',
                     accountGroup,
                     subProjectAccountList,
                     subProjectAllAccountList,
@@ -305,7 +308,7 @@ module.exports = app => {
                 };
                 await this.layout('sp_setting/permission.ejs', renderData, 'sp_setting/user_modal.ejs');
             } catch (error) {
-                console.log(error);
+                ctx.log(error);
                 ctx.redirect(`/sp/${ctx.subProject.id}/dashboard`);
             }
         }
@@ -336,7 +339,7 @@ module.exports = app => {
                 };
                 await this.layout('sp_setting/logs.ejs', renderData);
             } catch (error) {
-                console.log(error);
+                ctx.log(error);
                 ctx.redirect(`/sp/${ctx.subProject.id}/dashboard`);
             }
         }
@@ -353,7 +356,7 @@ module.exports = app => {
                     funSet: fun_set,
                 }, 'sp_setting/fun_modal.ejs');
             } catch (error) {
-                ctx.helper.log(error);
+                ctx.log(error);
                 ctx.redirect(`/sp/${ctx.subProject.id}/dashboard`);
             }
         }
@@ -384,6 +387,11 @@ module.exports = app => {
                 this.ctx.subProject.page_show.openMaterialSelf = data.openMaterialSelf ? 1 : 0;
                 this.ctx.subProject.page_show.openMaterialEditForAudit = data.openMaterialEditForAudit ? 1 : 0;
                 this.ctx.subProject.page_show.openStageStart = data.openStageStart ? 1 : 0;
+                this.ctx.subProject.page_show.openMaterialStageRepeat = data.openMaterialStageRepeat ? 1 : 0;
+                this.ctx.subProject.page_show.openContractExpr = data.openContractExpr ? 1 : 0;
+                this.ctx.subProject.page_show.close1stStageCheckDealParam = data.close1stStageCheckDealParam ? 1 : 0;
+                this.ctx.subProject.page_show.openMultiStageCalc = data.openMultiStageCalc ? 1 : 0;
+                this.ctx.subProject.page_show.closeWapYfSf = data.closeWapYfSf ? 1 : 0;
                 const result2 = await ctx.service.subProject.updatePageshow(ctx.subProject.id);
                 if (!result2) throw '保存数据失败';
                 if (data.addFunSet) {
@@ -395,7 +403,7 @@ module.exports = app => {
 
                 ctx.body = {err: 0, msg: '', data: null};
             } catch (error) {
-                ctx.helper.log(error);
+                ctx.log(error);
                 this.ajaxErrorBody(error, '保存数据失败');
             }
         }
@@ -403,7 +411,7 @@ module.exports = app => {
         async dataCollect(ctx) {
             try {
                 this.defaultCheck(ctx);
-                if (!ctx.session.sessionProject.page_show.openDataCollect) {
+                if (!ctx.subProject.page_show.openDataCollect) {
                     throw '该功能已关闭或无法查看';
                 }
                 ctx.subProject.data_collect_pages = ctx.subProject.data_collect_pages ? ctx.subProject.data_collect_pages.split(',') : [];
@@ -439,7 +447,7 @@ module.exports = app => {
                 }
                 await this.layout('sp_setting/datacollect.ejs', renderData, 'sp_setting/datacollect_modal.ejs');
             } catch (error) {
-                ctx.helper.log(error);
+                ctx.log(error);
                 ctx.session.postError = error.toString();
                 ctx.redirect(`/sp/${ctx.subProject.id}/dashboard`);
             }
@@ -528,7 +536,7 @@ module.exports = app => {
                 }
                 ctx.body = responseData;
             } catch (err) {
-                this.log(err);
+                ctx.log(err);
                 ctx.body = {err: 1, msg: err.toString(), data: null};
             }
         }
@@ -562,7 +570,7 @@ module.exports = app => {
                 const accountGroupList = unitList.map(item => {
                     const groupList = accountList.filter(item1 => item1.company === item.name);
                     return {groupName: item.name, groupList};
-                });
+                }).filter(x => { return x.groupList.length > 0; });
 
                 // 获取项目列表
                 const subProjects = await ctx.service.subProject.getAllDataByCondition({ where: { project_id: projectId, is_delete: 0 } });
@@ -587,7 +595,7 @@ module.exports = app => {
                 renderData.selfCategoryLevel = await this.ctx.service.projectAccount.getSelfCategoryLevel(this.ctx.session.sessionUser.accountId);
                 await this.layout('sp_setting/manage.ejs', renderData, 'sp_setting/manage_modal.ejs');
             } catch (error) {
-                ctx.helper.log(error);
+                ctx.log(error);
                 ctx.redirect(`/sp/${ctx.subProject.id}/dashboard`);
             }
         }
@@ -634,14 +642,17 @@ module.exports = app => {
                             t.permission = await ctx.service.tenderTourist.getTouristPermission(t);
                         }
                         responseData.data.tourists = tourists;
-                        responseData.data.scheduleAuditList = ctx.session.sessionProject.page_show.xxjd ? await ctx.service.scheduleAudit.getAllDataByCondition({ where: { tid: tender.id } }) : [];
-                        responseData.data.constructionAuditList = ctx.session.sessionProject.page_show.openConstruction ? await ctx.service.constructionAudit.getList(tender.id) : [];
+                        responseData.data.scheduleAuditList = await ctx.service.scheduleAudit.getAllDataByCondition({ where: { tid: tender.id } });
+                        responseData.data.contractAuditList = await ctx.service.contractAudit.getList({ tid: tender.id });
+                        responseData.data.constructionAuditList = await ctx.service.constructionAudit.getList(tender.id);
                         break;
                     case 'copy2otu':
                         if (data.userType === 'tourist') {
                             await ctx.service.tenderTourist.setOtherTender(data.tidList, data.auditList);
                         } else if (data.userType === 'schedule') {
                             await ctx.service.scheduleAudit.setOtherTender(data.tidList, data.auditList);
+                        } else if (data.userType === 'contract') {
+                            await ctx.service.contractAudit.setOtherTender(data.tidList, data.auditList);
                         } else if (data.userType === 'construction') {
                             await ctx.service.constructionAudit.setOtherTender(data.tidList, data.auditList);
                         } else {
@@ -668,7 +679,7 @@ module.exports = app => {
                 }
                 ctx.body = responseData;
             } catch (err) {
-                this.log(err);
+                ctx.log(err);
                 ctx.body = { err: 1, msg: err.toString(), data: null };
             }
         }

+ 6 - 1
app/controller/tender_controller.js

@@ -628,7 +628,7 @@ module.exports = app => {
                     renderData.accountList = accountList;
                     renderData.accountGroup = accountGroupList;
                 }
-                if (ctx.session.sessionProject.page_show.xxjd && ctx.session.sessionUser.is_admin) {
+                if (ctx.subProject.page_show.xxjd && ctx.session.sessionUser.is_admin) {
                     // 投资进度内容
                     renderData.scheduleAuditList = await ctx.service.scheduleAudit.getAllDataByCondition({ where: { tid: tender.id } });
                     renderData.scPermission = scheduleConst.permission;
@@ -1441,6 +1441,11 @@ module.exports = app => {
                         return x.ledger_status === auditConst.ledger.status.checked && !!x.lastStage;
                     });
                 }
+                if (data.filter) {
+                    responseData.data.tenders = responseData.data.tenders.filter(x => {
+                        return !x[data.filter];
+                    })
+                }
                 ctx.body = responseData;
             } catch (err) {
                 this.log(err);

+ 76 - 9
app/controller/wap_controller.js

@@ -122,6 +122,7 @@ module.exports = app => {
         async dashboard(ctx) {
             // 获取待审批的期
             const auditStages = await ctx.service.stageAudit.getAuditStageByWap(ctx.session.sessionUser.accountId);
+            const subProjects = [];
             for (const audit of auditStages) {
                 if (audit.status !== auditConst.stage.status.uncheck) {
                     const isLastage = await ctx.service.stage.isLastStage(audit.tid, audit.id);
@@ -132,23 +133,89 @@ module.exports = app => {
                 audit.end_qc_tp = ctx.helper.sum([audit.qc_tp, audit.pre_qc_tp, audit.qc_pc_tp]);
                 audit.pre_gather_tp = ctx.helper.add(audit.pre_contract_tp, audit.pre_qc_tp);
                 audit.end_gather_tp = ctx.helper.add(audit.gather_tp, audit.pre_gather_tp);
+                let sp = null;
+                if (audit.spid) {
+                    if (ctx.helper._.findIndex(subProjects, { id: audit.spid }) !== -1) {
+                        sp = ctx.helper._.find(subProjects, { id: audit.spid });
+                    } else {
+                        sp = await ctx.service.subProject.getDataById(audit.spid);
+                        subProjects.push(sp);
+                    }
+                }
+                if (sp) {
+                    const pageShow = JSON.parse(sp.page_show);
+                    audit.closeWapYfSf = pageShow.closeWapYfSf || 0;
+                } else {
+                    audit.closeWapYfSf = 0;
+                }
             }
             // 获取待审批的变更期
             const auditChanges = await ctx.service.changeAudit.getAuditChangeByWap(ctx.session.sessionUser.accountId);
             // 获取待审批的变更立项
-            let auditChangeProjects = [];
-            if (ctx.subProject.page_show.openChangeProject) {
-                auditChangeProjects = await ctx.service.changeProjectAudit.getAuditChangeProjectByWap(ctx.session.sessionUser.accountId);
+            const auditChangeProjects = [];
+            const changeProjects = await ctx.service.changeProjectAudit.getAuditChangeProjectByWap(ctx.session.sessionUser.accountId);
+            for (const cp of changeProjects) {
+                let sp = null;
+                if (cp.spid) {
+                    if (ctx.helper._.findIndex(subProjects, { id: cp.spid }) !== -1) {
+                        sp = ctx.helper._.find(subProjects, { id: cp.spid });
+                    } else {
+                        sp = await ctx.service.subProject.getDataById(cp.spid);
+                        subProjects.push(sp);
+                    }
+                }
+                if (sp) {
+                    const pageShow = JSON.parse(sp.page_show);
+                    if (pageShow.openChangeProject) {
+                        auditChangeProjects.push(cp);
+                    }
+                } else {
+                    auditChangeProjects.push(cp);
+                }
             }
             // 获取待审批的变更申请
-            let auditChangeApplys = [];
-            if (ctx.subProject.page_show.openChangeApply) {
-                auditChangeApplys = await ctx.service.changeApplyAudit.getAuditChangeApplyByWap(ctx.session.sessionUser.accountId);
+            const auditChangeApplys = [];
+            const changeApplys = await ctx.service.changeApplyAudit.getAuditChangeApplyByWap(ctx.session.sessionUser.accountId);
+            for (const ca of changeApplys) {
+                let sp = null;
+                if (ca.spid) {
+                    if (ctx.helper._.findIndex(subProjects, { id: ca.spid }) !== -1) {
+                        sp = ctx.helper._.find(subProjects, { id: ca.spid });
+                    } else {
+                        sp = await ctx.service.subProject.getDataById(ca.spid);
+                        subProjects.push(sp);
+                    }
+                }
+                if (sp) {
+                    const pageShow = JSON.parse(sp.page_show);
+                    if (pageShow.openChangeApply) {
+                        auditChangeApplys.push(ca);
+                    }
+                } else {
+                    auditChangeApplys.push(ca);
+                }
             }
             // 获取待审批的变更方案
-            let auditChangePlans = [];
-            if (ctx.subProject.page_show.openChangePlan) {
-                auditChangePlans = await ctx.service.changePlanAudit.getAuditChangePlanByWap(ctx.session.sessionUser.accountId);
+            const auditChangePlans = [];
+            const changePlans = await ctx.service.changePlanAudit.getAuditChangePlanByWap(ctx.session.sessionUser.accountId);
+            for (const cp of changePlans) {
+                let sp = null;
+                if (cp.spid) {
+                    if (ctx.helper._.findIndex(subProjects, { id: cp.spid }) !== -1) {
+                        sp = ctx.helper._.find(subProjects, { id: cp.spid });
+                    } else {
+                        sp = await ctx.service.subProject.getDataById(cp.spid);
+                        subProjects.push(sp);
+                    }
+                }
+                if (sp) {
+                    const pageShow = JSON.parse(sp.page_show);
+                    if (pageShow.openChangePlan) {
+                        auditChangePlans.push(cp);
+                    }
+                } else {
+                    auditChangePlans.push(cp);
+                }
             }
             // 获取待审批的台账修订
             const auditRevise = await ctx.service.reviseAudit.getAuditReviseByWap(ctx.session.sessionUser.accountId);

+ 42 - 0
app/lib/rm/change.js

@@ -84,6 +84,42 @@ class rptMemChange extends RptMemBase {
         return changeBills;
     }
 
+    async getChangeLedgerBillsData(showLevel) {
+        try {
+            await this.ctx.service.tender.checkTender(tid);
+
+            const billsData = await this.ctx.service.ledger.getData(this.ctx.tender.id);
+            const changeBillsData = await this.ctx.service.changeLedger.getAllDataByCondition({ where: { ccid: this.ctx.change.id } });
+            billsData.push(...changeBillsData);
+
+            const billsTree = this._getNewBillsTree();
+            billsTree.loadDatas(billsData);
+            billsTree.calculateAll();
+
+            if (this._checkFieldsExist(fields, [''])) {
+                this._calcLeafXmjRela(billsTree);
+            }
+
+            return showLevel ? billsTree.getDefaultDatasByLevel(this.ctx.tender.rpt_show_level) : billsTree.getDefaultDatas();
+        } catch(err) {
+            this.ctx.log(err);
+            return [];
+        }
+    }
+    async getChangeLedgerPosData() {
+        try {
+            const posData = await this.ctx.service.pos.getAllDataByCondition({ where: {tid: this.ctx.tender.id }});
+            const changePosData = await this.ctx.service.changePos.getAllDataByCondition({ where: { ccid: this.ctx.change.id } });
+            posData.push(...changePosData);
+            this.pos.loadDatas(posData);
+            this.pos.calculateAll();
+
+            return this.pos.getDatas();
+        } catch (err) {
+            return [];
+        }
+    }
+
     getCommonData(params, tableName, fields, customDefine, customSelect) {
         switch (tableName) {
             case 'mem_change':
@@ -100,6 +136,12 @@ class rptMemChange extends RptMemBase {
                 return [this.ctx.tender.data];
             case 'mem_tender_info':
                 return [this.ctx.tender.info];
+            case 'mem_change_ledger_bills':
+                return this.getChangeLedgerBillsData();
+            case 'mem_change_ledger_bills_filter':
+                return this.getChangeLedgerBillsData(true);
+            case 'mem_change_ledger_pos':
+                return this.getChangeLedgerPosData();
             default:
                 return [];
         }

+ 29 - 0
app/lib/rm/material.js

@@ -297,6 +297,33 @@ class rptMemChange extends RptMemBase {
         }
     }
 
+    async getMaterialExponent(fields) {
+        if (!this.ctx.material) return [];
+
+        const materials = await this.ctx.service.material.getAllDataByCondition({
+            where: {tid: this.ctx.material.tid},
+            orders: [['order', 'desc']],
+        });
+        if (materials.length === 0) return [];
+
+        let result, material;
+        material = this.ctx.material;
+        if (materials[0].order === material.order) {
+            result = await this.ctx.service.materialExponent.getAllDataByCondition({
+                where: { tid: material.tid }
+            });
+        } else {
+            const sql = 'SELECT me.id, me.tid, me.mid, mb.type, mb.symbol, mb.symbol_desc, mb.code, mb.remark, mb.in_time,' +
+                '    meh.type, meh.weight_num, meh.basic_price, meh.basic_times, meh.m_price, meh.calc_num, meh.is_summary' +
+                '  FROM ' + this.ctx.service.materialExponentHistory.tableName + ' meh ' +
+                '  LEFT JOIN ' + this.ctx.service.materialExponent.tableName + ' me ON meh.me_id = me.id ' +
+                '  WHERE meh.tid = ? And meh.mid = ?'+
+                '  ORDER By me.id';
+            result = await this.ctx.app.mysql.query(sql, [material.tid, material.id]);
+        }
+        return result;
+    }
+
     getCommonData(params, tableName, fields, customDefine, customSelect) {
         switch (tableName) {
             case 'mem_project':
@@ -323,6 +350,8 @@ class rptMemChange extends RptMemBase {
                 return this.getMaterialPos(fields);
             case 'mem_material_stage':
                 return this.getMaterialStage(fields);
+            case 'mem_material_exponent':
+                return this.getMaterialExponent(fields);
             default:
                 return [];
         }

+ 36 - 0
app/lib/rpt_data_analysis.js

@@ -2026,6 +2026,41 @@ const orderBy = {
         });
     }
 };
+const GroupBy = {
+    name: "分类汇总",
+    hint: "类似Sql语句中的Group By",
+    defaultSetting: {
+        table: 'mem_change_bills',
+        keyFields: ['cid', 'gcl_id'],
+        sumFields: ['qty'],
+        outputTable: '',
+    },
+    fun(ctx, data, fieldsKey, options, csRela) {
+        if (!options || !options.table || !options.keyFields) return;
+        if (!options.sumFields) options.sumFields = [];
+        if (!options.outputTable) options.outputTable = options.table;
+
+        const groupData = [];
+        for (const d of data[options.table]) {
+            let gd = groupData.find(x => {
+                for (const kf of options.keyFields) {
+                    if (x[kf] !== d[kf]) return false;
+                }
+                return true;
+            });
+            if (!gd) {
+                gd = JSON.parse(JSON.stringify(d));
+                groupData.push(gd);
+            } else {
+                for (const sf of options.sumFields) {
+                    gd[sf] = ctx.helper.add(gd[sf], d[sf]);
+                }
+            }
+        }
+
+        data[options.outputTable] = groupData;
+    }
+};
 
 const analysisObj = {
     changeSort,
@@ -2053,6 +2088,7 @@ const analysisObj = {
     gatherMaterialGl,
     masterCross,
     orderBy,
+    GroupBy,
 };
 const analysisDefine = (function(obj) {
     const result = [];

+ 3 - 9
app/middleware/budget_check.js

@@ -19,22 +19,16 @@ module.exports = options => {
      */
     return function* budgetCheck(next) {
         try {
-            if (!this.session.sessionProject.showBudget) {
+            if (!this.subProject.page_show.openBudget) {
                 throw '该功能已关闭或无法查看';
             }
             // 读取标段数据
             this.budget = yield this.service.budget.getCurBudget(this.subProject.budget_id);
             this.budget.name = this.subProject.name || '';
-            if (!this.budget) throw '项目不存在';
+            if (!this.budget) throw '未设置概预算标准';
             if (this.budget.pid !== this.session.sessionProject.id) throw '您无权查看该项目';
 
-            if (this.session.sessionUser.is_admin) {
-                this.budget.readOnly = false;
-            } else {
-                const bp = yield this.service.subProjPermission.getBudgetUserPermission(id);
-                if (!bp) throw '您无权查看该项目动态投资数据';
-                this.budget.readOnly = bp.budget_permission.indexOf(this.service.subProjPermission.PermissionConst.budget.edit.value) < 0;
-            }
+            this.budget.readOnly = this.subProject.permission.budget_permission.indexOf(this.service.subProjPermission.PermissionConst.budget.edit.value) < 0;
             yield next;
         } catch (err) {
             this.log(err);

+ 1 - 1
app/middleware/construction_check.js

@@ -22,7 +22,7 @@ module.exports = options => {
      */
     return function* constructionCheck(next) {
         try {
-            if (!this.session.sessionProject.page_show.openConstruction) {
+            if (!this.subProject.page_show.openConstruction) {
                 throw '该功能已关闭或无法查看';
             }
             const id = parseInt(this.params.tid);

+ 10 - 2
app/middleware/contract_check.js

@@ -23,7 +23,7 @@ module.exports = options => {
      */
     return function* contractCheck(next) {
         try {
-            if (!this.session.sessionProject.page_show.openContract) {
+            if (!this.subProject.page_show.openContract) {
                 throw '该功能已关闭或无法查看';
             }
             const tid = this.params.tid || null;
@@ -35,7 +35,15 @@ module.exports = options => {
             // 权限控制
             const cloneOptions = _.cloneDeep(options);
             cloneOptions.uid = this.session.sessionUser.accountId;
-            const result = yield this.service.contractAudit.getDataByCondition(cloneOptions);
+            let result = false;
+            if (tid) {
+                result = yield this.service.contractAudit.getDataByCondition(cloneOptions);
+            } else {
+                const contractPermission = this.subProject.permission.contract_permission;
+                if (contractPermission.length > 0 && _.intersection([3, 4, 5], contractPermission).length > 0) {
+                    result = yield this.service.subProjPermission.getContractPermission(contractPermission);
+                }
+            }
             // const result = yield this.service.contractAudit.checkPermission(options, this.session.sessionUser.accountId);
             if (!result && !this.session.sessionUser.is_admin) {
                 throw '当前账号权限不足,请联系管理员添加权限';

+ 3 - 2
app/middleware/financial_check.js

@@ -35,8 +35,9 @@ module.exports = options => {
             // }
             // this.subProject = yield this.service.subProject.getDataById(spid);
             if (this.subProject.project_id !== this.session.sessionProject.id) throw '您无权查看该项目资金监管';
-            const fAudit = yield this.service.financialAudit.getDataByCondition({ spid: this.subProject.id, uid: this.session.sessionUser.accountId });
-            if (!fAudit && !this.session.sessionUser.is_admin) throw '您无权查看该项目资金监管,请联系管理员添加';
+            const financialPermission = yield this.service.subProjPermission.getFinancailPermission(this.subProject.permission.fund_trans_permission, this.subProject.permission.fund_pay_permission);
+            // const fAudit = yield this.service.financialAudit.getDataByCondition({ spid: this.subProject.id, uid: this.session.sessionUser.accountId });
+            if (!financialPermission.transfer_show && !financialPermission.pay_show && !this.session.sessionUser.is_admin) throw '您无权查看该项目资金监管,请联系管理员添加';
             // if (!this.subProject) throw '项目不存在';
             yield next;
         } catch (err) {

+ 2 - 2
app/middleware/financial_pay_check.js

@@ -24,10 +24,10 @@ module.exports = options => {
      */
     return function* financialPayCheck(next) {
         try {
-            if (!this.session.sessionProject.page_show.openFinancial) {
+            if (!this.subProject) throw '项目不存在';
+            if (!this.subProject.page_show.openFinancial) {
                 throw '该功能已关闭或无法查看';
             }
-            if (!this.subProject) throw '项目不存在';
             const fpid = this.params.fpid;
             if (!fpid) {
                 throw '参数数据错误';

+ 1 - 1
app/middleware/material_check.js

@@ -33,7 +33,7 @@ module.exports = options => {
      */
     return function* materialCheck(next) {
         try {
-            if (!this.session.sessionProject.page_show.openMaterial) {
+            if (!this.subProject.page_show.openMaterial) {
                 throw '该功能已关闭';
             }
             // 读取标段数据

+ 1 - 1
app/middleware/payment_detail_check.js

@@ -138,7 +138,7 @@ module.exports = options => {
                 if (this.helper.isWap(this.request)) {
                     this.redirect('/wap/list');
                 } else {
-                    err === '您无权查看该内容' ? this.redirect(this.request.headers.referer) : this.redirect('/payment');
+                    err === '您无权查看该内容' ? this.redirect(this.request.headers.referer) : this.redirect('/sp/' + this.subProject.id + '/payment');
                 }
             }
         }

+ 8 - 8
app/middleware/payment_tender_check.js

@@ -23,20 +23,20 @@ module.exports = options => {
      */
     return function* paymentTenderCheck(next) {
         try {
-            if (!this.session.sessionProject.showPayment) {
+            if (!this.subProject.showPayment) {
                 throw '该功能已关闭或无法查看';
             }
-            if (!this.params.id) {
+            if (!this.params.pid) {
                 throw '当前未打开标段';
             }
-            const tender = yield this.service.paymentTender.getDataById(this.params.id);
-            if (tender.pid !== this.session.sessionProject.id) throw '您无权查看该项目';
-            const projectInfo = yield this.service.project.getDataById(this.session.sessionProject.id);
-            const modes = projectInfo.payment_setting ? JSON.parse(projectInfo.payment_setting) : _.cloneDeep(paymentConst.setting_modes);
+            const tender = yield this.service.paymentTender.getDataById(this.params.pid);
+            if (tender.pid !== this.session.sessionProject.id || tender.spid !== this.subProject.id) throw '您无权查看该项目';
+            // const projectInfo = yield this.service.project.getDataById(this.subProject.id);
+            const modes = this.subProject.payment_setting ? JSON.parse(this.subProject.payment_setting) : _.cloneDeep(paymentConst.setting_modes);
             for (const m in paymentConst.setting_modes) {
                 if (!modes[m]) modes[m] = _.cloneDeep(paymentConst.setting_modes[m]);
             }
-            const auditPermission = yield this.service.paymentPermissionAudit.getOnePermission(this.session.sessionUser.is_admin, this.session.sessionUser.accountId);
+            const auditPermission = yield this.service.subProjPermission.getPaymentPermission(this.subProject.permission.payment_permission);
             if (!auditPermission) {
                 throw '权限不足';
             }
@@ -78,7 +78,7 @@ module.exports = options => {
                     this.redirect('/wap/list');
                 } else {
                     this.postError(err, '未知错误');
-                    err === '该功能已关闭或无法查看' ? this.redirect('/dashboard') : (err === '您无权查看该内容' ? this.redirect(this.request.headers.referer) : this.redirect('/payment'));
+                    err === '该功能已关闭或无法查看' ? this.redirect('/dashboard') : (err === '您无权查看该内容' ? this.redirect(this.request.headers.referer) : this.redirect('/sp/' + this.subProject.id + '/payment'));
                 }
             }
         }

+ 0 - 56
app/middleware/session_auth.js

@@ -38,62 +38,6 @@ module.exports = options => {
             this.session.sessionProject.dataCollect = projectData.data_collect;
             this.session.sessionProject.customType = projectData.customType;
             this.session.sessionProject.funSet = projectData.fun_set ? JSON.parse(projectData.fun_set) : null;
-            // 判断是否有权限查看决策大屏
-            let showDataCollect = 0;
-            if (projectData.data_collect && this.session.sessionProject.page_show.openDataCollect) {
-                if (sessionUser.is_admin) {
-                    showDataCollect = 1;
-                } else {
-                    const auditInfo = yield this.service.datacollectAudit.getDataByCondition({ pid: projectData.id, uid: accountInfo.id });
-                    if (auditInfo) {
-                        showDataCollect = 1;
-                    } else {
-                        let companyInfo = null;
-                        if (accountInfo.company_id) {
-                            companyInfo = yield this.service.datacollectAudit.getDataByCondition({
-                                pid: projectData.id,
-                                company_id: accountInfo.company_id,
-                            });
-                        } else {
-                            const cuInfo = yield this.service.constructionUnit.getDataByCondition({
-                                pid: projectData.id,
-                                name: accountInfo.company,
-                            });
-                            if (cuInfo) {
-                                companyInfo = yield this.service.datacollectAudit.getDataByCondition({
-                                    pid: projectData.id,
-                                    company_id: cuInfo.id,
-                                });
-                                yield this.service.projectAccount.update({ company_id: cuInfo.id }, { id: accountInfo.id });
-                            }
-                        }
-                        if (companyInfo) {
-                            showDataCollect = 1;
-                        } else {
-                            const grounpInfo = yield this.service.datacollectAudit.getGroupInfo(projectData.id, accountInfo.account_group);
-                            if (grounpInfo) {
-                                showDataCollect = 1;
-                            }
-                        }
-                    }
-                }
-            }
-            this.session.sessionProject.showDataCollect = showDataCollect;
-            // 判断是否有权限查看支付审批
-            let showPayment = 0;
-            if (sessionUser.is_admin) {
-                this.session.sessionProject.showBudget = this.session.sessionProject.page_show.openBudget;
-                showPayment = this.session.sessionProject.page_show.openPayment ? 1 : 0;
-            } else {
-                this.session.sessionProject.showBudget = this.session.sessionProject.page_show.openBudget ? yield this.service.subProjPermission.showBudget(sessionUser.accountId) : false;
-                if (this.session.sessionProject.page_show.openPayment) {
-                    const auditInfo = yield this.service.paymentPermissionAudit.getDataByCondition({ pid: projectData.id, uid: accountInfo.id });
-                    if (auditInfo) {
-                        showPayment = 1;
-                    }
-                }
-            }
-            this.session.sessionProject.showPayment = showPayment;
 
             // 同步消息
             yield this.service.notify.syncNotifyData();

+ 63 - 6
app/middleware/sub_project_check.js

@@ -32,7 +32,15 @@ module.exports = options => {
             this.subProject.fun_set = this.service.subProject.getFunSet(this.subProject.fun_set);
             this.subProject.fun_rela = this.service.subProject.getFunRela(this.subProject);
 
-            const financialPermission = yield this.service.financialAudit.getPermission(this.subProject.id, this.session.sessionUser.accountId);
+            if (this.session.sessionUser.is_admin) {
+                this.subProject.readOnly = false;
+                this.subProject.permission = this.service.subProjPermission.adminPermission;
+            } else {
+                const bp = yield this.service.subProjPermission.getSubProjectUserPermission(id, this.session.sessionUser.accountId);
+                if (!bp) throw '您无权查看该项目';
+                this.subProject.permission = bp;
+            }
+            const financialPermission = yield this.service.subProjPermission.getFinancailPermission(this.subProject.permission.fund_trans_permission, this.subProject.permission.fund_pay_permission);
             if (financialPermission.transfer_show) {
                 this.subProject.financialToUrl = 'transfer';
             } else if (financialPermission.pay_show) {
@@ -41,14 +49,63 @@ module.exports = options => {
                 this.subProject.financialToUrl = 'transfer';
             }
 
+            // 判断是否有权限查看决策大屏
+            // const accountInfo = yield this.service.projectAccount.getDataById(this.session.sessionUser.accountId);
+            // const projectData = yield this.service.project.getDataById(this.session.sessionProject.id);
+            // let showDataCollect = 0;
+            // if (projectData.data_collect && this.subProject.page_show.openDataCollect) {
+            //     if (this.session.sessionUser.is_admin) {
+            //         showDataCollect = 1;
+            //     } else {
+            //         const auditInfo = yield this.service.datacollectAudit.getDataByCondition({ pid: projectData.id, uid: accountInfo.id });
+            //         if (auditInfo) {
+            //             showDataCollect = 1;
+            //         } else {
+            //             let companyInfo = null;
+            //             if (accountInfo.company_id) {
+            //                 companyInfo = yield this.service.datacollectAudit.getDataByCondition({
+            //                     pid: projectData.id,
+            //                     company_id: accountInfo.company_id,
+            //                 });
+            //             } else {
+            //                 const cuInfo = yield this.service.constructionUnit.getDataByCondition({
+            //                     pid: projectData.id,
+            //                     name: accountInfo.company,
+            //                 });
+            //                 if (cuInfo) {
+            //                     companyInfo = yield this.service.datacollectAudit.getDataByCondition({
+            //                         pid: projectData.id,
+            //                         company_id: cuInfo.id,
+            //                     });
+            //                     yield this.service.projectAccount.update({ company_id: cuInfo.id }, { id: accountInfo.id });
+            //                 }
+            //             }
+            //             if (companyInfo) {
+            //                 showDataCollect = 1;
+            //             } else {
+            //                 const grounpInfo = yield this.service.datacollectAudit.getGroupInfo(projectData.id, accountInfo.account_group);
+            //                 if (grounpInfo) {
+            //                     showDataCollect = 1;
+            //                 }
+            //             }
+            //         }
+            //     }
+            // }
+            // this.session.sessionProject.showDataCollect = showDataCollect;
+            // 判断是否有权限查看支付审批
+            let showPayment = 0;
             if (this.session.sessionUser.is_admin) {
-                this.subProject.readOnly = false;
-                this.subProject.permission = this.service.subProjPermission.adminPermission;
+                showPayment = this.subProject.page_show.openPayment ? 1 : 0;
             } else {
-                const bp = yield this.service.subProjPermission.getSubProjectUserPermission(id, this.session.sessionUser.accountId);
-                if (!bp) throw '您无权查看该项目';
-                this.subProject.permission = bp;
+                if (this.subProject.page_show.openPayment) {
+                    const auditInfo = yield this.service.subProjPermission.showPayment(this.session.sessionUser.accountId, this.subProject.id);
+                    if (auditInfo) {
+                        showPayment = 1;
+                    }
+                }
             }
+            this.subProject.showPayment = showPayment;
+
             if (this.helper.isAjax(this.request) || this.method === 'POST' || this.service.subProjPermission.checkViewPermission(this)) {
                 yield next;
             } else {

+ 3 - 2
app/middleware/tender_check.js

@@ -87,6 +87,7 @@ module.exports = options => {
             const changePlanAuditorsId = this.helper._.map(changePlanAuditors, 'aid');
             const tenderPermission = this.session.sessionUser.permission ? this.session.sessionUser.permission.tender : null;
             const isTenderTourist = yield this.service.tenderTourist.getDataByCondition({ tid: tender.id, user_id: accountId });
+            const scheduleUser = subProject.page_show.xxjd ? yield this.service.scheduleAudit.getDataByCondition({ tid: tender.id, audit_id: this.session.sessionUser.accountId }) : [];
             // 判断访问人是否具有游客身份
             tender.isTourist = isTenderTourist !== null;
             // 游客权限
@@ -98,7 +99,8 @@ module.exports = options => {
                 reviseAuditorsId.indexOf(accountId) === -1 && materialAuditorsId.indexOf(accountId) === -1 &&
                 changeProjectAuditorsId.indexOf(accountId) === -1 && changeProjectXsAuditorsId.indexOf(accountId) === -1 &&
                 changeApplyAuditorsId.indexOf(accountId) === -1 && changePlanAuditorsId.indexOf(accountId) === -1 &&
-                advanceAuditorsId.indexOf(accountId) === -1 && !this.session.sessionUser.is_admin && !isTenderTourist) {
+                advanceAuditorsId.indexOf(accountId) === -1 && !this.session.sessionUser.is_admin && !isTenderTourist &&
+                (!scheduleUser || scheduleUser.permission === scPermission.no)) {
                 throw '您无权查看该项目';
             }
 
@@ -113,7 +115,6 @@ module.exports = options => {
             if (this.session.sessionUser.accountId === tender.data.user_id) {
                 schedule_permission = scPermission.edit;
             } else {
-                const scheduleUser = yield this.service.scheduleAudit.getDataByCondition({ tid: tender.id, audit_id: this.session.sessionUser.accountId });
                 if (scheduleUser) {
                     if (tender.isTourist && scheduleUser.permission === scPermission.no) {
                         schedule_permission = scPermission.show;

+ 459 - 460
app/public/js/change_revise.js

@@ -4458,517 +4458,516 @@ $(document).ready(() => {
             }, 100);
         });
     })('a[name=showLevel]', billsSheet);
-    if (openRevise) {
-        const dataChecker = DataChecker({
-            checkUrl: window.location.pathname + '/check',
-            completeData: function (data) {
-                pos.updateDatas({update: data.source.pos});
-                const loadResult = billsTree.loadPostData({update: data.source.bills});
-                billsTreeSpreadObj.refreshTree(billsSheet, loadResult);
-                posSpreadObj.loadCurPosData();
-                for (const e of data.error) {
-                    e.serialNo = billsTree.getNodeIndex(billsTree.getItems(e.ledger_id)) + 1;
-                }
-            },
-            errorList: errorList,
-        });
 
-        $('#ledger-check2').click(() => {
-            ledgerCheck2({
-                ledgerTree: billsTree,
-                ledgerPos: pos,
+    const dataChecker = DataChecker({
+        checkUrl: window.location.pathname + '/check',
+        completeData: function (data) {
+            pos.updateDatas({update: data.source.pos});
+            const loadResult = billsTree.loadPostData({update: data.source.bills});
+            billsTreeSpreadObj.refreshTree(billsSheet, loadResult);
+            posSpreadObj.loadCurPosData();
+            for (const e of data.error) {
+                e.serialNo = billsTree.getNodeIndex(billsTree.getItems(e.ledger_id)) + 1;
+            }
+        },
+        errorList: errorList,
+    });
+
+    $('#ledger-check2').click(() => {
+        ledgerCheck2({
+            ledgerTree: billsTree,
+            ledgerPos: pos,
+            checkList: checkList,
+            decimal: decimal,
+            checkOption: checkOption,
+        }).then(result => {
+            check2Viewing({
+                extra: ZhCalc.div(billsTree.datas.length + pos.datas.length, 10000, 0),
+                randomWait: true,
+                prefix: 'check2-',
+                checks: result,
                 checkList: checkList,
-                decimal: decimal,
-                checkOption: checkOption,
-            }).then(result => {
-                check2Viewing({
-                    extra: ZhCalc.div(billsTree.datas.length + pos.datas.length, 10000, 0),
-                    randomWait: true,
-                    prefix: 'check2-',
-                    checks: result,
-                    checkList: checkList,
-                });
             });
         });
-        if (isYb) {
-            let compilationList = [];
-            $('#get-dsk-btn').click(function () {
-                // 判断是否已绑定dsk用户
-                postData('/profile/dsk/api', {type: 'hadbind'}, function (result) {
-                    if (result === 1) {
-                        $('#error-dsk .modal-body').find('h5').eq(0).show();
-                        $('#error-dsk .modal-body').find('h5').eq(1).hide();
-                        $('#error-dsk').modal('show');
-                        $('#error-dsk .modal-footer').find('a').eq(0).text('绑定手机');
-                    } else if (result === 2) {
-                        $('#error-dsk .modal-body').find('h5').eq(1).show();
-                        $('#error-dsk .modal-body').find('h5').eq(0).hide();
-                        $('#error-dsk').modal('show');
-                        $('#error-dsk .modal-footer').find('a').eq(0).text('绑定账号');
-                    } else {
-                        postData('/profile/dsk/api', {
-                            type: 'compilation',
-                            getProject: 1,
-                            compilationId: getLocalCache(dskCompilation)
-                        }, function (result) {
-                            let html = '';
-                            for (const data of result.compilation) {
-                                if (data.ID !== '5c66649650da2d000d8d37ba' && data.ID !== '5b52b027fd3bb0000b257cf8') {
-                                    html += `<option value="${data.ID}" ${result.select_compilation === data.ID ? 'selected' : ''}>${data.name}</option>`;
-                                }
+    });
+    if (isYb) {
+        let compilationList = [];
+        $('#get-dsk-btn').click(function () {
+            // 判断是否已绑定dsk用户
+            postData('/profile/dsk/api', {type: 'hadbind'}, function (result) {
+                if (result === 1) {
+                    $('#error-dsk .modal-body').find('h5').eq(0).show();
+                    $('#error-dsk .modal-body').find('h5').eq(1).hide();
+                    $('#error-dsk').modal('show');
+                    $('#error-dsk .modal-footer').find('a').eq(0).text('绑定手机');
+                } else if (result === 2) {
+                    $('#error-dsk .modal-body').find('h5').eq(1).show();
+                    $('#error-dsk .modal-body').find('h5').eq(0).hide();
+                    $('#error-dsk').modal('show');
+                    $('#error-dsk .modal-footer').find('a').eq(0).text('绑定账号');
+                } else {
+                    postData('/profile/dsk/api', {
+                        type: 'compilation',
+                        getProject: 1,
+                        compilationId: getLocalCache(dskCompilation)
+                    }, function (result) {
+                        let html = '';
+                        for (const data of result.compilation) {
+                            if (data.ID !== '5c66649650da2d000d8d37ba' && data.ID !== '5b52b027fd3bb0000b257cf8') {
+                                html += `<option value="${data.ID}" ${result.select_compilation === data.ID ? 'selected' : ''}>${data.name}</option>`;
                             }
-                            dskAccountData = result.dskAccountData;
-                            compilationList = result.compilation;
-                            console.log(compilationList);
-                            $('#dsk-compilation-list').html(html);
-                            $('#add-dsk').modal('show');
-                            setLocalCache(dskCompilation, result.select_compilation);
-                            makeDskProjectSjsHtml(result.project);
-                        });
-                    }
-                })
-            });
-            $('#get-dsk-bills-btn').click(function () {
-                const projectInfo = _.find(dskProjects, {pid: dskAccountData.select_project ? dskAccountData.select_project : null});
-                changeDskProjectTree(projectInfo, dskAccountData.select_tree ? dskAccountData.select_tree : null);
-            });
+                        }
+                        dskAccountData = result.dskAccountData;
+                        compilationList = result.compilation;
+                        console.log(compilationList);
+                        $('#dsk-compilation-list').html(html);
+                        $('#add-dsk').modal('show');
+                        setLocalCache(dskCompilation, result.select_compilation);
+                        makeDskProjectSjsHtml(result.project);
+                    });
+                }
+            })
+        });
+        $('#get-dsk-bills-btn').click(function () {
+            const projectInfo = _.find(dskProjects, {pid: dskAccountData.select_project ? dskAccountData.select_project : null});
+            changeDskProjectTree(projectInfo, dskAccountData.select_tree ? dskAccountData.select_tree : null);
+        });
 
-            $('body').on('change', '#dsk-compilation-list', function () {
-                const compilationId = $(this).val();
-                setLocalCache(dskCompilation, compilationId);
-                dskProjectSpreadObj.refreshSourceTree();
-            });
+        $('body').on('change', '#dsk-compilation-list', function () {
+            const compilationId = $(this).val();
+            setLocalCache(dskCompilation, compilationId);
+            dskProjectSpreadObj.refreshSourceTree();
+        });
 
-            $('.hide-dsk-modal').click(function () {
-                $('#error-dsk').modal('hide');
-            });
-            let dp = false;
-            let gsObj = {
-                setting: null,
+        $('.hide-dsk-modal').click(function () {
+            $('#error-dsk').modal('hide');
+        });
+        let dp = false;
+        let gsObj = {
+            setting: null,
 
-                gsSheet: null,
-                grSheet: null,
+            gsSheet: null,
+            grSheet: null,
 
-                tenderSourceTree: null,
-                grArray: dskProjects ? dskProjects : [],
-                orgSelect: null,
-            };
+            tenderSourceTree: null,
+            grArray: dskProjects ? dskProjects : [],
+            orgSelect: null,
+        };
 
-            function makeDskProjectSjsHtml(datas) {
-                if (!dp) {
-                    initDskProjectTree();
-                    dp = true;
-                }
-                gsObj.tenderSourceTree = dskProject2Tree.convert(datas);
-                SpreadJsObj.loadSheetData(gsObj.gsSheet, SpreadJsObj.DataType.Tree, gsObj.tenderSourceTree);
-                SpreadJsObj.loadSheetData(gsObj.grSheet, SpreadJsObj.DataType.Data, gsObj.grArray);
-                if (datas.length === 0) {
-                    $('#show-project-0').show();
-                } else {
-                    $('#show-project-0').hide();
-                }
+        function makeDskProjectSjsHtml(datas) {
+            if (!dp) {
+                initDskProjectTree();
+                dp = true;
+            }
+            gsObj.tenderSourceTree = dskProject2Tree.convert(datas);
+            SpreadJsObj.loadSheetData(gsObj.gsSheet, SpreadJsObj.DataType.Tree, gsObj.tenderSourceTree);
+            SpreadJsObj.loadSheetData(gsObj.grSheet, SpreadJsObj.DataType.Data, gsObj.grArray);
+            if (datas.length === 0) {
+                $('#show-project-0').show();
+            } else {
+                $('#show-project-0').hide();
             }
+        }
 
-            const dskProjectSpreadObj = {
-                _addTender: function (tender) {
-                    const gr = gsObj.grArray.find(function (x) {
-                        return x.pid === tender.pid;
-                    });
-                    const c_id = getLocalCache(dskCompilation);
-                    const t = {
-                        pid: tender.pid,
-                        name: tender.name,
-                        compilationId: c_id,
-                        compilationName: _.find(compilationList, {ID: c_id}).name
-                    };
-                    if (!gr) gsObj.grArray.push(t);
-                    return t;
-                },
-                _removeTender: function (tender) {
-                    const gri = gsObj.grArray.findIndex(function (x, i, arr) {
-                        return x.pid === tender.pid;
+        const dskProjectSpreadObj = {
+            _addTender: function (tender) {
+                const gr = gsObj.grArray.find(function (x) {
+                    return x.pid === tender.pid;
+                });
+                const c_id = getLocalCache(dskCompilation);
+                const t = {
+                    pid: tender.pid,
+                    name: tender.name,
+                    compilationId: c_id,
+                    compilationName: _.find(compilationList, {ID: c_id}).name
+                };
+                if (!gr) gsObj.grArray.push(t);
+                return t;
+            },
+            _removeTender: function (tender) {
+                const gri = gsObj.grArray.findIndex(function (x, i, arr) {
+                    return x.pid === tender.pid;
+                });
+                if (gri >= 0) gsObj.grArray.splice(gri, 1);
+            },
+            reloadResultData: function () {
+                SpreadJsObj.reLoadSheetData(gsObj.grSheet);
+            },
+            refreshSourceTree: function () {
+                const c_id = getLocalCache(dskCompilation);
+                if (c_id) {
+                    postData('/profile/dsk/api', {type: 'project', compilationId: c_id}, function (result) {
+                        makeDskProjectSjsHtml(result);
                     });
-                    if (gri >= 0) gsObj.grArray.splice(gri, 1);
-                },
-                reloadResultData: function () {
-                    SpreadJsObj.reLoadSheetData(gsObj.grSheet);
-                },
-                refreshSourceTree: function () {
-                    const c_id = getLocalCache(dskCompilation);
-                    if (c_id) {
-                        postData('/profile/dsk/api', {type: 'project', compilationId: c_id}, function (result) {
-                            makeDskProjectSjsHtml(result);
-                        });
-                    }
-                },
-                gsButtonClicked: function (e, info) {
-                    if (!info.sheet.zh_setting) return;
+                }
+            },
+            gsButtonClicked: function (e, info) {
+                if (!info.sheet.zh_setting) return;
 
-                    const col = info.sheet.zh_setting.cols[info.col];
-                    if (col.field !== 'selected') return;
+                const col = info.sheet.zh_setting.cols[info.col];
+                if (col.field !== 'selected') return;
 
-                    const node = SpreadJsObj.getSelectObject(info.sheet);
-                    node.selected = !node.selected;
-                    if (node.children && node.children.length > 0) {
-                        const posterity = gsObj.tenderSourceTree.getPosterity(node);
-                        for (const p of posterity) {
-                            p.selected = node.selected;
-                            if ((!p.children || p.children.length === 0) && p.type === 2) {
-                                if (p.selected) {
-                                    dskProjectSpreadObj._addTender(p);
-                                } else {
-                                    dskProjectSpreadObj._removeTender(p);
-                                }
+                const node = SpreadJsObj.getSelectObject(info.sheet);
+                node.selected = !node.selected;
+                if (node.children && node.children.length > 0) {
+                    const posterity = gsObj.tenderSourceTree.getPosterity(node);
+                    for (const p of posterity) {
+                        p.selected = node.selected;
+                        if ((!p.children || p.children.length === 0) && p.type === 2) {
+                            if (p.selected) {
+                                dskProjectSpreadObj._addTender(p);
+                            } else {
+                                dskProjectSpreadObj._removeTender(p);
                             }
                         }
-                        SpreadJsObj.reLoadRowData(info.sheet, info.row, posterity.length + 1);
-                    } else if (node.type === 2) {
-                        if (node.selected) {
-                            dskProjectSpreadObj._addTender(node);
-                        } else {
-                            dskProjectSpreadObj._removeTender(node);
-                        }
-                        SpreadJsObj.reLoadRowData(info.sheet, info.row, 1);
                     }
-                    dskProjectSpreadObj.reloadResultData();
-                },
-                deleteGr: function () {
-                    if (gsObj.grArray.length === 0) return;
-                    if (gsObj.grSheet.getSelections().length === 0) return;
-                    const selections = gsObj.grSheet.getSelections();
-                    const sel = selections ? selections[0] : gsObj.grSheet.getSelections()[0];
-                    const row = sel && sel.row !== undefined ? sel.row : -1;
-                    if (row === -1 || sel.row + sel.rowCount > gsObj.grArray.length) {
-                        return false;
-                    }
-                    const delList = [];
-                    for (let r = 0; r < sel.rowCount; r++) {
-                        const select = gsObj.grArray[row + r];
-                        delList.push(select);
+                    SpreadJsObj.reLoadRowData(info.sheet, info.row, posterity.length + 1);
+                } else if (node.type === 2) {
+                    if (node.selected) {
+                        dskProjectSpreadObj._addTender(node);
+                    } else {
+                        dskProjectSpreadObj._removeTender(node);
                     }
-                    _.pullAll(gsObj.grArray, delList);
-                    dskProjectSpreadObj.reloadResultData();
-                    dskProjectSpreadObj.refreshSourceTree();
-                },
+                    SpreadJsObj.reLoadRowData(info.sheet, info.row, 1);
+                }
+                dskProjectSpreadObj.reloadResultData();
+            },
+            deleteGr: function () {
+                if (gsObj.grArray.length === 0) return;
+                if (gsObj.grSheet.getSelections().length === 0) return;
+                const selections = gsObj.grSheet.getSelections();
+                const sel = selections ? selections[0] : gsObj.grSheet.getSelections()[0];
+                const row = sel && sel.row !== undefined ? sel.row : -1;
+                if (row === -1 || sel.row + sel.rowCount > gsObj.grArray.length) {
+                    return false;
+                }
+                const delList = [];
+                for (let r = 0; r < sel.rowCount; r++) {
+                    const select = gsObj.grArray[row + r];
+                    delList.push(select);
+                }
+                _.pullAll(gsObj.grArray, delList);
+                dskProjectSpreadObj.reloadResultData();
+                dskProjectSpreadObj.refreshSourceTree();
+            },
+        };
+
+        const initDskProjectTree = function () {
+            const gsSpread = SpreadJsObj.createNewSpread($('#dsk-project-source-spread')[0]);
+            gsObj.gsSheet = gsSpread.getActiveSheet();
+            const gsSpreadSetting = {
+                cols: [
+                    {
+                        title: '选择',
+                        field: 'selected',
+                        hAlign: 1,
+                        width: 40,
+                        formatter: '@',
+                        cellType: 'checkbox',
+                        readOnly: true,
+                    },
+                    {
+                        title: '名称',
+                        field: 'name',
+                        hAlign: 0,
+                        width: 400,
+                        formatter: '@',
+                        readOnly: true,
+                        folderCell: true,
+                        cellType: 'tree'
+                    },
+                ],
+                emptyRows: 0,
+                headRows: 1,
+                headRowHeight: [32],
+                defaultRowHeight: 21,
+                headerFont: '12px 微软雅黑',
+                font: '12px 微软雅黑',
+                headColWidth: [0],
+                selectedBackColor: '#fffacd',
             };
+            SpreadJsObj.initSheet(gsObj.gsSheet, gsSpreadSetting);
+            gsSpread.bind(spreadNS.Events.ButtonClicked, dskProjectSpreadObj.gsButtonClicked);
 
-            const initDskProjectTree = function () {
-                const gsSpread = SpreadJsObj.createNewSpread($('#dsk-project-source-spread')[0]);
-                gsObj.gsSheet = gsSpread.getActiveSheet();
-                const gsSpreadSetting = {
-                    cols: [
-                        {
-                            title: '选择',
-                            field: 'selected',
-                            hAlign: 1,
-                            width: 40,
-                            formatter: '@',
-                            cellType: 'checkbox',
-                            readOnly: true,
-                        },
-                        {
-                            title: '名称',
-                            field: 'name',
-                            hAlign: 0,
-                            width: 400,
-                            formatter: '@',
-                            readOnly: true,
-                            folderCell: true,
-                            cellType: 'tree'
-                        },
-                    ],
-                    emptyRows: 0,
-                    headRows: 1,
-                    headRowHeight: [32],
-                    defaultRowHeight: 21,
-                    headerFont: '12px 微软雅黑',
-                    font: '12px 微软雅黑',
-                    headColWidth: [0],
-                    selectedBackColor: '#fffacd',
-                };
-                SpreadJsObj.initSheet(gsObj.gsSheet, gsSpreadSetting);
-                gsSpread.bind(spreadNS.Events.ButtonClicked, dskProjectSpreadObj.gsButtonClicked);
+            const grSpread = SpreadJsObj.createNewSpread($('#dsk-project-result-spread')[0]);
+            gsObj.grSheet = grSpread.getActiveSheet();
+            const grSpreadSetting = {
+                cols: [
+                    {
+                        title: '名称',
+                        colSpan: '1',
+                        rowSpan: '1',
+                        field: 'name',
+                        hAlign: 0,
+                        width: 250,
+                        formatter: '@',
+                        readOnly: true,
+                        cellType: 'ellipsisAutoTip',
+                        scrollHeightClass: '.modal-height-500'
+                    },
+                    {
+                        title: '所属编办',
+                        colSpan: '1',
+                        rowSpan: '1',
+                        field: 'compilationName',
+                        hAlign: 0,
+                        width: 150,
+                        formatter: '@',
+                        readOnly: true
+                    },
+                ],
+                emptyRows: 0,
+                headRows: 1,
+                headRowHeight: [32],
+                defaultRowHeight: 21,
+                headerFont: '12px 微软雅黑',
+                font: '12px 微软雅黑',
+                headColWidth: []
+            };
+            SpreadJsObj.initSheet(gsObj.grSheet, grSpreadSetting);
 
-                const grSpread = SpreadJsObj.createNewSpread($('#dsk-project-result-spread')[0]);
-                gsObj.grSheet = grSpread.getActiveSheet();
-                const grSpreadSetting = {
-                    cols: [
-                        {
-                            title: '名称',
-                            colSpan: '1',
-                            rowSpan: '1',
-                            field: 'name',
-                            hAlign: 0,
-                            width: 250,
-                            formatter: '@',
-                            readOnly: true,
-                            cellType: 'ellipsisAutoTip',
-                            scrollHeightClass: '.modal-height-500'
-                        },
-                        {
-                            title: '所属编办',
-                            colSpan: '1',
-                            rowSpan: '1',
-                            field: 'compilationName',
-                            hAlign: 0,
-                            width: 150,
-                            formatter: '@',
-                            readOnly: true
+            // 右键删除已选项目
+            const gsContextMenuOptions = {
+                selector: '#dsk-project-result-spread',
+                build: function ($trigger, e) {
+                    const target = SpreadJsObj.safeRightClickSelection($trigger, e, grSpread);
+                    return target.hitTestType === spreadNS.SheetArea.viewport || target.hitTestType === spreadNS.SheetArea.rowHeader;
+                },
+                items: {
+                    delete: {
+                        name: '删除',
+                        icon: 'fa-remove',
+                        callback: function (key, opt) {
+                            dskProjectSpreadObj.deleteGr();
                         },
-                    ],
-                    emptyRows: 0,
-                    headRows: 1,
-                    headRowHeight: [32],
-                    defaultRowHeight: 21,
-                    headerFont: '12px 微软雅黑',
-                    font: '12px 微软雅黑',
-                    headColWidth: []
-                };
-                SpreadJsObj.initSheet(gsObj.grSheet, grSpreadSetting);
-
-                // 右键删除已选项目
-                const gsContextMenuOptions = {
-                    selector: '#dsk-project-result-spread',
-                    build: function ($trigger, e) {
-                        const target = SpreadJsObj.safeRightClickSelection($trigger, e, grSpread);
-                        return target.hitTestType === spreadNS.SheetArea.viewport || target.hitTestType === spreadNS.SheetArea.rowHeader;
-                    },
-                    items: {
-                        delete: {
-                            name: '删除',
-                            icon: 'fa-remove',
-                            callback: function (key, opt) {
-                                dskProjectSpreadObj.deleteGr();
-                            },
-                            disabled: function (key, opt) {
-                                const selection = gsObj.grSheet.getSelections();
-                                const sel = selection ? selection[0] : gsObj.grSheet.getSelections()[0];
-                                const row = sel && sel.row !== undefined ? sel.row : -1;
-                                if (row === -1 || sel.row + sel.rowCount > gsObj.grArray.length) {
-                                    return true;
-                                }
-                                return false;
+                        disabled: function (key, opt) {
+                            const selection = gsObj.grSheet.getSelections();
+                            const sel = selection ? selection[0] : gsObj.grSheet.getSelections()[0];
+                            const row = sel && sel.row !== undefined ? sel.row : -1;
+                            if (row === -1 || sel.row + sel.rowCount > gsObj.grArray.length) {
+                                return true;
                             }
-                        },
-                    }
-                };
-                $.contextMenu(gsContextMenuOptions);
-
-                $('#add-dsk').bind('shown.bs.modal', function () {
-                    if (gsSpread) gsSpread.refresh();
-                    if (grSpread) grSpread.refresh();
-                });
+                            return false;
+                        }
+                    },
+                }
             };
+            $.contextMenu(gsContextMenuOptions);
 
-            const dskProject2Tree = (function () {
-                const treeSetting = {
-                    id: 'tmt_id',
-                    pid: 'tmt_pid',
-                    order: 'seq',
-                    level: 'level',
-                    rootId: '-1',
-                    fullPath: 'full_path',
-                };
-                const tenderTree = createNewPathTree('gather', treeSetting);
+            $('#add-dsk').bind('shown.bs.modal', function () {
+                if (gsSpread) gsSpread.refresh();
+                if (grSpread) grSpread.refresh();
+            });
+        };
 
-                function setChildrenNode(node, files, tenders) {
-                    const children = _.filter(files, {parentID: node.pid});
-                    const tenderChildren = _.filter(tenders, {parentID: node.pid});
-                    const checkChildren = _.orderBy([...children, ...tenderChildren], ['seq', 'asc']);
-                    for (const c of checkChildren) {
-                        // if (c.type === 1 && _.filter(files, { parentID: c.ID }).length === 0 && _.filter(tenders, { parentID: c.ID }).length === 0) {
-                        //     // 判断文件夹下有无东西,没有就不插入
-                        //     continue;
-                        // }
-                        const child = {
-                            pid: c.ID,
-                            parentID: c.parentID,
-                            name: c.name,
-                            type: c.type,
-                            selected: _.findIndex(gsObj.grArray, {pid: c.ID}) >= 0
-                        };
-                        tenderTree.addNode(child, node);
-                        if (c.type === 1) setChildrenNode(child, files, tenders);
-                    }
+        const dskProject2Tree = (function () {
+            const treeSetting = {
+                id: 'tmt_id',
+                pid: 'tmt_pid',
+                order: 'seq',
+                level: 'level',
+                rootId: '-1',
+                fullPath: 'full_path',
+            };
+            const tenderTree = createNewPathTree('gather', treeSetting);
+
+            function setChildrenNode(node, files, tenders) {
+                const children = _.filter(files, {parentID: node.pid});
+                const tenderChildren = _.filter(tenders, {parentID: node.pid});
+                const checkChildren = _.orderBy([...children, ...tenderChildren], ['seq', 'asc']);
+                for (const c of checkChildren) {
+                    // if (c.type === 1 && _.filter(files, { parentID: c.ID }).length === 0 && _.filter(tenders, { parentID: c.ID }).length === 0) {
+                    //     // 判断文件夹下有无东西,没有就不插入
+                    //     continue;
+                    // }
+                    const child = {
+                        pid: c.ID,
+                        parentID: c.parentID,
+                        name: c.name,
+                        type: c.type,
+                        selected: _.findIndex(gsObj.grArray, {pid: c.ID}) >= 0
+                    };
+                    tenderTree.addNode(child, node);
+                    if (c.type === 1) setChildrenNode(child, files, tenders);
                 }
+            }
 
-                function convert(projects) {
-                    tenderTree.clearDatas();
-                    const result = filterFolders(projects);
-                    const topLevel = _.orderBy(_.filter(result, {parentID: '-1'}), ['seq', 'asc']);
-                    const files = _.filter(result, {type: 1});
-                    const tenders = _.filter(result, {type: 2});
+            function convert(projects) {
+                tenderTree.clearDatas();
+                const result = filterFolders(projects);
+                const topLevel = _.orderBy(_.filter(result, {parentID: '-1'}), ['seq', 'asc']);
+                const files = _.filter(result, {type: 1});
+                const tenders = _.filter(result, {type: 2});
 
-                    for (const t of topLevel) {
-                        const node = {
-                            pid: t.ID,
-                            parentID: t.parentID,
-                            name: t.name,
-                            type: t.type,
-                            selected: t.type === 2 ? _.findIndex(gsObj.grArray, {pid: t.ID}) >= 0 : false,
-                        };
-                        tenderTree.addNode(node, null);
-                        if (t.type === 1) setChildrenNode(node, files, tenders);
-                    }
-                    tenderTree.sortTreeNode(true);
-                    return tenderTree;
+                for (const t of topLevel) {
+                    const node = {
+                        pid: t.ID,
+                        parentID: t.parentID,
+                        name: t.name,
+                        type: t.type,
+                        selected: t.type === 2 ? _.findIndex(gsObj.grArray, {pid: t.ID}) >= 0 : false,
+                    };
+                    tenderTree.addNode(node, null);
+                    if (t.type === 1) setChildrenNode(node, files, tenders);
                 }
+                tenderTree.sortTreeNode(true);
+                return tenderTree;
+            }
 
-                return {tenderTree, convert}
-            })();
+            return {tenderTree, convert}
+        })();
 
-            function filterFolders(data) {
-                // 构建ID到节点的映射
-                const idMap = data.reduce((map, node) => {
-                    map[node.ID] = node;
-                    return map;
-                }, {});
+        function filterFolders(data) {
+            // 构建ID到节点的映射
+            const idMap = data.reduce((map, node) => {
+                map[node.ID] = node;
+                return map;
+            }, {});
 
-                // 建立父子关系映射
-                const parentMap = data.reduce((map, node) => {
-                    if (node.parentID !== '-1') {
-                        if (!map[node.parentID]) {
-                            map[node.parentID] = [];
-                        }
-                        map[node.parentID].push(node.ID);
+            // 建立父子关系映射
+            const parentMap = data.reduce((map, node) => {
+                if (node.parentID !== '-1') {
+                    if (!map[node.parentID]) {
+                        map[node.parentID] = [];
                     }
-                    return map;
-                }, {});
+                    map[node.parentID].push(node.ID);
+                }
+                return map;
+            }, {});
 
-                // 检查节点及其子节点是否包含清单(type=1)
-                const hasChecklist = (id) => {
-                    const node = idMap[id];
-                    if (node.type === 2) {
-                        return true;
-                    }
-                    if (!parentMap[id]) {
-                        return false;
-                    }
-                    return parentMap[id].some(childID => hasChecklist(childID));
-                };
+            // 检查节点及其子节点是否包含清单(type=1)
+            const hasChecklist = (id) => {
+                const node = idMap[id];
+                if (node.type === 2) {
+                    return true;
+                }
+                if (!parentMap[id]) {
+                    return false;
+                }
+                return parentMap[id].some(childID => hasChecklist(childID));
+            };
 
-                // 过滤节点
-                const filteredIDs = new Set();
-                data.forEach(node => {
-                    if (node.type === 2 || hasChecklist(node.ID)) {
-                        let currentID = node.ID;
-                        while (currentID !== '-1') {
-                            filteredIDs.add(currentID);
-                            currentID = idMap[currentID].parentID;
-                        }
+            // 过滤节点
+            const filteredIDs = new Set();
+            data.forEach(node => {
+                if (node.type === 2 || hasChecklist(node.ID)) {
+                    let currentID = node.ID;
+                    while (currentID !== '-1') {
+                        filteredIDs.add(currentID);
+                        currentID = idMap[currentID].parentID;
                     }
-                });
+                }
+            });
 
-                // 返回过滤后的数据
-                return data.filter(node => filteredIDs.has(node.ID));
-            }
+            // 返回过滤后的数据
+            return data.filter(node => filteredIDs.has(node.ID));
+        }
 
-            $('#set-dsk-project').click(function () {
-                postData('/profile/dsk/api', {
-                    type: 'save_projects',
-                    tid: window.location.pathname.split('/')[2],
-                    project_list: gsObj.grArray
-                }, function (result) {
-                    // dskAccountData.select_project = result;
-                    dskProjects = gsObj.grArray;
-                    if (!dskAccountData.select_project || dskAccountData.select_project !== result) {
-                        dskAccountData.select_project = result;
-                        changeDskProject(result);
-                        dskBills.spread.refresh();
-                    }
-                    setDskProjectSelect(gsObj.grArray);
-                    $('#add-dsk').modal('hide');
-                });
-            });
-            $('#add-dsk').on('hide.bs.modal', function () {
-                $('#autoTip').hide();
+        $('#set-dsk-project').click(function () {
+            postData('/profile/dsk/api', {
+                type: 'save_projects',
+                tid: window.location.pathname.split('/')[2],
+                project_list: gsObj.grArray
+            }, function (result) {
+                // dskAccountData.select_project = result;
+                dskProjects = gsObj.grArray;
+                if (!dskAccountData.select_project || dskAccountData.select_project !== result) {
+                    dskAccountData.select_project = result;
+                    changeDskProject(result);
+                    dskBills.spread.refresh();
+                }
+                setDskProjectSelect(gsObj.grArray);
+                $('#add-dsk').modal('hide');
             });
+        });
+        $('#add-dsk').on('hide.bs.modal', function () {
+            $('#autoTip').hide();
+        });
 
-            function setDskProjectSelect(projects) {
-                let html = '';
-                for (const project of projects) {
-                    html += `<option value="${project.pid}" ${project.pid === dskAccountData.select_project ? 'selected' : ''}>${project.name}</option>`;
-                }
-                $('#change-dsk-project').html(html);
+        function setDskProjectSelect(projects) {
+            let html = '';
+            for (const project of projects) {
+                html += `<option value="${project.pid}" ${project.pid === dskAccountData.select_project ? 'selected' : ''}>${project.name}</option>`;
             }
+            $('#change-dsk-project').html(html);
+        }
 
-            // 选中所有新增部位/清单
-            $('#add-all-revise').click(function() {
-                const this_cid = window.location.pathname.split('/')[4];
-                makeGclGatherData();
-                postData('/tender/' + window.location.pathname.split('/')[2] + '/change/' + window.location.pathname.split('/')[4] + '/information/save', {
-                    type: 'get-revise-list',
-                }, function (result) {
-                    const addDatas = [];
-                    for (const ggd in gclGatherData) {
-                        gclGatherData[ggd].code = gclGatherData[ggd].b_code;
-                        let hadcid = 0;
-                        for (const xmj of gclGatherData[ggd].leafXmjs) {
-                            const changeLedger = _.find(result.changeLedgerList, {id: xmj.gcl_id});
-                            const changePos = _.find(result.changePosList, {id: xmj.mx_id, lid: xmj.gcl_id});
-                            if (changeLedger || changePos) {
-                                xmj.cid = 1;
-                                xmj.ccid = changePos ? changePos.ccid : changeLedger ? changeLedger.ccid : 0;
-                                hadcid = 1;
-                            }
+        // 选中所有新增部位/清单
+        $('#add-all-revise').click(function() {
+            const this_cid = window.location.pathname.split('/')[4];
+            makeGclGatherData();
+            postData('/tender/' + window.location.pathname.split('/')[2] + '/change/' + window.location.pathname.split('/')[4] + '/information/save', {
+                type: 'get-revise-list',
+            }, function (result) {
+                const addDatas = [];
+                for (const ggd in gclGatherData) {
+                    gclGatherData[ggd].code = gclGatherData[ggd].b_code;
+                    let hadcid = 0;
+                    for (const xmj of gclGatherData[ggd].leafXmjs) {
+                        const changeLedger = _.find(result.changeLedgerList, {id: xmj.gcl_id});
+                        const changePos = _.find(result.changePosList, {id: xmj.mx_id, lid: xmj.gcl_id});
+                        if (changeLedger || changePos) {
+                            xmj.cid = 1;
+                            xmj.ccid = changePos ? changePos.ccid : changeLedger ? changeLedger.ccid : 0;
+                            hadcid = 1;
                         }
-                        if (hadcid !== 0) gclGatherData[ggd].cid = 1;
                     }
-                    for (const gclInfo of _.filter(gclGatherData, {cid: 1})) {
-                        const leafXmjs = _.filter(gclInfo.leafXmjs, {ccid: this_cid});
-                        if (leafXmjs.length > 0) {
-                            gclInfo.is_change = 1;
-                            for (const xmj of leafXmjs) {
-                                if (_.findIndex(changeList, function (item) {
-                                    return item.gcl_id === xmj.gcl_id && item.mx_id === (xmj.mx_id || '');
-                                }) === -1) {
-                                    addDatas.push({
-                                        lid: xmj.gcl_id,
-                                        code: gclInfo.code,
-                                        name: gclInfo.name || '',
-                                        unit: gclInfo.unit || '',
-                                        unit_price: gclInfo.unit_price,
-                                        oamount: xmj.quantity,
-                                        oamount2: xmj.quantity,
-                                        bwmx: xmj.bwmx || xmj.jldy || '',
-                                        xmj_code: xmj.code || '',
-                                        xmj_jldy: xmj.jldy || '',
-                                        xmj_dwgc: xmj.dwgc || '',
-                                        xmj_fbgc: xmj.fbgc || '',
-                                        xmj_fxgc: xmj.fxgc || '',
-                                        gcl_id: xmj.gcl_id,
-                                        mx_id: xmj.mx_id || '',
-                                    });
-                                }
+                    if (hadcid !== 0) gclGatherData[ggd].cid = 1;
+                }
+                for (const gclInfo of _.filter(gclGatherData, {cid: 1})) {
+                    const leafXmjs = _.filter(gclInfo.leafXmjs, {ccid: this_cid});
+                    if (leafXmjs.length > 0) {
+                        gclInfo.is_change = 1;
+                        for (const xmj of leafXmjs) {
+                            if (_.findIndex(changeList, function (item) {
+                                return item.gcl_id === xmj.gcl_id && item.mx_id === (xmj.mx_id || '');
+                            }) === -1) {
+                                addDatas.push({
+                                    lid: xmj.gcl_id,
+                                    code: gclInfo.code,
+                                    name: gclInfo.name || '',
+                                    unit: gclInfo.unit || '',
+                                    unit_price: gclInfo.unit_price,
+                                    oamount: xmj.quantity,
+                                    oamount2: xmj.quantity,
+                                    bwmx: xmj.bwmx || xmj.jldy || '',
+                                    xmj_code: xmj.code || '',
+                                    xmj_jldy: xmj.jldy || '',
+                                    xmj_dwgc: xmj.dwgc || '',
+                                    xmj_fbgc: xmj.fbgc || '',
+                                    xmj_fxgc: xmj.fxgc || '',
+                                    gcl_id: xmj.gcl_id,
+                                    mx_id: xmj.mx_id || '',
+                                });
                             }
                         }
                     }
-                    console.log(addDatas);
-                    if (addDatas.length > 0) {
-                        // 更新至服务器
-                        postData('/tender/' + window.location.pathname.split('/')[2] + '/change/' + window.location.pathname.split('/')[4] + '/information/save', {
-                            type: 'add-change-list',
-                            postData: addDatas,
-                        }, function (result) {
-                            toastr.success('已新增当前变更令新增的所有部位/清单');
-                            changeList = result.changeList;
-                            const sortData = SpreadJsObj.getSortData(billsSheet);
-                            const billsNodes = _.filter(sortData, function (item) {
-                                return _.findIndex(addDatas, {gcl_id: item.id}) !== -1;
-                            });
-                            for (const billsNode of billsNodes) {
-                                billsNode.is_change = 1;
-                            }
-                            const loadResult = { update: billsNodes };
-                            billsTreeSpreadObj.refreshTree(billsSheet, loadResult);
-                            posSpreadObj.loadCurPosData();
+                }
+                console.log(addDatas);
+                if (addDatas.length > 0) {
+                    // 更新至服务器
+                    postData('/tender/' + window.location.pathname.split('/')[2] + '/change/' + window.location.pathname.split('/')[4] + '/information/save', {
+                        type: 'add-change-list',
+                        postData: addDatas,
+                    }, function (result) {
+                        toastr.success('已新增当前变更令新增的所有部位/清单');
+                        changeList = result.changeList;
+                        const sortData = SpreadJsObj.getSortData(billsSheet);
+                        const billsNodes = _.filter(sortData, function (item) {
+                            return _.findIndex(addDatas, {gcl_id: item.id}) !== -1;
                         });
-                    } else {
-                        toastr.warning('未存在当前变更令新增的部位/清单');
-                    }
-                });
+                        for (const billsNode of billsNodes) {
+                            billsNode.is_change = 1;
+                        }
+                        const loadResult = { update: billsNodes };
+                        billsTreeSpreadObj.refreshTree(billsSheet, loadResult);
+                        posSpreadObj.loadCurPosData();
+                    });
+                } else {
+                    toastr.warning('未存在当前变更令新增的部位/清单');
+                }
             });
-        }
+        });
     }
 });
 function findDecimal(unit) {

+ 5 - 4
app/public/js/contract_detail.js

@@ -61,10 +61,10 @@ $(document).ready(function() {
     };
     if (contract_type === contractConst.type.expenses) {
         contractSpreadSetting.cols.push({title: '累计应付', colSpan: '1', rowSpan: '2', field: 'yf_price', hAlign: 2, width: 120, formatter: '@', readOnly: true});
-        contractSpreadSetting.cols.push({title: '支付进度', colSpan: '1', rowSpan: '2', formatter: '@', readOnly: true, field: 'stackedBar', hAlign: 0, width: 200, cellType: 'stackedBar', stackedBarCover: true, bc_type: 'grid', getTip: getStackedBarTip});
+        contractSpreadSetting.cols.push({title: '支付进度', colSpan: '1', rowSpan: '2', formatter: '@', readOnly: true, field: 'stackedBar', hAlign: 0, width: 200, cellType: 'stackedBar', stackedBarCover: true, bc_type: 'grid', getTip: getStackedBarTip, hintNum: true});
     } else if (contract_type === contractConst.type.income) {
         contractSpreadSetting.cols.push({title: '累计应回', colSpan: '1', rowSpan: '2', field: 'yf_price', hAlign: 2, width: 120, formatter: '@', readOnly: true});
-        contractSpreadSetting.cols.push({title: '回款进度', colSpan: '1', rowSpan: '2', formatter: '@', readOnly: true, field: 'stackedBar', hAlign: 0, width: 200, cellType: 'stackedBar', stackedBarCover: true, bc_type: 'grid', getTip: getStackedBarTip});
+        contractSpreadSetting.cols.push({title: '回款进度', colSpan: '1', rowSpan: '2', formatter: '@', readOnly: true, field: 'stackedBar', hAlign: 0, width: 200, cellType: 'stackedBar', stackedBarCover: true, bc_type: 'grid', getTip: getStackedBarTip, hintNum: true});
     }
     contractSpreadSetting.cols.push({title: '合同状态', colSpan: '1', rowSpan: '2', field: 'status', hAlign: 1, width: 100, formatter: '@', readOnly: true, getValue:'getValue.status', foreColor:'foreColor.status'});
     contractSpreadSetting.cols.push({title: '备注', colSpan: '1', rowSpan: '2', field: 'remark', hAlign: 0, width: 120, formatter: '@', readOnly: 'readOnly.code', cellType: 'ellipsisAutoTip', scrollHeightClass: '.sjs-height-1'});
@@ -96,7 +96,7 @@ $(document).ready(function() {
             node.stackedBar = [];
             node.stackedBarTips = [];
             for (const cf of calcField) {
-                node.stackedBar.push({ color: calcFieldColor[cf], percent: ZhCalc.div(node[cf], base), field: cf });
+                node.stackedBar.push({ color: calcFieldColor[cf], percent: ZhCalc.div(node[cf], base), field: cf, hintNum: cf === 'yf_price' });
                 node.stackedBarTips.push(`${calcFieldCaption[cf]}: ${node[cf] || 0}`);
             }
         }
@@ -523,6 +523,7 @@ $(document).ready(function() {
                         if (sel) {
                             sheet.setSelection(sel.row, sel.col, 1, sel.colCount);
                         }
+                        contractTreeSpreadObj.setContract(sheet);
                         self.refreshOperationValid(sheet);
                     });
                 }, '确认删除「当前合同或节点及子项」?');
@@ -1683,7 +1684,7 @@ $(document).ready(function() {
                     contractTreeAudits = result;
                     sqTreeSpreadObj.setTreeAudits(sqSheet);
                 });
-            }, '确认除「当前节点授权用户」?');
+            }, '确认除「当前节点授权用户」?');
         });
     }
 

+ 1 - 1
app/public/js/contract_index.js

@@ -34,7 +34,7 @@ $(document).ready(function() {
                     }
                 } else {
                     html.push(`<span class="text-muted mr-2">${tree.isLastSibling(node) ? '└' : '├'}</span>`);
-                    html.push('<a href="/sp/' + spid +'/contract/'+ node.id +'/detail" name="name" id="' + node.id + '">', node.name, '</a>');
+                    html.push('<a href="/sp/' + spid +'/contract/tender/'+ node.id +'/detail" name="name" id="' + node.id + '">', node.name, '</a>');
                 }
                 html.push('</td>');
                 // 创建时间

+ 1 - 1
app/public/js/contract_tender.js

@@ -56,7 +56,7 @@ const tenderListSpec = (function(){
         if (is_admin) {
             html.push('<td style="width: 10%" class="text-center">');
             if (!node.cid) {
-                html.push(`<a href="javascript:void(0);" data-toggle="modal" data-stid="${node.id}" class="btn btn-sm btn-primary get-audits"> 成员管理</a>`);
+                html.push(`<a href="javascript:void(0);" data-toggle="modal" data-stid="${node.id}" class="btn btn-sm btn-outline-primary get-audits"> 成员管理</a>`);
                 // html.push('<a href="#empower" data-toggle="modal" data-target="#empower" class="btn btn-sm btn-primary ">成员管理</a>');
             }
             html.push('</td>');

+ 17 - 1
app/public/js/filing_manage.js

@@ -108,7 +108,7 @@ $(document).ready(function() {
         async setCurFiling(node) {
             filingObj.curFiling = node;
         }
-        moveFiling(node, tree_pid, tree_order) {
+        moveFiling(node, tree_pid, tree_order, callback) {
             if (node.file_count > 0) return;
             if (tree_pid === node.source_node.tree_pid && tree_order === node.source_node.tree_order) return;
 
@@ -131,6 +131,7 @@ $(document).ready(function() {
                         }
                     }
                 }
+                if (callback) callback();
             });
         }
         batchUpdateFiling(data, callback) {
@@ -229,6 +230,21 @@ $(document).ready(function() {
         if (!filingObj.curFiling) return;
         filingObj.addChildFiling(filingObj.curFiling);
     });
+    $('#up-move').click(() => {
+        if (!filingObj.curFiling) return;
+        if (!filingObj.curFiling.getPreNode()) return;
+        filingObj.moveFiling(filingObj.curFiling, filingObj.curFiling.tree_pid, filingObj.curFiling.source_node.tree_order - 1, function () {
+            filingObj.filingTree.moveNode(filingObj.curFiling.getPreNode(), filingObj.curFiling, "prev", true);
+        });
+    });
+    $('#down-move').click(() => {
+        if (!filingObj.curFiling) return;
+        if (!filingObj.curFiling.getNextNode()) return;
+        filingObj.moveFiling(filingObj.curFiling, filingObj.curFiling.tree_pid, filingObj.curFiling.source_node.tree_order + 1, function () {
+            filingObj.filingTree.moveNode(filingObj.curFiling.getNextNode(), filingObj.curFiling, "next", true);
+        });
+    });
+
     $('#del-filing-ok').click(() => {
         if (!filingObj.deleteNode) return;
         filingObj.delFiling(filingObj.deleteNode, function() {

+ 6 - 5
app/public/js/ledger.js

@@ -4578,6 +4578,7 @@ $(document).ready(function() {
                 {title: '合价', colSpan: '1', rowSpan: '1', field: 'total_price', hAlign: 2, width: 80, type: 'Number'},
                 {title: '图号', colSpan: '1', rowSpan: '1', field: 'drawing_code', hAlign: 0, width: 100, formatter: '@'},
                 {title: '备注', colSpan: '1', rowSpan: '1', field: 'memo', hAlign: 0, width: 100, formatter: '@'},
+                {title: '项目特征', colSpan: '1', rowSpan: '1', field: 'features', hAlign: 0, width: 120, formatter: '@', wordWrap: true },
             ],
             headRows: 1,
             headRowHeight: [32],
@@ -4594,7 +4595,7 @@ $(document).ready(function() {
                 unit_price: node.unit_price, quantity: node[qtyF], total_price: node[tpF],
                 deal_qty: node.deal_qty, deal_tp: node.deal_tp,
                 dgn_qty1: node.dgn_qty1, dgn_qty2: node.dgn_qty2,
-                drawing_code: node.drawing_code, memo: node.memo
+                drawing_code: node.drawing_code, memo: node.memo, features: node.features,
             });
             const posRange = pos.getLedgerPos(node.id);
             if (posRange && posRange.length > 0) {
@@ -4676,7 +4677,7 @@ $(document).ready(function() {
     });
     // 上传附件
     $('#upload-file-btn').click(function () {
-        // if (curAuditor && curAuditor.aid !== cur_uid) {
+        // if (curAuditor && curAuditor.aid !== userID) {
         //     return toastr.error('当前操作没有权限!');
         // }
         const node = SpreadJsObj.getSelectObject(ledgerSpread.getActiveSheet());
@@ -4737,7 +4738,7 @@ $(document).ready(function() {
           $('#show-att tr').eq(2).children('td').eq(1).text(att.in_time);
           $('#show-att tr').eq(3).children('td').text(att.remark);
           // 附件uid等于当前用户id, 附件上传本人
-          if (parseInt(cur_uid) === att.uid) {
+          if (parseInt(userID) === att.uid) {
               $('#btn-att').show();
               const showDel = tender.ledger_status === auditConst.status.checked ? Boolean(att.extra_upload) : true;
               if (showDel) $('#btn-att a').eq(3).show();
@@ -5059,7 +5060,7 @@ function getNodeList(node) {
   for(const att of attData) {
       if (node === att.lid) {
           // html += '<tr><td><a href="javascript:void(0)" file-id="'+ att.id +'">'+ att.filename + att.fileext +'</a></td><td>'+ att.username +'</td></tr>';
-          const delHtml = deleteFilePermission && parseInt(cur_uid) === att.uid
+          const delHtml = deleteFilePermission && parseInt(userID) === att.uid
               ? `<a class="ml-1 text-danger" href="javascript:void(0)" name="att-delete" file-id="${att.id}"><i class="fa fa-close" title="删除"></i></a>`
               : '';
           html += `<tr>
@@ -5097,7 +5098,7 @@ function getAllList(currPageNum = 1) {
   currPageFileData = currPageAttData;
   let html = '';
   for(const att of currPageAttData) {
-      const delHtml = deleteFilePermission && parseInt(cur_uid) === att.uid
+      const delHtml = deleteFilePermission && parseInt(userID) === att.uid
           ? `<a class="ml-1 text-danger" href="javascript:void(0)" name="att-delete" file-id="${att.id}"><i class="fa fa-close" title="删除"></i></a>`
           : '';
       html += `<tr>

+ 5 - 5
app/public/js/payment_detail.js

@@ -82,7 +82,7 @@ $(function () {
             tesRpttData.items[0].interact_cells[index].link = link !== '' ? parseInt(link) : '';
             tesRpttData.items[0].interact_cells[index].Value = tesRpttData.items[0].interact_cells[index].Prefix ? tesRpttData.items[0].interact_cells[index].Prefix + chineseNum : chineseNum;
             const _self = $(this);
-            postData('/payment/' + tenderId + '/detail/' + detailId + '/save', { type: 'update_rpt', report_json: tesRpttData }, function (result) {
+            postData('/sp/' + spid + '/payment/' + tenderId + '/detail/' + detailId + '/save', { type: 'update_rpt', report_json: tesRpttData }, function (result) {
                 $('#rpt-form input[data-index="'+ index +'"]').val(chineseNum);
                 auditRptPrintHelper.showPage();
                 _self.parents('.show-link-dropdown').dropdown('toggle');
@@ -180,7 +180,7 @@ $(function () {
             if (content_index !== -1) {
                 tesRpttData.items[0].signature_audit_cells[content_index].Value = rptAudit.signature_msg.content ? rptAudit.signature_msg.content : '';
             }
-            postData('/payment/' + tenderId + '/detail/' + detailId + '/save', { type: 'update_sign', signature_msg: rptAudit.signature_msg }, function (result) {
+            postData('/sp/' + spid + '/payment/' + tenderId + '/detail/' + detailId + '/save', { type: 'update_sign', signature_msg: rptAudit.signature_msg }, function (result) {
                 auditRptPrintHelper.showPage();
                 // 更新签署进度图表展示
                 $('#rpt_audit_sign td').eq(3).html(rptAudit.signature_msg.sign_path !== null ? '<i class="fa fa-check text-success"></i>' : '');
@@ -201,7 +201,7 @@ $(function () {
         clearTimeout(timer);
         timer = setTimeout(() => {
             tesRpttData.items[0].interact_cells[index].Value = tesRpttData.items[0].interact_cells[index].Prefix ? tesRpttData.items[0].interact_cells[index].Prefix + newVal : newVal;
-            postData('/payment/' + tenderId + '/detail/' + detailId + '/save', { type: 'update_rpt', report_json: tesRpttData }, function (result) {
+            postData('/sp/' + spid + '/payment/' + tenderId + '/detail/' + detailId + '/save', { type: 'update_rpt', report_json: tesRpttData }, function (result) {
                 auditRptPrintHelper.showPage();
             });
             clearTimeout(timer);
@@ -290,7 +290,7 @@ $(function () {
 
     $('#attList').on('click', '.file-atn', function() {
         const id = $(this).attr('f-id');
-        postData(`/payment/${tenderId}/detail/${detailId}/file/${id}/download`, {}, (data) => {
+        postData(`'/sp/${spid}/payment/${tenderId}/detail/${detailId}/file/${id}/download`, {}, (data) => {
             const { filepath } = data;
             $('#file-upload').attr('href', filepath);
             $('#file-upload')[0].click();
@@ -372,7 +372,7 @@ function getAllList(currPageNum = 1) {
         <td><a href="${att.filepath}" target="_blank" class="pl-0 col-11 att-file-name" file-id=${att.id}>${att.filename}${att.fileext}</a></td>
         <td>${moment(att.upload_time).format("YYYY-MM-DD HH:mm:ss")}<br>${bytesToSize(att.filesize)}</td>
         <td>
-            <a href="/payment/${tenderId}/detail/${detailId}/file/${att.id}/download" class="mr-2" title="下载"><span class="fa fa-download text-primary"></span></a>`
+            <a href="'/sp/${spid}/payment/${tenderId}/detail/${detailId}/file/${att.id}/download" class="mr-2" title="下载"><span class="fa fa-download text-primary"></span></a>`
         html += (att.uid === accountId && (detailStatus === auditConst.status.checked ? Boolean(att.extra_upload) : true)) ?
             `<a href="javascript:void(0)" class="mr-2 delete-file" data-attid="${att.id}" title="删除附件"><span class="fa fa-trash text-danger"></span></a>` : '';
         html += `</td>`;

+ 3 - 3
app/public/js/payment_detail_audit.js

@@ -113,7 +113,7 @@ $(document).ready(function () {
     $('dl').on('click', 'dd', function () {
         const id = parseInt($(this).data('id'));
         if (id) {
-            postData('/payment/' + tenderId + '/detail/' + detailId + '/save', { type: 'add_audit', auditorId: id }, (datas) => {
+            postData('/sp/' + spid + '/payment/' + tenderId + '/detail/' + detailId + '/save', { type: 'add_audit', auditorId: id }, (datas) => {
                 remakeShenpiHtml(datas);
             });
         }
@@ -121,7 +121,7 @@ $(document).ready(function () {
     // 删除审批人
     $('body').on('click', '#auditors li>a', function () {
         const li = $(this).parent();
-        postData('/payment/' + tenderId + '/detail/' + detailId + '/save', { type: 'del_audit', auditorId: parseInt(li.attr('auditorId')) }, (result) => {
+        postData('/sp/' + spid + '/payment/' + tenderId + '/detail/' + detailId + '/save', { type: 'del_audit', auditorId: parseInt(li.attr('auditorId')) }, (result) => {
             li.remove();
             for (const rst of result) {
                 const aLi = $('li[auditorId=' + rst.aid + ']');
@@ -194,7 +194,7 @@ $(document).ready(function () {
 
     // 同步报表角色
     $('#follow_rpt_audit_btn').click(function () {
-        postData('/payment/' + tenderId + '/detail/' + detailId + '/save', { type: 'follow_rpt_audit' }, (datas) => {
+        postData('/sp/' + spid + '/payment/' + tenderId + '/detail/' + detailId + '/save', { type: 'follow_rpt_audit' }, (datas) => {
             toastr.success('同步成功');
             remakeShenpiHtml(datas);
         });

+ 10 - 10
app/public/js/payment_index.js

@@ -12,7 +12,7 @@ $(function () {
         const tenders = tenderList;
         function makeTenderTree(parent) {
             if (parent.is_leaf) {
-                parent.children = _.filter(tenders, { folder_id: parent.id });
+                parent.children = _.filter(tenders, { folder_id: parent.folder_id });
                 if (parent.children.length > 0) {
                     parent.is_tender = true;
                     parent.children.forEach((value, index) => {
@@ -20,7 +20,7 @@ $(function () {
                     });
                 }
             } else {
-                const children = _.filter(folders, { parent_id: parent.id });
+                const children = _.filter(folders, { parent_id: parent.folder_id });
                 parent.children = children;
                 if (children.length > 0) {
                     for (const c of children) {
@@ -50,7 +50,7 @@ $(function () {
             html.push(arr.indexOf(node) === arr.length - 1 ? '└' : '├');
             html.push('</span>');
             //html.push('<a href="/tender/' + node.id + '">', node[c.field], '</a>');
-            html.push('<a href="/payment/'+ node.id +'/list" target="_blank" id="' + node.id + '">', node.name, '</a>');
+            html.push('<a href="/sp/'+ spid +'/payment/'+ node.id +'/list" target="_blank" id="' + node.id + '">', node.name, '</a>');
             if (node.have_notice){
                 html.push('<i class="fa fa-bell text-warning float-right mt-1" data-toggle="tooltip" data-placement="bottom" title="待处理提醒"></i>');
             }
@@ -63,7 +63,7 @@ $(function () {
         // 审批流程
         html.push('<td style="width: 15%" class="text-center">');
         if (node.parent_id === undefined && auditPermission.admin && (node.uid === uid || is_admin)) {
-            html.push('<a href="/payment/'+ node.id +'/process" target="_blank">设置</a>');
+            html.push('<a href="/sp/'+ spid +'/payment/'+ node.id +'/process" target="_blank">设置</a>');
         }
         html.push('</td>');
         // 操作
@@ -88,7 +88,7 @@ $(function () {
                 html.push('<div class="dropdown-divider"></div>\n');
             }
             if (auditPermission.admin && node.parent_id !== undefined && !node.is_tender) {
-                html.push('<a class="dropdown-item show_new_folder_btn" href="#add-folder" data-toggle="modal" data-target="#add-folder" data-parentName="'+ node.name +'" data-parentId="'+ node.id +'"><i class="fa fa-folder-o mr-2"></i>新建子文件夹</a>\n');
+                html.push('<a class="dropdown-item show_new_folder_btn" href="#add-folder" data-toggle="modal" data-target="#add-folder" data-parentName="'+ node.name +'" data-parentId="'+ node.folder_id +'"><i class="fa fa-folder-o mr-2"></i>新建子文件夹</a>\n');
             }
             if (auditPermission.admin && node.is_leaf) {
                 html.push('<a class="dropdown-item show_new_tender_btn" href="javascript:void(0);"><i class="fa fa-folder-o mr-2"></i>新建标段</a>\n');
@@ -137,7 +137,7 @@ $(function () {
     }
 
     // 首次加载展示目录
-    postData('/payment/list/load', {}, function (result) {
+    postData('/sp/'+ spid +'/payment/list/load', {}, function (result) {
         allFolders = result.folderList;
         allTenders = result.tenderList;
         makeList(result.folderList, result.tenderList);
@@ -181,7 +181,7 @@ $(function () {
         if (name === false) {
             return;
         }
-        postData('/payment/save', { type: 'add-folder', parentId: parseInt($('#parent_id').val()), name }, function (result) {
+        postData('/sp/'+ spid +'/payment/save', { type: 'add-folder', parentId: parseInt($('#parent_id').val()), name }, function (result) {
             allFolders = result.folderList;
             allTenders = result.tenderList;
             makeList(result.folderList, result.tenderList);
@@ -214,7 +214,7 @@ $(function () {
             id: $('#edit_name_id').val(),
             name,
         };
-        postData('/payment/save', { type: 'edit-name', postData: data }, function (result) {
+        postData('/sp/'+ spid +'/payment/save', { type: 'edit-name', postData: data }, function (result) {
             allFolders = result.folderList;
             allTenders = result.tenderList;
             makeList(result.folderList, result.tenderList);
@@ -258,7 +258,7 @@ $(function () {
         if (name === false) {
             return;
         }
-        postData('/payment/save', { type: 'add-tender', folderId: parseInt($('#add_tender_folder_id').val()), name }, function (result) {
+        postData('/sp/'+ spid +'/payment/save', { type: 'add-tender', folderId: parseInt($('#add_tender_folder_id').val()), name }, function (result) {
             allFolders = result.folderList;
             allTenders = result.tenderList;
             makeList(result.folderList, result.tenderList);
@@ -287,7 +287,7 @@ $(function () {
             type: $('#del_type').val(),
             id: $('#del_id').val(),
         };
-        postData('/payment/save', { type: 'del', postData: data }, function (result) {
+        postData('/sp/'+ spid +'/payment/save', { type: 'del', postData: data }, function (result) {
             allFolders = result.folderList;
             allTenders = result.tenderList;
             makeList(result.folderList, result.tenderList);

+ 7 - 7
app/public/js/payment_list.js

@@ -119,7 +119,7 @@ $(function () {
                 return;
             }
         }
-        postData('/payment/' + tenderId + '/list/' + trId + '/save', { type: 'rpt_audit', rpt_audit }, function (result) {
+        postData('/sp/' + spid + '/payment/' + tenderId + '/list/' + trId + '/save', { type: 'rpt_audit', rpt_audit }, function (result) {
             toastr.success('设置成功');
             old_rpt_audit = _.cloneDeep(rpt_audit);
             if (result.is_first) {
@@ -154,11 +154,11 @@ $(function () {
             return false;
         }
         console.log($('#add-detail-time').val());
-        postData('/payment/' + tenderId + '/list/' + trId + '/save', { type: 'add-detail', code: _.trim($('#add-detail-code').val()), s_time: $('#add-detail-time').val() }, function (result) {
+        postData('/sp/' + spid + '/payment/' + tenderId + '/list/' + trId + '/save', { type: 'add-detail', code: _.trim($('#add-detail-code').val()), s_time: $('#add-detail-time').val() }, function (result) {
             if (result.type) {
-                window.location.href = '/payment/' + tenderId + '/safe/' + result.id + '/bills';
+                window.location.href = '/sp/' + spid + '/payment/' + tenderId + '/safe/' + result.id + '/bills';
             } else {
-                window.location.href = '/payment/' + tenderId + '/detail/' + result.id;
+                window.location.href = '/sp/' + spid + '/payment/' + tenderId + '/detail/' + result.id;
             }
         });
     });
@@ -168,7 +168,7 @@ $(function () {
         const data = {
             order: $(this).attr('m-order'),
         };
-        postData('/payment/' + tenderId + '/list/'+ trId + '/auditors', data, function (result) {
+        postData('/sp/' + spid + '/payment/' + tenderId + '/list/'+ trId + '/auditors', data, function (result) {
             const { auditHistory, auditors, user } = result
             let auditorsHTML = ''
             let historyHTML = ''
@@ -440,7 +440,7 @@ $(function () {
         }
         init() {
             const self = this;
-            postData(`/list/load2`, { type: 'all'}, result => {
+            postData(`/sp/${spid}/list/load2`, { type: 'all'}, result => {
                 self.selectTree = Tender2Tree.convert(category, result.tenders);
                 SpreadJsObj.loadSheetData(this.sheet, SpreadJsObj.DataType.Tree, this.selectTree);
             });
@@ -634,7 +634,7 @@ function postAttr () {
         },
     };
     const tenderId = window.location.pathname.split('/')[2];
-    postData('/payment/info/save', { type: 'info', postData: { id: tenderId, info} }, function (data) {
+    postData('/sp/' + spid + '/payment/info/save', { type: 'info', postData: { id: tenderId, info} }, function (data) {
         property.deal_info = info.deal_info;
         property.construction_unit = info.construction_unit;
         property.tech_param = info.tech_param;

+ 9 - 9
app/public/js/payment_process.js

@@ -19,7 +19,7 @@ $(function () {
                 name: $(this).attr('data-name'),
             }); //向数组中添加元素
         });
-        postData('/payment/' + tenderId + '/process/save', { type: 'add-rpt', rpt_list: checkArray }, function (result) {
+        postData('/sp/' + spid + '/payment/' + tenderId + '/process/save', { type: 'add-rpt', rpt_list: checkArray }, function (result) {
             const html = [];
             for (const data of result) {
                 html.push(`<tr data-id="${data.id}">\n`);
@@ -204,7 +204,7 @@ $(function () {
             tr_id: trInfo.id,
             status: trInfo.sp_status,
         };
-        postData('/payment/' + tenderId + '/process/save', prop, function (data) {
+        postData('/sp/' + spid + '/payment/' + tenderId + '/process/save', prop, function (data) {
             setLcShowHtml(trInfo.sp_status, trInfo.id, data);
         });
     }
@@ -241,7 +241,7 @@ $(function () {
             tr_id: this_tr_id,
             status: this_status
         };
-        postData('/payment/' + tenderId + '/process/save', prop, function (data) {
+        postData('/sp/' + spid + '/payment/' + tenderId + '/process/save', prop, function (data) {
             const trInfo = _.find(tenderRptList, { id: this_tr_id });
             trInfo.sp_status = this_status;
             setLcShowHtml(this_status, this_tr_id, data);
@@ -279,7 +279,7 @@ $(function () {
             type: 'add-audit',
         };
         const _self = $(this);
-        postData('/payment/' + tenderId + '/process/save', prop, function (data) {
+        postData('/sp/' + spid + '/payment/' + tenderId + '/process/save', prop, function (data) {
             if (this_status === sp_status.gdspl) {
                 _self.parents('ul').append('<li class="pl-3"><a href="javascript:void(0);" class="add-audit"><i class="fa fa-plus"></i> 添加流程</a></li>');
             }
@@ -317,7 +317,7 @@ $(function () {
             uid: id,
             type: 'update-report',
         };
-        postData('/payment/' + tenderId + '/process/save', prop, function (result) {
+        postData('/sp/' + spid + '/payment/' + tenderId + '/process/save', prop, function (result) {
             tenderRptList = result.list;
             if (result.updateRows) {
                 toastr.warning('上报人不能同时作为审批人,审批流已移除 ' + user.name);
@@ -347,7 +347,7 @@ $(function () {
         //     type: 'add-audit',
         // };
         // const _self = $(this);
-        // postData('/payment/' + tenderId + '/process/save', prop, function (data) {
+        // postData('/sp/' + spid + '/payment/' + tenderId + '/process/save', prop, function (data) {
         //     if (this_status === sp_status.gdspl) {
         //         _self.parents('ul').append('<li class="pl-3"><a href="javascript:void(0);" class="add-audit"><i class="fa fa-plus"></i> 添加流程</a></li>');
         //     }
@@ -380,7 +380,7 @@ $(function () {
             type: 'del-audit',
         };
         const _self = $(this);
-        postData('/payment/' + tenderId + '/process/save', prop, function (data) {
+        postData('/sp/' + spid + '/payment/' + tenderId + '/process/save', prop, function (data) {
             if (this_status === sp_status.gdspl) {
                 const _selflc = _self.parents('.lc-show');
                 _self.parents('li').remove();
@@ -553,7 +553,7 @@ $(function () {
                 $(this).parents('.form-group').siblings('.alert-warning').text(spt.name + ':' + spt.msg);
                 // 拼接post json
                 const prop = { type: 'change-status', tr_id, status };
-                postData('/payment/' + tenderId + '/process/save', prop, function (data) {
+                postData('/sp/' + spid + '/payment/' + tenderId + '/process/save', prop, function (data) {
                     self.rptInfo.sp_status = status;
                     self.rptInfo.auditData = data;
                     self.setLcShowHtml();
@@ -584,7 +584,7 @@ $(function () {
 
                 const prop = { status, tr_id, audit_id: id, type: 'add-audit' };
                 const _self = $(this);
-                postData('/payment/' + tenderId + '/process/save', prop, function (data) {
+                postData('/sp/' + spid + '/payment/' + tenderId + '/process/save', prop, function (data) {
                     if (status === sp_status.gdspl) {
                         _self.parents('ul').append('<li class="pl-3"><a href="javascript:void(0);" class="add-audit"><i class="fa fa-plus"></i> 添加流程</a></li>');
                     }

+ 1 - 1
app/public/js/payment_setting.js

@@ -2,7 +2,7 @@ $(function () {
     autoFlashHeight();
 
     $('#mode-form input').on('click', function () {
-        postData('/payment/save', { type: 'mode-setting', mode_type: $(this).attr('mode-type'), checked: $(this).is(':checked') }, function (result) {
+        postData('/sp/' + spid + '/payment/save', { type: 'mode-setting', mode_type: $(this).attr('mode-type'), checked: $(this).is(':checked') }, function (result) {
             toastr.success('已配置');
         })
     });

+ 94 - 23
app/public/js/setting_manage.js

@@ -132,6 +132,14 @@ $(document).ready(() => {
     const cHeader = getObjHeight($(".c-header"));
     $('.tab-content').height($(window).height()-cHeader-90+53-46);
 
+    const tabTypes = {
+        tourist: '游客',
+        schedule: '投资进度',
+        contract: '合同管理',
+        construction: '施工日志',
+    };
+    const tabTypeKeys = ['tourist', 'schedule', 'contract', 'construction'];
+
     $('body').on('click', '.c-body .tender-info', function () {
         $('.c-body .tender-info').removeClass('table-warning');
         $(this).addClass('table-warning');
@@ -151,6 +159,7 @@ $(document).ready(() => {
             setShenpiHtml(result.shenpi, result.tender, result.revising);
             setTouristHtml(result.tourists);
             setScheduleHtml(result.scheduleAuditList);
+            setContractHtml(result.contractAuditList);
             setConstructionHtml(result.constructionAuditList);
             resetAddUserHtml();
         });
@@ -162,6 +171,7 @@ $(document).ready(() => {
 
 
     $('body').on('click', '.nav .nav-link', function () {
+        $('#contract-tip').hide();
         if ($(this).attr('href') === '#splc') {
             $('#user-set').hide();
         } else {
@@ -170,6 +180,9 @@ $(document).ready(() => {
                 $('#add_user_dropdownMenuButton').attr('data-type', 'tourist');
             } else if ($(this).attr('href') === '#tzpro') {
                 $('#add_user_dropdownMenuButton').attr('data-type', 'schedule');
+            } else if ($(this).attr('href') === '#htgl') {
+                $('#add_user_dropdownMenuButton').attr('data-type', 'contract');
+                $('#contract-tip').show();
             } else if ($(this).attr('href') === '#sgrz') {
                 $('#add_user_dropdownMenuButton').attr('data-type', 'construction');
             }
@@ -228,6 +241,17 @@ $(document).ready(() => {
     });
 
     // 权限更改
+    $('body').on('click', '#contract-users input[type="checkbox"]', function () {
+        const type = $(this).attr('data-type');
+        const value = $(this).is(':checked') ? 1 : 0;
+        const id = parseInt($(this).val());
+        const updateInfo = { uid: id };
+        updateInfo[type] = value;
+        postData(`/sp/${spid}/contract/tender/${cur_tenderid}/audit/save`, { type: 'save-permission', updateData: updateInfo }, function (result) {
+        })
+    });
+
+    // 权限更改
     $('body').on('click', '#construction-users input[type="checkbox"]', function () {
         const id = parseInt($(this).data('id'));
         const prop = {
@@ -238,38 +262,32 @@ $(document).ready(() => {
             }
         };
         const _self = $(this);
-        postData('/construction/' + cur_tenderid + '/audit/save', prop, function (data) {
+        postData('/sp/' + spid + '/construction/' + cur_tenderid + '/audit/save', prop, function (data) {
         });
     });
 
-    // 移除游客用户
-    $('body').on('click', '#tourist-users .remove-tourist-user', function () {
-        $('#remove_user_type').val('tourist');
-        $('#remove_user_id').val($(this).data('id'));
-    });
-
-    // 移除投资进度用户
-    $('body').on('click', '#schedule-users .remove-schedule-user', function () {
-        $('#remove_user_type').val('schedule');
-        $('#remove_user_id').val($(this).data('id'));
-    });
-
-    // 移除施工日志用户
-    $('body').on('click', '#construction-users .remove-construction-user', function () {
-        $('#remove_user_type').val('construction');
-        $('#remove_user_id').val($(this).data('id'));
-    });
+    for (const key of tabTypeKeys) {
+        $('body').on('click', `#${key}-users .remove-${key}-user`, function () {
+            $('#remove_user_type').val(key);
+            $('#remove_user_id').val($(this).data('id'));
+        });
+    }
 
     // 移除用户确定
     $('#remove_user_btn').click(function () {
         const type = $('#remove_user_type').val();
-        if (type !== 'tourist' && type !== 'schedule' && type !== 'construction') {
+        if (tabTypeKeys.indexOf(type) === -1) {
             toastr.error('参数有误');
             return;
         }
         const id = parseInt($('#remove_user_id').val());
-        if (type === 'construction') {
-            postData('/construction/' + cur_tenderid + '/audit/save', { type: 'del-audit', id }, function (data) {
+        if (type === 'contract') {
+            postData('/sp/' + spid + '/contract/tender/' + cur_tenderid + '/audit/save', { type: 'del-audit', id }, function (data) {
+                $('#'+ type + '-users').find('tr[data-id="'+ id +'"]').remove();
+                $('#remove-user').modal('hide');
+            });
+        } else if (type === 'construction') {
+            postData('/sp/' + spid + '/construction/' + cur_tenderid + '/audit/save', { type: 'del-audit', id }, function (data) {
                 $('#'+ type + '-users').find('tr[data-id="'+ id +'"]').remove();
                 $('#remove-user').modal('hide');
             });
@@ -437,6 +455,26 @@ $(document).ready(() => {
                                 </tr>`;
                     $('#schedule-users').append(html);
                 });
+            } else if (type === 'contract') {
+                const user = _.find(accountList, function (item) {
+                    return item.id === id;
+                });
+                const saIdList = [];
+                for (let i = 0; i < $('#contract-users tr').length; i++) {
+                    saIdList.push(parseInt($('#contract-users tr').eq(i).data('uid')));
+                }
+                if (_.includes(saIdList, id)) {
+                    toastr.error('该用户已存在列表中,无需重复添加');
+                    return;
+                }
+
+                const prop = {
+                    id: id,
+                    type: 'add-audit',
+                };
+                postData('/sp/' + spid + '/contract/tender/' + cur_tenderid + '/audit/save', prop, function (datas) {
+                    setContractHtml(datas);
+                });
             } else if (type === 'construction') {
                 const user = _.find(accountList, function (item) {
                     return item.id === id;
@@ -454,7 +492,7 @@ $(document).ready(() => {
                     id: id,
                     type: 'add-audit',
                 };
-                postData('/construction/' + cur_tenderid + '/audit/save', prop, function (datas) {
+                postData('/sp/' + spid + '/construction/' + cur_tenderid + '/audit/save', prop, function (datas) {
                     setConstructionHtml(datas);
                 });
             }
@@ -475,7 +513,7 @@ $(document).ready(() => {
         if (saIdList.length > 0) {
             $('#bdcopy').modal('show');
         } else {
-            toastr.warning('未存在'+ (userType === 'tourist' ? '游客' : userType === 'schedule' ? '投资进度' : userType === 'construction' ? '施工日志' : '') +'用户账号,无法应用至其他标段');
+            toastr.warning('未存在'+ tabTypes[userType] +'用户账号,无法应用至其他标段');
             return;
         }
     });
@@ -593,6 +631,13 @@ $(document).ready(() => {
                     permission = scPermission.show;
                 }
                 userData.permission = permission;
+            } else if (userType === 'contract') {
+                userData.permission = {
+                    add: $('#contract-users tr').eq(i).find('input[data-type="permission_add"]').eq(0).is(':checked') ? 1 : 0,
+                    edit: $('#contract-users tr').eq(i).find('input[data-type="permission_edit"]').eq(0).is(':checked') ? 1 : 0,
+                    showUnit: $('#contract-users tr').eq(i).find('input[data-type="permission_show_unit"]').eq(0).is(':checked') ? 1 : 0,
+                    showNode: $('#contract-users tr').eq(i).find('input[data-type="permission_show_node"]').eq(0).is(':checked') ? 1 : 0,
+                }
             } else if (userType === 'construction') {
                 userData.is_report = $('#construction-users tr').eq(i).find('input[type="checkbox"]').eq(0).is(':checked') ? 1 : 0;
             }
@@ -837,6 +882,32 @@ function setScheduleHtml(scheduleAuditList) {
     $('#schedule-users').html(html);
 }
 
+function setContractHtml(datas) {
+    let list = '';
+    for (const ca of datas) {
+        list += `<tr data-uid="${ca.uid}" data-id="${ca.id}">
+                            <td>${ca.name}</td>
+                            <td>${ca.role}</td>
+                            <td class="text-center">
+                                <input type="checkbox" class="permission-checkbox" data-type="permission_edit" value="${ca.uid}" ${ca.permission_edit ? 'checked' : ''}>
+                            </td>
+                            <td class="text-center">
+                                <input type="checkbox" class="permission-checkbox" data-type="permission_add" value="${ca.uid}" ${ca.permission_add ? 'checked' : ''}>
+                            </td>
+                            <td class="text-center">
+                                <input type="checkbox" class="permission-checkbox" data-type="permission_show_unit" value="${ca.uid}" ${ca.permission_show_unit ? 'checked' : ''}>
+                            </td>
+                            <td class="text-center">
+                                <input type="checkbox" class="permission-checkbox" data-type="permission_show_node" value="${ca.uid}" ${ca.permission_show_node ? 'checked' : ''}>
+                            </td>
+                            <td class="text-center">
+                                <a href="#remove-user1" data-toggle="modal" data-target="#remove-user" class="btn btn-outline-danger btn-sm ml-1 remove-contract-user" data-id="${ca.uid}">移除</a>
+                            </td>
+                        </tr>`;
+    }
+    $('#contract-users').html(list);
+}
+
 function setConstructionHtml(constructionAuditList) {
     let html = '';
     if (constructionAuditList.length > 0) {

+ 4 - 1
app/public/js/shares/export_excel.js

@@ -49,6 +49,7 @@ const SpreadExcelObj = (function() {
             }
         }
 
+        const autoFit = !!setting.cols.find(x => { return x.wordWrap; });
         for (let iRow = 0; iRow < data.length; iRow++) {
             const curRow = setting.headRows + iRow;
             const d = data[iRow];
@@ -57,6 +58,7 @@ const SpreadExcelObj = (function() {
                 const col = setting.cols[iCol];
                 if (col.field !== '' && d[col.field]) {
                     cell.value(col.getValue ? col.getValue(d) : d[col.field]);
+                    if (col.wordWrap) cell.wordWrap(true);
                     if (typeof d[col.field] === 'string') {
                         cell.formatter('@');
                     }
@@ -66,8 +68,9 @@ const SpreadExcelObj = (function() {
                 } else if (setting.font) {
                     cell.font(setting.font);
                 }
-                cell.hAlign(col.hAlign);
+                cell.hAlign(col.hAlign).vAlign(1);
             }
+            if (autoFit) sheet.autoFitRow(curRow);
         }
         SpreadJsObj.endMassOperation(sheet);
     };

+ 1 - 1
app/public/js/shenpi.js

@@ -149,7 +149,7 @@ function recursiveGetTenderNodeHtml2 (node, arr, pid, this_code, this_status, ai
             if(auditList) {
                 for (const uid of auditList) {
                     const user = _.find(accountList, { id: uid });
-                    nameList.push(user.name);
+                    if (user) nameList.push(user.name);
                 }
             }
             // html.push('<i class="fa fa-question-circle text-primary" data-container="body" data-toggle="tooltip" data-placement="bottom" ' +

+ 5 - 1
app/public/js/sp_data.js

@@ -172,10 +172,12 @@ $(document).ready(() => {
             defaultRowHeight: 21,
             headerFont: '12px 微软雅黑',
             font: '12px 微软雅黑',
+            readOnly: readOnly,
         },
         data: mainQty,
         isTree: false,
         type: 'main_quantity',
+        readOnly: readOnly,
     });
     const gclQtyObj = new QtyObj({
         obj: $('#gcl_qty_spread')[0],
@@ -192,6 +194,7 @@ $(document).ready(() => {
             defaultRowHeight: 21,
             headerFont: '12px 微软雅黑',
             font: '12px 微软雅黑',
+            readOnly: readOnly,
         },
         data: gclQty,
         type: 'gcl_quantity',
@@ -203,6 +206,7 @@ $(document).ready(() => {
             level: 'level',
             fullPath: 'full_path',
             rootId: -1,
-        }
+        },
+        readOnly: readOnly,
     })
 });

+ 3 - 2
app/public/js/sp_progress.js

@@ -64,7 +64,7 @@ $(document).ready(() => {
                     key: 'sub-proj-progress',
                     colWidth: true,
                 },
-                readOnly: false,
+                readOnly: readOnly,
                 imageClick: function (data, hitinfo) {
                     if (!data) return;
 
@@ -498,7 +498,7 @@ $(document).ready(() => {
         deleteUrl: 'progress/file/delete',
         checked: false,
         zipName: `阶段进度-附件.zip`,
-        readOnly: false,
+        readOnly: readOnly,
         fileIdType: 'string',
         fileInfo: {
             user_name: 'user_name',
@@ -559,6 +559,7 @@ $(document).ready(() => {
                         },
                         page: 'sp_progress',
                         cellDoubleClick: function(updateData, stdNode, stdTree) {
+                            if (readOnly) return;
                             if (!stdNode) return;
                             const mainTree = progressObj.tree;
                             const mainNode = SpreadJsObj.getSelectObject(progressObj.sheet);

+ 2 - 1
app/public/js/sp_push.js

@@ -52,6 +52,7 @@ $(document).ready(() => {
                     colWidth: true,
                 },
                 forceLoadEmpty: true,
+                readOnly: readOnly,
                 imageClick: function (data, hitinfo) {
                     const setting = hitinfo.sheet.zh_setting;
                     if (!setting) return;
@@ -413,7 +414,7 @@ $(document).ready(() => {
         deleteUrl: 'push/file/delete',
         checked: false,
         zipName: `推进记录-附件.zip`,
-        readOnly: false,
+        readOnly: readOnly,
         fileIdType: 'string',
         fileInfo: {
             user_name: 'user_name',

+ 29 - 1
app/public/js/sp_setting_permission.js

@@ -57,6 +57,34 @@ $(document).ready(() => {
             window.location.reload();
         });
     });
+    $('[name=permission-check]').click(function() {
+        const ptype = $(this).attr('ptype');
+        if (ptype === 'contract') {
+            const pvalue = $(this).attr('pvalue');
+            if (this.checked) {
+                if ((pvalue === '1' || pvalue === '2') && !$(this).parents('.permission-parent').find('[ptype=contract][pvalue="3"]').prop('checked') && !$(this).parents('.permission-parent').find('[ptype=contract][pvalue="4"]').prop('checked')) {
+                    $(this).parents('.permission-parent').find('[ptype=contract][pvalue="5"]').prop('checked', true);
+                }
+                if (pvalue === '3' || pvalue === '4') {
+                    $(this).parents('.permission-parent').find('[ptype=contract][pvalue="5"]').prop('checked', false);
+                } else if (pvalue === '5') {
+                    $(this).parents('.permission-parent').find('[ptype=contract][pvalue="3"]').prop('checked', false);
+                    $(this).parents('.permission-parent').find('[ptype=contract][pvalue="4"]').prop('checked', false);
+                }
+            } else if (!this.checked) {
+                if (pvalue === '3' || pvalue === '4') {
+                    if (!$(this).parents('.permission-parent').find('[ptype=contract][pvalue="3"]').prop('checked') && !$(this).parents('.permission-parent').find('[ptype=contract][pvalue="4"]').prop('checked')) {
+                        $(this).parents('.permission-parent').find('[ptype=contract][pvalue="5"]').prop('checked', true);
+                    }
+                }
+            }
+        } else if (ptype === 'payment') {
+            const pvalue = $(this).attr('pvalue');
+            if (this.checked && pvalue === '2') {
+                $(this).parents('.permission-parent').find('[ptype=payment][pvalue="3"]').prop('checked', true);
+            }
+        }
+    });
     $('[name=set-permission]').click(function() {
         const data = JSON.parse(this.getAttribute('data-account'));
         const permissionCheck = $('[name="permission-check"]');
@@ -131,4 +159,4 @@ $(document).ready(() => {
             window.location.reload();
         })
     });
-});
+});

+ 15 - 0
app/public/js/spreadjs_rela/spreadjs_zh.js

@@ -2737,6 +2737,16 @@ const SpreadJsObj = {
                 canvas.fill();
                 canvas.restore();
             };
+            const drawText = function (canvas, x, y, w, h, text) {
+                // if (w < 33) return; // 33为100%的长度
+                const textWidth = canvas.measureText(text).width;
+                if (textWidth > w - 4) return;
+                const tx = x + w - textWidth - 2;
+                const ty = y + h - 2;
+
+                canvas.textAlign = 'left';
+                canvas.fillText(text, tx, ty);
+            };
             const proto = stackedBarCellType.prototype;
             /**
              * 绘制方法
@@ -2766,13 +2776,18 @@ const SpreadJsObj = {
                 for (const [i, bd] of barData.entries()) {
                     let width = ZhCalc.mul(validWidth, bd.percent, 2);
                     if (width < defaultR) continue;
+                    let percent = ZhCalc.mul(bd.percent, 100, 0);
+                    const hintText = bd.hint || (percent ? percent + '%' : '');
+                    const hintNum = bd.hintNum !== undefined ? bd.hintNum : (col.hintNum || false);
                     const top = col.stackedBarCover ? startTop : startTop + height * i + i - 1;
                     //drawBarBefore99(canvas, left, top, width, height, ZhCalc.mul(height, defaultR, 2), bd.color);
                     //drawBarBefore99(canvas, left, top, width, height, [0, 0, ZhCalc.div(height, 2, 2), 0], bd.color);
                     if (col.stackedBarCover) {
                         drawSB(canvas, left, top, width, height, ZhCalc.div(height, 2, 2), bd.color);
+                        if (hintNum && hintText) drawText(canvas, left, top, width, height, hintText);
                     } else {
                         drawBarBefore99(canvas, left, top, width, height, ZhCalc.mul(height, defaultR, 2), bd.color);
+                        if (hintNum && hintText) drawText(canvas, left, top, width, height, hintText);
                     }
                 }
             };

+ 54 - 5
app/public/js/stage.js

@@ -15,13 +15,14 @@ function checkTzMeasureType () {
 function transExpr(expr) {
     return $.trim(expr).replace('\t', '').replace('=', '').replace(new RegExp('%', 'gm'), '/100');
 }
-function getExprInfo (field) {
+function getExprInfo (field, converse = false) {
     const exprField = [
         {qty: 'sgfh_qty', expr: 'sgfh_expr'},
         {qty: 'sjcl_qty', expr: 'sjcl_expr'},
         {qty: 'qtcl_qty', expr: 'qtcl_expr'},
         {qty: 'contract_qty', expr: 'contract_expr'},
     ];
+    if (converse) return _.find(exprField, { expr: field });
     return _.find(exprField, {qty: field});
 }
 
@@ -2125,6 +2126,23 @@ $(document).ready(() => {
                                 return;
                             }
                         }
+                    } else if (col.field.indexOf('_expr') > 0) {
+                        const exprInfo = getExprInfo(col.field, true);
+                        if (!exprInfo) return;
+
+                        if (newText) {
+                            try {
+                                data.updateData[exprInfo.qty] = ZhCalc.mathCalcExpr(transExpr(newText));
+                                data.updateData[exprInfo.expr] = newText;
+                            } catch(err) {
+                                toastr.error('输入的表达式非法');
+                                SpreadJsObj.reLoadRowData(info.sheet, info.row);
+                                return;
+                            }
+                        } else {
+                            data.updateData[exprInfo.qty] = 0;
+                            data.updateData[exprInfo.expr] = '';
+                        }
                     } else {
                         data.updateData[col.field] = newText;
                     }
@@ -2162,6 +2180,7 @@ $(document).ready(() => {
             }
             switch (col.field) {
                 case 'contract_qty':
+                case 'contract_expr':
                 case 'qc_qty':
                 case 'qc_minus_qty':
                     info.cancel = node.settle_status === settleStatus.finish;
@@ -2172,7 +2191,7 @@ $(document).ready(() => {
             if (info.sheet.zh_setting) {
                 const sortData = info.sheet.zh_data;
                 const range = info.cellRange;
-                const validField = ['contract_qty', 'postil', 'real_qty', 'ex_memo1', 'ex_memo2', 'ex_memo3'];
+                const validField = ['contract_qty', 'contract_expr', 'postil', 'real_qty', 'ex_memo1', 'ex_memo2', 'ex_memo3'];
                 if (!checkTzMeasureType()) {
                     validField.push('name', 'sgfh_qty', 'sjcl_qty', 'qtcl_qty', 'position', 'drawing_code');
                 }
@@ -2198,6 +2217,9 @@ $(document).ready(() => {
             }
         },
         clipboardPasted: function (e, info) {
+            const hint = {
+                expr: {type: 'warning', msg: '粘贴了表达式非法,已过滤'},
+            };
             if (info.sheet.zh_setting) {
                 if (info.sheet.getColumnCount() > info.sheet.zh_setting.cols.length) {
                     info.sheet.setColumnCount(info.sheet.zh_setting.cols.length);
@@ -2254,6 +2276,16 @@ $(document).ready(() => {
                                     newData[colSetting.field] = null;
                                     if (exprInfo) newData[exprInfo.expr] = '';
                                 }
+                            } else if (colSetting.field.indexOf('_expr') > 0) {
+                                try {
+                                    const exprInfo = getExprInfo(colSetting.field, true);
+                                    newData[exprInfo.expr] = trimInvalidChar(info.sheet.getText(curRow, curCol));
+                                    if (newData[exprInfo.expr] || newData[exprInfo.qty] === undefined) {
+                                        newData[exprInfo.qty] = ZhCalc.mathCalcExpr(transExpr(newData[exprInfo.expr]));
+                                    }
+                                } catch (err) {
+                                    toastMessageUniq(hint.expr);
+                                }
                             } else {
                                 newData[colSetting.field] = newValue;
                             }
@@ -2298,6 +2330,16 @@ $(document).ready(() => {
                                             return;
                                         }
                                     }
+                                } else if (colSetting.field.indexOf('_expr') > 0) {
+                                    try {
+                                        const exprInfo = getExprInfo(colSetting.field, true);
+                                        newData[exprInfo.expr] = trimInvalidChar(info.sheet.getText(curRow, curCol));
+                                        if (newData[exprInfo.expr] || newData[exprInfo.qty] === undefined) {
+                                            newData[exprInfo.qty] = ZhCalc.mathCalcExpr(transExpr(newData[exprInfo.expr]));
+                                        }
+                                    } catch (err) {
+                                        toastMessageUniq(hint.expr);
+                                    }
                                 } else {
                                     newData[colSetting.field] = newValue;
                                 }
@@ -2356,10 +2398,17 @@ $(document).ready(() => {
                                 toastr.error('已结算节点不可计量');
                                 return;
                             }
-                            data[colSetting.field] = null;
-                            const exprInfo = getExprInfo(colSetting.field);
-                            if (exprInfo) {
+                            if (colSetting.field.indexOf('_expr') > 0) {
+                                const exprInfo = getExprInfo(colSetting.field, true);
+                                if (!exprInfo) continue;
                                 data[exprInfo.expr] = '';
+                                data[exprInfo.qty] = 0;
+                            } else {
+                                data[colSetting.field] = null;
+                                const exprInfo = getExprInfo(colSetting.field);
+                                if (exprInfo) {
+                                    data[exprInfo.expr] = '';
+                                }
                             }
                         }
                         datas.push(data);

+ 1 - 1
app/public/js/stage_gather.js

@@ -426,7 +426,7 @@ $(document).ready(function () {
                 }
                 SpreadJsObj.refreshTreeRowVisible(sheet);
                 const node = SpreadJsObj.getSelectObject(sheet);
-                if (!node.visible) {
+                if (!node || !node.visible) {
                     const showIndex = datas.findIndex(x => { return x.visible; });
                     SpreadJsObj.locateRow(sheet, showIndex);
                     loadRelaData(showIndex);

+ 19 - 5
app/public/js/sub_project.js

@@ -58,10 +58,21 @@ $(document).ready(function() {
                 html.push(`<td>`);
                 if (canEdit) {
                     html.push('<button class="btn btn-outline-primary btn-sm ml-1" name="edit">编辑</button>');
-                    html.push('<button class="btn btn-outline-danger btn-sm ml-1" name="del">删除</button>');
                     html.push('<button class="btn btn-outline-primary btn-sm ml-1" name="up"><i class="fa fa-arrow-up"></i></button>');
                     html.push('<button class="btn btn-outline-primary btn-sm ml-1" name="down"><i class="fa fa-arrow-down"></i></button>');
                     html.push('<button class="btn btn-outline-primary btn-sm ml-1" name="top">顶层</button>');
+                    if (node.is_folder) {
+                        if (!node.children || node.children.length === 0) {
+                            html.push('<button class="btn btn-outline-danger btn-sm ml-1" name="del">删除</button>');
+                        }
+                    } else {
+                        const delHint = node.tender_count > 0 ? '请先删除所有标段' : (node.contract_count > 0 ? '请先删除所有合同' : (node.file_count > 0 ? '请先删除所有资料归集文件' : ''));
+                        if (delHint) {
+                            html.push(`<button class="btn btn-outline-secondary btn-sm ml-1" data-toggle="tooltip" data-placement="top" data-original-title="${delHint}" name="del">删除</button>`);
+                        } else {
+                            html.push('<button class="btn btn-outline-danger btn-sm ml-1" name="del">删除</button>');
+                        }
+                    }
                 }
                 html.push('</td>');
                 return html.join('');
@@ -187,13 +198,16 @@ $(document).ready(function() {
             const treeId = $(this).parent().parent().attr('tree_id');
             const node = ProjectTree.getItems(treeId);
             if (node.is_folder) {
+                if (node.children && node.children.length > 0) return;
                 $('.modal-title', '#del').html('确认删除文件夹');
-                $('#del-hint').attr('tree_id', treeId).html(`确定删除「<strong style="word-break: break-word;">${node.name}</strong>」及其下所有内容?`)
+                $('#del-hint').attr('tree_id', treeId).html(`确定删除「<strong style="word-break: break-word;">${node.name}</strong>」及其下所有内容?`);
+                $('#del').modal('show');
             } else {
-                $('.modal-title', '#del').html('确认删除标段');
-                $('#del-hint').attr('tree_id', treeId).html(`确定删除「<strong style="word-break: break-word;">${node.name}</strong>」?`)
+                if (node.tender_count || node.file_count || node.contract_count) return;
+                $('.modal-title', '#del').html('确认删除项目');
+                $('#del-hint').attr('tree_id', treeId).html(`确定删除「<strong style="word-break: break-word;">${node.name}</strong>」?`);
+                $('#del').modal('show');
             }
-            $('#del').modal('show');
         });
         $('body').on('click', 'button[name=up]', function (e) {
             const treeId = $(this).parent().parent().attr('tree_id');

+ 48 - 49
app/router.js

@@ -295,6 +295,7 @@ module.exports = app => {
     app.get('/sp/:id/contract/tender/:tid/detail/:type/:cid/pay/:cpid/file/:fid/download', sessionAuth, subProjectCheck, contractCheck, 'contractController.downloadFile');
     // 项目合同管理
     app.get('/sp/:id/contract', sessionAuth, subProjectCheck, contractCheck, 'contractController.detail');
+    app.post('/sp/:id/contract/audit/save', sessionAuth, subProjectCheck, contractCheck, 'contractController.auditSave');
     app.get('/sp/:id/contract/detail', sessionAuth, subProjectCheck, contractCheck, 'contractController.detail');
     app.get('/sp/:id/contract/detail/:type', sessionAuth, subProjectCheck, contractCheck, 'contractController.detail');
     app.post('/sp/:id/contract/load', sessionAuth, subProjectCheck, contractCheck, 'contractController.loadDetail');
@@ -349,15 +350,14 @@ module.exports = app => {
     app.get('/sp/:id/construction/:tid/list', sessionAuth, subProjectCheck, constructionCheck, 'constructionController.list');
     app.post('/sp/:id/construction/:tid/list/add', sessionAuth, subProjectCheck, constructionCheck, 'constructionController.addLog');
     app.post('/sp/:id/construction/:tid/list/startmulti', sessionAuth, subProjectCheck, constructionCheck, 'constructionController.startMulti');
-    app.get('/sp/:id/construction/:tid/log/:id', sessionAuth, subProjectCheck, constructionCheck, 'constructionController.logInfo');
-    app.post('/sp/:id/construction/:tid/log/:id/delete', sessionAuth, subProjectCheck, constructionCheck, 'constructionController.deleteLog');
-    app.post('/sp/:id/construction/:tid/log/:id/save', sessionAuth, subProjectCheck, constructionCheck, 'constructionController.logSave');
-    app.post('/sp/:id/construction/:tid/log/:id/file/upload', sessionAuth, subProjectCheck, constructionCheck, 'constructionController.uploadFile');
-    app.post('/sp/:id/construction/:tid/log/:id/file/delete', sessionAuth, subProjectCheck, constructionCheck, 'constructionController.deleteFile');
-    app.get('/sp/:id/construction/:tid/log/:id/file/:fid/download', sessionAuth, subProjectCheck, constructionCheck, 'constructionController.downloadFile');
+    app.get('/sp/:id/construction/:tid/log/:lid', sessionAuth, subProjectCheck, constructionCheck, 'constructionController.logInfo');
+    app.post('/sp/:id/construction/:tid/log/:lid/delete', sessionAuth, subProjectCheck, constructionCheck, 'constructionController.deleteLog');
+    app.post('/sp/:id/construction/:tid/log/:lid/save', sessionAuth, subProjectCheck, constructionCheck, 'constructionController.logSave');
+    app.post('/sp/:id/construction/:tid/log/:lid/file/upload', sessionAuth, subProjectCheck, constructionCheck, 'constructionController.uploadFile');
+    app.post('/sp/:id/construction/:tid/log/:lid/file/delete', sessionAuth, subProjectCheck, constructionCheck, 'constructionController.deleteFile');
+    app.get('/sp/:id/construction/:tid/log/:lid/file/:fid/download', sessionAuth, subProjectCheck, constructionCheck, 'constructionController.downloadFile');
 
     // **概算投资/动态投资
-    // app.get('/budget', sessionAuth, 'budgetController.list');
     app.get('/sp/:id/budget', sessionAuth, subProjectCheck, budgetCheck, 'budgetController.budgetInfo');
     app.get('/sp/:id/budget/compare', sessionAuth, subProjectCheck, budgetCheck, 'budgetController.compare');
     app.post('/sp/:id/budget/compare/load', sessionAuth, subProjectCheck, budgetCheck, 'budgetController.compareLoad');
@@ -368,20 +368,51 @@ module.exports = app => {
     app.post('/sp/:id/budget/:btype/upload-excel/:ueType', sessionAuth, subProjectCheck, budgetCheck, 'budgetController.detailUploadExcel');
     app.post('/sp/:id/budget/decimal', sessionAuth, subProjectCheck, budgetCheck, 'budgetController.decimal');
 
+    // 支付审批
+    app.get('/sp/:id/payment', sessionAuth, subProjectCheck, 'paymentController.index');
+    app.get('/sp/:id/payment/setting', sessionAuth, subProjectCheck, 'paymentController.setting');
+    app.post('/sp/:id/payment/permission/save', sessionAuth, subProjectCheck, 'paymentController.permissionSave');
+    app.post('/sp/:id/payment/info/save', sessionAuth, subProjectCheck, 'paymentController.paymentInfoSave');
+    app.get('/sp/:id/payment/:pid/detail/:did', sessionAuth, subProjectCheck, paymentTenderCheck, paymentDetailCheck, 'paymentController.detail');
+    app.post('/sp/:id/payment/:pid/detail/:did/save', sessionAuth, subProjectCheck, paymentTenderCheck, paymentDetailCheck, 'paymentController.detailSave');
+    app.post('/sp/:id/payment/save', sessionAuth, subProjectCheck, 'paymentController.save');
+    app.post('/sp/:id/payment/list/load', sessionAuth, subProjectCheck, 'paymentController.listLoad');
+    app.get('/sp/:id/payment/:pid/process', sessionAuth, subProjectCheck, paymentTenderCheck, 'paymentController.process');
+    app.post('/sp/:id/payment/:pid/process/save', sessionAuth, subProjectCheck, paymentTenderCheck, 'paymentController.processSave');
+    app.get('/sp/:id/payment/:pid/list', sessionAuth, subProjectCheck, paymentTenderCheck, 'paymentController.rptList');
+    app.get('/sp/:id/payment/:pid/list/:trid', sessionAuth, subProjectCheck, paymentTenderCheck, 'paymentController.rptList');
+    app.post('/sp/:id/payment/:pid/list/:trid/save', sessionAuth, subProjectCheck, paymentTenderCheck, 'paymentController.rptSave');
+    app.post('/sp/:id/payment/:pid/list/:trid/delete', sessionAuth, subProjectCheck, paymentTenderCheck, 'paymentController.deleteDetail');
+    app.post('/sp/:id/payment/:pid/list/:trid/auditors', sessionAuth, subProjectCheck, paymentTenderCheck, 'paymentController.detailAuditors');
+    app.post('/sp/:id/payment/:pid/detail/:did/audit/start', sessionAuth, subProjectCheck, paymentTenderCheck, paymentDetailCheck, 'paymentController.startAudit');
+    app.post('/sp/:id/payment/:pid/detail/:did/audit/check', sessionAuth, subProjectCheck, paymentTenderCheck, paymentDetailCheck, 'paymentController.checkAudit');
+    // 附件
+    app.post('/sp/:id/payment/:pid/detail/:did/file/upload', sessionAuth, subProjectCheck, paymentTenderCheck, paymentDetailCheck, 'paymentController.uploadDetailFile');
+    app.post('/sp/:id/payment/:pid/detail/:did/file/delete', sessionAuth, subProjectCheck, paymentTenderCheck, paymentDetailCheck, 'paymentController.deleteDetailFile');
+    app.get('/sp/:id/payment/:pid/detail/:did/file/:fid/download', sessionAuth, subProjectCheck, paymentTenderCheck, paymentDetailCheck, 'paymentController.downloadDetailFile');
+    // 安全生产费
+    app.get('/sp/:id/payment/:pid/safe/:did/bills', sessionAuth, subProjectCheck, paymentTenderCheck, paymentDetailCheck, 'paymentController.safeBills');
+    app.get('/sp/:id/payment/:pid/safe/:did/compare', sessionAuth, subProjectCheck, paymentTenderCheck, paymentDetailCheck, 'paymentController.safeCompare');
+    app.post('/sp/:id/payment/:pid/safe/:did/load', sessionAuth, subProjectCheck, paymentTenderCheck, paymentDetailCheck, 'paymentController.safeLoad');
+    app.post('/sp/:id/payment/:pid/safe/:did/update', sessionAuth, subProjectCheck, paymentTenderCheck, paymentDetailCheck, 'paymentController.safeUpdate');
+    app.post('/sp/:id/payment/:pid/safe/:did/decimal', sessionAuth, subProjectCheck, paymentTenderCheck, paymentDetailCheck, 'paymentController.safeDecimal');
+    app.post('/sp/:id/payment/:pid/safe/:did/file/upload', sessionAuth, subProjectCheck, paymentTenderCheck, paymentDetailCheck, 'paymentController.uploadDetailFile');
+    app.post('/sp/:id/payment/:pid/safe/:did/file/delete', sessionAuth, subProjectCheck, paymentTenderCheck, paymentDetailCheck, 'paymentController.deleteDetailFile');
+
     // **资金监管 todo 接入项目内部
     // app.get('/financial', sessionAuth, 'financialController.index');
-    app.post('/sp/:id/financial/audit/save', sessionAuth, subProjectCheck, financialCheck, 'financialController.auditSave');
+    // app.post('/financial/audit/save', sessionAuth, financialCheck, 'financialController.auditSave');
     app.get('/sp/:id/financial/transfer', sessionAuth, subProjectCheck, financialCheck, 'financialController.transfer');
     app.post('/sp/:id/financial/transfer/add', sessionAuth, subProjectCheck, financialCheck, 'financialController.transferAdd');
     app.post('/sp/:id/financial/transfer/update', sessionAuth, subProjectCheck, financialCheck, 'financialController.transferUpdate');
-    app.post('/sp/:id/financial/transfer/:id/file/upload', sessionAuth, subProjectCheck, financialCheck, 'financialController.transferUploadFile');
-    app.post('/sp/:id/financial/transfer/:id/file/delete', sessionAuth, subProjectCheck, financialCheck, 'financialController.transferDeleteFile');
-    app.get('/sp/:id/financial/transfer/:id/file/:fid/download', sessionAuth, subProjectCheck, financialCheck, 'financialController.transferDownloadFile');
-    app.get('/sp/:id/financial/transfer/:id/tender', sessionAuth, subProjectCheck, financialCheck, 'financialController.transferTender');
-    app.post('/sp/:id/financial/transfer/:id/tender/update', sessionAuth, subProjectCheck, financialCheck, 'financialController.transferTenderUpdate');
-    app.post('/sp/:id/financial/transfer/:trid/tender/:id/file/upload', sessionAuth, subProjectCheck, financialCheck, 'financialController.transferTenderUploadFile');
-    app.post('/sp/:id/financial/transfer/:trid/tender/:id/file/delete', sessionAuth, subProjectCheck, financialCheck, 'financialController.transferTenderDeleteFile');
-    app.get('/sp/:id/financial/transfer/:trid/tender/:id/file/:fid/download', sessionAuth, subProjectCheck, financialCheck, 'financialController.transferTenderDownloadFile');
+    app.post('/sp/:id/financial/transfer/:trid/file/upload', sessionAuth, subProjectCheck, financialCheck, 'financialController.transferUploadFile');
+    app.post('/sp/:id/financial/transfer/:trid/file/delete', sessionAuth, subProjectCheck, financialCheck, 'financialController.transferDeleteFile');
+    app.get('/sp/:id/financial/transfer/:trid/file/:fid/download', sessionAuth, subProjectCheck, financialCheck, 'financialController.transferDownloadFile');
+    app.get('/sp/:id/financial/transfer/:trid/tender', sessionAuth, subProjectCheck, financialCheck, 'financialController.transferTender');
+    app.post('/sp/:id/financial/transfer/:trid/tender/update', sessionAuth, subProjectCheck, financialCheck, 'financialController.transferTenderUpdate');
+    app.post('/sp/:id/financial/transfer/:trid/tender/:ttid/file/upload', sessionAuth, subProjectCheck, financialCheck, 'financialController.transferTenderUploadFile');
+    app.post('/sp/:id/financial/transfer/:trid/tender/:ttid/file/delete', sessionAuth, subProjectCheck, financialCheck, 'financialController.transferTenderDeleteFile');
+    app.get('/sp/:id/financial/transfer/:trid/tender/:ttid/file/:fid/download', sessionAuth, subProjectCheck, financialCheck, 'financialController.transferTenderDownloadFile');
     app.get('/sp/:id/financial/pay', sessionAuth, subProjectCheck, financialCheck, 'financialController.pay');
     app.post('/sp/:id/financial/pay/save', sessionAuth, subProjectCheck, financialCheck, 'financialController.paySave');
     app.get('/sp/:id/financial/pay/:fpid/detail', sessionAuth, subProjectCheck, financialCheck, financialPayCheck, financialPayAuditCheck, 'financialController.payDetail');
@@ -727,7 +758,7 @@ module.exports = app => {
     app.get('/tender/:id/change/project/:cprjid/report', sessionAuth, tenderCheck, subProjectCheck, uncheckTenderCheck, 'reportController.indexForChangeProject');
     app.get('/tender/:id/change/apply/:caid/report', sessionAuth, tenderCheck, subProjectCheck, uncheckTenderCheck, 'reportController.indexForChangeApply');
     app.get('/tender/:id/measure/stage/:order/report', sessionAuth, tenderCheck, subProjectCheck, uncheckTenderCheck, stageCheck, 'reportController.index');
-    app.get('/payment/:id/safe/:did/report', sessionAuth, paymentTenderCheck, paymentDetailCheck, 'reportController.indexForPaymentSafe');
+    app.get('/sp/:id/payment/:pid/safe/:did/report', sessionAuth, subProjectCheck, paymentTenderCheck, paymentDetailCheck, 'reportController.indexForPaymentSafe');
     app.get('/budget/:id/report', sessionAuth, budgetCheck, 'reportController.indexForDynamicGrandTotal');
     app.get('/tender/:id/archiveReport', sessionAuth, tenderCheck, subProjectCheck, 'reportArchiveController.index');
     app.post('/tender/report_api/getReportArchive', sessionAuth, 'reportArchiveController.getReportArchive');
@@ -1026,38 +1057,6 @@ module.exports = app => {
     app.post('/wap/shoufang/editfile', 'wapController.shoufangEditFile');
     app.get('/wap/shoufang/download/file/:fid', 'wapController.shoufangDownloadFile');
 
-    // 支付审批
-    app.get('/payment', sessionAuth, 'paymentController.index');
-    app.get('/payment/setting', sessionAuth, 'paymentController.setting');
-    app.post('/payment/permission/save', sessionAuth, 'paymentController.permissionSave');
-    app.post('/payment/info/save', sessionAuth, 'paymentController.paymentInfoSave');
-    app.get('/payment/:id/detail/:did', sessionAuth, paymentTenderCheck, paymentDetailCheck, 'paymentController.detail');
-    app.post('/payment/:id/detail/:did/save', sessionAuth, paymentTenderCheck, paymentDetailCheck, 'paymentController.detailSave');
-    app.post('/payment/save', sessionAuth, 'paymentController.save');
-    app.post('/payment/list/load', sessionAuth, 'paymentController.listLoad');
-    app.get('/payment/:id/process', sessionAuth, paymentTenderCheck, 'paymentController.process');
-    app.post('/payment/:id/process/save', sessionAuth, paymentTenderCheck, 'paymentController.processSave');
-    app.get('/payment/:id/list', sessionAuth, paymentTenderCheck, 'paymentController.rptList');
-    app.get('/payment/:id/list/:trid', sessionAuth, paymentTenderCheck, 'paymentController.rptList');
-    app.post('/payment/:id/list/:trid/save', sessionAuth, paymentTenderCheck, 'paymentController.rptSave');
-    app.post('/payment/:id/list/:trid/delete', sessionAuth, paymentTenderCheck, 'paymentController.deleteDetail');
-    app.post('/payment/:id/list/:trid/auditors', sessionAuth, paymentTenderCheck, 'paymentController.detailAuditors');
-    app.post('/payment/:id/detail/:did/audit/start', sessionAuth, paymentTenderCheck, paymentDetailCheck, 'paymentController.startAudit');
-    app.post('/payment/:id/detail/:did/audit/check', sessionAuth, paymentTenderCheck, paymentDetailCheck, 'paymentController.checkAudit');
-    // 附件
-    app.post('/payment/:id/detail/:did/file/upload', sessionAuth, paymentTenderCheck, paymentDetailCheck, 'paymentController.uploadDetailFile');
-    app.post('/payment/:id/detail/:did/file/delete', sessionAuth, paymentTenderCheck, paymentDetailCheck, 'paymentController.deleteDetailFile');
-    app.get('/payment/:id/detail/:did/file/:fid/download', sessionAuth, paymentTenderCheck, paymentDetailCheck, 'paymentController.downloadDetailFile');
-    // 安全生产费
-    app.get('/payment/:id/safe/:did/bills', sessionAuth, paymentTenderCheck, paymentDetailCheck, 'paymentController.safeBills');
-    app.get('/payment/:id/safe/:did/compare', sessionAuth, paymentTenderCheck, paymentDetailCheck, 'paymentController.safeCompare');
-    app.post('/payment/:id/safe/:did/load', sessionAuth, paymentTenderCheck, paymentDetailCheck, 'paymentController.safeLoad');
-    app.post('/payment/:id/safe/:did/update', sessionAuth, paymentTenderCheck, paymentDetailCheck, 'paymentController.safeUpdate');
-    app.post('/payment/:id/safe/:did/decimal', sessionAuth, paymentTenderCheck, paymentDetailCheck, 'paymentController.safeDecimal');
-    app.post('/payment/:id/safe/:did/file/upload', sessionAuth, paymentTenderCheck, paymentDetailCheck, 'paymentController.uploadDetailFile');
-    app.post('/payment/:id/safe/:did/file/delete', sessionAuth, paymentTenderCheck, paymentDetailCheck, 'paymentController.deleteDetailFile');
-
-
     // 企业微信回调
     app.get('/wx/work/callback/command', 'wechatController.command');
     app.post('/wx/work/callback/command', 'wechatController.postCommand');

+ 4 - 2
app/service/budget.js

@@ -76,8 +76,10 @@ module.exports = app => {
 
         async getCurBudget(id) {
             const result = await this.getDataById(id);
-            result.decimal = result.decimal ? JSON.parse(result.decimal) : {};
-            this.ctx.helper._.defaults(result.decimal, defaultDecimal);
+            if (result) {
+                result.decimal = result.decimal ? JSON.parse(result.decimal) : {};
+                this.ctx.helper._.defaults(result.decimal, defaultDecimal);
+            }
             return result;
         }
 

+ 1 - 1
app/service/change_apply_audit.js

@@ -1388,7 +1388,7 @@ module.exports = app => {
             const sql =
                 'SELECT sa.`aid`, sa.`times`, sa.`begin_time`, sa.`end_time`, sa.`tid`, sa.`caid`,' +
                 '    s.*,' +
-                '    t.`name` as `t_name`, t.`project_id`, t.`type`, t.`user_id`,' +
+                '    t.`name` as `t_name`, t.`project_id`, t.`type`, t.`user_id`, t.`spid`, ' +
                 '    ti.`deal_info`, ti.`decimal` ' +
                 '  FROM ?? AS sa' +
                 '    Left Join ?? AS s On sa.`caid` = s.`id`' +

+ 1 - 0
app/service/change_ledger.js

@@ -1227,6 +1227,7 @@ module.exports = app => {
                         check_calc: 1,
                         ccid: this.ctx.change.cid,
                         formc: 1,
+                        features: d.features,
                     };
                     for (const c of d.children) {
                         c.ledger_pid = newBills.ledger_id;

+ 1 - 1
app/service/change_plan_audit.js

@@ -725,7 +725,7 @@ module.exports = app => {
             const sql =
                 'SELECT sa.`aid`, sa.`times`, sa.`begin_time`, sa.`end_time`, sa.`tid`, sa.`cpid`,' +
                 '    s.*,' +
-                '    t.`name` as `t_name`, t.`project_id`, t.`type`, t.`user_id`,' +
+                '    t.`name` as `t_name`, t.`project_id`, t.`type`, t.`user_id`, t.`spid`,' +
                 '    ti.`deal_info`, ti.`decimal` ' +
                 '  FROM ?? AS sa' +
                 '    Left Join ?? AS s On sa.`cpid` = s.`id`' +

+ 1 - 1
app/service/change_project_audit.js

@@ -1524,7 +1524,7 @@ module.exports = app => {
             const sql =
                 'SELECT sa.`aid`, sa.`times`, sa.`begin_time`, sa.`end_time`, sa.`tid`, sa.`cpid`,' +
                 '    s.*,' +
-                '    t.`name` as `t_name`, t.`project_id`, t.`type`, t.`user_id`,' +
+                '    t.`name` as `t_name`, t.`project_id`, t.`type`, t.`user_id`, t.`spid`,' +
                 '    ti.`deal_info`, ti.`decimal` ' +
                 '  FROM ?? AS sa' +
                 '    Left Join ?? AS s On sa.`cpid` = s.`id`' +

+ 1 - 1
app/service/contract.js

@@ -143,7 +143,7 @@ module.exports = app => {
             if (user.is_admin) {
                 return list;
             }
-            const userPermission = await this.ctx.service.contractAudit.getDataByCondition({ spid: options.spid || null, tid: options.tid || null, uid: user.accountId });
+            const userPermission = options.tid ? await this.ctx.service.contractAudit.getDataByCondition({ spid: options.spid || null, tid: options.tid || null, uid: user.accountId }) : await this.ctx.service.subProjPermission.getContractPermission(this.ctx.subProject.permission.contract_permission);
             if (!userPermission) return [];
             const cloneOptions = this._.cloneDeep(options);
             cloneOptions.uid = user.accountId;

+ 1 - 1
app/service/contract_att.js

@@ -30,7 +30,7 @@ module.exports = app => {
             return result.map(item => {
                 item.orginpath = this.ctx.app.config.fujianOssPath + item.filepath;
                 if (!this.ctx.helper.canPreview(item.fileext)) {
-                    item.filepath = `/contract/${item.spid || item.tid}/detail/${contractConst.typeMap[item.contract_type]}/${item.cid}/file/${item.id}/download`;
+                    item.filepath = `/sp/${this.ctx.subProject.id}/contract${item.tid ? '/tender/' + item.tid : ''}/detail/${contractConst.typeMap[item.contract_type]}/${item.cid}/file/${item.id}/download`;
                 } else {
                     item.filepath = this.ctx.app.config.fujianOssPath + item.filepath;
                     item.viewpath = item.filepath;

+ 49 - 20
app/service/contract_audit.js

@@ -23,7 +23,7 @@ module.exports = app => {
         }
 
         async getList(options) {
-            const list = await this.db.select(this.tableName, { where: options, orders: [['id', 'desc']] });
+            const list = options.spid ? await this.ctx.service.subProjPermission.getContractAuditList(options.spid) : await this.db.select(this.tableName, { where: options, orders: [['id', 'desc']] });
             for (const l of list) {
                 const accountInfo = await this.ctx.service.projectAccount.getDataById(l.uid);
                 l.name = accountInfo.name;
@@ -36,6 +36,22 @@ module.exports = app => {
 
         async saveAudits(options, accountList, transaction = null) {
             // 判断是否已存在该用户,存在则不插入
+            if (options.spid) {
+                const spAudits = await this.ctx.service.subProjPermission.getAllDataByCondition({ where: { spid: options.spid, uid: this._.map(accountList, 'id') } });
+                const insertData = [];
+                for (const a of spAudits) {
+                    if (!a.contract_permission) {
+                        insertData.push({
+                            id: a.id,
+                            contract_permission: '5',
+                        });
+                    }
+                }
+                if (insertData.length > 0) {
+                    return transaction ? await transaction.updateRows(this.ctx.service.subProjPermission.tableName, insertData) : await this.db.updateRows(this.ctx.service.subProjPermission.tableName, insertData);
+                }
+                return false;
+            }
             const pauditList = await this.getAllDataByCondition({ where: options });
             const pushData = [];
             for (const a of this._.uniqBy(accountList, 'id')) {
@@ -55,29 +71,38 @@ module.exports = app => {
             return false;
         }
 
-        async delAudit(id) {
-            return await this.db.delete(this.tableName, { id });
+        async delAudit(options, ids) {
+            if (options.spid) {
+                const updateData = [];
+                for (const id of ids) {
+                    updateData.push({
+                        id,
+                        contract_permission: '',
+                    });
+                }
+                return await this.db.updateRows(this.ctx.service.subProjPermission.tableName, updateData);
+            }
+            return await this.db.delete(this.tableName, { id: ids });
         }
 
-        async updatePermission(updateData) {
-            if (!updateData.id) {
+        async updatePermission(options, updateData) {
+            if (!updateData.uid) {
                 return false;
             }
-            return await this.db.update(this.tableName, updateData);
-        }
-
-        async checkPermission(options, uid) {
-            if (this.ctx.session.sessionUser.is_admin) {
-                return true;
+            if (options.spid) {
+                const spAudit = await this.ctx.service.subProjPermission.getDataByCondition({ spid: options.spid, uid: updateData.uid });
+                if (!spAudit) {
+                    return false;
+                }
+                const newContractPermission = await this.ctx.service.subProjPermission.getNewContractPermission(spAudit.contract_permission, updateData);
+                return await this.db.update(this.ctx.service.subProjPermission.tableName, { id: spAudit.id, contract_permission: newContractPermission });
             }
-            let flag = false;
-            const cloneOptions = this._.cloneDeep(options);
-            cloneOptions.uid = uid;
-            const info = await this.getDataByCondition(cloneOptions);
-            if (info) {
-                flag = true;
+            const contractAudit = await this.getDataByCondition({ tid: options.tid, uid: updateData.uid });
+            if (!contractAudit) {
+                return false;
             }
-            return flag;
+            updateData.id = contractAudit.id;
+            return await this.db.update(this.tableName, updateData);
         }
 
         async getUserPermissionEdit(options, uid) {
@@ -112,10 +137,14 @@ module.exports = app => {
                         if (delId) deleteIdData.push(delId.id);
                         if (user.uid !== t.user_id) {
                             insertData.push({
+                                spid: null,
                                 tid: t.id,
                                 uid: user.uid,
-                                is_report: user.is_report,
-                                in_time: new Date(),
+                                permission_add: user.permission.add,
+                                permission_edit: user.permission.edit,
+                                permission_show_unit: user.permission.showUnit,
+                                permission_show_node: user.permission.showNode,
+                                create_time: new Date(),
                             });
                         }
                     }

+ 1 - 1
app/service/contract_pay_att.js

@@ -30,7 +30,7 @@ module.exports = app => {
             return result.map(item => {
                 item.orginpath = this.ctx.app.config.fujianOssPath + item.filepath;
                 if (!this.ctx.helper.canPreview(item.fileext)) {
-                    item.filepath = `/contract/${item.spid || item.tid}/detail/${contractConst.typeMap[item.contract_type]}/${item.cid}/pay/${item.cpid}/file/${item.id}/download`;
+                    item.filepath = `/sp/${this.ctx.subProject.id}/contract${item.tid ? '/tender/' + item.tid : ''}/detail/${contractConst.typeMap[item.contract_type]}/${item.cid}/pay/${item.cpid}/file/${item.id}/download`;
                 } else {
                     item.filepath = this.ctx.app.config.fujianOssPath + item.filepath;
                     item.viewpath = item.filepath;

+ 3 - 3
app/service/filing.js

@@ -241,12 +241,12 @@ module.exports = app => {
             const filing = await this.getDataById(data.id);
             if (!filing) throw '移动的分类不存在,请刷新页面后重试';
             const parent = await this.getDataById(data.tree_pid);
-            if (!parent) throw '移动后的分类不存在,请刷新页面后重试';
+            if (!parent && filing.tree_pid !== data.tree_pid) throw '移动后的分类不存在,请刷新页面后重试';
             const sibling = await this.getAllDataByCondition({ where: { tree_pid: data.tree_pid, is_deleted: 0 } });
             const posterity = await this.getPosterityData(filing.id);
-            const updateData = { id: filing.id, tree_order: data.tree_order, tree_pid: data.tree_pid, tree_level: parent.tree_level + 1 };
+            const updateData = { id: filing.id, tree_order: data.tree_order, tree_pid: data.tree_pid, tree_level: (parent ? parent.tree_level : 0) + 1 };
             const posterityUpdateData = posterity.map(x => {
-               return { id: x.id,  tree_level: parent.tree_level + 1 - filing.tree_level + x.tree_level };
+               return { id: x.id,  tree_level: (parent ? parent.tree_level : 0) + 1 - filing.tree_level + x.tree_level };
             });
             const siblingUpdateData = [];
             if (data.tree_pid === filing.tree_pid) {

+ 1 - 1
app/service/financial_pay.js

@@ -271,7 +271,7 @@ module.exports = app => {
         async loadPayUser(pay) {
             const status = auditConst.status;
             const accountId = this.ctx.session.sessionUser.accountId;
-            pay.permission = await this.ctx.service.financialAudit.getPermission(this.ctx.subProject.id, accountId);
+            pay.permission = await this.ctx.service.subProjPermission.getFinancailPermission(this.ctx.subProject.permission.fund_trans_permission, this.ctx.subProject.permission.fund_pay_permission);
             pay.user = await this.ctx.service.projectAccount.getAccountInfoById(pay.uid);
             pay.auditors = await this.ctx.service.financialPayAudit.getAuditors(pay.id, pay.times); // 全部参与的审批人
             pay.auditorIds = this._.map(pay.auditors, 'aid');

+ 54 - 9
app/service/financial_pay_tender_audit.js

@@ -55,9 +55,10 @@ module.exports = app => {
             try {
                 // 判断是否已存在该用户,存在则不插入
                 const pauditList = await this.getAllDataByCondition({ where: { spid, tid } });
-                const financialAudits = await this.ctx.service.financialAudit.getAllDataByCondition({ where: { spid } });
+                const financialAudits = await this.ctx.service.subProjPermission.getAllDataByCondition({ where: { spid } });
                 const pushData = [];
-                const pushFinancialData = [];
+                const pushSubProjPermissionData = [];
+                const updateSubProjPermissionData = [];
                 for (const a of this._.uniqBy(accountList, 'id')) {
                     if (this._.findIndex(pauditList, { uid: a.id }) === -1) {
                         const data = {
@@ -68,19 +69,40 @@ module.exports = app => {
                         };
                         pushData.push(data);
                     }
-                    if (this._.findIndex(financialAudits, { uid: a.id }) === -1) {
-                        pushFinancialData.push({
+                    const subProjPermission = this._.find(financialAudits, { uid: a.id });
+                    if (!subProjPermission) {
+                        pushSubProjPermissionData.push({
+                            id: this.uuid.v4(),
                             spid,
+                            pid: this.ctx.session.sessionProject.id,
                             uid: a.id,
-                            create_time: new Date(),
+                            fund_trans_permission: 1,
+                            fund_pay_permission: 1,
                         });
+                    } else {
+                        subProjPermission.fund_trans_permission = subProjPermission.fund_trans_permission ? this._.map(subProjPermission.fund_trans_permission.split(','), this._.toInteger) : [];
+                        subProjPermission.fund_pay_permission = subProjPermission.fund_pay_permission ? this._.map(subProjPermission.fund_pay_permission.split(','), this._.toInteger) : [];
+                        const financialPermission = await this.ctx.service.subProjPermission.getFinancailPermission(subProjPermission.fund_trans_permission, subProjPermission.fund_pay_permission);
+                        if (!financialPermission.pay_show) {
+                            const upPermission = {
+                                id: subProjPermission.id,
+                                fund_pay_permission: subProjPermission.fund_pay_permission.push(1).join(','),
+                            };
+                            if (!financialPermission.transfer_show) {
+                                upPermission.fund_tran_permission = subProjPermission.fund_trans_permission.push(1).join(',');
+                            }
+                            updateSubProjPermissionData.push(upPermission);
+                        }
                     }
                 }
                 if (pushData.length > 0) {
                     await transaction.insert(this.tableName, pushData);
                 }
-                if (pushFinancialData.length > 0) {
-                    await transaction.insert(this.ctx.service.financialAudit.tableName, pushFinancialData);
+                if (pushSubProjPermissionData.length > 0) {
+                    await transaction.insert(this.ctx.service.subProjPermission.tableName, pushSubProjPermissionData);
+                }
+                if (updateSubProjPermissionData.length > 0) {
+                    await transaction.updateRows(this.ctx.service.subProjPermission.tableName, updateSubProjPermissionData);
                 }
                 transaction.commit();
             } catch (error) {
@@ -159,9 +181,32 @@ module.exports = app => {
                         await transaction.insert(this.tableName, { spid, tid, uid: data.audit_id, create_time: new Date() });
                     }
                     // 判断是否存在并加入到成员表中
-                    const fAudit = await this.ctx.service.financialAudit.getDataByCondition({ spid, uid: data.audit_id });
+                    const fAudit = await this.ctx.service.subProjPermission.getDataByCondition({ spid, uid: data.audit_id });
                     if (!fAudit) {
-                        await transaction.insert(this.ctx.service.financialAudit.tableName, { spid, uid: data.audit_id, create_time: new Date() });
+                        await transaction.insert(this.ctx.service.subProjPermission.tableName, {
+                            id: this.uuid.v4(),
+                            spid,
+                            pid: this.ctx.session.sessionProject.id,
+                            uid: data.audit_id,
+                            fund_trans_permission: 1,
+                            fund_pay_permission: 1,
+                        });
+                    } else {
+                        fAudit.fund_trans_permission = fAudit.fund_trans_permission ? this._.map(fAudit.fund_trans_permission.split(','), this._.toInteger) : [];
+                        fAudit.fund_pay_permission = fAudit.fund_pay_permission ? this._.map(fAudit.fund_pay_permission.split(','), this._.toInteger) : [];
+                        const financialPermission = await this.ctx.service.subProjPermission.getFinancailPermission(fAudit.fund_trans_permission, fAudit.fund_pay_permission);
+                        if (!financialPermission.pay_show) {
+                            fAudit.fund_pay_permission.push(1);
+                            const upPermission = {
+                                id: fAudit.id,
+                                fund_pay_permission: fAudit.fund_pay_permission.join(','),
+                            };
+                            if (!financialPermission.transfer_show) {
+                                fAudit.fund_trans_permission.push(1);
+                                upPermission.fund_tran_permission = fAudit.fund_trans_permission.join(',');
+                            }
+                            await transaction.update(this.ctx.service.subProjPermission.tableName, upPermission);
+                        }
                     }
                     await transaction.commit();
                     reponseData.permissionList = await this.getList(spid, tid);

+ 1 - 1
app/service/payment_detail.js

@@ -352,7 +352,7 @@ module.exports = app => {
         async doCheckDetail(id) {
             const status = auditConst.status;
             const accountId = this.ctx.session.sessionUser.accountId;
-            const auditPermission = await this.service.paymentPermissionAudit.getOnePermission(this.ctx.session.sessionUser.is_admin, accountId);
+            const auditPermission = await this.ctx.service.subProjPermission.getPaymentPermission(this.ctx.subProject.permission.payment_permission);
             if (!auditPermission) throw '权限不足';
 
             const detail = await this.getDataById(id);

+ 1 - 1
app/service/payment_detail_att.js

@@ -56,7 +56,7 @@ module.exports = app => {
             return result.map(item => {
                 item.orginpath = this.ctx.app.config.fujianOssPath + item.filepath;
                 if (!this.ctx.helper.canPreview(item.fileext)) {
-                    item.filepath = `/payment/${item.tender_id}/detail/${item.td_id}/file/${item.id}/download`;
+                    item.filepath = `'/sp/${this.ctx.subProject.id}/payment/${item.tender_id}/detail/${item.td_id}/file/${item.id}/download`;
                 } else {
                     item.filepath = this.ctx.app.config.fujianOssPath + item.filepath;
                     item.viewpath = item.filepath;

+ 2 - 6
app/service/payment_detail_audit.js

@@ -400,16 +400,12 @@ module.exports = app => {
                 const rptAuditList = await this.ctx.service.paymentRptAudit.getAllDataByCondition({ where: { td_id: detailId } });
                 const auditIdList = this._.map(auditList, 'aid');
                 const rptAuditIdList = this._.map(rptAuditList, 'uid');
-                const permissionAuditList = await this.ctx.service.paymentPermissionAudit.getAllDataByCondition({ where: { pid: this.ctx.session.sessionProject.id } });
+                const permissionAuditList = await this.ctx.service.subProjPermission.getPaymentAuditList(this.ctx.subProject.id);
                 const paIdList = this._.map(permissionAuditList, 'uid');
                 const detailIdList = this._.union(auditIdList, rptAuditIdList);
                 const newAudits = this._.difference(detailIdList, paIdList);
                 if (newAudits.length > 0) {
-                    const accountList = await this.ctx.service.projectAccount.getAllDataByCondition({
-                        where: { project_id: this.ctx.session.sessionProject.id, id: newAudits },
-                        columns: ['id', 'name', 'company', 'role', 'enable', 'is_admin', 'account_group', 'mobile'],
-                    });
-                    await this.ctx.service.paymentPermissionAudit.saveAudits(this.ctx.session.sessionProject.id, accountList, transaction);
+                    await this.ctx.service.subProjPermission.savePaymentPermissionAudits(this.ctx.subProject.id, newAudits, 'add', transaction);
                 }
                 // todo 更新标段tender状态 ?
                 await transaction.commit();

+ 47 - 11
app/service/payment_folder.js

@@ -19,14 +19,14 @@ module.exports = app => {
         async addFolder(projectId, uid, parentId = 0, name) {
             const transaction = await this.db.beginTransaction();
             try {
-                const tenderCount = await this.ctx.service.paymentTender.count({ folder_id: parentId });
+                const tenderCount = await this.ctx.service.paymentTender.count({ spid: this.ctx.subProject.id, folder_id: parentId });
                 if (tenderCount > 0) {
                     throw '文件夹下存在标段无法创建子文件夹';
                 }
                 let level = 1;
                 let parent_path = '';
                 if (parentId !== 0) {
-                    const parentFolderInfo = await this.getDataById(parentId);
+                    const parentFolderInfo = await this.getDataByCondition({ spid: this.ctx.subProject.id, folder_id: parentId });
                     if (!parentFolderInfo) throw '父文件夹不存在';
                     level = parentFolderInfo.level + level;
                     if (parentFolderInfo.is_leaf) {
@@ -34,12 +34,16 @@ module.exports = app => {
                     }
                     parent_path = parentFolderInfo.parent_path ? parentFolderInfo.parent_path + '-' + parentFolderInfo.id : parentFolderInfo.id;
                 }
-                const childrenCount = await transaction.count(this.tableName, { parent_id: parentId });
-                const order = childrenCount + 1;
+                const childrenCount = await transaction.select(this.tableName, { where: { spid: this.ctx.subProject.id, parent_id: parentId }, orders: [['order', 'desc']] });
+                const order = childrenCount && childrenCount.length > 0 ? childrenCount[0].order + 1 : 1;
+                const maxFolderId = await this.getMaxId(this.ctx.subProject.id);
                 const insertData = {
+                    id: this.uuid.v4(),
                     pid: projectId,
+                    spid: this.ctx.subProject.id,
                     uid,
                     name,
+                    folder_id: maxFolderId + 1,
                     parent_id: parentId,
                     parent_path,
                     level,
@@ -65,7 +69,7 @@ module.exports = app => {
                 }
                 let ids = [info.id];
                 if (info.parent_id === 0) {
-                    const childList = await this.getAllDataByCondition({ where: { parent_id: info.id } });
+                    const childList = await this.getAllDataByCondition({ where: { spid: this.ctx.subProject.id, parent_id: info.id } });
                     if (childList.length > 0) {
                         ids = [...ids, ...this._.map(childList, 'id')];
                         for (const c of childList) {
@@ -84,7 +88,7 @@ module.exports = app => {
                     }
                 }
                 // 判断是否存在标段,有则无法删除目录
-                const tenderCount = await this.ctx.service.paymentTender.count({ folder_id: ids });
+                const tenderCount = await this.ctx.service.paymentTender.count({ spid: this.ctx.subProject.id, folder_id: ids });
                 if (tenderCount > 0) {
                     throw '文件夹下存在标段,无法删除';
                 }
@@ -98,6 +102,10 @@ module.exports = app => {
 
         async getDataByParentPath(tableName, parent_path, transaction = null) {
             this.initSqlBuilder();
+            this.sqlBuilder.setAndWhere('spid', {
+                value: this.ctx.subProject.id,
+                operate: '=',
+            });
             this.sqlBuilder.setAndWhere('parent_path', {
                 value: this.db.escape(parent_path),
                 operate: 'Like',
@@ -115,14 +123,14 @@ module.exports = app => {
             });
             let folderList = [];
             if (auditPermission.view_all) {
-                folderList = await this.getAllDataByCondition({ where: { pid: this.ctx.session.sessionProject.id } });
+                folderList = await this.getAllDataByCondition({ where: { spid: this.ctx.subProject.id } });
             } else {
-                folderList = await this.getAllDataByCondition({ where: { uid } });
+                folderList = await this.getAllDataByCondition({ where: { spid: this.ctx.subProject.id, uid } });
                 // 再找出标段对应的目录及自建的目录下的子目录
                 if (tenderList.length > 0) {
                     for (const t of tenderList) {
-                        if (this._.findIndex(folderList, { id: t.folder_id }) === -1) {
-                            const folderInfo = await this.getDataById(t.folder_id);
+                        if (this._.findIndex(folderList, { folder_id: t.folder_id }) === -1) {
+                            const folderInfo = await this.getDataByCondition({ spid: this.ctx.subProject.id, folder_id: t.folder_id });
                             folderList.push(folderInfo);
                         }
                     }
@@ -148,7 +156,7 @@ module.exports = app => {
                         }
                     }
                     if (allNotExistFolderIds.length > 0) {
-                        const newFolderList = await this.getAllDataByCondition({ where: { id: allNotExistFolderIds } });
+                        const newFolderList = await this.getAllDataByCondition({ where: { spid: this.ctx.subProject.id, folder_id: allNotExistFolderIds } });
                         folderList = [...folderList, ...newFolderList];
                     }
                 }
@@ -163,6 +171,34 @@ module.exports = app => {
             return folderList;
         }
 
+        async getNoSpList(pid) {
+            // 获取所有项目参与者
+            const accountList = await this.ctx.service.projectAccount.getAllDataByCondition({
+                where: { project_id: this.ctx.session.sessionProject.id, enable: 1 },
+                columns: ['id', 'name'],
+            });
+            const folderList = await this.getAllDataByCondition({ where: { pid, spid: '' } });
+            if (folderList.length > 0) {
+                // folderList = this._.uniqBy(folderList, 'id');
+                for (const f of folderList) {
+                    const userInfo = this._.find(accountList, { id: f.uid });
+                    f.user_name = userInfo ? userInfo.name : '';
+                }
+            }
+            return folderList;
+        }
+
+        async getMaxId(spid, needFlag = false) {
+            const result = await this.db.queryOne(`select max(folder_id) as max_id from ${this.tableName} where spid = ?`, [spid]);
+            const maxId = result ? result.max_id : 0;
+            if (needFlag) {
+                const oldResult = await this.db.queryOne(`select max(folder_id) as max_id from ${this.tableName} where pid = ? AND spid = ?`, [this.ctx.session.sessionProject.id, '']);
+                const oldMaxId = oldResult ? oldResult.max_id : 0;
+                return maxId > oldMaxId ? maxId : oldMaxId;
+            }
+            return maxId;
+        }
+
         // async getChildrenByParentId(parentId, transaction = null) {
         //     const list = await this.getAllDataByCondition({ where: { parent_id: parentId } });
         // }

+ 1 - 1
app/service/payment_permission_audit.js

@@ -66,7 +66,7 @@ module.exports = app => {
             return await this.db.delete(this.tableName, { id });
         }
 
-        async getOnePermission(is_admin, uid) {
+        async getOnePermission(is_admin, spid, uid) {
             if (is_admin) {
                 return paymentConst.audit_admin_permission;
             }

+ 107 - 6
app/service/payment_tender.js

@@ -19,13 +19,12 @@ module.exports = app => {
 
         async getList(uid, auditPermission) {
             if (auditPermission.view_all) {
-                const sql1 = 'SELECT pt.*, pa.name as user_name FROM ?? as pt LEFT JOIN ?? as pa ON pt.`uid` = pa.`id` WHERE pid = ?';
-                const params1 = [this.tableName, this.ctx.service.projectAccount.tableName, this.ctx.session.sessionProject.id];
+                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` = ?';
+                const params1 = [this.tableName, this.ctx.service.projectAccount.tableName, this.ctx.session.sessionProject.id, this.ctx.subProject.id];
                 return await this.db.query(sql1, params1);
             }
             const typeValues = [];
-            const projectInfo = await this.ctx.service.project.getDataById(this.ctx.session.sessionProject.id);
-            const modes = projectInfo.payment_setting ? JSON.parse(projectInfo.payment_setting) : this._.cloneDeep(paymentConst.setting_modes);
+            const modes = this.ctx.subProject.payment_setting ? JSON.parse(this.ctx.subProject.payment_setting) : this._.cloneDeep(paymentConst.setting_modes);
             for (const m in paymentConst.setting_modes) {
                 if (!modes[m]) modes[m] = this._.cloneDeep(paymentConst.setting_modes[m]);
                 if (modes[m].checked) {
@@ -35,14 +34,14 @@ module.exports = app => {
             if (typeValues.length === 0) {
                 return -1;
             }
-            const sql = 'SELECT pt.*, pa.name as user_name FROM ?? as pt LEFT JOIN ?? as pa ON pt.`uid` = pa.`id` WHERE pid = ? AND (pt.`uid` = ? ' +
+            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` = ? ' +
                 'OR pt.`id` in (SELECT pr.`tender_id` FROM ?? as pr WHERE pr.`uid` = ? AND pr.`type` IN (' + this.ctx.helper.getInArrStrSqlFilter(typeValues) + '))' +
                 'OR pt.`id` in (SELECT pd.`tender_id` FROM ?? as pd WHERE pd.`uid` = ?)' +
                 'OR pt.`id` in (SELECT pda.`tender_id` FROM ?? as pda LEFT JOIN ?? as pd ON pda.`tender_id` = pd.`tender_id` ' +
                 'WHERE pd.`status` != ' + auditConst.status.uncheck + ' AND pda.`aid` = ?)' +
                 'OR pt.`id` in (SELECT pra.`tender_id` FROM ?? as pra LEFT JOIN ?? as pd ON pra.`tender_id` = pd.`tender_id` ' +
                 'WHERE pd.`status` != ' + auditConst.status.uncheck + ' AND pd.`status` !=' + auditConst.status.checkNo + ' AND pra.`uid` = ?))';
-            const params = [this.tableName, this.ctx.service.projectAccount.tableName, this.ctx.session.sessionProject.id, uid,
+            const params = [this.tableName, this.ctx.service.projectAccount.tableName, this.ctx.session.sessionProject.id, this.ctx.subProject.id, uid,
                 this.ctx.service.paymentTenderRpt.tableName, uid,
                 this.ctx.service.paymentDetail.tableName, uid,
                 this.ctx.service.paymentDetailAudit.tableName, this.ctx.service.paymentDetail.tableName, uid,
@@ -50,6 +49,13 @@ module.exports = app => {
             return await this.db.query(sql, params);
         }
 
+        async getNoSpList(pid, spIsNull = true) {
+            const spSql = spIsNull ? ' AND pt.`spid` = ?' : ' AND pt.`spid` != ?';
+            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;
+            const params1 = [this.tableName, this.ctx.service.projectAccount.tableName, pid, ''];
+            return await this.db.query(sql1, params1);
+        }
+
         async addTender(projectId, uid, folderId, name) {
             const transaction = await this.db.beginTransaction();
             try {
@@ -59,6 +65,7 @@ module.exports = app => {
                 }
                 const insertData = {
                     pid: projectId,
+                    spid: this.ctx.subProject.id,
                     uid,
                     name,
                     folder_id: folderId,
@@ -147,6 +154,100 @@ module.exports = app => {
         async doCheckTender(id) {
             return await this.service.paymentTender.getDataById(id);
         }
+
+        async bindSp(tids) {
+            const noSpTenderList = await this.getNoSpList(this.ctx.session.sessionProject.id);
+            const noSpFolderList = await this.ctx.service.paymentFolder.getNoSpList(this.ctx.session.sessionProject.id);
+            const transaction = await this.db.beginTransaction();
+            try {
+                const hadSpTenderList = await this.getNoSpList(this.ctx.session.sessionProject.id, false);
+                if (tids.length === noSpTenderList.length && hadSpTenderList.length === 0) {
+                    // 一次性迁移所有可以不用复制folder数据,也不用调整tender数据,直接更新spid
+                    await transaction.update(this.tableName, { spid: this.ctx.subProject.id }, { where: { pid: this.ctx.session.sessionProject.id } });
+                    await transaction.update(this.ctx.service.paymentFolder.tableName, { spid: this.ctx.subProject.id }, { where: { pid: this.ctx.session.sessionProject.id } });
+                } else {
+                    const hadSpTenderIds = hadSpTenderList.map(item => item.id);
+                    // tids里过滤掉hadSpTenderIds存在的值
+                    const filterTids = tids.filter(item => !hadSpTenderIds.includes(item));
+                    if (filterTids.length > 0) {
+                        const folderList = await this.ctx.service.paymentFolder.getAllDataByCondition({ where: { spid: this.ctx.subProject.id } });
+                        // 需要复制一份folder数据,且比对folderList,如果存在则不复制,且可能需要调整id,parent_id,parent_path, order值
+                        const allNotExistFolderIds = [];
+                        for (const tid of filterTids) {
+                            const tender = this._.find(noSpTenderList, { id: tid });
+                            if (tender) {
+                                const parentFolder = this._.find(noSpFolderList, { folder_id: tender.folder_id });
+                                if (parentFolder) {
+                                    const spParentFolder = this._.find(folderList, { folder_id: tender.folder_id });
+                                    if (!spParentFolder) allNotExistFolderIds.push(tender.folder_id);
+                                    const parentPathArray = parentFolder.parent_path ? this._.map(parentFolder.parent_path.split('-'), this._.toInteger) : [];
+                                    if (parentPathArray.length > 0) {
+                                        for (const id of parentPathArray) {
+                                            const spFolder = this._.find(folderList, { folder_id: id });
+                                            if (!spFolder && !this._.includes(allNotExistFolderIds, id)) {
+                                                allNotExistFolderIds.push(id);
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                        const newFolderList = [];
+                        if (allNotExistFolderIds.length > 0) {
+                            const allNotExistFolderList = this._.orderBy(this._.filter(noSpFolderList, item => this._.includes(allNotExistFolderIds, item.folder_id)), ['in_time'], ['asc']);
+                            for (const f of allNotExistFolderList) {
+                                newFolderList.push({
+                                    id: this.uuid.v4(),
+                                    pid: this.ctx.session.sessionProject.id,
+                                    spid: this.ctx.subProject.id,
+                                    uid: f.uid,
+                                    name: f.name,
+                                    folder_id: f.folder_id,
+                                    parent_id: f.parent_id,
+                                    parent_path: f.parent_path,
+                                    level: f.level,
+                                    order: f.order,
+                                    is_leaf: f.is_leaf,
+                                    had_tender: f.had_tender,
+                                    in_time: f.in_time,
+                                });
+                            }
+                        }
+                        await transaction.update(this.tableName, { spid: this.ctx.subProject.id }, { where: { id: filterTids } });
+                        if (newFolderList.length > 0) await transaction.insert(this.ctx.service.paymentFolder.tableName, newFolderList);
+                    }
+                }
+                // 权限也要迁移至本子项目
+                const ppAudits = await this.ctx.service.paymentPermissionAudit.getAllDataByCondition({ where: { pid: this.ctx.session.sessionProject.id } });
+                for (const audit of ppAudits) {
+                    if (audit.uid) {
+                        const spAudit = await this.ctx.service.subProjPermission.getDataByCondition({ spid: this.ctx.subProject.id, uid: audit.uid });
+                        const payment_permission = [1];
+                        const one_pp = audit.permission_json ? JSON.parse(audit.permission_json) : null;
+                        if (one_pp) {
+                            if (one_pp.admin) payment_permission.push(2);
+                            if (one_pp.view_all) payment_permission.push(3);
+                        }
+                        const new_payment_permission = payment_permission.join(',');
+                        console.log(spAudit, new_payment_permission);
+                        if (spAudit && spAudit.payment_permission !== new_payment_permission) {
+                            await transaction.update(this.ctx.service.subProjPermission.tableName, { id: spAudit.id, payment_permission: new_payment_permission });
+                        } else if (!spAudit) {
+                            const a = await this.ctx.service.projectAccount.getDataById(audit.uid);
+                            if (a) {
+                                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 };
+                                await transaction.insert(this.ctx.service.subProjPermission.tableName, sp_permission);
+                            }
+                        }
+                    }
+                }
+                await transaction.commit();
+            } catch (err) {
+                await transaction.rollback();
+                throw err;
+            }
+            return true;
+        }
     }
     return paymentTender;
 };

+ 1 - 1
app/service/payment_tender_rpt.js

@@ -237,7 +237,7 @@ module.exports = app => {
                 const result1 = await this.ctx.service.paymentDetail.updateReport(transaction, tr_id, data.uid);
                 // 判断固定审批流或固定终审是否存在上报人,有则移除
                 const result2 = await this.ctx.service.paymentShenpiAudit.removeAuditByReport(transaction, tr_id, data.uid);
-                await this.ctx.service.paymentPermissionAudit.saveAudits(this.ctx.session.sessionProject.id, [userInfo], transaction);
+                await this.ctx.service.subProjPermission.savePaymentPermissionAudits(this.ctx.subProject.id, [data.uid], 'add', transaction);
                 await transaction.commit();
                 let tenderRptList = await this.getProcessList(this.ctx.paymentTender.id);
                 tenderRptList = this._.filter(tenderRptList, { type: 0, is_del: 0 });

+ 5 - 5
app/service/project_account.js

@@ -782,7 +782,6 @@ module.exports = app => {
             } else {
                 updateData.wx_type = JSON.stringify(data);
             }
-            console.log(updateData);
 
             const operate = await this.db.update(this.tableName, updateData);
 
@@ -1037,8 +1036,9 @@ module.exports = app => {
         }
 
         async getAllSubProjectAccount(subProject, columns) {
-            // const defaultColumns = ['id', 'name', 'company', 'role', 'enable', 'is_admin', 'account_group', 'mobile', 'company_id'];
-            const defaultColumns = ['id', 'name', 'company', 'role', 'enable', 'is_admin', 'account_group', 'mobile', 'company_id', 'account', 'telephone', 'permission', 'sign_path', 'stamp_path']; // 新加的字段给报表用
+            // 请勿随意修改defaultColumns
+            const defaultColumns = ['id', 'name', 'company', 'role', 'enable', 'is_admin', 'account_group', 'mobile', 'company_id'];
+            // const defaultColumns = ['id', 'name', 'company', 'role', 'enable', 'is_admin', 'account_group', 'mobile', 'company_id', 'account', 'telephone', 'permission', 'sign_path', 'stamp_path']; // 新加的字段给报表用
             const columnsSql = columns
                 ? columns.map(x => { return 'pa.`' + x + '`'; }).join(', ')
                 : defaultColumns.map(x => { return 'pa.`' + x + '`'; }).join(', ');
@@ -1080,7 +1080,7 @@ module.exports = app => {
             if (filter) filterInfo.push({ filter, tableName: 'pa' });
             const filterSql = this._getFilterSql(filterInfo);
             const sql = `SELECT pa.*, spp.id AS permission_id, 
-                    spp.file_permission, spp.budget_permission, spp.info_permission, spp.datacollect_permission, spp.fund_trans_permission, spp.fund_pay_permission, spp.contract_permission 
+                    spp.file_permission, spp.budget_permission, spp.info_permission, spp.datacollect_permission, spp.fund_trans_permission, spp.fund_pay_permission, spp.contract_permission, spp.payment_permission
                 FROM ${this.ctx.service.subProjPermission.tableName} spp LEFT JOIN ${this.tableName} pa ON spp.uid = pa.id WHERE ` + filterSql + ' ORDER BY spp.create_time DESC';
             const result = await this.db.query(sql);
             return result;
@@ -1093,7 +1093,7 @@ module.exports = app => {
             const limit = this.ctx.pageSize ? this.ctx.pageSize : this.app.config.pageSize;
             const offset = limit * (this.ctx.page - 1);
             const sql = `SELECT pa.*, spp.id AS permission_id, 
-                    spp.file_permission, spp.budget_permission, spp.info_permission, spp.datacollect_permission, spp.fund_trans_permission, spp.fund_pay_permission, spp.contract_permission 
+                    spp.file_permission, spp.budget_permission, spp.info_permission, spp.datacollect_permission, spp.fund_trans_permission, spp.fund_pay_permission, spp.contract_permission, spp.payment_permission 
                 FROM ${this.ctx.service.subProjPermission.tableName} spp LEFT JOIN ${this.tableName} pa ON spp.uid = pa.id WHERE ` + filterSql + ' ORDER BY spp.create_time DESC LIMIT ?, ?';
             const result = await this.db.query(sql, [offset, limit]);
             return result;

+ 48 - 0
app/service/report.js

@@ -439,6 +439,54 @@ module.exports = app => {
                             runnableRst.push(service.constructionUnit.getReportData(this.ctx.session.sessionProject.id));
                             runnableKey.push(filter);
                             break;
+                        case 'contract_tree_1':
+                            runnableRst.push(service.reportMemory.getContractTree(params.tender_id, 1));
+                            runnableKey.push(filter);
+                            break;
+                        case 'contract_1':
+                            runnableRst.push(service.reportMemory.getContract(params.tender_id, 1));
+                            runnableKey.push(filter);
+                            break;
+                        case 'contract_pay_1':
+                            runnableRst.push(service.reportMemory.getContractPay(params.tender_id, 1));
+                            runnableKey.push(filter);
+                            break;
+                        case 'contract_tree_2':
+                            runnableRst.push(service.reportMemory.getContractTree(params.tender_id, 2));
+                            runnableKey.push(filter);
+                            break;
+                        case 'contract_2':
+                            runnableRst.push(service.reportMemory.getContract(params.tender_id, 2));
+                            runnableKey.push(filter);
+                            break;
+                        case 'contract_pay_2':
+                            runnableRst.push(service.reportMemory.getContractPay(params.tender_id, 2));
+                            runnableKey.push(filter);
+                            break;
+                        case 'sp_contract_tree_1':
+                            runnableRst.push(service.reportMemory.getSpContractTree(params.tender_id, 1));
+                            runnableKey.push(filter);
+                            break;
+                        case 'sp_contract_1':
+                            runnableRst.push(service.reportMemory.getSpContract(params.tender_id, 1));
+                            runnableKey.push(filter);
+                            break;
+                        case 'sp_contract_pay_1':
+                            runnableRst.push(service.reportMemory.getSpContractPay(params.tender_id, 1));
+                            runnableKey.push(filter);
+                            break;
+                        case 'sp_contract_tree_2':
+                            runnableRst.push(service.reportMemory.getSpContractTree(params.tender_id, 2));
+                            runnableKey.push(filter);
+                            break;
+                        case 'sp_contract_2':
+                            runnableRst.push(service.reportMemory.getSpContract(params.tender_id, 2));
+                            runnableKey.push(filter);
+                            break;
+                        case 'sp_contract_pay_2':
+                            runnableRst.push(service.reportMemory.getSpContractPay(params.tender_id, 2));
+                            runnableKey.push(filter);
+                            break;
                         default:
                             break;
                     }

+ 85 - 0
app/service/report_memory.js

@@ -1044,6 +1044,44 @@ module.exports = app => {
             }
         }
 
+        async getChangeLedgerBillsData(tid, showLevel) {
+            try {
+                await this.ctx.service.tender.checkTender(tid);
+
+                const billsData = await this.ctx.service.ledger.getData(this.ctx.tender.id);
+                const changeBillsData = await this.ctx.service.changeLedger.getAllDataByCondition({ where: { tender_id: tid } });
+                billsData.push(...changeBillsData);
+
+                const billsTree = this._getNewBillsTree();
+                billsTree.loadDatas(billsData);
+                billsTree.calculateAll();
+
+                if (this._checkFieldsExist(fields, billsFields.leafXmj)) {
+                    this._calcLeafXmjRela(billsTree);
+                }
+
+                return showLevel ? billsTree.getDefaultDatasByLevel(this.ctx.tender.rpt_show_level) : billsTree.getDefaultDatas();
+            } catch(err) {
+                this.ctx.log(err);
+                return [];
+            }
+        }
+
+        async getChangeLedgerPosData(tid) {
+
+            try {
+                await this.ctx.service.tender.checkTender(tid);
+
+                const posData = await this.ctx.service.pos.getAllDataByCondition({ where: {tid: this.ctx.tender.id }});
+                this.pos.loadDatas(posData);
+                this.pos.calculateAll();
+
+                return this.pos.getDatas();
+            } catch (err) {
+                return [];
+            }
+        }
+
         async _generateImportChange(sid) {
             if (this.importChange !== undefined) return;
             const self = this;
@@ -1651,6 +1689,53 @@ module.exports = app => {
             });
             return result;
         }
+
+        async _getContractTree(condition) {
+            const data = await this.ctx.service.contractTree.getAllDataByCondition({ where: condition });
+            const contract_data = await this.ctx.service.contract.getAllDataByCondition({ where: condition });
+            const tree = new Ledger.billsTree(this.ctx, {
+                id: 'contract_id',
+                pid: 'contract_pid',
+                order: 'order',
+                level: 'level',
+                rootId: -1,
+                calcFields: [ 'total_price', 'pay_price', 'debit_price', 'yf_price', 'sf_price'],
+                calc: function (node, helper, decimal) {},
+            });
+            tree.loadDatas([...data, ...contract_data]);
+            return tree.getDefaultDatas();
+        }
+        async _getContract(condition) {
+            const data = await this.ctx.service.contract.getAllDataByCondition({ where: condition });
+            return data;
+        }
+        async _getContractPay(condition) {
+            const data = await this.ctx.service.contractPay.getAllDataByCondition({ where: condition, orders: [['cid', 'asc'], ['create_time', 'asc']] });
+            return data;
+        }
+
+        async getContractTree(tid, contract_type) {
+            return await this._getContractTree({ tid, contract_type });
+        }
+        async getContract(tid, contract_type) {
+            return await this._getContract({ tid, contract_type });
+        }
+        async getContractPay(tid, contract_type) {
+            return await this._getContractPay({ tid, contract_type });
+        }
+
+        async getSpContractTree(tid, contract_type) {
+            await this.ctx.service.tender.checkTender(tid);
+            return await this._getContractTree({ spid: this.ctx.tender.spid, contract_type });
+        }
+        async getSpContract(tid, contract_type) {
+            await this.ctx.service.tender.checkTender(tid);
+            return await this._getContract({ spid: this.ctx.tender.spid, contract_type });
+        }
+        async getSpContractPay(tid, contract_type) {
+            await this.ctx.service.tender.checkTender(tid);
+            return await this._getContractPay({ spid: this.ctx.tender.spid, contract_type });
+        }
     }
 
     return ReportMemory;

+ 1 - 1
app/service/stage_audit.js

@@ -1860,7 +1860,7 @@ module.exports = app => {
                 'SELECT sa.`aid`, sa.`times`, sa.`begin_time`, sa.`end_time`, sa.`tid`, sa.`sid`,' +
                 // '    s.`order` As `sorder`, s.`status` As `sstatus`, s.`s_time`, s.`contract_tp`, s.`qc_tp`, s.`pre_contract_tp`, s.`pre_qc_tp`, s.`yf_tp`, s.`pre_yf_tp`, ' +
                 '    s.*,' +
-                '    t.`name`, t.`project_id`, t.`type`, t.`user_id`,' +
+                '    t.`name`, t.`project_id`, t.`type`, t.`user_id`, t.`spid`,' +
                 '    ti.`deal_info` ' +
                 '  FROM ?? AS sa' +
                 '    Left Join ?? AS s On sa.`sid` = s.`id`' +

+ 232 - 9
app/service/sub_proj_permission.js

@@ -49,9 +49,9 @@ module.exports = app => {
                 contract: {
                     edit: { title: '编辑节点', value: 1 },
                     add: { title: '添加合同', value: 2 },
-                    node: { title: '授权查看本节点合同', value: 3 },
-                    unit: { title: '授权查看本单位合同', value: 4 },
-
+                    node: { title: '授权节点下查看本节点合同', value: 3 },
+                    unit: { title: '授权节点下查看本单位合同', value: 4 },
+                    view: { title: '查看所有合同', value: 5 },
                 },
                 fund_trans: {
                     view: { title: '查看', value: 1 },
@@ -62,11 +62,22 @@ module.exports = app => {
                     view: { title: '查看', value: 1 },
                     att: { title: '上传附件', value: 3 },
                 },
+                payment: {
+                    view: { title: '查看', value: 1 },
+                    admin: { title: '模块管理员', value: 2 },
+                    view_all: { title: '查看所有标段', value: 3 },
+                }
             };
             this.PermissionBlock = [
                 { key: 'datacollect', name: '决策大屏', field: 'datacollect_permission' },
                 { key: 'info', name: '项目概况', field: 'info_permission' },
-                { key: 'contract', name: '合同管理', field: 'contract_permission', hint: ['1、编辑节点:编辑合同管理内页树结构', '2、添加合同:允许添加合同', '3、授权查看本节点合同:授权节点下查看所有人上传的合同', '4、授权查看本单位合同:授权节点下查看本单位人员添加的所有合同'] },
+                { key: 'contract', name: '合同管理', field: 'contract_permission', hint: ['1、编辑节点:编辑合同管理内页树结构',
+                        '2、添加合同:允许添加合同',
+                        '3、授权节点下查看本节点合同:授权节点下查看所有人上传的合同',
+                        '4、授权节点下查看本单位合同:授权节点下查看本单位人员添加的所有合同',
+                        '5、查看所有合同:未授权节点情况下可以查看包括其他单位人员添加的合同',
+                        '注:查看合同第3、4、5必须选择其一,否则无法查看本项目合同管理',
+                    ] },
                 { key: 'file', name: '资料归集', field: 'file_permission' },
                 { key: 'budget', name: '动态投资', field: 'budget_permission' },
                 {
@@ -75,6 +86,7 @@ module.exports = app => {
                         { key: 'fund_pay', name: '资金支付', field: 'fund_pay_permission' },
                     ]
                 },
+                { key: 'payment', name: '支付审批', field: 'payment_permission' },
             ];
             for (const p of this.PermissionBlock) {
                 if (p.children) {
@@ -97,6 +109,17 @@ module.exports = app => {
             }
         }
 
+        getRelaPermissionBlock(key) {
+            for (const p of this.PermissionBlock) {
+                if (p.key === key) return p;
+                if (p.children) {
+                    for (const c of p.children) {
+                        if (c.key === key) return c;
+                    }
+                }
+            }
+        }
+
         get adminPermission () {
             return {
                 budget_permission: this.ctx.helper.mapAllSubField(this.PermissionConst.budget, 'value'),
@@ -108,11 +131,13 @@ module.exports = app => {
                 contract_permission: this.ctx.helper.mapAllSubField(this.PermissionConst.contract, 'value'),
                 fund_pay_permission: this.ctx.helper.mapAllSubField(this.PermissionConst.fund_pay, 'value'),
                 fund_trans_permission: this.ctx.helper.mapAllSubField(this.PermissionConst.fund_trans, 'value'),
+                payment_permission: this.ctx.helper.mapAllSubField(this.PermissionConst.payment, 'value'),
             }
         }
 
-        async showSubTab(uid, type) {
-            const sql = `SELECT count(*) as count FROM ${this.tableName} WHERE ${type}_permission <> '' AND uid = ?`;
+        async showSubTab(uid, type, spid = null) {
+            const spidSql = spid ? ` AND spid = ${spid}` : '';
+            const sql = `SELECT count(*) as count FROM ${this.tableName} WHERE ${type}_permission <> '' AND uid = ?` + spidSql;
             const result = await this.db.queryOne(sql, [uid]);
             return result.count;
         }
@@ -122,6 +147,9 @@ module.exports = app => {
         async showFile(uid) {
             return await this.showSubTab(uid, 'file');
         }
+        async showPayment(uid, spid) {
+            return await this.showSubTab(uid, 'payment', spid);
+        }
 
         parsePermission(data) {
             const _ = this.ctx.helper._;
@@ -136,6 +164,7 @@ module.exports = app => {
                 x.fund_pay_permission = x.fund_pay_permission ? _.map(x.fund_pay_permission.split(','), _.toInteger) : [];
                 x.fund_trans_permission = x.fund_trans_permission ? _.map(x.fund_trans_permission.split(','), _.toInteger) : [];
                 x.filing_type = x.filing_type ? _.map(x.filing_type.split(','), _.toInteger): [];
+                x.payment_permission = x.payment_permission ? _.map(x.payment_permission.split(','), _.toInteger) : [];
             });
         }
 
@@ -235,7 +264,8 @@ module.exports = app => {
         async _updateUserPermission(data) {
             const datas = data instanceof Array ? data : [data];
             const updateData = [];
-            datas.forEach(x => {
+            // const contractData = [];
+            for (const x of datas) {
                 const ud = { id: x.id };
                 for (const p of this.PermissionBlock) {
                     if (p.children) {
@@ -244,11 +274,65 @@ module.exports = app => {
                         }
                     } else {
                         if (x[p.field] !== undefined) ud[p.field] = x[p.field] || '';
+                        // if (p.field === 'contract_permission') {
+                        //     const spAudit = await this.getDataById(x.id);
+                        //     if (spAudit) {
+                        //         const contractAudit = await this.ctx.service.contractAudit.getDataByCondition({ spid: spAudit.spid, uid: spAudit.uid });
+                        //         const contractPermission = x.contract_permission ? this._.map(x.contract_permission.split(','), this._.toInteger) : [];
+                        //         const newContractPermission = contractPermission.length > 0 ? await this.getContractPermission(contractPermission) : [];
+                        //         console.log(newContractPermission, contractAudit);
+                        //         if (!contractAudit && contractPermission.length === 0) continue;
+                        //         if (contractAudit) {
+                        //             if (contractPermission.length === 0 || this._.intersection([3,4,5], contractPermission).length === 0) {
+                        //                 contractData.push({ delete: { id: contractAudit.id }});
+                        //             } else if (contractAudit.permission_add !== newContractPermission.permission_add ||
+                        //                 contractAudit.permission_edit !== newContractPermission.permission_edit ||
+                        //                 contractAudit.permission_show_unit !== newContractPermission.permission_show_unit ||
+                        //                 contractAudit.permission_show_node !== newContractPermission.permission_show_node) {
+                        //                 contractData.push({ update: { id: contractAudit.id,
+                        //                     permission_add: newContractPermission.permission_add,
+                        //                     permission_edit: newContractPermission.permission_edit,
+                        //                     permission_show_unit: newContractPermission.permission_show_unit,
+                        //                     permission_show_node: newContractPermission.permission_show_node,
+                        //                 }});
+                        //             }
+                        //         } else if (!contractAudit && contractPermission.length > 0) {
+                        //             contractData.push({ add: {
+                        //                 spid: spAudit.spid,
+                        //                 tid: null,
+                        //                 uid: spAudit.uid,
+                        //                 permission_add: newContractPermission.permission_add,
+                        //                 permission_edit: newContractPermission.permission_edit,
+                        //                 permission_show_unit: newContractPermission.permission_show_unit,
+                        //                 permission_show_node: newContractPermission.permission_show_node,
+                        //                 create_time: new Date(),
+                        //             }});
+                        //         }
+                        //     }
+                        // }
                     }
                 }
                 updateData.push(ud);
-            });
-            await this.db.updateRows(this.tableName, updateData);
+            }
+            const conn = await this.db.beginTransaction();
+            try {
+                // if (contractData.length > 0) {
+                //     for (const d of contractData) {
+                //         if (d.add) {
+                //             await conn.insert(this.ctx.service.contractAudit.tableName, d.add);
+                //         } else if (d.update) {
+                //             await conn.update(this.ctx.service.contractAudit.tableName, d.update);
+                //         } else if (d.delete) {
+                //             await conn.delete(this.ctx.service.contractAudit.tableName, d.delete);
+                //         }
+                //     }
+                // }
+                await conn.updateRows(this.tableName, updateData);
+                await conn.commit();
+            } catch(err) {
+                await conn.rollback();
+                throw err;
+            }
             return updateData;
         }
 
@@ -297,12 +381,151 @@ module.exports = app => {
                     if (!viewPermission || ctx.subProject.permission[c.field].indexOf(viewPermission.value) >= 0) canView = true;
                 }
                 return canView;
+            } else if (ctx.controllerName === 'contract') {
+                if (ctx.url.indexOf('contract/tender') >= 0) return true;
+                const contractViewPermission = this._.map(permissionBlock.permission.filter(x => { return ['view', 'unit', 'node'].indexOf(x.key) >= 0; }), 'value');
+                if (!contractViewPermission) return true;
+                return this._.intersection(ctx.subProject.permission[permissionBlock.field], contractViewPermission).length > 0;
             } else {
                 const viewPermission = permissionBlock.permission.find(x => { return x.key === 'view'; });
                 if (!viewPermission) return true;
                 return ctx.subProject.permission[permissionBlock.field].indexOf(viewPermission.value) >= 0;
             }
         };
+
+        async getContractAuditList(spid, uid = null) {
+            const uidSql = uid ? 'AND uid in (' + uid.join(',') + ')' : '';
+            const sql = `SELECT * FROM ?? WHERE spid = ? AND contract_permission <> ''` + uidSql;
+            const sqlParams = [this.tableName, spid];
+            const result = await this.db.query(sql, sqlParams);
+            const list = [];
+            for (const r of result) {
+                const permission = await this.getContractPermission(this._.map(r.contract_permission.split(','), this._.toInteger));
+                list.push({
+                    id: r.id,
+                    spid: r.spid,
+                    tid: null,
+                    uid: r.uid,
+                    permission_add: permission.permission_add,
+                    permission_edit: permission.permission_edit,
+                    permission_show_node: permission.permission_show_node,
+                    permission_show_unit: permission.permission_show_unit,
+                });
+            }
+            return list;
+        }
+
+        async getNewContractPermission(permission, newContractPermission) {
+            const oldPermission = await this.getContractPermission(this._.map(permission.split(','), this._.toInteger));
+            if (newContractPermission.permission_add !== undefined) {
+                oldPermission.permission_add = newContractPermission.permission_add;
+            }
+            if (newContractPermission.permission_edit !== undefined) {
+                oldPermission.permission_edit = newContractPermission.permission_edit;
+            }
+            if (newContractPermission.permission_show_node !== undefined) {
+                oldPermission.permission_show_node = newContractPermission.permission_show_node;
+            }
+            if (newContractPermission.permission_show_unit !== undefined) {
+                oldPermission.permission_show_unit = newContractPermission.permission_show_unit;
+            }
+            const permissionArr = [];
+            if (oldPermission.permission_edit) permissionArr.push(1);
+            if (oldPermission.permission_add) permissionArr.push(2);
+            if (oldPermission.permission_show_node) permissionArr.push(3);
+            if (oldPermission.permission_show_unit) permissionArr.push(4);
+            if (!oldPermission.permission_show_unit && !oldPermission.permission_show_node) permissionArr.push(5);
+            return permissionArr.join(',');
+        }
+
+        async getContractPermission(cp) {
+            const permission = {
+                permission_edit: cp.indexOf(1) !== -1 ? 1: 0,
+                permission_add: cp.indexOf(2) !== -1 ? 1: 0,
+                permission_show_node: cp.indexOf(3) !== -1 ? 1: 0,
+                permission_show_unit: cp.indexOf(4) !== -1 ? 1: 0,
+            };
+            return permission;
+        }
+
+        async getFinancailPermission(trans_permission, pay_permission) {
+            const permission = {
+                transfer_show: trans_permission.indexOf(1) !== -1,
+                transfer_add: trans_permission.indexOf(2) !== -1,
+                transfer_file: trans_permission.indexOf(3) !== -1,
+                pay_show: pay_permission.indexOf(1) !== -1,
+                pay_file: pay_permission.indexOf(3) !== -1,
+            };
+            return permission;
+        }
+
+        async getPaymentAuditList(spid, uid = null) {
+            const uidSql = uid ? 'AND uid in (' + uid.join(',') + ')' : '';
+            const sql = `SELECT * FROM ?? WHERE spid = ? AND payment_permission <> ''` + uidSql;
+            const sqlParams = [this.tableName, spid];
+            const result = await this.db.query(sql, sqlParams);
+            const list = [];
+            for (const r of result) {
+                const permission = await this.getPaymentPermission(this._.map(r.payment_permission.split(','), this._.toInteger));
+                const accountInfo = await this.ctx.service.projectAccount.getDataById(r.uid);
+                list.push({
+                    id: r.id,
+                    name: accountInfo.name,
+                    company: accountInfo.company,
+                    uid: r.uid,
+                    permission_json: permission,
+                });
+            }
+            return list;
+        }
+
+        async getPaymentPermission(pp) {
+            if (!pp || pp.length === 0) return false;
+            const permission = {
+                admin: pp.indexOf(2) !== -1,
+                view_all: pp.indexOf(3) !== -1,
+            };
+            return permission;
+        }
+
+        async savePaymentPermissionAudits(spid, uids, operation = 'add', transaction= null) {
+            const updateArr = [];
+            const spAudits = await this.getAllDataByCondition({ where: { spid: spid, uid: uids } });
+            for (const a of spAudits) {
+                if (operation === 'add' && a.payment_permission !== '') continue;
+                updateArr.push({
+                    id: a.id,
+                    payment_permission: operation === 'add' ? '1' : (operation === 'del' ? '' : a.payment_permission),
+                });
+            }
+            if (updateArr.length > 0) transaction ? await transaction.updateRows(this.tableName, updateArr) : await this.db.updateRows(this.tableName, updateArr);
+        }
+
+        async updateOnePaymentPermission(spid, updateData) {
+            if (!updateData.uid || !updateData.permission_json) {
+                return false;
+            }
+            const spAudit = await this.getDataByCondition({ spid: spid, uid: updateData.uid });
+            if (spAudit) {
+                const newPermission = await this.getNewPaymentPermission(spAudit.payment_permission, updateData.permission_json);
+                return await this.db.update(this.tableName, { id: spAudit.id, payment_permission: newPermission });
+            }
+            return false;
+        }
+
+        async getNewPaymentPermission(permission, newPermission) {
+            const oldPermission = await this.getPaymentPermission(this._.map(permission.split(','), this._.toInteger));
+            if (newPermission.admin !== undefined) {
+                oldPermission.admin = newPermission.admin;
+            }
+            if (newPermission.view_all !== undefined) {
+                oldPermission.view_all = newPermission.view_all;
+            }
+            const permissionArr = [1];
+            if (oldPermission.admin) permissionArr.push(2);
+            if (oldPermission.view_all) permissionArr.push(3);
+            return permissionArr.join(',');
+        }
     }
 
     return subProjPermission;

+ 14 - 14
app/service/sub_project.js

@@ -21,7 +21,7 @@ const defaultFunRela = {
 };
 const funSet = require('../const/fun_set');
 const defaultFunSet = funSet.defaultInfo;
-const pageShowConst = require('../const/page_show').defaultSetting;
+const pageShowConst = require('../const/sp_page_show').defaultSetting;
 
 module.exports = app => {
     class SubProject extends app.BaseService {
@@ -536,19 +536,19 @@ module.exports = app => {
         }
 
         // 合同管理获取项目列表
-        async getSubProjectByFinancial(pid, uid, admin, filterFolder = false) {
-            let result = await this.getAllDataByCondition({ where: { project_id: pid, is_delete: 0 } });
-            if (admin) return this._filterEmptyFolder(result);
-
-            const permission = await this.ctx.service.financialAudit.getAllDataByCondition({ where: { uid } });
-            result = result.filter(x => {
-                if (x.is_folder) return !filterFolder;
-                const pb = permission.find(y => { return x.id === y.spid; });
-                if (!pb) return false;
-                return true;
-            });
-            return this._filterEmptyFolder(result);
-        }
+        // async getSubProjectByFinancial(pid, uid, admin, filterFolder = false) {
+        //     let result = await this.getAllDataByCondition({ where: { project_id: pid, is_delete: 0 } });
+        //     if (admin) return this._filterEmptyFolder(result);
+        //
+        //     const permission = await this.ctx.service.financialAudit.getAllDataByCondition({ where: { uid } });
+        //     result = result.filter(x => {
+        //         if (x.is_folder) return !filterFolder;
+        //         const pb = permission.find(y => { return x.id === y.spid; });
+        //         if (!pb) return false;
+        //         return true;
+        //     });
+        //     return this._filterEmptyFolder(result);
+        // }
 
         async getFileReference(subProject, file_type) {
             if (file_type) {

+ 11 - 2
app/service/tender.js

@@ -95,7 +95,7 @@ module.exports = app => {
             if (listStatus === 'manage') {
                 const userFilter = getAll ? '' : this.db.format(' And t.user_id = ? ', [session.sessionUser.accountId]);
                 // 管理页面只取属于自己创建的标段
-                sql = 'SELECT t.`id`, t.`project_id`, t.`name`, t.`status`, t.`category`, t.`ledger_times`, t.`ledger_status`, t.`measure_type`, t.`user_id`, t.`create_time`, t.`total_price`, t.`deal_tp`, t.`spid`,' +
+                sql = 'SELECT t.`id`, t.`project_id`, t.`name`, t.`status`, t.`category`, t.`ledger_times`, t.`ledger_status`, t.`measure_type`, t.`user_id`, t.`create_time`, t.`total_price`, t.`deal_tp`, t.`spid`, t.filter_budget, t.filter_fund,' +
                     '    pa.`name` As `user_name`, pa.`role` As `user_role`, pa.`company` As `user_company` ' +
                     '  FROM ?? As t ' +
                     '  Left Join ?? As pa ' +
@@ -123,6 +123,7 @@ module.exports = app => {
                     '        t.id IN ( SELECT cpla.`tid` FROM ' + this.ctx.service.changePlanAudit.tableName + ' AS cpla WHERE cpla.`aid` = ' + session.sessionUser.accountId + ' GROUP BY cpla.`tid`))' : '';
                 const changeProjectXsSql = this.ctx.subProject.page_show.openChangeProject ? '    OR (t.`ledger_status` = ' + auditConst.ledger.status.checked + ' AND ' +
                     '        t.id IN ( SELECT cpxa.`tid` FROM ' + this.ctx.service.changeProjectXsAudit.tableName + ' AS cpxa WHERE cpxa.`aid` = ' + session.sessionUser.accountId + ' GROUP BY cpxa.`tid`))' : '';
+                const xxjdSql = this.ctx.subProject.page_show.xxjd ? '    OR (t.id IN ( SELECT xxjd.`tid` FROM ' + this.ctx.service.scheduleAudit.tableName + ' AS xxjd WHERE xxjd.`permission` != 0 AND xxjd.`audit_id` = ' + session.sessionUser.accountId + ' GROUP BY xxjd.`tid`))' : '';
                 sql = 'SELECT t.`id`, t.`project_id`, t.`name`, t.`status`, t.`category`, t.`ledger_times`, t.`ledger_status`, t.`measure_type`, t.`user_id`, t.`create_time`, t.`total_price`, t.`deal_tp`,' +
                     '    pa.`name` As `user_name`, pa.`role` As `user_role`, pa.`company` As `user_company` ' +
                     // '  FROM ?? As t, ?? As pa ' +
@@ -145,6 +146,9 @@ module.exports = app => {
                     // 参与审批 结算期 的标段
                     '    OR (t.`ledger_status` = ' + auditConst.ledger.status.checked + ' AND ' +
                     '        t.id IN ( SELECT sa.`tid` FROM ?? As sa WHERE sa.`audit_id` = ? GROUP BY sa.`tid`))' +
+                    // 参与审批 合同支付期 的标段
+                    '    OR (t.`ledger_status` = ' + auditConst.ledger.status.checked + ' AND ' +
+                    '        t.id IN ( SELECT sa.`tid` FROM ?? As sa WHERE sa.`audit_id` = ? GROUP BY sa.`tid`))' +
                     // 参与审批 变更令 的标段
                     '    OR (t.`ledger_status` = ' + auditConst.ledger.status.checked + ' AND ' +
                     '        t.id IN ( SELECT ca.`tid` FROM ?? AS ca WHERE ca.`uid` = ? GROUP BY ca.`tid`))' +
@@ -157,7 +161,7 @@ module.exports = app => {
                     // 参与审批 预付款 的标段
                     '    OR (t.id IN ( SELECT ad.`tid` FROM ?? AS ad WHERE ad.`audit_id` = ? GROUP BY ad.`tid`))' +
                     // 参与审批 变更立项书及变更申请 的标段
-                    changeProjectSql + changeApplySql + changePlanSql + changeProjectXsSql +
+                    changeProjectSql + changeApplySql + changePlanSql + changeProjectXsSql + xxjdSql +
                     // 游客权限的标段
                     '    OR (t.id IN ( SELECT tt.`tid` FROM ?? AS tt WHERE tt.`user_id` = ?))' +
                     // 未参与,但可见的标段
@@ -167,6 +171,7 @@ module.exports = app => {
                     this.ctx.service.stageAudit.tableName, session.sessionUser.accountId,
                     this.ctx.service.auditAss.tableName, session.sessionUser.accountId,
                     this.ctx.service.settleAudit.tableName, session.sessionUser.accountId,
+                    this.ctx.service.phasePayAudit.tableName, session.sessionUser.accountId,
                     this.ctx.service.changeAudit.tableName, session.sessionUser.accountId,
                     this.ctx.service.reviseAudit.tableName, session.sessionUser.accountId,
                     this.ctx.service.materialAudit.tableName, session.sessionUser.accountId,
@@ -781,6 +786,10 @@ module.exports = app => {
             const tenderTouristParams = [this.ctx.service.tenderTourist.tableName];
             const tenderTouristResult = await conn.query(tenderTouristSql, tenderTouristParams);
             newUids.push(...this._.map(tenderTouristResult, 'user_id'));
+            const xxjdAuditsSql = `SELECT audit_id FROM ?? WHERE tid in (${tids.join(',')}) ${newUids.length > 0 ? ` AND audit_id NOT IN (${newUids.join(',')})` : ''} GROUP BY audit_id`;
+            const xxjdAuditParams = [this.ctx.service.scheduleAudit.tableName];
+            const xxjdResult = await conn.query(xxjdAuditsSql, xxjdAuditParams);
+            newUids.push(...this._.map(xxjdResult, 'audit_id'));
             const diffUids = this._.difference(newUids, hadUids);
             if (diffUids.length > 0) {
                 const insertData = diffUids.map(x => {

+ 0 - 2
app/view/change/addlist.ejs

@@ -16,11 +16,9 @@
                     </div>
                 </div>
             </div>
-            <% if (ctx.session.sessionProject.page_show.openChangeRevise) { %>
             <div class="ml-auto">
                 <a class="btn btn-sm btn-primary mr-1" id="add-all-revise" href="javascript: void(0);">勾选当前新增部位/清单</a>
             </div>
-            <% } %>
         </div>
     </div>
     <div class="content-wrap row pr-46">

+ 4 - 8
app/view/change/information_modal.ejs

@@ -51,12 +51,10 @@
                                 <div class="search-group">
                                     <div class="input-group input-group-sm">
                                         <div class="input-group-prepend">
-                                            <% if (ctx.session.sessionProject.page_show.openChangeRevise) { %>
-                                                <select class="input-group-text" id="select-list">
-                                                    <option value="0" selected>所有清单</option>
-                                                    <option value="1">新增清单</option>
-                                                </select>
-                                            <% } %>
+                                            <select class="input-group-text" id="select-list">
+                                                <option value="0" selected>所有清单</option>
+                                                <option value="1">新增清单</option>
+                                            </select>
                                         </div>
                                         <input class="form-control form-control-sm" style="width:300px;" id="list-input" placeholder="输入 清单编号、名称 检索" value="">
                                         <a href="javascript:void(0);" style="display: none" data-btn="list" class="text-danger remove-btn" title="移除关键词"><i class="fa fa-times-circle "></i></a>
@@ -92,11 +90,9 @@
                             <div class="d-flex justify-content-between align-items-center">
                                 <div>请选择清单所属部位</div>
                                 <div class="d-flex justify-content-start search-group">
-                                    <% if (ctx.session.sessionProject.page_show.openChangeRevise) { %>
                                         <span>
                                 <a href="/tender/<%- change.tid %>/change/<%- change.cid %>/information/revise" class="btn btn-primary btn-sm mr-2" style="padding: 0.25rem 0.5rem;">新增部位/清单</a>
                             </span>
-                                    <% } %>
                                     <input class="form-control form-control-sm" id="code-input" style="width:350px;" placeholder="输入 项目节编号、细目、计量单元 检索">
                                     <a href="javascript:void(0);" style="display: none" data-btn="code" class="text-danger remove-btn" title="移除关键词"><i class="fa fa-times-circle "></i></a>
                                 </div>

+ 0 - 11
app/view/change/revise.ejs

@@ -26,7 +26,6 @@
                         </div>
                     </div>
                 </div>
-                <% if (ctx.session.sessionProject.page_show.openChangeRevise) { %>
                 <div class="d-inline-block">
                     <a href="javascript: void(0);" name="base-opr" type="add" class="btn btn-sm btn-light text-primary" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="新增"><i class="fa fa-plus" aria-hidden="true"></i></a>
                     <a href="javascript: void(0);" name="base-opr" type="delete" class="btn btn-sm btn-light text-primary" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="删除"><i class="fa fa-remove" aria-hidden="true"></i></a>
@@ -38,7 +37,6 @@
                     <a href="javascript: void(0);" name="cpc" type="cut" class="btn btn-sm btn-light text-primary" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="剪切"><i class="fa fa-scissors" aria-hidden="true"></i></a>
                     <a href="javascript: void(0);" name="cpc" type="paste" class="btn btn-sm btn-light text-primary" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="粘贴"><i class="fa fa-clipboard" aria-hidden="true"></i></a>
                 </div>
-                <% } %>
                 <div class="d-inline-block">
                     <div class="input-group input-group-sm ml-2">
                         <div class="input-group-prepend">
@@ -48,12 +46,10 @@
                     </div>
                 </div>
             </div>
-            <% if (ctx.session.sessionProject.page_show.openChangeRevise) { %>
             <div class="ml-auto">
                 <a class="btn btn-sm btn-primary mr-1" id="add-all-revise" href="javascript: void(0);">勾选当前新增部位/清单</a>
                 <a class="btn btn-sm btn-primary mr-1" id="ledger-check2" href="javascript: void(0);">数据检查</a>
             </div>
-            <% } %>
         </div>
     </div>
     <div class="content-wrap row pr-46">
@@ -72,14 +68,12 @@
                             <li class="nav-item">
                                 <a class="nav-link active" href="javascript:void(0)">计量单元</a>
                             </li>
-                            <% if (ctx.session.sessionProject.page_show.openChangeRevise) { %>
                             <li class="ml-2 nav-item">
                                 <div class="d-inline-flex">
                                     <a href="javascript: void(0);" name="pos-opr" type="down-move" class="btn btn-sm btn-light text-primary" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="下移"><i class="fa fa-arrow-down" aria-hidden="true"></i></a>
                                     <a href="javascript: void(0);" name="pos-opr" type="up-move" class="btn btn-sm btn-light text-primary" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="上移"><i class="fa fa-arrow-up" aria-hidden="true"></i></a>
                                 </div>
                             </li>
-                            <% } %>
                             <li class="nav-item" id="pos-search">
                             </li>
                             <li class="nav-item">
@@ -104,7 +98,6 @@
                 <div class="tab-content">
                     <div id="search" class="tab-pane">
                     </div>
-                    <% if (ctx.session.sessionProject.page_show.openChangeRevise) { %>
                     <div id="std-xmj" class="tab-pane">
                     </div>
                     <div id="std-gcl" class="tab-pane">
@@ -141,7 +134,6 @@
                             </div>
                         </div>
                     </div>
-                    <% } %>
                 </div>
             </div>
         </div>
@@ -152,7 +144,6 @@
                 <li class="nav-item">
                     <a class="nav-link" content="#search" href="javascript: void(0);">查找定位</a>
                 </li>
-                <% if (ctx.session.sessionProject.page_show.openChangeRevise) { %>
                 <li class="nav-item">
                     <a class="nav-link" content="#std-xmj" href="javascript: void(0);">项目节</a>
                 </li>
@@ -171,7 +162,6 @@
                 <li class="nav-item">
                     <a class="nav-link" content="#dsk-list" href="javascript: void(0);">新增清单</a>
                 </li>
-                <% } %>
             </ul>
         </div>
     </div>
@@ -196,6 +186,5 @@
     const oldChangeList = _.cloneDeep(changeList);
     const settleBills = JSON.parse(unescape('<%- escape(JSON.stringify(settleBills)) %>'));
     const settlePos = JSON.parse(unescape('<%- escape(JSON.stringify(settlePos)) %>'));
-    const openRevise = <%- ctx.session.sessionProject.page_show.openChangeRevise %>;
     const precision = JSON.parse('<%- JSON.stringify(precision) %>');
 </script>

+ 0 - 2
app/view/change/revise_modal.ejs

@@ -17,7 +17,6 @@
     </div>
     <script type="text/javascript">$('#unedit2').modal('show');</script>
 <% } %>
-<% if (ctx.session.sessionProject.page_show.openChangeRevise) { %>
 <!--批量添加清单部位-->
 <div class="modal fade" id="batch" data-backdrop="static">
     <div class="modal-dialog modal-xl" role="document">
@@ -130,4 +129,3 @@
 <% include ../shares/delete_hint_modal.ejs %>
 <% include ../shares/check_data_modal.ejs %>
 <% include ../shares/check_modal2.ejs %>
-<% } %>

+ 1 - 1
app/view/contract/detail.ejs

@@ -35,7 +35,7 @@
             <% } %>
             <div class="ml-auto">
                 <% if (ctx.session.sessionUser.is_admin) { %>
-                <a href="javascript:void(0);" data-stid="<%- ctx.contractOptions.spid || ctx.contractOptions.tid %>" class="btn btn-sm btn-primary get-audits mr-2">成员管理</a>
+                <a href="javascript:void(0);" data-stid="<%- ctx.contract_tender ? ctx.contractOptions.tid : '' %>" class="btn btn-sm btn-primary get-audits mr-2">成员管理</a>
                 <a href="#empower" data-toggle="modal" data-target="#empower" class="btn btn-sm btn-primary mr-2">节点授权</a>
                 <% } %>
 <!--                <a href="#cons-relat" data-toggle="modal" data-target="#cons-relat" class="btn btn-primary btn-sm pull-right">关联合同</a>-->

+ 16 - 18
app/view/contract/modal.ejs

@@ -174,14 +174,14 @@
         // 添加到成员中
         $('body').on('click', '#authority-list dl dd', function () {
             const id = parseInt($(this).data('id'));
-            console.log(id);
             if (!isNaN(id) && id !== 0) {
-                postData(`/sp/${spid}/contract/${$('#stid').val()}/audit/save`, {type: 'add-audit', id: id}, function (result) {
+                postData(auditSaveUrl, {type: 'add-audit', id: id}, function (result) {
                     setList(result);
                 })
             }
         });
         let first = 1;
+        let auditSaveUrl = '';
         $('#authority-list').on('shown.bs.modal', function () {
             if (first) {
                 const option = {
@@ -191,18 +191,16 @@
                 $("#contract-audit-table").bootstrapTable('destroy').bootstrapTable(option);
                 first = 0;
             }
-            const stid = $('#stid').val();
-            if (stid) {
-                postData(`/sp/${spid}/contract/${$('#stid').val()}/audit/save`, { type: 'list' }, function (result) {
-                    setList(result);
-                });
-            }
+            postData(auditSaveUrl, { type: 'list' }, function (result) {
+                setList(result);
+            });
         });
         $('body').on('click', '.get-audits', function () {
             const stid = $(this).data('stid');
             $('#stid').val(stid);
+            auditSaveUrl = stid ? `/sp/${spid}/contract/tender/${stid}/audit/save`: `/sp/${spid}/contract/audit/save`;
             $('#contract-audit-list').html('');
-            postData(`/sp/${spid}/contract/${$('#stid').val()}/audit/save`, { type: 'check' }, function (result) {
+            postData(auditSaveUrl, { type: 'check' }, function (result) {
                 $('#authority-list').modal('show');
             });
         });
@@ -214,19 +212,19 @@
                             <td>${ca.name}</td>
                             <td>${ca.role}</td>
                             <td>
-                                <input type="checkbox" class="permission-checkbox" data-type="permission_edit" value="${ca.id}" ${ca.permission_edit ? 'checked' : ''}>
+                                <input type="checkbox" class="permission-checkbox" data-type="permission_edit" value="${ca.uid}" ${ca.permission_edit ? 'checked' : ''}>
                             </td>
                             <td>
-                                <input type="checkbox" class="permission-checkbox" data-type="permission_add" value="${ca.id}" ${ca.permission_add ? 'checked' : ''}>
+                                <input type="checkbox" class="permission-checkbox" data-type="permission_add" value="${ca.uid}" ${ca.permission_add ? 'checked' : ''}>
                             </td>
                             <td>
-                                <input type="checkbox" class="permission-checkbox" data-type="permission_show_unit" value="${ca.id}" ${ca.permission_show_unit ? 'checked' : ''}>
+                                <input type="checkbox" class="permission-checkbox" data-type="permission_show_unit" value="${ca.uid}" ${ca.permission_show_unit ? 'checked' : ''}>
                             </td>
                             <td>
-                                <input type="checkbox" class="permission-checkbox" data-type="permission_show_node" value="${ca.id}" ${ca.permission_show_node ? 'checked' : ''}>
+                                <input type="checkbox" class="permission-checkbox" data-type="permission_show_node" value="${ca.uid}" ${ca.permission_show_node ? 'checked' : ''}>
                             </td>
                             <td>
-                                <a href="#del-contract-audit" data-toggle="modal" data-target="#del-contract-audit" class="btn btn-outline-danger btn-sm ml-1 del-contract-audit-a" data-id="${ca.id}">移除</a>
+                                <a href="#del-contract-audit" data-toggle="modal" data-target="#del-contract-audit" class="btn btn-outline-danger btn-sm ml-1 del-contract-audit-a" data-id="${ca.uid}">移除</a>
                             </td>
                         </tr>`;
             }
@@ -241,7 +239,7 @@
 
         $('#del-audit-btn').click(function () {
             let uids = $('#del-audit-ids').val();
-            postData(`/sp/${spid}/contract/${$('#stid').val()}/audit/save`, { type: 'del-audit', id: uids.split(',') }, function (result) {
+            postData(auditSaveUrl, { type: 'del-audit', id: uids.split(',') }, function (result) {
                 // toastr.success(`成功添加 位用户`);
                 $('#del-contract-audit').modal('hide');
                 setList(result);
@@ -252,10 +250,10 @@
         $('body').on('click', '.permission-checkbox', function () {
             const type = $(this).attr('data-type');
             const value = $(this).is(':checked') ? 1 : 0;
-            const id = parseInt($(this).val());
-            const updateInfo = { id };
+            const uid = parseInt($(this).val());
+            const updateInfo = { uid };
             updateInfo[type] = value;
-            postData(`/sp/${spid}/contract/${$('#stid').val()}/audit/save`, { type: 'save-permission', updateData: updateInfo }, function (result) {
+            postData(auditSaveUrl, { type: 'save-permission', updateData: updateInfo }, function (result) {
             })
         });
     });

+ 10 - 10
app/view/dashboard/index.ejs

@@ -1,7 +1,7 @@
 <div class="panel-content">
     <div class="panel-title fluid">
         <div class="title-main d-flex">
-            <h2><%= ctx.session.sessionProject.name %></h2>
+            <h2><%= ctx.subProject.name %></h2>
             <div class="ml-auto">
                 <i class="fa fa-bell mr-1"></i><a href="#version" data-toggle="modal" data-target="#version">当前版本:<%= versionList[0].name %></a>
                 <% if (sysMsgList.length > 0) { %>
@@ -63,13 +63,13 @@
                                     <% if (ctx.subProject.page_show.openChangePlan && auditChangePlan.length !== 0) { %>
                                         <option value="9">变更方案(<%- auditChangePlan.length %>)</option>
                                     <% } %>
-                                    <% if (ctx.session.sessionProject.page_show.openMaterial && auditMaterial.length !== 0) { %>
+                                    <% if (ctx.subProject.page_show.openMaterial && auditMaterial.length !== 0) { %>
                                     <option value="1">材料调差(<%- auditMaterial.length %>)</option>
                                     <% } %>
-                                    <% if (ctx.session.sessionProject.page_show.openPayment && auditPayments.length !== 0) { %>
+                                    <% if (ctx.subProject.page_show.openPayment && auditPayments.length !== 0) { %>
                                         <option value="10">支付审批(<%- auditPayments.length %>)</option>
                                     <% } %>
-                                    <% if (ctx.session.sessionProject.page_show.openFinancial && auditFinancials.length !== 0) { %>
+                                    <% if (ctx.subProject.page_show.openFinancial && auditFinancials.length !== 0) { %>
                                         <option value="11">资金支付(<%- auditFinancials.length %>)</option>
                                     <% } %>
                                 </select>
@@ -401,10 +401,10 @@
                                     <% if (ctx.subProject.page_show.openChangePlan) { %>
                                         <option value="9">变更方案</option>
                                     <% } %>
-                                    <% if (ctx.session.sessionProject.page_show.openMaterial) { %>
+                                    <% if (ctx.subProject.page_show.openMaterial) { %>
                                         <option value="1">材料调差</option>
                                     <% } %>
-                                    <% if (ctx.session.sessionProject.page_show.openFinancial) { %>
+                                    <% if (ctx.subProject.page_show.openFinancial) { %>
                                         <option value="11">资金支付</option>
                                     <% } %>
                                 </select>
@@ -443,7 +443,7 @@
                                                     <td class="<%- acStage.statusClass[notice.status]%>"><%- acStage.statusString[notice.status]%></td>
                                                     <td><%- notice.opinion ? notice.opinion : '' %></td>
                                                 </tr>
-                                            <% } else if(notice.type === pushType.material && ctx.session.sessionProject.page_show.openMaterial) { %>
+                                            <% } else if(notice.type === pushType.material && ctx.subProject.page_show.openMaterial) { %>
                                                 <tr data-type="1">
                                                     <td><span class="bg-new-material text-new-material badge text-width">材料调差</span></td>
                                                     <td><a href="/tender/<%- notice.tid %>"><%- notice.name %></a> <a href="/tender/<%- notice.tid %>/measure/material/<%- notice.order %>">第<%- notice.order %>期</a></td>
@@ -523,7 +523,7 @@
                                                     <td class="<%- acAdvance.statusClass[notice.status]%>"><%- acAdvance.statusString[notice.status]%></td>
                                                     <td><%- notice.opinion ? notice.opinion : '' %></td>
                                                 </tr>
-                                            <% } else if(notice.type === pushType.financial && ctx.session.sessionProject.page_show.openFinancial) { %>
+                                            <% } else if(notice.type === pushType.financial && ctx.subProject.page_show.openFinancial) { %>
                                                 <tr data-type="11">
                                                     <td><span class="bg-new-financial text-new-financial badge text-width">资金支付</span></td>
                                                     <td><a href="/sp/<%- notice.spid %>/financial/pay"><%- notice.name %></a> <a href="/sp/<%- notice.spid %>/financial/pay/<%- notice.fpid %>/detail"><%- notice.code %></a></td>
@@ -664,10 +664,10 @@
             <% if (ctx.subProject.page_show.openChangePlan) { %>
             'rgba(114, 46, 209,'+ transparentCount +')',
             <% } %>
-            <% if (ctx.session.sessionProject.page_show.openMaterial) { %>
+            <% if (ctx.subProject.page_show.openMaterial) { %>
             'rgba(187, 41, 210,'+ transparentCount +')',
             <% } %>
-            <% if (ctx.session.sessionProject.page_show.openFinancial) { %>
+            <% if (ctx.subProject.page_show.openFinancial) { %>
             'rgba(58, 88, 50,'+ transparentCount +')',
             <% } %>
         ],

+ 1 - 0
app/view/file/file.ejs

@@ -4,6 +4,7 @@
             <div>资料归集/<%- ctx.subProject.name %></div>
             <div class="ml-auto">
                 <% if (ctx.session.sessionUser.is_admin) { %>
+                <a href="/sp/<%- ctx.subProject.id %>/fm" class="btn btn-outline-primary btn-sm ml-1">管理分类</a>
                 <a class="btn btn-sm btn-outline-primary mr-1" href="#filing-permission" data-toggle="modal" data-backdrop="static" data-target="#filing-permission">授权用户</a>
                 <% } %>
             </div>

+ 2 - 0
app/view/file/manage.ejs

@@ -23,6 +23,8 @@
                         <div class="p-2">
                             <a href="javascript: void(0);" class="btn btn-sm btn-light text-primary" id="add-slibing"><i class="fa fa-plus" aria-hidden="true"></i> 同层</a>
                             <a href="javascript: void(0);" class="btn btn-sm btn-light text-primary" id="add-child"><i class="fa fa-plus" aria-hidden="true"></i> 子项</a>
+                            <a href="javascript: void(0);" class="btn btn-sm btn-light text-primary" id="up-move"><i class="fa fa-arrow-up" aria-hidden="true"></i> 上移</a>
+                            <a href="javascript: void(0);" class="btn btn-sm btn-light text-primary" id="down-move"><i class="fa fa-arrow-down" aria-hidden="true"></i> 下移</a>
                         </div>
                         <div class="ml-auto p-2">
                             <a href="javascript: void(0);" class="btn btn-sm btn-primary" id="multi-setting">附加配置</a>

+ 1 - 1
app/view/financial/transfer_tender_modal.ejs

@@ -44,7 +44,7 @@
             <div class="modal-header">
                 <h5 class="modal-title">添加标段</h5>
             </div>
-            <div class="modal-body">
+            <div class="modal-body" style="max-height: 500px;overflow: auto;">
                 <table class="table table-bordered">
                     <thead class="text-center">
                     <tr>

+ 1 - 1
app/view/ledger/explode.ejs

@@ -366,7 +366,7 @@
 <script type="text/javascript">
     const dskAccountData = JSON.parse('<%- JSON.stringify(ctx.session.sessionUser.dskAccountData) %>');
     const readOnly = <%- ctx.tender.ledgerReadOnly %>;
-    const contractExpr = <%- !!ctx.session.sessionProject.page_show.openContractExpr && tender.ledger_status === auditConst.status.checked %>;
+    const contractExpr = <%- !!ctx.subProject.page_show.openContractExpr && tender.ledger_status === auditConst.status.checked %>;
     const deleteFilePermission = <%- deleteFilePermission %>;
     const tender = JSON.parse('<%- JSON.stringify(tender) %>');
     const tenderInfo = JSON.parse(unescape('<%- escape(JSON.stringify(tenderInfo)) %>'));

+ 1 - 1
app/view/ledger/explode_modal.ejs

@@ -454,7 +454,7 @@
         </div>
     </div>
 </div>
-<% if (ctx.session.sessionProject.page_show.openContractExpr) { %>
+<% if (ctx.subProject.page_show.openContractExpr) { %>
 <div class="modal fade" id="contract_expr" data-backdrop="static">
     <div class="modal-dialog modal-xl" role="document">
         <div class="modal-content">

+ 3 - 3
app/view/measure/stage.ejs

@@ -7,14 +7,14 @@
                 期列表
             </h2>
             <div class="ml-auto">
-                <% if (ctx.session.sessionProject.page_show.openSettle) { %>
+                <% if (ctx.subProject.page_show.openSettle) { %>
                 <a href="/tender/<%= ctx.tender.id %>/settle" class="btn btn-primary btn-sm">计量结算</a>
                 <% } %>
                 <% if ((ctx.session.sessionUser.accountId === ctx.tender.data.user_id || ctx.tender.userAssistsId.indexOf(ctx.session.sessionUser.accountId) >= 0) && ctx.tender.data.ledger_status === auditConst.status.checked) { %>
-                    <% if (!ctx.session.sessionProject.page_show.close1stStageCheckDealParam && ctx.helper.checkZero(ctx.tender.info.deal_param.contractPrice) && stages.length === 0) { %>
+                    <% if (!ctx.subProject.page_show.close1stStageCheckDealParam && ctx.helper.checkZero(ctx.tender.info.deal_param.contractPrice) && stages.length === 0) { %>
                         <a href="#add-qi" data-toggle="modal" data-target="#tips" class="btn btn-primary btn-sm">开始新一期</a>
                     <% } else { %>
-                        <% if (ctx.session.sessionProject.page_show.openMultiStageCalc && unCompleteStageCount < ctx.session.sessionProject.page_show.maxMultiStageCount) { %>
+                        <% if (ctx.subProject.page_show.openMultiStageCalc && unCompleteStageCount < ctx.session.sessionProject.page_show.maxMultiStageCount) { %>
                         <a href="#add-qi" data-toggle="modal" data-target="#add-qi" class="btn btn-primary btn-sm">开始新一期</a>
                         <% } else if (unCompleteStageCount === 0) {%>
                         <a href="#add-qi" data-toggle="modal" data-target="#add-qi" class="btn btn-primary btn-sm">开始新一期</a>

+ 2 - 2
app/view/payment/detail.ejs

@@ -11,7 +11,7 @@
 <div class="panel-content">
     <div class="panel-title fluid">
         <div class="title-main  d-flex justify-content-between">
-            <div><a class="mr-2" href="/payment/<%- ctx.paymentTender.id %>/list/<%- trInfo.id %>"><i class="fa fa-chevron-left"></i> 返回</a><%- ctx.paymentTender.name %> / <%- trInfo.rpt_name %> / <%- ctx.detail.code %></div>
+            <div><a class="mr-2" href="/sp/<%- ctx.subProject.id %>/payment/<%- ctx.paymentTender.id %>/list/<%- trInfo.id %>"><i class="fa fa-chevron-left"></i> 返回</a><%- ctx.paymentTender.name %> / <%- trInfo.rpt_name %> / <%- ctx.detail.code %></div>
             <div>
                 <% if ((ctx.detail.status == auditConst.status.uncheck || ctx.detail.status == auditConst.status.checkNo) && trInfo.is_change) { %>
                 <span class="text-danger pull-right">报表内容已发生变化,请删除并重新生成详情</span>
@@ -131,7 +131,7 @@
                                                         <td><a href="javascript: void(0);" class="file-atn" f-id="<%- att.id %>"><%- att.filename %><%- att.fileext %></a></td>
                                                         <td><%- moment(att.upload_time).format("YYYY-MM-DD HH:mm:ss") %><br><%- ctx.helper.bytesToSize(att.filesize) %></td>
                                                         <td>
-                                                            <a href="/payment/<%- ctx.paymentTender.id %>/detail/<%- ctx.detail.id %>/file/<%- att.id %>/download" class="mr-2" title="下载"><span class="fa fa-download text-primary"></span></a>
+                                                            <a href="/sp/<%- ctx.subProject.id %>/payment/<%- ctx.paymentTender.id %>/detail/<%- ctx.detail.id %>/file/<%- att.id %>/download" class="mr-2" title="下载"><span class="fa fa-download text-primary"></span></a>
                                                             <% if (att.uid === ctx.session.sessionUser.accountId && (ctx.detail.status === auditConst.status.checked ? Boolean(att.extra_upload) : true )) { %>
                                                                 <a href="javascript:void(0)" class="mr-2 delete-file" data-attid="<%- att.id %>" title="删除附件"><span class="fa fa-trash text-danger"></span></a>
                                                             <% } %>

+ 0 - 0
app/view/payment/index.ejs


Some files were not shown because too many files changed in this diff