浏览代码

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

laiguoran 1 年之前
父节点
当前提交
47979db972

+ 13 - 0
app/const/tender.js

@@ -79,6 +79,18 @@ typeString[type.TJ] = '土建标';
 typeString[type.XX] = 'XX标';
 typeString[type.YY] = 'YY标';
 
+const buildStatus = (function (){
+    const status = {
+        build: 1,
+        finish: 2,
+    };
+    const statusStr = [];
+    statusStr[status.build] = '在建中';
+    statusStr[status.finish] = '已完工';
+    return {status, statusStr}
+})();
+
+
 module.exports = {
     status,
     statusString,
@@ -90,4 +102,5 @@ module.exports = {
     measureType,
     imType,
     valuationField,
+    buildStatus,
 };

+ 11 - 0
app/controller/report_controller.js

@@ -79,6 +79,7 @@ module.exports = app => {
          * @return {void}
          */
         async index(ctx) {
+            // 普通情况(计量期入口)
             try {
                 await this._getStageAuditViewData(ctx);
                 const pageShow = ctx.session.sessionProject.page_show;
@@ -482,6 +483,16 @@ module.exports = app => {
                 // ctx.redirect('/tender/' + ctx.tender.id + '/measure/stage');
             }
         }
+
+        async indexForDynamicGrandTotal(ctx) {
+            // 动态决算入口
+            try {
+                //
+            } catch (err) {
+                this.log(err);
+            }
+        }
+
         /**
          * 报表打印页面
          *

+ 122 - 4
app/controller/tender_controller.js

@@ -132,7 +132,7 @@ module.exports = app => {
                 const userPermission = accountInfo !== undefined && accountInfo.permission !== ''
                     ? JSON.parse(accountInfo.permission) : null;
 
-                const tenderList = await this.ctx.service.tender.getList('', userPermission, this.ctx.session.sessionUser.is_admin);
+                const tenderList = await this.ctx.service.tender.getBuildList('', userPermission, this.ctx.session.sessionUser.is_admin);
 
                 for (const t of tenderList) {
                     const tenderInfo = await this.ctx.service.tenderInfo.getTenderInfo(t.id);
@@ -182,6 +182,7 @@ module.exports = app => {
                     pid: this.ctx.session.sessionProject.id,
                 };
                 renderData.selfCategoryLevel = await this.ctx.service.projectAccount.getSelfCategoryLevel(this.ctx.session.sessionUser.accountId);
+                renderData.is_finish = false;
                 await this.layout(view, renderData, modal);
             } catch (err) {
                 this.log(err);
@@ -195,7 +196,7 @@ module.exports = app => {
                 const accountInfo = await this.ctx.service.projectAccount.getDataById(this.ctx.session.sessionUser.accountId);
                 const userPermission = accountInfo !== undefined && accountInfo.permission !== ''
                     ? JSON.parse(accountInfo.permission) : null;
-                const tenderList = await this.ctx.service.tender.getList('', userPermission, this.ctx.session.sessionUser.is_admin);
+                const tenderList = await this.ctx.service.tender.getBuildList('', userPermission, this.ctx.session.sessionUser.is_admin);
                 for (const t of tenderList) {
                     await this.ctx.service.tenderCache.loadTenderCache(t, this.ctx.session.sessionUser.accountId);
                 }
@@ -215,6 +216,41 @@ module.exports = app => {
                     pid: this.ctx.session.sessionProject.id,
                 };
                 renderData.selfCategoryLevel = await this.ctx.service.projectAccount.getSelfCategoryLevel(this.ctx.session.sessionUser.accountId);
+                renderData.is_finish = false;
+                await this.layout(view, renderData, modal);
+            } catch (err) {
+                this.log(err);
+                this.ctx.redirect('/dashboard');
+            }
+        }
+
+        async _listDetailFinish(view, modal = '') {
+            try {
+                // 获取用户新建标段权利
+                const accountInfo = await this.ctx.service.projectAccount.getDataById(this.ctx.session.sessionUser.accountId);
+                const userPermission = accountInfo !== undefined && accountInfo.permission !== ''
+                    ? JSON.parse(accountInfo.permission) : null;
+                const tenderList = await this.ctx.service.tender.getFinishList('', userPermission, this.ctx.session.sessionUser.is_admin);
+                for (const t of tenderList) {
+                    await this.ctx.service.tenderCache.loadTenderCache(t, this.ctx.session.sessionUser.accountId);
+                }
+                const categoryData = await this.ctx.service.category.getAllCategory(this.ctx.session.sessionProject.id);
+                const valuations = await this.ctx.service.valuation.getProjectValidValuation(this.ctx.session.sessionProject.id);
+                const renderData = {
+                    tenderList,
+                    tenderConst,
+                    settingConst,
+                    categoryData,
+                    measureType: tenderConst.measureType,
+                    jsFiles: this.app.jsFiles.common.concat(this.jsFiles),
+                    auditConst,
+                    userPermission,
+                    valuations,
+                    uid: this.ctx.session.sessionUser.accountId,
+                    pid: this.ctx.session.sessionProject.id,
+                };
+                renderData.selfCategoryLevel = await this.ctx.service.projectAccount.getSelfCategoryLevel(this.ctx.session.sessionUser.accountId);
+                renderData.is_finish = true;
                 await this.layout(view, renderData, modal);
             } catch (err) {
                 this.log(err);
@@ -224,7 +260,33 @@ module.exports = app => {
 
         async _listCache(view, renderData, modal = '', list_status = '') {
             try {
-                renderData.tenderList = await this.ctx.service.tender.getList(list_status, renderData.userPermission, this.ctx.session.sessionUser.is_admin);
+                renderData.tenderList = await this.ctx.service.tender.getBuildList(list_status, renderData.userPermission, this.ctx.session.sessionUser.is_admin);
+
+                for (const t of renderData.tenderList) {
+                    t.visitor = (await this.ctx.service.tenderTourist.getTourists(t.id)).map(x => { return x.user_name; });
+                    await this.ctx.service.tenderCache.loadTenderCache(t, this.ctx.session.sessionUser.accountId);
+                }
+                renderData.categoryData = await this.ctx.service.category.getAllCategory(this.ctx.session.sessionProject.id);
+                renderData.valuations = await this.ctx.service.valuation.getProjectValidValuation(this.ctx.session.sessionProject.id);
+                renderData.tenderConst = tenderConst;
+                renderData.settingConst = settingConst;
+                renderData.measureType = tenderConst.measureType;
+                renderData.jsFiles = this.app.jsFiles.common.concat(this.jsFiles);
+                renderData.auditConst = auditConst;
+                renderData.uid = this.ctx.session.sessionUser.accountId;
+                renderData.pid = this.ctx.session.sessionProject.id;
+                renderData.selfCategoryLevel = await this.ctx.service.projectAccount.getSelfCategoryLevel(this.ctx.session.sessionUser.accountId);
+                renderData.is_finish = false;
+                await this.layout(view, renderData, modal);
+            } catch (err) {
+                this.log(err);
+                this.ctx.redirect('/dashboard');
+            }
+        }
+
+        async _listFinish(view, renderData, modal = '', list_status = '') {
+            try {
+                renderData.tenderList = await this.ctx.service.tender.getFinishList(list_status, renderData.userPermission, this.ctx.session.sessionUser.is_admin);
 
                 for (const t of renderData.tenderList) {
                     t.visitor = (await this.ctx.service.tenderTourist.getTourists(t.id)).map(x => { return x.user_name; });
@@ -240,6 +302,7 @@ module.exports = app => {
                 renderData.uid = this.ctx.session.sessionUser.accountId;
                 renderData.pid = this.ctx.session.sessionProject.id;
                 renderData.selfCategoryLevel = await this.ctx.service.projectAccount.getSelfCategoryLevel(this.ctx.session.sessionUser.accountId);
+                renderData.is_finish = true;
                 await this.layout(view, renderData, modal);
             } catch (err) {
                 this.log(err);
@@ -249,7 +312,7 @@ module.exports = app => {
 
         async _list(view, renderData, modal = '', list_status = '') {
             try {
-                renderData.tenderList = await this.ctx.service.tender.getList(list_status, renderData.userPermission, this.ctx.session.sessionUser.is_admin);
+                renderData.tenderList = await this.ctx.service.tender.getBuildList(list_status, renderData.userPermission, this.ctx.session.sessionUser.is_admin);
 
                 for (const t of renderData.tenderList) {
                     t.visitor = (await this.ctx.service.tenderTourist.getTourists(t.id)).map(x => { return x.user_name; });
@@ -284,6 +347,7 @@ module.exports = app => {
                 renderData.uid = this.ctx.session.sessionUser.accountId;
                 renderData.pid = this.ctx.session.sessionProject.id;
                 renderData.selfCategoryLevel = await this.ctx.service.projectAccount.getSelfCategoryLevel(this.ctx.session.sessionUser.accountId);
+                renderData.is_finish = false;
                 await this.layout(view, renderData, modal);
             } catch (err) {
                 this.log(err);
@@ -357,6 +421,7 @@ module.exports = app => {
             };
             await this._list('tender/index.ejs', renderData, 'tender/modal.ejs');
         }
+
         /**
          * 标段概况(Get)
          *
@@ -402,6 +467,45 @@ module.exports = app => {
             }
         }
 
+        async listDefaultFinish(ctx) {
+            this.jsFiles = this.app.jsFiles.tender.list;
+            const accountInfo = await this.ctx.service.projectAccount.getDataById(this.ctx.session.sessionUser.accountId);
+            const userPermission = accountInfo !== undefined && accountInfo.permission !== '' ? JSON.parse(accountInfo.permission) : null;
+            const renderData = {
+                accountInfo,
+                userPermission,
+            };
+            await this._listFinish('tender/index.ejs', renderData, 'tender/modal.ejs');
+        }
+
+        async listInfoFinish(ctx) {
+            this.jsFiles = this.app.jsFiles.tender.info;
+            await this._listDetailFinish('tender/info.ejs', 'tender/modal.ejs');
+        }
+
+        /**
+         * 标段管理(Get)
+         *
+         * @param ctx
+         * @return {Promise<void>}
+         */
+        async listManageFinish(ctx) {
+            this.jsFiles = this.app.jsFiles.tender.manage;
+            // 先判断权限
+            // 获取用户新建标段权利
+            const accountInfo = await this.ctx.service.projectAccount.getDataById(this.ctx.session.sessionUser.accountId);
+            const userPermission = accountInfo !== undefined && accountInfo.permission !== '' ? JSON.parse(accountInfo.permission) : null;
+            if (userPermission !== null && userPermission.tender !== undefined && userPermission.tender.indexOf('1') !== -1) {
+                const renderData = {
+                    accountInfo,
+                    userPermission,
+                };
+                await this._listFinish('tender/manage.ejs', renderData, 'tender/manage_modal.ejs', 'manage');
+            } else {
+                this.ctx.redirect(ctx.request.header.referer);
+            }
+        }
+
         /**
          * 新增标段(Ajax)
          *
@@ -655,6 +759,7 @@ module.exports = app => {
                         map_json.lat = mapInfo.lat;
                     }
                 }
+                const canFinish = await this.ctx.service.tender.checkTenderCanFinish(tender);
 
                 const renderData = {
                     tenders,
@@ -681,6 +786,8 @@ module.exports = app => {
                     tenderMapList,
                     map_json,
                     fujianOssPath: ctx.app.config.fujianOssPath,
+                    canFinish: canFinish,
+                    buildStatus: tenderConst.buildStatus,
                 };
                 if (ctx.session.sessionUser.is_admin) {
                     renderData.tourists = await ctx.service.tenderTourist.getTourists(tender.id);
@@ -780,6 +887,17 @@ module.exports = app => {
                 ctx.body = this.ajaxErrorBody(err, '保存失败');
             }
         }
+        async saveBuildStatus(ctx) {
+            try {
+                const status = parseInt(ctx.query.status);
+                await ctx.service.tender.saveBuildStatus(ctx.tender.data, status);
+            } catch (err) {
+                this.log(err);
+                this.postError(err, '修改在建状态失败');
+            }
+            ctx.redirect('/tender/' + ctx.params.id);
+        }
+
 
         /**
          * 设置标段计量类型并调整到标段概况(Get)

+ 1 - 1
app/controller/wap_controller.js

@@ -170,7 +170,7 @@ module.exports = app => {
                 const accountInfo = await this.ctx.service.projectAccount.getDataById(ctx.session.sessionUser.accountId);
                 const userPermission = accountInfo !== undefined && accountInfo.permission !== '' ? JSON.parse(accountInfo.permission) : null;
 
-                const tenderList = await this.ctx.service.tender.getList('', userPermission);
+                const tenderList = await this.ctx.service.tender.getBuildList('', userPermission);
                 for (const t of tenderList) {
                     if (t.user_id === this.ctx.session.sessionUser.accountId && (
                         t.ledger_status === auditConst.ledger.status.checkNo || t.ledger_status === auditConst.ledger.status.uncheck)) {

+ 0 - 1
app/extend/context.js

@@ -58,7 +58,6 @@ module.exports = {
         if (error.stack) {
             this.logger.error(error);
         } else {
-            this.setMessage(error, messageType.ERROR);
             this.getLogger('fail').info(JSON.stringify({
                 error: error,
                 project: this.session.sessionProject,

+ 43 - 0
app/middleware/tender_build_check.js

@@ -0,0 +1,43 @@
+'use strict';
+
+/**
+ *
+ *
+ * @author Mai
+ * @date
+ * @version
+ */
+
+module.exports = options => {
+    /**
+     * 标段校验 中间件
+     * 1. 读取标段数据(包括属性)
+     * 2. 检验用户是否可见标段(不校验具体权限)
+     *
+     * @param {function} next - 中间件继续执行的方法
+     * @return {void}
+     */
+    return function* tenderBuildCheck(next) {
+        try {
+            if (this.tender.readOnly) throw '当前标段已完工,不可进行该操作';
+            yield next;
+        } catch (err) {
+            // 输出错误到日志
+            this.log(err);
+            if (this.helper.isAjax(this.request)) {
+                if (err.stack) {
+                    this.body = {err: 4, msg: '标段数据未知错误', data: null};
+                } else {
+                    this.body = {err: 3, msg: err.toString(), data: null};
+                }
+            } else {
+                if (this.helper.isWap(this.request)) {
+                    this.redirect('/wap/list');
+                } else {
+                    this.postError(err, '操作失败');
+                    this.redirect(this.request.headers.referer);
+                }
+            }
+        }
+    };
+};

+ 2 - 0
app/middleware/tender_check.js

@@ -11,6 +11,7 @@
 const auditConst = require('../const/audit').ledger;
 const messageType = require('../const/message_type');
 const scPermission = require('../const/schedule').permission;
+const buildStatus = require('../const/tender').buildStatus;
 
 module.exports = options => {
     /**
@@ -35,6 +36,7 @@ module.exports = options => {
             if (!tender.data.measure_type) {
                 throw '请先选择计量模式';
             }
+            tender.readOnly = tender.data.build_status === buildStatus.status.finish;
             tender.info = yield this.service.tenderInfo.getTenderInfo(tender.id);
             if (!tender.data.ledger_status) {
                 tender.data.ledger_status = auditConst.status.uncheck;

+ 1 - 0
app/public/js/file_detail.js

@@ -177,6 +177,7 @@ $(document).ready(function() {
                     const path = parent.getPath();
                     for (const p of path) {
                         p.name = p.source_node.name + (p.source_node.total_file_count > 0 ? `(${p.source_node.total_file_count})` : '');
+                        if (p.source_node.is_fixed) p.isParent = true;
                         filingObj.filingTree.updateNode(p);
                     }
                 }

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

@@ -1267,9 +1267,10 @@ $(document).ready(() => {
                 const node = SpreadJsObj.getSelectObject(info.sheet);
                 const col = info.sheet.zh_setting.cols[info.col];
                 const posRange = stagePos.getLedgerPos(node.id);
+                const tpUnit = ['总额', '元', '台', '个', '处', '月', '棵', '套', '组', '辆'];
                 if (node.pre_used === 1 ||
                     (node.children && node.children.length > 0) ||
-                    (node.unit !== '总额' && node.unit !== '元') ||
+                    (tpUnit.indexOf(node.unit) < 0) ||
                     (posRange && posRange.length > 0) /*|| !checkZero(node.qc_qty)*/) {
                     SpreadJsObj.reLoadRowData(info.sheet, info.row);
                     return;

+ 44 - 39
app/router.js

@@ -9,6 +9,7 @@ module.exports = app => {
     const projectManagerCheck = app.middlewares.projectManagerCheck();
     // 标段读取中间件
     const tenderCheck = app.middlewares.tenderCheck();
+    const tenderBuildCheck = app.middlewares.tenderBuildCheck();
     const ledgerAuditCheck = app.middlewares.ledgerAuditCheck();
     const reviseAuditCheck = app.middlewares.reviseAuditCheck();
     const changeAuditCheck = app.middlewares.changeAuditCheck();
@@ -145,10 +146,12 @@ module.exports = app => {
     // 金额概况
     app.get('/list', sessionAuth, 'tenderController.listDefault');
     app.get('/listOrg', sessionAuth, 'tenderController.listDefaultOrg');
+    app.get('/list/finish', sessionAuth, 'tenderController.listDefaultFinish');
     app.post('/list/load', sessionAuth, 'tenderController.listLoad');
     app.post('/list/load2', sessionAuth, 'tenderController.listLoad2');
     app.get('/list/info', sessionAuth, 'tenderController.listInfo');
     app.get('/list/infoOrg', sessionAuth, 'tenderController.listInfoOrg');
+    app.get('/list/info/finish', sessionAuth, 'tenderController.listInfoFinish');
 
     // 计量进度
     app.get('/list/progress', sessionAuth, 'tenderController.listProgress');
@@ -157,6 +160,7 @@ module.exports = app => {
     // 管理标段
     app.get('/list/manage', sessionAuth, 'tenderController.listManage');
     app.get('/list/manageOrg', sessionAuth, 'tenderController.listManageOrg');
+    app.get('/list/manage/finish', sessionAuth, 'tenderController.listManageFinish');
     app.post('/list/add', sessionAuth, 'tenderController.addTender');
     app.post('/list/update', sessionAuth, 'tenderController.updateTender');
     app.post('/list/del', sessionAuth, 'tenderController.deleteTender');
@@ -167,6 +171,7 @@ module.exports = app => {
     app.get('/tender/:id/type', sessionAuth, 'tenderController.tenderType');
     app.post('/tender/:id/save', sessionAuth, tenderCheck, 'tenderController.saveTenderInfo');
     app.post('/tender/:id/save2', sessionAuth, tenderCheck, 'tenderController.saveTenderInfo2');
+    app.post('/tender/:id/build', sessionAuth, tenderCheck, 'tenderController.saveBuildStatus');
     app.post('/tender/rule', sessionAuth, 'tenderController.rule');
     app.post('/tender/:id/rule/first', sessionAuth, tenderCheck, 'tenderController.ruleFirst');
     app.get('/tender/:id/shenpi', sessionAuth, tenderCheck, 'tenderController.shenpiSet');
@@ -184,13 +189,13 @@ module.exports = app => {
     // 预付款
     app.get('/tender/:id/advance/:type', sessionAuth, tenderCheck, 'advanceController.index');
     // app.get('/tender/:id/advance/material', sessionAuth, tenderCheck, 'advanceController.materialList');
-    app.post('/tender/:id/advance/:type/create', sessionAuth, tenderCheck, 'advanceController.create');
-    app.post('/tender/:id/advance/:type/delete', sessionAuth, tenderCheck, 'advanceController.delete');
+    app.post('/tender/:id/advance/:type/create', sessionAuth, tenderCheck, tenderBuildCheck, 'advanceController.create');
+    app.post('/tender/:id/advance/:type/delete', sessionAuth, tenderCheck, tenderBuildCheck, 'advanceController.delete');
     app.get('/tender/:id/advance/:order/detail', sessionAuth, tenderCheck, advanceCheck, 'advanceController.detail');
     app.post('/tender/:id/advance/:order/audit/add', sessionAuth, tenderCheck, advanceCheck, 'advanceController.addAudit');
     app.post('/tender/:id/advance/:order/audit/delete', sessionAuth, tenderCheck, advanceCheck, 'advanceController.deleteAudit');
-    app.post('/tender/:id/advance/:order/audit/start', sessionAuth, tenderCheck, advanceCheck, 'advanceController.start');
-    app.post('/tender/:id/advance/:order/audit/check', sessionAuth, tenderCheck, advanceCheck, 'advanceController.checkAudit');
+    app.post('/tender/:id/advance/:order/audit/start', sessionAuth, tenderCheck, tenderBuildCheck, advanceCheck, tenderBuildCheck, 'advanceController.start');
+    app.post('/tender/:id/advance/:order/audit/check', sessionAuth, tenderCheck, tenderBuildCheck, advanceCheck, tenderBuildCheck, 'advanceController.checkAudit');
     app.post('/tender/:id/advance/:order/update', sessionAuth, tenderCheck, advanceCheck, 'advanceController.update');
     app.post('/tender/:id/advance/:order/file/upload', sessionAuth, tenderCheck, advanceCheck, 'advanceController.upload');
     app.get('/tender/:id/advance/:order/file/:fid/download', sessionAuth, tenderCheck, 'advanceController.downloadFile');
@@ -225,8 +230,8 @@ module.exports = app => {
     app.get('/tender/:id/ledger/audit', sessionAuth, tenderCheck, uncheckTenderCheck, 'ledgerAuditController.index');
     app.post('/tender/:id/ledger/audit/add', sessionAuth, tenderCheck, uncheckTenderCheck, 'ledgerAuditController.add');
     app.post('/tender/:id/ledger/audit/delete', sessionAuth, tenderCheck, uncheckTenderCheck, 'ledgerAuditController.remove');
-    app.post('/tender/:id/ledger/audit/start', sessionAuth, tenderCheck, uncheckTenderCheck, ledgerAuditCheck, 'ledgerAuditController.start');
-    app.post('/tender/:id/ledger/audit/check', sessionAuth, tenderCheck, uncheckTenderCheck, 'ledgerAuditController.check');
+    app.post('/tender/:id/ledger/audit/start', sessionAuth, tenderCheck, uncheckTenderCheck, ledgerAuditCheck, tenderBuildCheck, 'ledgerAuditController.start');
+    app.post('/tender/:id/ledger/audit/check', sessionAuth, tenderCheck, uncheckTenderCheck, tenderBuildCheck, 'ledgerAuditController.check');
 
     // 部位台账
     app.get('/tender/:id/ledger/bwtz', sessionAuth, tenderCheck, uncheckTenderCheck, 'ledgerController.bwtz');
@@ -238,8 +243,8 @@ module.exports = app => {
 
     // 台账修订
     app.get('/tender/:id/revise', sessionAuth, tenderCheck, uncheckTenderCheck, 'reviseController.index');
-    app.post('/tender/:id/revise/add', sessionAuth, tenderCheck, uncheckTenderCheck, 'reviseController.add');
-    app.post('/tender/:id/revise/cancel', sessionAuth, tenderCheck, uncheckTenderCheck, 'reviseController.cancel');
+    app.post('/tender/:id/revise/add', sessionAuth, tenderCheck, uncheckTenderCheck, tenderBuildCheck, 'reviseController.add');
+    app.post('/tender/:id/revise/cancel', sessionAuth, tenderCheck, uncheckTenderCheck, tenderBuildCheck, 'reviseController.cancel');
     app.post('/tender/:id/revise/save', sessionAuth, tenderCheck, uncheckTenderCheck, 'reviseController.save');
     app.post('/setting/revise/show-invalid', sessionAuth, 'reviseController.showInvalid');
 
@@ -269,8 +274,8 @@ module.exports = app => {
     // 修订审批
     app.post('/tender/:id/revise/audit/add', sessionAuth, tenderCheck, uncheckTenderCheck, 'reviseController.addAuditor');
     app.post('/tender/:id/revise/audit/remove', sessionAuth, tenderCheck, uncheckTenderCheck, 'reviseController.removeAuditor');
-    app.post('/tender/:id/revise/audit/start', sessionAuth, tenderCheck, uncheckTenderCheck, reviseCheck, reviseAuditCheck, 'reviseController.start');
-    app.post('/tender/:id/revise/audit/check', sessionAuth, tenderCheck, uncheckTenderCheck, reviseCheck, 'reviseController.check');
+    app.post('/tender/:id/revise/audit/start', sessionAuth, tenderCheck, uncheckTenderCheck, reviseCheck, reviseAuditCheck, tenderBuildCheck, 'reviseController.start');
+    app.post('/tender/:id/revise/audit/check', sessionAuth, tenderCheck, uncheckTenderCheck, reviseCheck, tenderBuildCheck, 'reviseController.check');
 
     // 签约清单
     app.post('/tender/:id/deal/get-data', sessionAuth, tenderCheck, uncheckTenderCheck, 'dealBillsController.getData');
@@ -282,9 +287,9 @@ module.exports = app => {
     // 期计量
     app.get('/tender/:id/measure/stage', sessionAuth, tenderCheck, uncheckTenderCheck, 'measureController.stage');
     app.post('/tender/:id/measure/stage/auditors', sessionAuth, tenderCheck, uncheckTenderCheck, 'measureController.stageAuditors');
-    app.post('/tender/:id/measure/add', sessionAuth, tenderCheck, uncheckTenderCheck, 'measureController.add');
+    app.post('/tender/:id/measure/add', sessionAuth, tenderCheck, uncheckTenderCheck, tenderBuildCheck, 'measureController.add');
     app.post('/tender/:id/measure/save', sessionAuth, tenderCheck, uncheckTenderCheck, 'measureController.save');
-    app.post('/tender/:id/measure/stage/delete', sessionAuth, tenderCheck, uncheckTenderCheck, 'measureController.delete');
+    app.post('/tender/:id/measure/stage/delete', sessionAuth, tenderCheck, uncheckTenderCheck, tenderBuildCheck, 'measureController.delete');
 
     // 计量台账 -- 清单汇总
     app.get('/tender/:id/measure/gather', sessionAuth, tenderCheck, uncheckTenderCheck, 'measureController.gather');
@@ -353,10 +358,10 @@ module.exports = app => {
     // 审批
     app.post('/tender/:id/measure/stage/:order/audit/add', sessionAuth, tenderCheck, uncheckTenderCheck, stageCheck, 'stageController.addAudit');
     app.post('/tender/:id/measure/stage/:order/audit/delete', sessionAuth, tenderCheck, uncheckTenderCheck, stageCheck, 'stageController.deleteAudit');
-    app.post('/tender/:id/measure/stage/:order/audit/start', sessionAuth, tenderCheck, uncheckTenderCheck, stageCheck, 'stageController.startAudit');
-    app.post('/tender/:id/measure/stage/:order/audit/check', sessionAuth, tenderCheck, uncheckTenderCheck, stageCheck, 'stageController.checkAudit');
-    app.get('/tender/:id/measure/stage/:order/audit/check/again', sessionAuth, tenderCheck, uncheckTenderCheck, stageCheck, 'stageController.checkAuditAgain');
-    app.get('/tender/:id/measure/stage/:order/audit/check/cancel', sessionAuth, tenderCheck, uncheckTenderCheck, stageCheck, 'stageController.checkAuditCancel');
+    app.post('/tender/:id/measure/stage/:order/audit/start', sessionAuth, tenderCheck, uncheckTenderCheck, stageCheck, tenderBuildCheck, 'stageController.startAudit');
+    app.post('/tender/:id/measure/stage/:order/audit/check', sessionAuth, tenderCheck, uncheckTenderCheck, stageCheck, tenderBuildCheck, 'stageController.checkAudit');
+    app.get('/tender/:id/measure/stage/:order/audit/check/again', sessionAuth, tenderCheck, uncheckTenderCheck, stageCheck, tenderBuildCheck, 'stageController.checkAuditAgain');
+    app.get('/tender/:id/measure/stage/:order/audit/check/cancel', sessionAuth, tenderCheck, uncheckTenderCheck, stageCheck, tenderBuildCheck, 'stageController.checkAuditCancel');
     app.post('/tender/:id/measure/stage/:order/audit/save', sessionAuth, tenderCheck, uncheckTenderCheck, stageCheck, 'stageController.saveAudit');
 
     // 部位台账
@@ -408,7 +413,7 @@ module.exports = app => {
 
     // 期审批管理
     app.get('/tender/:id/measure/stage/:order/manager', sessionAuth, tenderCheck, uncheckTenderCheck, stageCheck, 'stageController.manager');
-    app.post('/tender/:id/measure/stage/:order/manager/audit/delete', sessionAuth, tenderCheck, uncheckTenderCheck, stageCheck, 'stageController.managerAuditDelete');
+    app.post('/tender/:id/measure/stage/:order/manager/audit/delete', sessionAuth, tenderCheck, uncheckTenderCheck, stageCheck, tenderBuildCheck, 'stageController.managerAuditDelete');
 
     // 报表
     app.get('/tender/:id/report', sessionAuth, tenderCheck, uncheckTenderCheck, 'reportController.index');
@@ -465,21 +470,21 @@ module.exports = app => {
     app.get('/tender/:id/change', sessionAuth, tenderCheck, uncheckTenderCheck, 'changeController.index');
     app.get('/tender/:id/change/status/:status', sessionAuth, tenderCheck, uncheckTenderCheck, 'changeController.status');
     app.post('/tender/:id/change/newCode', sessionAuth, tenderCheck, uncheckTenderCheck, 'changeController.newCode');
-    app.post('/tender/:id/change/add', sessionAuth, tenderCheck, uncheckTenderCheck, 'changeController.add');
+    app.post('/tender/:id/change/add', sessionAuth, tenderCheck, uncheckTenderCheck, tenderBuildCheck, 'changeController.add');
     app.post('/tender/:id/change/defaultBills', sessionAuth, tenderCheck, uncheckTenderCheck, 'changeController.defaultBills');
     app.post('/tender/:id/change/:cid/info/file/upload', sessionAuth, 'changeController.uploadFile');
     app.get('/change/download/file/:id', sessionAuth, 'changeController.downloadFile');
     app.post('/change/download/file/:id', sessionAuth, 'changeController.checkFile');
     app.post('/tender/:id/change/:cid/info/file/delete', sessionAuth, 'changeController.deleteFile');
     app.post('/tender/:id/change/:cid/download/compresse-file', sessionAuth, tenderCheck, uncheckTenderCheck, 'changeController.downloadZip');
-    app.post('/tender/:id/change/delete', sessionAuth, tenderCheck, uncheckTenderCheck, 'changeController.delete');
+    app.post('/tender/:id/change/delete', sessionAuth, tenderCheck, uncheckTenderCheck, tenderBuildCheck, 'changeController.delete');
     app.post('/tender/:id/change/bills', sessionAuth, tenderCheck, uncheckTenderCheck, 'changeController.bills');
 
     app.post('/tender/:id/change/save', sessionAuth, tenderCheck, uncheckTenderCheck, changeAuditCheck, 'changeController.save');
 
-    app.post('/tender/:id/change/approval', sessionAuth, tenderCheck, uncheckTenderCheck, 'changeController.approval');
-    app.post('/tender/:id/change/check/again', sessionAuth, tenderCheck, uncheckTenderCheck, 'changeController.checkAgain');
-    app.post('/tender/:id/change/check/revise', sessionAuth, tenderCheck, uncheckTenderCheck, 'changeController.checkRevise');
+    app.post('/tender/:id/change/approval', sessionAuth, tenderCheck, uncheckTenderCheck, tenderBuildCheck, 'changeController.approval');
+    app.post('/tender/:id/change/check/again', sessionAuth, tenderCheck, uncheckTenderCheck, tenderBuildCheck, 'changeController.checkAgain');
+    app.post('/tender/:id/change/check/revise', sessionAuth, tenderCheck, uncheckTenderCheck, tenderBuildCheck, 'changeController.checkRevise');
 
     app.post('/tender/:id/change/:cid/check/codeRepeat', sessionAuth, tenderCheck, uncheckTenderCheck, 'changeController.checkCodeRepeat');
     app.post('/tender/:id/change/:cid/info/copy', sessionAuth, tenderCheck, uncheckTenderCheck, 'changeController.copyChange');
@@ -502,8 +507,8 @@ module.exports = app => {
     // 变更立项
     app.get('/tender/:id/change/project', sessionAuth, tenderCheck, uncheckTenderCheck, 'changeController.project');
     app.get('/tender/:id/change/project/status/:status', sessionAuth, tenderCheck, uncheckTenderCheck, 'changeController.projectStatus');
-    app.post('/tender/:id/change/project/add', sessionAuth, tenderCheck, uncheckTenderCheck, 'changeController.projectAdd');
-    app.post('/tender/:id/change/project/delete', sessionAuth, tenderCheck, uncheckTenderCheck, 'changeController.projectDelete');
+    app.post('/tender/:id/change/project/add', sessionAuth, tenderCheck, uncheckTenderCheck, tenderBuildCheck, 'changeController.projectAdd');
+    app.post('/tender/:id/change/project/delete', sessionAuth, tenderCheck, uncheckTenderCheck, tenderBuildCheck, 'changeController.projectDelete');
     app.get('/tender/:id/change/project/:cpid/information', sessionAuth, tenderCheck, uncheckTenderCheck, changeProjectCheck, 'changeController.projectInformation');
     app.post('/tender/:id/change/project/:cpid/information/save', sessionAuth, tenderCheck, uncheckTenderCheck, changeProjectCheck, 'changeController.projectInformationSave');
     app.post('/tender/:id/change/project/:cpid/information/file/upload', sessionAuth, tenderCheck, uncheckTenderCheck, changeProjectCheck, 'changeController.uploadProjectFile');
@@ -511,15 +516,15 @@ module.exports = app => {
     app.get('/tender/:id/change/project/:cpid/information/file/:fid/download', sessionAuth, tenderCheck, uncheckTenderCheck, changeProjectCheck, 'changeController.downloadProjectFile');
     app.post('/tender/:id/change/project/:cpid/information/audit/add', sessionAuth, tenderCheck, uncheckTenderCheck, changeProjectCheck, 'changeController.addProjectAudit');
     app.post('/tender/:id/change/project/:cpid/information/audit/delete', sessionAuth, tenderCheck, uncheckTenderCheck, changeProjectCheck, 'changeController.deleteProjectAudit');
-    app.post('/tender/:id/change/project/:cpid/information/audit/start', sessionAuth, tenderCheck, uncheckTenderCheck, changeProjectCheck, 'changeController.startProjectAudit');
-    app.post('/tender/:id/change/project/:cpid/information/audit/check', sessionAuth, tenderCheck, uncheckTenderCheck, changeProjectCheck, 'changeController.checkProjectAudit');
+    app.post('/tender/:id/change/project/:cpid/information/audit/start', sessionAuth, tenderCheck, uncheckTenderCheck, changeProjectCheck, tenderBuildCheck, 'changeController.startProjectAudit');
+    app.post('/tender/:id/change/project/:cpid/information/audit/check', sessionAuth, tenderCheck, uncheckTenderCheck, changeProjectCheck, tenderBuildCheck, 'changeController.checkProjectAudit');
     app.post('/tender/:id/change/project/:cpid/information/xsaudit/add', sessionAuth, tenderCheck, uncheckTenderCheck, changeProjectCheck, 'changeController.addProjectXsAudit');
     app.post('/tender/:id/change/project/:cpid/information/xsaudit/delete', sessionAuth, tenderCheck, uncheckTenderCheck, changeProjectCheck, 'changeController.deleteProjectXsAudit');
     // 变更申请
     app.get('/tender/:id/change/apply', sessionAuth, tenderCheck, uncheckTenderCheck, 'changeController.apply');
     app.get('/tender/:id/change/apply/status/:status', sessionAuth, tenderCheck, uncheckTenderCheck, 'changeController.applyStatus');
-    app.post('/tender/:id/change/apply/add', sessionAuth, tenderCheck, uncheckTenderCheck, 'changeController.applyAdd');
-    app.post('/tender/:id/change/apply/delete', sessionAuth, tenderCheck, uncheckTenderCheck, 'changeController.applyDelete');
+    app.post('/tender/:id/change/apply/add', sessionAuth, tenderCheck, uncheckTenderCheck, tenderBuildCheck, 'changeController.applyAdd');
+    app.post('/tender/:id/change/apply/delete', sessionAuth, tenderCheck, uncheckTenderCheck, tenderBuildCheck, 'changeController.applyDelete');
     app.get('/tender/:id/change/apply/:caid/information', sessionAuth, tenderCheck, uncheckTenderCheck, changeApplyCheck, 'changeController.applyInformation');
     app.post('/tender/:id/change/apply/:caid/information/save', sessionAuth, tenderCheck, uncheckTenderCheck, changeApplyCheck, 'changeController.applyInformationSave');
     app.post('/tender/:id/change/apply/:caid/information/file/upload', sessionAuth, tenderCheck, uncheckTenderCheck, changeApplyCheck, 'changeController.uploadApplyFile');
@@ -527,15 +532,15 @@ module.exports = app => {
     app.get('/tender/:id/change/apply/:caid/information/file/:fid/download', sessionAuth, tenderCheck, uncheckTenderCheck, changeApplyCheck, 'changeController.downloadApplyFile');
     app.post('/tender/:id/change/apply/:caid/information/audit/add', sessionAuth, tenderCheck, uncheckTenderCheck, changeApplyCheck, 'changeController.addApplyAudit');
     app.post('/tender/:id/change/apply/:caid/information/audit/delete', sessionAuth, tenderCheck, uncheckTenderCheck, changeApplyCheck, 'changeController.deleteApplyAudit');
-    app.post('/tender/:id/change/apply/:caid/information/audit/start', sessionAuth, tenderCheck, uncheckTenderCheck, changeApplyCheck, 'changeController.startApplyAudit');
-    app.post('/tender/:id/change/apply/:caid/information/audit/check', sessionAuth, tenderCheck, uncheckTenderCheck, changeApplyCheck, 'changeController.checkApplyAudit');
+    app.post('/tender/:id/change/apply/:caid/information/audit/start', sessionAuth, tenderCheck, uncheckTenderCheck, changeApplyCheck, tenderBuildCheck, 'changeController.startApplyAudit');
+    app.post('/tender/:id/change/apply/:caid/information/audit/check', sessionAuth, tenderCheck, uncheckTenderCheck, changeApplyCheck, tenderBuildCheck, 'changeController.checkApplyAudit');
     app.get('/tender/:id/change/apply/:caid/information/notice', sessionAuth, tenderCheck, uncheckTenderCheck, changeApplyCheck, 'changeController.applyInformationNotice');
     app.post('/tender/:id/change/apply/:caid/information/list/save', sessionAuth, tenderCheck, uncheckTenderCheck, changeApplyCheck, 'changeController.saveApplyListsData');
     // 变更方案
     app.get('/tender/:id/change/plan', sessionAuth, tenderCheck, uncheckTenderCheck, 'changeController.plan');
     app.get('/tender/:id/change/plan/status/:status', sessionAuth, tenderCheck, uncheckTenderCheck, 'changeController.planStatus');
-    app.post('/tender/:id/change/plan/add', sessionAuth, tenderCheck, uncheckTenderCheck, 'changeController.planAdd');
-    app.post('/tender/:id/change/plan/delete', sessionAuth, tenderCheck, uncheckTenderCheck, 'changeController.planDelete');
+    app.post('/tender/:id/change/plan/add', sessionAuth, tenderCheck, uncheckTenderCheck, tenderBuildCheck, 'changeController.planAdd');
+    app.post('/tender/:id/change/plan/delete', sessionAuth, tenderCheck, uncheckTenderCheck, tenderBuildCheck, 'changeController.planDelete');
     app.get('/tender/:id/change/plan/:cpid/info', sessionAuth, tenderCheck, uncheckTenderCheck, changePlanCheck, 'changeController.planInformation');// 针对旧数据wap端跳转web问题
     app.get('/tender/:id/change/plan/:cpid/information', sessionAuth, tenderCheck, uncheckTenderCheck, changePlanCheck, 'changeController.planInformation');
     app.post('/tender/:id/change/plan/:cpid/information/save', sessionAuth, tenderCheck, uncheckTenderCheck, changePlanCheck, 'changeController.planInformationSave');
@@ -544,21 +549,21 @@ module.exports = app => {
     app.get('/tender/:id/change/plan/:cpid/information/file/:fid/download', sessionAuth, tenderCheck, uncheckTenderCheck, changePlanCheck, 'changeController.downloadPlanFile');
     app.post('/tender/:id/change/plan/:cpid/information/audit/add', sessionAuth, tenderCheck, uncheckTenderCheck, changePlanCheck, 'changeController.addPlanAudit');
     app.post('/tender/:id/change/plan/:cpid/information/audit/delete', sessionAuth, tenderCheck, uncheckTenderCheck, changePlanCheck, 'changeController.deletePlanAudit');
-    app.post('/tender/:id/change/plan/:cpid/information/audit/start', sessionAuth, tenderCheck, uncheckTenderCheck, changePlanCheck, 'changeController.startPlanAudit');
-    app.post('/tender/:id/change/plan/:cpid/information/audit/check', sessionAuth, tenderCheck, uncheckTenderCheck, changePlanCheck, 'changeController.checkPlanAudit');
+    app.post('/tender/:id/change/plan/:cpid/information/audit/start', sessionAuth, tenderCheck, uncheckTenderCheck, changePlanCheck, tenderBuildCheck, 'changeController.startPlanAudit');
+    app.post('/tender/:id/change/plan/:cpid/information/audit/check', sessionAuth, tenderCheck, uncheckTenderCheck, changePlanCheck, tenderBuildCheck, 'changeController.checkPlanAudit');
     app.post('/tender/:id/change/plan/:cpid/information/list/save', sessionAuth, tenderCheck, uncheckTenderCheck, changePlanCheck, 'changeController.savePlanListsData');
     // 材料调差
     app.get('/tender/:id/measure/material', sessionAuth, tenderCheck, uncheckTenderCheck, 'materialController.index');
-    app.post('/tender/:id/measure/material/add', sessionAuth, tenderCheck, uncheckTenderCheck, 'materialController.add');
-    app.post('/tender/:id/measure/material/delete', sessionAuth, tenderCheck, uncheckTenderCheck, 'materialController.delete');
+    app.post('/tender/:id/measure/material/add', sessionAuth, tenderCheck, uncheckTenderCheck, tenderBuildCheck, 'materialController.add');
+    app.post('/tender/:id/measure/material/delete', sessionAuth, tenderCheck, uncheckTenderCheck, tenderBuildCheck, 'materialController.delete');
     app.post('/tender/:id/measure/material/auditors', sessionAuth, tenderCheck, uncheckTenderCheck, 'materialController.materialAuditors');
     app.post('/tender/:id/measure/material/:order/save/decimal', sessionAuth, tenderCheck, uncheckTenderCheck, materialCheck, 'materialController.saveDecimal');
     app.post('/tender/:id/measure/material/save', sessionAuth, tenderCheck, uncheckTenderCheck, 'materialController.save');
     // 审批
     app.post('/tender/:id/measure/material/:order/audit/add', sessionAuth, tenderCheck, uncheckTenderCheck, materialCheck, 'materialController.addAudit');
     app.post('/tender/:id/measure/material/:order/audit/delete', sessionAuth, tenderCheck, uncheckTenderCheck, materialCheck, 'materialController.deleteAudit');
-    app.post('/tender/:id/measure/material/:order/audit/start', sessionAuth, tenderCheck, uncheckTenderCheck, materialCheck, 'materialController.startAudit');
-    app.post('/tender/:id/measure/material/:order/audit/check', sessionAuth, tenderCheck, uncheckTenderCheck, materialCheck, 'materialController.checkAudit');
+    app.post('/tender/:id/measure/material/:order/audit/start', sessionAuth, tenderCheck, uncheckTenderCheck, materialCheck, tenderBuildCheck, 'materialController.startAudit');
+    app.post('/tender/:id/measure/material/:order/audit/check', sessionAuth, tenderCheck, uncheckTenderCheck, materialCheck, tenderBuildCheck, 'materialController.checkAudit');
     app.get('/tender/:id/measure/material/:order/audit/check/again', sessionAuth, tenderCheck, uncheckTenderCheck, materialCheck, 'materialController.checkAuditAgain');
     // 调差工料
     app.get('/tender/:id/measure/material/:order', sessionAuth, tenderCheck, uncheckTenderCheck, materialCheck, 'materialController.info');
@@ -638,7 +643,7 @@ module.exports = app => {
     app.get('/wap/tender/:id/stage/:order', sessionAuth, tenderCheck, uncheckTenderCheck, 'wapController.stage');
     app.get('/wap/tender/:id/change/:cid/info', sessionAuth, tenderCheck, uncheckTenderCheck, 'wapController.change');
     app.get('/wap/tender/:id/change/plan/:cpid/info', sessionAuth, tenderCheck, uncheckTenderCheck, 'wapController.changePlan');
-    app.post('/wap/tender/:id/change/approval', sessionAuth, tenderCheck, uncheckTenderCheck, 'wapController.changeApproval');
+    app.post('/wap/tender/:id/change/approval', sessionAuth, tenderCheck, uncheckTenderCheck, tenderBuildCheck, 'wapController.changeApproval');
     app.get('/wap/tender/:id/revise/:rid/info', sessionAuth, tenderCheck, uncheckTenderCheck, 'wapController.revise');
     app.get('/wap/tender/:id/advance', sessionAuth, tenderCheck, uncheckTenderCheck, 'wapController.advance');
     app.get('/wap/tender/:id/advance/:order/detail', sessionAuth, tenderCheck, advanceCheck, 'wapController.advanceDetail');

+ 65 - 4
app/service/tender.js

@@ -16,6 +16,7 @@ const path = require('path');
 const commonQueryColumns = [
     'id', 'project_id', 'name', 'status', 'category', 'ledger_times', 'ledger_status', 'measure_type', 'user_id', 'valuation', 'create_time',
     'total_price', 'deal_tp', 'copy_id', 's2b_gxby_check', 's2b_gxby_limit', 's2b_dagl_check', 's2b_dagl_limit', 'has_rela', 'his_id', 'rpt_show_level',
+    'build_status',
 ];
 
 module.exports = app => {
@@ -84,7 +85,7 @@ module.exports = app => {
          * @param {Number} getAll - 是否取所有标段
          * @return {Array} - 返回标段数据
          */
-        async getList(listStatus = '', permission = null, getAll = 0) {
+        async getList(listStatus = '', permission = null, getAll = 0, buildStatusFilter = '') {
             // 获取当前项目信息
             const session = this.ctx.session;
             let sql = '';
@@ -96,7 +97,7 @@ module.exports = app => {
                     '  FROM ?? As t ' +
                     '  Left Join ?? As pa ' +
                     '  ON t.`user_id` = pa.`id` ' +
-                    '  WHERE t.`project_id` = ? AND t.`user_id` = ? ORDER BY CONVERT(t.`name` USING GBK) ASC';
+                    '  WHERE t.`project_id` = ? ' + buildStatusFilter + ' AND t.`user_id` = ? ORDER BY CONVERT(t.`name` USING GBK) ASC';
                 sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, session.sessionProject.id, session.sessionUser.accountId];
             } else if (getAll === 1 || (permission !== null && permission.tender !== undefined && permission.tender.indexOf('2') !== -1)) {
                 // 具有查看所有标段权限的用户查阅标段
@@ -105,7 +106,7 @@ module.exports = app => {
                     '  FROM ?? As t ' +
                     '  Left Join ?? As pa ' +
                     '  ON t.`user_id` = pa.`id` ' +
-                    '  WHERE t.`project_id` = ? ORDER BY CONVERT(t.`name` USING GBK) ASC';
+                    '  WHERE t.`project_id` = ?' + buildStatusFilter + ' ORDER BY CONVERT(t.`name` USING GBK) ASC';
                 sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, session.sessionProject.id];
             } else {
                 // 根据用户权限查阅标段
@@ -126,7 +127,7 @@ module.exports = app => {
                     '  FROM ?? As t ' +
                     '  Left Join ?? As pa ' +
                     '  ON t.`user_id` = pa.`id` ' +
-                    '  WHERE t.`project_id` = ? AND (' +
+                    '  WHERE t.`project_id` = ? ' + buildStatusFilter + ' AND (' +
                     // 创建的标段
                     '    t.`user_id` = ?' +
                     // 参与审批 台账 的标段
@@ -174,6 +175,32 @@ module.exports = app => {
             return list;
         }
 
+        /**
+         * 获取你所参与的标段的列表 - 完工
+         *
+         * @param {String} listStatus - 取列表状态,如果是管理页要传
+         * @param {String} permission - 根据权限取值
+         * @param {Number} getAll - 是否取所有标段
+         * @return {Array} - 返回标段数据
+         */
+        async getFinishList(listStatus = '', permission = null, getAll = 0) {
+            const buildStatusFilter = this.db.format(' AND build_status = ?', [tenderConst.buildStatus.status.finish]);
+            return await this.getList(listStatus, permission, getAll, buildStatusFilter);
+        }
+
+        /**
+         * 获取你所参与的标段的列表 - 在建
+         *
+         * @param {String} listStatus - 取列表状态,如果是管理页要传
+         * @param {String} permission - 根据权限取值
+         * @param {Number} getAll - 是否取所有标段
+         * @return {Array} - 返回标段数据
+         */
+        async getBuildList(listStatus = '', permission = null, getAll = 0) {
+            const buildStatusFilter = this.db.format(' AND build_status = ?', [tenderConst.buildStatus.status.build]);
+            return await this.getList(listStatus, permission, getAll, buildStatusFilter);
+        }
+
         async getList4Select(selectType) {
             const accountInfo = await this.ctx.service.projectAccount.getDataById(this.ctx.session.sessionUser.accountId);
             const userPermission = accountInfo !== undefined && accountInfo.permission !== '' ? JSON.parse(accountInfo.permission) : null;
@@ -473,6 +500,40 @@ module.exports = app => {
             }
         }
 
+        async checkTenderCanFinish(tender) {
+            // 检查台账、台账修订、预付款、计量期、材差期、变更令状态
+            if (tender.ledger_status !== auditConst.ledger.status.checked) return false;
+            const lastRevise = await this.ctx.service.ledgerRevise.getLastestRevise(tender.id, true);
+            if (lastRevise && lastRevise.status !== auditConst.revise.status.checked) return false;
+            const advanceOn = await this.db.queryOne(`SELECT * FROM ${this.ctx.service.advance.tableName} WHERE tid = ${tender.id} AND status <> ${auditConst.advance.status.checked}`);
+            if (advanceOn) return false;
+            const stageOn = await this.db.queryOne(`SELECT * FROM ${this.ctx.service.stage.tableName} WHERE tid = ${tender.id} AND status <> ${auditConst.stage.status.checked}`);
+            if (stageOn) return false;
+            const materialOn = await this.db.queryOne(`SELECT * FROM ${this.ctx.service.material.tableName} WHERE tid = ${tender.id} AND status <> ${auditConst.material.status.checked}`);
+            if (materialOn) return false;
+            const changeOn = await this.db.queryOne(`SELECT * FROM ${this.ctx.service.change.tableName} WHERE tid = ${tender.id} AND valid = 1 AND status <> ${auditConst.flow.status.checked}`);
+            if (changeOn) return false;
+            const changeApplyOn = await this.db.queryOne(`SELECT * FROM ${this.ctx.service.changeApply.tableName} WHERE tid = ${tender.id} AND status <> ${auditConst.changeApply.status.checked}`);
+            if (changeApplyOn) return false;
+            const changeProjectOn = await this.db.queryOne(`SELECT * FROM ${this.ctx.service.changeProject.tableName} WHERE tid = ${tender.id} AND status <> ${auditConst.changeProject.status.checked}`);
+            if (changeProjectOn) return false;
+            const changePlanOn = await this.db.queryOne(`SELECT * FROM ${this.ctx.service.changePlan.tableName} WHERE tid = ${tender.id} AND status <> ${auditConst.changePlan.status.checked}`);
+            if (changePlanOn) return false;
+            return true;
+        }
+
+        async saveBuildStatus(tender, status) {
+            const str = tenderConst.buildStatus.statusStr[status];
+            if (!str) throw '参数错误';
+
+            if (status === tenderConst.buildStatus.status.finish) {
+                const check = await this.checkTenderCanFinish(tender);
+                if (!check) throw '存在未审批完成的流程,请审批完成后再修改状态';
+            }
+
+            await this.defaultUpdate({ id: tender.id, build_status: status });
+        }
+
         async saveApiRela(tid, updateData) {
             await this.db.update(this.tableName, updateData, {where: { id: tid } });
         }

+ 15 - 0
app/view/report/rpt_all_popup.ejs

@@ -760,6 +760,21 @@
                 sortedCat.push(cat);
             }
         }
+        for (const tender of tenders) {
+            if (tender.lastStage !== undefined && tender.lastStage !== null && tender.category && tender.category.length === sortedCat.length) {
+                for (let cat of tender.category) {
+                    for (let cIdx = 0; cIdx < sortedCat.length; cIdx++) {
+                        if (cat.cid === sortedCat[cIdx].id) {
+                            cat.level = sortedCat[cIdx].level;
+                            break;
+                        }
+                    }
+                }
+                tender.category.sort(function(i1, i2){
+                    return i1.level - i2.level;
+                });
+            }
+        }
         let treeCache = [];
         //1. 选择用户已设置的分类
         if (sortedCat.length > 0) {

+ 23 - 2
app/view/tender/detail.ejs

@@ -2,7 +2,7 @@
 <% include ./tender_sub_menu.ejs %>
 <div class="panel-content">
     <div class="panel-title">
-        <div class="title-main d-flex">
+        <div class="title-main d-flex justify-content-between">
             <% include ./tender_sub_mini_menu.ejs %>
             <% if (tender.ledger_status !== audit.ledger.status.uncheck) { %>
                 <h2>进行至
@@ -13,12 +13,33 @@
                     <% } %>
                 </h2>
             <% } %>
+            <div class="align-items-center">
+                <% if (ctx.tender.data.build_status === buildStatus.status.build) { %>
+                <div class="d-inline-block">
+                    在建状态:在建中
+                    <% if (!ctx.tender.isTourist) { %>
+                    <% if (canFinish) { %>
+                    <a href="#mod-status" data-toggle="modal" data-target="#mod-status" class="btn btn-primary btn-sm ml-2">修改状态</a>
+                    <% } else { %>
+                    <a href="#mod-status2" data-toggle="modal" data-target="#mod-status1" class="btn btn-primary btn-sm ml-2">修改状态</a>
+                    <% } %>
+                    <% } %>
+                </div>
+                <% } else { %>
+                <div class="d-inline-block ml-2">
+                    在建状态:已完工
+                    <% if (!ctx.tender.isTourist) { %>
+                    <a href="#mod-status1" data-toggle="modal" data-target="#mod-status2" class="btn btn-primary btn-sm ml-2">修改状态</a>
+                    <% } %>
+                </div>
+                <% } %>
+            </div>
             <% if (cooperation) { %>
                 <div>
                     <a href="/tender/<%= tender.id %>/cooperation" class="btn btn-sm btn-light" ><i class="fa fa-users"></i> 协作办公</a>
                 </div>
             <% } %>
-            <div class="ml-auto">
+            <div class="clearfix">
                 <a href="javascript:void(0)" title="全屏显示" id="showFull" style="font-size: 16px" class="float-left text-dark mr-3"><i class="fa fa-arrows-alt"></i></a>
                 <div class="dropdown d-flex float-left mt-1 mr-2">
                     <!--<button id="showFull" class="btn btn-sm btn-outline-dark mr-2">全屏</button>-->

+ 56 - 0
app/view/tender/detail_modal.ejs

@@ -3027,3 +3027,59 @@
     })
 </script>
 <% } %>
+
+<!--在建状态-->
+<% if (ctx.tender.data.build_status === buildStatus.status.build) { %>
+<div class="modal fade" id="mod-status" data-backdrop="static" aria-hidden="true" style="display: none;">
+    <form class="modal-dialog" role="document" method="POST" action="/tender/<%- ctx.tender.id %>/build?status=<%- buildStatus.status.finish %>">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">修改在建状态</h5>
+            </div>
+            <div class="modal-body">
+                <h6>确认修改标段状态为「已完工」?</h6>
+                <h6>修改后,将<strong class="text-danger">无法</strong>再进行任一审批流程,且标段会被移至已完工页面。</h6>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">关闭</button>
+                <input type="hidden" name="_csrf_j" value="<%= ctx.csrf %>" />
+                <button type="submit" class="btn btn-sm btn-primary">确定修改</button>
+            </div>
+        </div>
+    </form>
+</div>
+<div class="modal fade" id="mod-status1" data-backdrop="static" style="display: none;" aria-hidden="true">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">修改在建状态</h5>
+            </div>
+            <div class="modal-body">
+                <h6>存在未审批完成的流程,请审批完成后再修改状态。</h6>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">关闭</button>
+            </div>
+        </div>
+    </div>
+</div>
+<% } else { %>
+<div class="modal fade" id="mod-status2" data-backdrop="static" aria-hidden="true" style="display: none;">
+    <form class="modal-dialog" role="document" method="POST" action="/tender/<%- ctx.tender.id %>/build?status=<%- buildStatus.status.build %>">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">修改在建状态</h5>
+            </div>
+            <div class="modal-body">
+                <h6>确认修改标段状态为「在建中」?</h6>
+
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">关闭</button>
+                <input type="hidden" name="_csrf_j" value="<%= ctx.csrf %>" />
+                <button type="submit" class="btn btn-sm btn-primary">确定修改</button>
+            </div>
+        </div>
+    </form>
+</div>
+<% } %>

+ 4 - 0
app/view/tender/index.ejs

@@ -1,5 +1,9 @@
 <div class="panel-content">
+    <% if (is_finish) { %>
+    <% include sub_memu_finish.ejs %>
+    <% } else { %>
     <% include ./sub_menu.ejs %>
+    <% } %>
     <div class="content-wrap">
         <div class="sjs-height-0" style="background-color: #fff">
             <div class="c-body">

+ 4 - 0
app/view/tender/info.ejs

@@ -1,5 +1,9 @@
 <div class="panel-content">
+    <% if (is_finish) { %>
+    <% include sub_memu_finish.ejs %>
+    <% } else { %>
     <% include ./sub_menu.ejs %>
+    <% } %>
     <div class="content-wrap">
         <div class="sjs-height-0" style="background-color: #fff">
             <div class="c-body">

+ 4 - 0
app/view/tender/manage.ejs

@@ -1,5 +1,9 @@
 <div class="panel-content">
+    <% if (is_finish) { %>
+    <% include sub_memu_finish.ejs %>
+    <% } else { %>
     <% include ./sub_menu.ejs %>
+    <% } %>
     <div class="content-wrap">
         <div class="sjs-height-0" style="background-color: #fff">
             <div class="c-body">

+ 4 - 0
app/view/tender/progress.ejs

@@ -1,5 +1,9 @@
 <div class="panel-content">
+    <% if (is_finish) { %>
+    <% include sub_memu_finish.ejs %>
+    <% } else { %>
     <% include ./sub_menu.ejs %>
+    <% } %>
     <div class="content-wrap">
         <div class="sjs-height-0" style="background-color: #fff">
             <div class="c-body">

+ 15 - 7
app/view/tender/shenpi.ejs

@@ -15,7 +15,7 @@
                             <div class="card mb-3">
                                 <div class="card-body <%- sp.code %>_div">
                                     <a class="pull-right set-otherTender" data-name="<%- sp.name %>" data-code="<%- sp.code %>" href="#batch" data-toggle="modal" data-target="#batch">设置其他标段</a>
-                                    <a class="pull-right set-otherShenpi mr-3" data-name="<%- sp.name %>" data-code="<%- sp.code %>" href="#batch2" data-toggle="modal" data-target="#batch2">设置其他流程</a>
+                                    <a class="pull-right set-otherShenpi mr-3" data-name="<%- sp.name %>" data-code="<%- sp.code %>" href="javascript: void(0);">设置其他流程</a>
                                     <% if (sp.code === 'stage' && !revising && ctx.tender.data.ledger_status === auditConst.ledger.status.checked) { %>
                                     <a class="pull-right mr-3" id="stage_cooperation" <% if (sp.status !== shenpi.sp_status.gdspl) { %>style="display: none"<% } %> data-name="<%- sp.name %>" data-code="<%- sp.code %>" href="#cooperation" data-toggle="modal" data-target="#cooperation">多人协同 <i class="fa fa-lock"></i></a>
                                     <% } %>
@@ -34,12 +34,19 @@
                                     <div class="lc-show">
                                     <% if (sp.status === shenpi.sp_status.gdspl) { %>
                                     <ul class="list-unstyled">
-                                        <% if (sp.auditList.length > 0) { %>
-                                        <% for (const [i, audit] of sp.auditList.entries()) { %>
+                                        <% if (sp.auditGroupList.length > 0) { %>
+                                        <% for (const [i, auditGroup] of sp.auditGroupList.entries()) { %>
                                         <li class="d-flex justify-content-start mb-3">
                                             <span class="col-auto"><%- ctx.helper.transFormToChinese(i+1) %>审</span>
                                             <span class="col-7 spr-span">
-                                                <span class="d-inline-block"></span>
+                                                <span class="d-inline-block">
+                                                    <select class="form-control form-control-sm" <% if (sp.code !== 'stage') { %> style="display: none;" <% } %>>
+                                                        <% for (const at of auditType.types) { %>
+                                                        <option value="<%- at.value %>" <% if (auditGroup[0].audit_type === at.value) { %>selected<%} %>><%- at.name %></option>
+                                                        <% } %>
+                                                    </select>
+                                                </span>
+                                                <% for (const audit of auditGroup) { %>
                                                 <span class="d-inline-block"><span class="badge badge-light"><%- audit.name %> <span class="dropdown">
                                                             <a href="javascript:void(0);" class="btn-sm text-danger px-1" title="移除" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="fa fa-remove"></i></a>
                                                             <div class="dropdown-menu">
@@ -50,9 +57,9 @@
                                                                     <button class="btn btn-sm btn-secondary">取消</button>
                                                                 </div>
                                                             </div>
-                                                        </span>
-                                                        <!--<a href="javascript:void(0);" class="remove-audit btn-sm text-danger px-1" title="移除" ><i class="fa fa-remove"></i></a></span> </span>-->
-                                            </span></span></span>
+                                                </span></span></span>
+                                                <% } %>
+                                            </span>
                                         </li>
                                         <% } %>
                                         <li class="pl-3"><a href="javascript:void(0);" class="add-audit" ><i class="fa fa-plus"></i> 添加流程</a></li>
@@ -176,4 +183,5 @@
     const tenders = JSON.parse(unescape('<%- escape(JSON.stringify(tenders)) %>'));
     const category = JSON.parse(unescape('<%- escape(JSON.stringify(categoryData)) %>'));
     const measureType = JSON.parse('<%- JSON.stringify(measureType) %>');
+    const auditType = JSON.parse(unescape('<%- escape(JSON.stringify(auditType)) %>'));
 </script>

+ 19 - 0
app/view/tender/sub_memu_finish.ejs

@@ -0,0 +1,19 @@
+<div class="panel-title fluid">
+    <div class="title-main  d-flex justify-content-between">
+        <div>
+            <div class="d-inline-block" id="show-level"></div>
+            <div class="d-inline-block">
+                <div class="btn-group btn-group-toggle group-tab" data-toggle="buttons">
+                    <label class="btn btn-sm btn-light <% if (ctx.url === '/list/info/finish') { %>active<% } %>" onclick="window.location.href='/list/info/finish'">
+                        <input type="radio" name="options" id="option1" autocomplete="off"> 金额概况
+                    </label>
+                    <% if (userPermission !== null && userPermission.tender !== undefined && userPermission.tender.indexOf('1') !== -1) { %>
+                    <label class="btn btn-sm btn-light  <% if (ctx.url === '/list/manage/finish') { %>active<% } %>" onclick="window.location.href='/list/manage/finish'">
+                        <input type="radio" name="options" id="option2" autocomplete="off"> 管理标段
+                    </label>
+                    <% } %>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>

+ 3 - 0
app/view/tender/sub_menu.ejs

@@ -57,6 +57,9 @@
             <a href="/compare/tz" class="btn btn-sm btn-primary pull-right" target="_blank">统计分析</a>
         </div>
         <% } %>
+        <div>
+            <a href="/list/info/finish" class="btn btn-sm btn-primary pull-right" target="_blank">完工标段</a>
+        </div>
         <% if (userPermission !== null && userPermission.tender !== undefined && userPermission.tender.indexOf('1') !== -1) { %>
         <div>
             <a href="#add-bd" name="add" data-toggle="modal" data-target="#add-bd" class="btn btn-sm btn-primary pull-right">新建标段</a>

+ 1 - 1
package.json

@@ -16,7 +16,7 @@
         "egg-etag": "^1.1.0",
         "egg-js-validator": "^1.0.2",
         "egg-multipart": "^2.7.1",
-        "egg-mysql": "^3.0.0",
+        "egg-mysql": "~3.0.0",
         "egg-oss": "^2.0.0",
         "egg-redis": "^1.0.2",
         "egg-scripts": "^1.0.0",

+ 15 - 0
sql/update.sql

@@ -37,3 +37,18 @@ CREATE TABLE `zh_construction_log` (
   `checked_time` datetime DEFAULT NULL COMMENT '审签时间',
   PRIMARY KEY (`id`) USING BTREE
 ) ENGINE=InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_unicode_ci COMMENT='施工日志内容表';
+
+ALTER TABLE `zh_tender`
+ADD COLUMN `build_status`  tinyint(4) UNSIGNED NOT NULL DEFAULT 1 COMMENT '建设状态(1在建,2完工)' AFTER `rpt_show_level`;
+
+-- 会签或签 暂不更新 --
+ALTER TABLE `zh_tender_cache`
+MODIFY COLUMN `stage_flow_cur_uid`  varchar(1000) NOT NULL DEFAULT 0 COMMENT '期-当前流程人id(,间隔)' AFTER `stage_complete_count`,
+MODIFY COLUMN `stage_flow_pre_uid`  varchar(1000) NOT NULL DEFAULT 0 COMMENT '期-上一流程人id(,间隔)' AFTER `stage_flow_cur_tp`;
+
+ALTER TABLE `zh_shenpi_audit`
+ADD COLUMN `audit_type`  tinyint(4) UNSIGNED NOT NULL DEFAULT 1 COMMENT '审批类型(1个人,2会签,3或签)' AFTER `audit_id`,
+ADD COLUMN `audit_order`  tinyint(4) UNSIGNED ZEROFILL NOT NULL DEFAULT 0 COMMENT '审批顺序' AFTER `audit_type`;
+
+ALTER TABLE `zh_stage_audit`
+ADD COLUMN `audit_type`  tinyint(4) UNSIGNED NOT NULL DEFAULT 1 COMMENT '审批类型(1个人,2会签,3或签)' AFTER `is_old`;