Prechádzať zdrojové kódy

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

TonyKang 4 rokov pred
rodič
commit
19b4f0140c

+ 2 - 2
app/const/audit.js

@@ -290,7 +290,7 @@ auditStatusString[auditStatus.checked] = '审批通过';
 auditStatusString[auditStatus.back] = '退回';
 auditStatusString[auditStatus.backnew] = '审批退回';
 auditStatusString[auditStatus.checkAgain] = '重新审批';
-auditStatusString[auditStatus.revise] = '修订';
+auditStatusString[auditStatus.revise] = '修订变更';
 
 const auditStatusClass = [];
 auditStatusClass[auditStatus.uncheck] = '';
@@ -300,7 +300,7 @@ auditStatusClass[auditStatus.checked] = 'text-success';
 auditStatusClass[auditStatus.back] = 'text-warning';
 auditStatusClass[auditStatus.backnew] = 'text-warning';
 auditStatusClass[auditStatus.checkAgain] = 'text-warning';
-auditStatusClass[auditStatus.revise] = '';
+auditStatusClass[auditStatus.revise] = 'text-warning';
 
 /* ------------------------------------------------------- */
 

+ 5 - 1
app/const/tender_info.js

@@ -8,7 +8,7 @@
  * @version
  */
 
-const parseInfo = ['deal_info', 'construction_unit', 'tech_param', 'decimal', 'precision', 'deal_param', 'display', 'pay_account', 'shenpi', 'bid_info'];
+const parseInfo = ['deal_info', 'construction_unit', 'tech_param', 'decimal', 'precision', 'deal_param', 'display', 'pay_account', 'shenpi', 'bid_info', 'ledger_check'];
 const arrayInfo = ['chapter'];
 const defaultInfo = {
     // 合同信息
@@ -155,6 +155,10 @@ const defaultInfo = {
         change: 1,
         material: 1,
     },
+    ledger_check: {
+        same_code: true,
+        sibling: true,
+    }
 };
 
 module.exports = {

+ 12 - 3
app/controller/change_controller.js

@@ -68,6 +68,8 @@ module.exports = app => {
                         case 5:
                             changeAudit = await ctx.service.changeAudit.getLastUser(c.cid, c.times - 1, status);
                             auditStatus = c.uid === ctx.session.sessionUser.accountId ? 1 : 0;
+                            const back_changeUsedData = await ctx.service.stageChange.getFinalUsedData(ctx.tender.id, c.cid);
+                            c.stageChangeNum = this.ctx.helper.sum(back_changeUsedData.map(x => { return Math.abs(x.used_qty); }));
                             break;
                         case 6:
                             changeAudit = await ctx.service.changeAudit.getLastBackUser(c.cid, c.times);
@@ -814,18 +816,25 @@ module.exports = app => {
                     throw '该变更令当前无法上报';
                 }
                 // 判断是否是修订,判断有无审批人员作弊
-                if (ctx.change.status === audit.flow.status.revise && ctx.tender.info.shenpi.change === shenpiConst.sp_status.sqspr) {
+                if ((ctx.change.status === audit.flow.status.revise || ctx.change.is_revise) && ctx.tender.info.shenpi.change === shenpiConst.sp_status.sqspr) {
                     // 获取上一次的审批人流程
                     const lastUserList = await ctx.service.changeAudit.getListGroupByTimes(ctx.change.cid, ctx.change.times - 1);
                     const lastUidList = ctx.helper._.map(lastUserList, 'uid');
                     // 判断上一次审批是否为非原报为审批人
                     const nowUidList = ctx.helper._.map(ctx.change.auditors, 'uid');
-                    if (!ctx.helper._.isEqual(lastUidList, nowUidList) && nowUidList.length === 2 && nowUidList[0] === nowUidList[1]) {
+                    // 判断条件修订可上报条件
+                    // 1.有原报,有其他人   可以添加原报作为审核人,但是不能只原报上报
+                    // 2.有原报,无其他人   可以添加原报作为审核人,可以只原报上报
+                    // 3.无原报,有其他人   不可以添加原报
+                    const noYBUidList = ctx.change.status === audit.flow.status.revise ? ctx.helper._.initial(ctx.helper._.tail(lastUidList)) : ctx.helper._.tail(lastUidList);
+                    if (!ctx.helper._.isEqual(lastUidList, nowUidList) && ctx.helper._.includes(noYBUidList, lastUidList[0]) && nowUidList.length === 2 && nowUidList[0] === nowUidList[1]) {
                         throw '该变更令不能指定原报人为单独审批人';
                     }
+                    if (!ctx.helper._.isEqual(lastUidList, nowUidList) && !ctx.helper._.includes(noYBUidList, lastUidList[0]) && ctx.helper._.includes(ctx.helper._.tail(nowUidList), nowUidList[0])) {
+                        throw '该变更令不能指定原报为审批人,请移除';
+                    }
                 }
                 await ctx.service.changeAudit.start(ctx.change.cid, ctx.change.times);
-
                 ctx.redirect(ctx.request.header.referer);
             } catch (err) {
                 this.log(err);

+ 2 - 2
app/controller/ledger_controller.js

@@ -474,8 +474,8 @@ module.exports = app => {
                 const checkDataModel = require('../lib/ledger').checkData;
                 const checkData = new checkDataModel(ctx);
                 checkData.loadData(ledgerData, posData);
-                const sameCodeError = checkData.checkSameCode();
-                const siblingError = checkData.checkSibling();
+                const sameCodeError = ctx.tender.info.ledger_check.same_code ? checkData.checkSameCode() : [];
+                const siblingError = ctx.tender.info.ledger_check.sibling ? checkData.checkSibling() : [];
 
                 const qtyData = ctx.helper.checkBillsWithPos(ledgerData, posData,
                     ['sgfh_qty', 'qtcl_qty', 'sjcl_qty', 'quantity']);

+ 2 - 2
app/controller/report_controller.js

@@ -134,7 +134,7 @@ module.exports = app => {
                 if (stage) {
                     lastAuditor = await ctx.service.stageAudit.getLastestAuditor(ctx.stage.id, ctx.stage.times, auditConst.stage.status.checked);
                 } else {
-                    lastAuditor = await ctx.service.stageAudit.getLastestAuditor(stageList[0].id, stageList[0].times, auditConst.stage.status.checked);
+                    lastAuditor = stageList.length > 0 ? await ctx.service.stageAudit.getLastestAuditor(stageList[0].id, stageList[0].times, auditConst.stage.status.checked) : null;
                 }
                 let archiveList = [];
                 if (stage) {
@@ -143,7 +143,7 @@ module.exports = app => {
                         archiveList = JSON.parse(archives[0].content);
                     }
                 } else {
-                    const archives = await ctx.service.rptArchive.getPrjStgArchive(tender.data.project_id, stageList[stageList.length - 1].id);
+                    const archives = stageList.length > 0 ? await ctx.service.rptArchive.getPrjStgArchive(tender.data.project_id, stageList[stageList.length - 1].id) : [];
                     // console.log(archives);
                     if (archives && archives.length > 0) {
                         archiveList = JSON.parse(archives[0].content);

+ 2 - 2
app/controller/revise_controller.js

@@ -462,8 +462,8 @@ module.exports = app => {
                 const checkDataModel = require('../lib/ledger').checkData;
                 const checkData = new checkDataModel(ctx);
                 checkData.loadData(reviseBills, revisePos);
-                const sameCodeError = checkData.checkSameCode();
-                const siblingError = checkData.checkSibling();
+                const sameCodeError = ctx.tender.info.ledger_check.same_code ? checkData.checkSameCode() : [];
+                const siblingError = ctx.tender.info.ledger_check.sibling ? checkData.checkSibling() : [];
 
                 const qtyData = ctx.helper.checkBillsWithPos(reviseBills, revisePos,
                     ['sgfh_qty', 'qtcl_qty', 'sjcl_qty', 'quantity']);

+ 2 - 2
app/controller/stage_controller.js

@@ -193,7 +193,7 @@ module.exports = app => {
                     attData[index].in_time = moment(attData[index].in_time * 1000).format('YYYY-MM-DD');
                 }
                 renderData.attData = attData;
-                renderData.coopwd = ((ctx.stage.status === auditConst.status.uncheck || ctx.stage.status === auditConst.status.checkNo) && ctx.session.sessionUser.accountId === ctx.stage.user_id) || (ctx.stage.status === auditConst.status.checking && ctx.stage.curAuditor && ctx.stage.curAuditor.aid === ctx.session.sessionUser.accountId);
+                renderData.coopwd = ((ctx.stage.status === auditConst.status.uncheck || ctx.stage.status === auditConst.status.checkNo) && ctx.session.sessionUser.accountId === ctx.stage.user_id) || ((ctx.stage.status === auditConst.status.checking || ctx.stage.status === auditConst.status.checkNoPre) && ctx.stage.curAuditor && ctx.stage.curAuditor.aid === ctx.session.sessionUser.accountId);
                 await this.layout('stage/index.ejs', renderData, 'stage/modal.ejs');
             } catch (err) {
                 this.log(err);
@@ -783,7 +783,7 @@ module.exports = app => {
                     (ctx.stage.status === auditConst.status.checkNoPre && ctx.session.sessionUser.accountId === ctx.stage.curAuditor.aid) ||
                     (ctx.stage.status === auditConst.status.checking && ctx.stage.curAuditor && ctx.stage.curAuditor.aid === ctx.session.sessionUser.accountId);
 
-                if (!ctx.stage.readOnly) {
+                if (!ctx.stage.readOnly || ctx.tender.isTourist) {
                     // 计算 本期金额
                     const payCalculator = new PayCalculator(ctx, ctx.stage, ctx.tender.info);
                     await payCalculator.calculateAll(renderData.dealPay);

+ 1 - 1
app/middleware/change_audit_check.js

@@ -30,7 +30,7 @@ module.exports = options => {
             }
             const change = yield this.service.change.getDataByCondition({ cid });
             if (!change) throw '变更令数据有误';
-            if ((change.status === status.uncheck || change.status === status.back) && this.tender.info.shenpi.change !== shenpiConst.sp_status.sqspr) {
+            if ((change.status === status.uncheck || change.status === status.back || change.status === status.revise) && this.tender.info.shenpi.change !== shenpiConst.sp_status.sqspr) {
                 const shenpi_status = this.tender.info.shenpi.change;
                 // 进一步比较审批流是否与审批流程设置的相同,不同则替换为固定审批流或固定的终审
                 const auditList = yield this.service.changeAudit.getAllDataByCondition({ where: { cid: change.cid, times: change.times } });

+ 46 - 6
app/public/css/main.css

@@ -44,6 +44,11 @@ font-size: .875rem;
   font-weight: normal;
   color:#000;
 }
+.table.table-dark th {
+  background:none;
+  font-weight: normal;
+  color:#fff;
+}
 .form-check,.form-check-label{
   cursor: pointer;
   line-height: 22px;
@@ -61,7 +66,8 @@ font-size: .875rem;
   top:.25rem;
 }
 .custom-control {
-  min-height: 1.2rem
+  min-height: 1.2rem;
+  line-height: 1.2rem
 }
 .custom-control-label {
   cursor: pointer;
@@ -464,6 +470,11 @@ input.nospin[type="number"]{-moz-appearance:textfield;}
 .modal-xl {
   max-width: 1200px
 }
+.modal-full{
+  max-width: 99%;
+  margin:10px auto;
+  max-height:97%;
+}
 .border-right-1 {
   border-right:1px solid #dee2e6;
 }
@@ -479,6 +490,25 @@ input.nospin[type="number"]{-moz-appearance:textfield;}
 .save-confirm {
   position:absolute;
 }
+.nav-tabs.panel-card-tabs .nav-link{
+  color:#ccc;
+  font-size:1rem;
+  padding-top:0;
+}
+.nav-tabs.panel-card-tabs .nav-link.active{
+  color:#fff;
+  background:none ;
+  border:none ;
+  border-bottom:2px solid #fff;
+}
+.nav-tabs.panel-card-tabs .nav-link:hover{
+  background:none ;
+  border:none ;
+  border-bottom:2px solid #fff;
+}
+.panel-card-header {
+  background-image: linear-gradient(to top, #586579, #2c3237 );
+}
 /*滚动*/
 .scrollbar-auto {
     overflow-y: auto;
@@ -768,6 +798,13 @@ input.nospin[type="number"]{-moz-appearance:textfield;}
   height:300px;
   overflow:auto
 }
+.modal-height-250{
+  height:250px;
+  overflow:auto
+}
+.modal-fullscreen{
+  overflow: auto;
+}
 .scroll-y {
   overflow-y: auto;
 }
@@ -843,6 +880,9 @@ input.nospin[type="number"]{-moz-appearance:textfield;}
   vertical-align:top;
   background:#f7f7f9
 }
+.print-toolsbar .panel .panel-body{
+  height:22px;
+}
 .print-toolsbar .panel .panel-foot{
   text-align: center;
   font-size: 12px
@@ -954,7 +994,6 @@ body{
 }
 .form-control-sm {
   font-size:12px;
-  padding-top:.1rem;
 }
 label{
   margin-bottom:.3rem;
@@ -1034,21 +1073,22 @@ legend {
   font-size:16px;
 }
 .input-group-sm > .custom-select, .input-group-sm > .form-control:not(textarea) {
-    height: calc(1.4125rem + 2px);
+    height: calc(1.4125rem - 1px);
 }
 .input-group-sm>.form-control, .input-group-sm>.input-group-append>.btn, .input-group-sm>.input-group-append>.input-group-text, .input-group-sm>.input-group-prepend>.btn, .input-group-sm>.input-group-prepend>.input-group-text{
-  height: calc(1.4125rem + 2px);
+  height: calc(1.4125rem - 1px);
 }
 .input-group-sm > .custom-select, .input-group-sm > .form-control, .input-group-sm > .input-group-append > .btn, .input-group-sm > .input-group-append > .input-group-text, .input-group-sm > .input-group-prepend > .btn, .input-group-sm > .input-group-prepend > .input-group-text {
   font-size:12px;
-  padding:.1rem .5rem;
+  padding:0rem .5rem;
   }
 .side-menu{
     right:0;
     top:35px;
   }
+
 .form-control-sm{
-  height:calc(1.4125rem + 2px);
+  /*height:calc(1.4125rem - 1px);*/
 }
 .form-group {
   margin-bottom:.5rem;

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 0 - 1246
app/public/css/main_s.css


+ 13 - 0
app/public/css/qa_side.css

@@ -0,0 +1,13 @@
+.main-nav {
+  background:#B13719;
+}
+.bg-nav > li.active a {
+    background:#6E220F;
+    color: #fff;
+}
+.bg-nav a {
+    color: #ccc;
+}
+.bg-nav > li > a:hover, .bg-nav > li.active > a:hover{
+  background:#6E220F;
+}

+ 2 - 2
app/public/js/change.js

@@ -268,8 +268,8 @@ $(document).ready(() => {
     });
 
     //状态切换
-    $('#status_select').change(function () {
-       const status = $(this).val();
+    $('#status_select a').on('click', function () {
+       const status = $(this).data('val');
        let url = '/tender/'+ $('#tenderId').val() +'/change';
        if (status !== 0) {
            url += '/status/'+ status;

+ 44 - 7
app/public/js/change_information_approval.js

@@ -7,6 +7,15 @@
  * @date 2018/11/22
  * @version
  */
+
+function getPasteHint (str, row = '') {
+    let returnObj = str;
+    if (row) {
+        returnObj.msg = '清单第' + (row+1) + '行' + str.msg;
+    }
+    return returnObj;
+}
+
 $(document).ready(() => {
     const changeSpreadSetting = {
         cols: [
@@ -181,10 +190,22 @@ $(document).ready(() => {
                         return;
                     }
                     validText = ZhCalc.round(validText, findDecimal(select.unit)) || 0;
+                    // 判断是否 正数必须大于等于限制值,负数必须小于等于限制值,否则无法更改
+                    const usedInfo = _.find(changeUsedData, { id: select.id });
+                    if (usedInfo && validText >= 0 && validText < usedInfo.used_qty) {
+                        toastr.error('清单变更数值必须大于等于已调用值 ' + usedInfo.used_qty);
+                        SpreadJsObj.reLoadRowData(info.sheet, info.row);
+                        changeSpreadObj.setRowValueAndSum(select, info.row, info.col);
+                        return;
+                    } else if (usedInfo && validText < 0 && validText > usedInfo.used_qty) {
+                        toastr.error('清单变更数值必须小于等于已调用值 ' + usedInfo.used_qty);
+                        SpreadJsObj.reLoadRowData(info.sheet, info.row);
+                        changeSpreadObj.setRowValueAndSum(select, info.row, info.col);
+                        return;
+                    }
                 }
                 select[col.field] = validText;
                 select.spamount = ZhCalc.round(validText, findDecimal(select.unit)) || 0;
-                console.log(select);
 
                 const data = {
                     id: select.id,
@@ -206,10 +227,11 @@ $(document).ready(() => {
             }
         },
         clipboardPasted(e, info) {
-            // const hint = {
-            //     cellError: {type: 'error', msg: '粘贴内容超出了表格范围'},
-            //     numberExpr: {type: 'error', msg: '不能粘贴其它非数字类型字符'},
-            // };
+            const hint = {
+                cellError: {type: 'error', msg: '粘贴内容超出了表格范围'},
+                numberExpr: {type: 'error', msg: '不能粘贴其它非数字类型字符'},
+                qtyError: {type: 'error', msg: '变更数值必须大于等于已调用值'},
+            };
             const range = info.cellRange;
             const sortData = info.sheet.zh_data || [];
             // console.log(info, range);
@@ -261,6 +283,21 @@ $(document).ready(() => {
                             continue;
                         }
                         validText = ZhCalc.round(validText, findDecimal(sortData[curRow].unit)) || 0;
+                        // 判断是否 正数必须大于等于限制值,负数必须小于等于限制值,否则无法更改
+                        const usedInfo = _.find(changeUsedData, { id: sortData[curRow].id });
+                        if (usedInfo && usedInfo.used_qty >= 0 && validText < usedInfo.used_qty) {
+                            toastr.error(hintRow ? '清单' + (hintRow+1) + '行变更数值必须大于等于已调用值 ' + usedInfo.used_qty : '清单变更数值必须大于等于已调用值 ' + usedInfo.used_qty);
+                            SpreadJsObj.reLoadRowData(info.sheet, curRow);
+                            changeSpreadObj.setRowValueAndSum(sortData[curRow], curRow, curCol);
+                            bPaste = false;
+                            continue;
+                        } else if (usedInfo && usedInfo.used_qty < 0 && validText > usedInfo.used_qty) {
+                            toastr.error(hintRow ? '清单' + (hintRow+1) + '行变更数值必须小于等于已调用值 ' + usedInfo.used_qty : '清单变更数值必须小于等于已调用值 ' + usedInfo.used_qty);
+                            SpreadJsObj.reLoadRowData(info.sheet, curRow);
+                            changeSpreadObj.setRowValueAndSum(sortData[curRow], curRow, curCol);
+                            bPaste = false;
+                            continue;
+                        }
                     }
                     // cLData[colSetting.field] = validText;
                     sortData[curRow][colSetting.field] = validText;
@@ -270,11 +307,11 @@ $(document).ready(() => {
                     data.push(cLData);
                     // rowData.push(curRow);
                 } else {
-                    SpreadJsObj.reLoadRowData(info.sheet, curRow);
+                    // SpreadJsObj.reLoadRowData(info.sheet, curRow);
                 }
             }
             if (data.length === 0) {
-                SpreadJsObj.reLoadRowData(info.sheet, info.cellRange.row, info.cellRange.rowCount);
+                // SpreadJsObj.reLoadRowData(info.sheet, info.cellRange.row, info.cellRange.rowCount);
                 return;
             }
             console.log(data);

+ 31 - 6
app/public/js/change_information_set.js

@@ -83,6 +83,14 @@ $.event.special.valuechange = {
         }
     }
 };
+function getPasteHint (str, row = '') {
+    let returnObj = str;
+    if (row) {
+        returnObj.msg = '清单第' + (row+1) + '行' + str.msg;
+    }
+    return returnObj;
+}
+
 $(document).ready(() => {
     const changeSpreadSetting = {
         cols: [
@@ -151,7 +159,7 @@ $(document).ready(() => {
                 return !readOnly && data.lid != 0;
             },
             isEdit2: function (data) {
-                return !readOnly && (data.lid != 0 || (data.lid == 0 && _.find(changeUsedData, { id: data.id })));
+                return !readOnly && (data.lid != 0 || (data.lid == 0 && _.findIndex(changeUsedData, { id: data.id }) !== -1));
             },
         },
     };
@@ -269,10 +277,14 @@ $(document).ready(() => {
                     select.oamount = ZhCalc.round(select.oamount, findDecimal(validText)) || 0;
                 }
                 if(col.field === 'camount') {
-                    // 判断是否大于等于限制值,否则无法更改
+                    // 判断是否 正数必须于等于限制值,负数必须小于等于限制值,否则无法更改
                     const usedInfo = _.find(changeUsedData, { id: select.id });
-                    if (usedInfo && validText < usedInfo.used_qty) {
-                        toastr.error('清单变更数值必须大于等于已调用值');
+                    if (usedInfo && usedInfo.used_qty >= 0 && validText < usedInfo.used_qty) {
+                        toastr.error('清单变更数值必须大于等于已调用值 ' + usedInfo.used_qty);
+                        SpreadJsObj.reLoadRowData(info.sheet, info.row);
+                        return;
+                    } else if (usedInfo && usedInfo.used_qty < 0  && validText > usedInfo.used_qty) {
+                        toastr.error('清单变更数值必须小于等于已调用值 ' + usedInfo.used_qty);
                         SpreadJsObj.reLoadRowData(info.sheet, info.row);
                         return;
                     }
@@ -354,6 +366,19 @@ $(document).ready(() => {
                         } else {
                             validText = ZhCalc.round(validText, findDecimal(sortData[curRow].unit)) || 0;
                         }
+                        if(colSetting.field === 'camount') {
+                            // 判断是否 正数必须大于等于限制值,负数必须小于等于限制值,否则无法更改
+                            const usedInfo = _.find(changeUsedData, { id: sortData[curRow].id });
+                            if (usedInfo && usedInfo.used_qty >= 0 && validText < usedInfo.used_qty) {
+                                toastr.error(hintRow ? '清单' + (hintRow+1) + '行变更数值必须大于等于已调用值 ' + usedInfo.used_qty : '清单变更数值必须大于等于已调用值 ' + usedInfo.used_qty);
+                                bPaste = false;
+                                continue;
+                            } else if (usedInfo && usedInfo.used_qty < 0 && validText > usedInfo.used_qty) {
+                                toastr.error(hintRow ? '清单' + (hintRow+1) + '行变更数值必须小于等于已调用值 ' + usedInfo.used_qty : '清单变更数值必须小于等于已调用值 ' + usedInfo.used_qty);
+                                bPaste = false;
+                                continue;
+                            }
+                        }
                     }
                     let unitdecimal = validText;
                     if (colSetting.field === 'unit') {
@@ -570,7 +595,7 @@ $(document).ready(() => {
                     name: '删除',
                     icon: 'fa-remove',
                     callback: function (key, opt) {
-                        // changeSpreadObj.del(changeSpreadSheet);
+                        changeSpreadObj.del(changeSpreadSheet);
                     },
                     disabled: function (key, opt) {
                         const select = SpreadJsObj.getSelectObject(changeSpreadSheet);
@@ -615,7 +640,7 @@ $(document).ready(() => {
                     + '!_!' + (leaf.gcl_id ? leaf.gcl_id : '0') + '!_!' +
                     (bwmx !== '' ? bwmx : leaf.jldy ? leaf.jldy : '') + '*;*' + quantity) !== -1 && isCheck ?
                     'checked' : '';
-                const isUsed = _.find(changeUsedData, { gcl_id: leaf.gcl_id, bwmx: bwmx, oamount: leaf.quantity });
+                const isUsed = _.find(changeUsedData, { gcl_id: leaf.gcl_id, bwmx: (bwmx ? bwmx : leaf.jldy ? leaf.jldy : ''), oamount: leaf.quantity });
                 const isDisabled = isUsed ? 'disabled ' : '';
                 codeHtml += '<tr quantity="' + quantity + '" gcl_id="' + gcl_id + '"><td>' + leaf.code + '</td>' +
                     '<td>' + (leaf.jldy ? leaf.jldy: '') + '</td>' +

+ 10 - 5
app/public/js/stage_pay.js

@@ -512,10 +512,10 @@ $(document).ready(() => {
                         .attr('readOnly', readOnly|| (payBase.isYF(data) || payBase.isWC(data)));
                 } else if (col.field === 'sprice') {
                     $('#expr').val(data.sexpr).attr('field', 'sexpr').attr('org', data.sexpr)
-                        .attr('readOnly', readOnly|| payCol.readOnly.sprice(data));
+                        .attr('readOnly', readOnly|| payCol.readOnly.sprice(data) || payBase.isYF(data));
                 } else if (col.field === 'rprice') {
                     $('#expr').val(data.rexpr).attr('field', 'rexpr').attr('org', data.rexpr)
-                        .attr('readOnly', readOnly|| payCol.readOnly.rprice(data));
+                        .attr('readOnly', readOnly|| payCol.readOnly.rprice(data) || payBase.isYF(data));
                 } else {
                     $('#expr').val('').attr('readOnly', true);
                 }
@@ -717,18 +717,23 @@ $(document).ready(() => {
         },
         editStarting: function (e, info) {
             const col = info.sheet.zh_setting.cols[info.col];
+            const select = SpreadJsObj.getSelectObject(info.sheet);
+            switch (col.field) {
+                case 'sprice':
+                case 'rprice':
+                    info.cancel = payBase.isYF(select);
+                    break;
+            }
+
             if (col.field === 'tp') {
-                const select = SpreadJsObj.getSelectObject(info.sheet);
                 if (select.expr && select.expr !== '') {
                     info.sheet.getCell(info.row, info.col).text(select.expr);
                 }
             } else if (col.field === 'sprice') {
-                const select = SpreadJsObj.getSelectObject(info.sheet);
                 if (select.sexpr && select.sexpr !== '') {
                     info.sheet.getCell(info.row, info.col).text(select.sexpr);
                 }
             } else if (col.field === 'rprice') {
-                const select = SpreadJsObj.getSelectObject(info.sheet);
                 if (select.rexpr && select.rexpr !== '') {
                     info.sheet.getCell(info.row, info.col).text(select.rexpr);
                 }

+ 34 - 7
app/service/change.js

@@ -167,7 +167,7 @@ module.exports = app => {
         }
 
         async getHaveAuditLastInfo(tenderId) {
-            const sql = 'SELECT * FROM ?? as a LEFT JOIN ?? as b ON a.`cid` = b.`cid` WHERE a.`tid` = ? AND b.`usite` > 0 ORDER BY a.`in_time` DESC';
+            const sql = 'SELECT a.* FROM ?? as a LEFT JOIN ?? as b ON a.`cid` = b.`cid` WHERE a.`tid` = ? AND b.`usite` > 0 ORDER BY a.`in_time` DESC';
             const sqlParam = [this.tableName, this.ctx.service.changeAudit.tableName, tenderId];
             return await this.db.queryOne(sql, sqlParam);
         }
@@ -629,6 +629,7 @@ module.exports = app => {
                     change_update.status = audit.flow.status.checked;
                     change_update.p_code = postData.p_code;
                     change_update.sin_time = Date.parse(new Date()) / 1000;
+                    change_update.is_revise = 0;
 
                     await this.ctx.service.tenderTag.saveTenderTag(changeData.tid, { bgl_time: new Date() }, this.transaction);
 
@@ -1225,13 +1226,29 @@ module.exports = app => {
                 });
                 await this.transaction.insert('zh_notice', records);
 
-                // 新增新一次的审批人列表
                 // 获取当前次数审批人列表
                 const auditList = await this.ctx.service.changeAudit.getListGroupByTimes(changeData.cid, changeData.times);
                 const lastauditInfo = await this.ctx.service.changeAudit.getLastUser(changeData.cid, changeData.times, 1, 0);
                 let usort = lastauditInfo.usort + 1;
                 const newTimes = changeData.times + 1;
                 const insert_audit_array = [];
+                // 新增一个发起修订状态到审批流程中
+                const revise_audit = {
+                    tid: auditList[0].tid,
+                    cid: auditList[0].cid,
+                    uid: auditList[0].uid,
+                    name: auditList[0].name,
+                    jobs: auditList[0].jobs,
+                    company: auditList[0].company,
+                    times: changeData.times,
+                    usite: lastauditInfo.usite + 1,
+                    usort,
+                    status: audit.flow.auditStatus.revise,
+                    sin_time: new Date(),
+                };
+                insert_audit_array.push(revise_audit);
+                usort++;
+                // 新增新一次的审批人列表
                 for (const al of auditList) {
                     const insert_audit = {
                         tid: al.tid,
@@ -1248,24 +1265,34 @@ module.exports = app => {
                     insert_audit_array.push(insert_audit);
                     usort++;
                 }
+
                 await this.transaction.insert(this.ctx.service.changeAudit.tableName, insert_audit_array);
-                // 变更金额也退回
                 const changeList = await this.ctx.service.changeAuditList.getAllDataByCondition({
                     where: { cid: changeData.cid },
                 });
-                let total_price = 0;
-                const tp_decimal = changeData.tp_decimal ? changeData.tp_decimal : this.ctx.tender.info.decimal.tp;
+                // 申请变更金额更新为上一次审批审批变更后数量,清空audit_amount值
+                const updateTpList = [];
                 for (const cl of changeList) {
-                    total_price = this.ctx.helper.add(total_price, this.ctx.helper.mul(cl.unit_price, cl.camount, tp_decimal));
+                    updateTpList.push({ id: cl.id, camount: cl.spamount, audit_amount: null, samount: '' });
                 }
+                if (updateTpList.length > 0) {
+                    await this.transaction.updateRows(this.ctx.service.changeAuditList.tableName, updateTpList);
+                }
+
+                // let total_price = 0;
+                // const tp_decimal = changeData.tp_decimal ? changeData.tp_decimal : this.ctx.tender.info.decimal.tp;
+                // for (const cl of changeList) {
+                //     total_price = this.ctx.helper.add(total_price, this.ctx.helper.mul(cl.unit_price, cl.camount, tp_decimal));
+                // }
                 // 设置变更令修订状态
                 const change_update = {
                     w_code: changeData.w_code,
                     status: audit.flow.status.revise,
                     times: newTimes,
                     cin_time: Date.parse(new Date()) / 1000,
-                    total_price,
+                    // total_price,
                     tp_decimal: null,
+                    is_revise: 1,
                 };
                 const options = {
                     where: {

+ 4 - 1
app/service/change_audit_list.js

@@ -230,7 +230,10 @@ module.exports = app => {
                 // 更新stage_change和stage_change_final的cbid
                 if (usedList.length > 0) {
                     const updateList = [];
-                    const newList = await transaction.select(this.tableName, { where: { cid: this.ctx.change.cid } });
+                    const sql2 = 'SELECT * FROM ?? WHERE `cid` = ? AND `lid` != "0"';
+                    const sqlParam2 = [this.tableName, this.ctx.change.cid];
+                    const newList = await transaction.query(sql2, sqlParam2);
+                    // const newList = await transaction.select(this.tableName, { where: { cid: this.ctx.change.cid } });
                     for (const used of usedList) {
                         const newone = this._.find(newList, { code: used.code, lid: used.lid, gcl_id: used.gcl_id, bwmx: used.bwmx });
                         if (newone) {

+ 2 - 0
app/service/project_account.js

@@ -505,6 +505,8 @@ module.exports = app => {
                 // const content = '【纵横计量支付】验证码:' + randString + ',15分钟内有效。';
                 // result = await sms.send(mobile, content);
                 result = await sms.aliSend(mobile, { code: randString }, SmsAliConst.template.yzm);
+                // console.log(randString);
+                // result = true;
             } catch (error) {
                 result = false;
             }

+ 2 - 2
app/service/stage_bonus.js

@@ -36,7 +36,7 @@ module.exports = app => {
 
         async getStageData(sid) {
             const data = await this.getAllDataByCondition({where: { sid: sid }});
-            if (this.ctx.stage && this.ctx.stage.readOnly && this.ctx.stage.status !== auditConst.status.checked) {
+            if (this.ctx.stage && this.ctx.stage.readOnly && !this.ctx.tender.isTourist && this.ctx.stage.status !== auditConst.status.checked) {
                 for (const d of data) {
                     const his = d.shistory ? JSON.parse(d.shistory) : [];
                     const h = this.ctx.helper._.find(his, {
@@ -217,4 +217,4 @@ module.exports = app => {
     }
 
     return StageBonus;
-};
+};

+ 1 - 1
app/service/stage_jgcl.js

@@ -24,7 +24,7 @@ module.exports = app => {
 
         async getStageData(stage) {
             const data = await this.getAllDataByCondition({where: { sid: stage.id }});
-            if (stage && stage.readOnly && stage.status !== auditConst.status.checked) {
+            if (stage && stage.readOnly && !this.ctx.tender.isTourist && stage.status !== auditConst.status.checked) {
                 for (const d of data) {
                     const his = d.shistory ? JSON.parse(d.shistory) : [];
                     const h = this.ctx.helper._.find(his, {

+ 1 - 1
app/service/stage_other.js

@@ -24,7 +24,7 @@ module.exports = app => {
 
         async getStageData(stage) {
             const data = await this.getAllDataByCondition({where: { sid: stage.id }});
-            if (stage && stage.readOnly && stage.status !== auditConst.status.checked) {
+            if (stage && stage.readOnly && !this.ctx.tender.isTourist && stage.status !== auditConst.status.checked) {
                 for (const d of data) {
                     const his = d.shistory ? JSON.parse(d.shistory) : [];
                     const h = this.ctx.helper._.find(his, {

+ 15 - 8
app/view/change/index.ejs

@@ -40,13 +40,16 @@
                     </div>
                 </div>
                 <div class="d-inline-block">
-                    <select class="form-control form-control-sm" id="status_select">
-                        <option value="0">全部</option>
-                        <% for (const fs in filter.status) { %>
-                        <% const f = filter.status[fs]; %>
-                        <option value="<%- f %>" <% if (f === status) { %>selected="selected"<% } %>><%- filter.statusString[f] %>(<%- filter.count[f] %>)</option>
-                        <% } %>
-                    </select>
+                    <div class="btn-group">
+                        <button type="button" class="btn btn-sm btn-light text-primary dropdown-toggle" data-toggle="dropdown" id="zhankai"><% if (status !== 0) { %><%- filter.statusString[status] %>(<%- filter.count[status] %>)<% } else { %>全部<% } %></button>
+                        <div class="dropdown-menu" aria-labelledby="zhankai" id="status_select">
+                            <% if (status !== 0) { %><a class="dropdown-item" data-val="0" href="javascript:void(0);">全部</a><% } %>
+                            <% for (const fs in filter.status) { %>
+                                <% const f = filter.status[fs]; %>
+                                <% if (f !== status) { %><a class="dropdown-item" data-val="<%- f %>" href="javascript:void(0);"><%- filter.statusString[f] %>(<%- filter.count[f] %>)</a><% } %>
+                            <% } %>
+                        </div>
+                    </div>
                 </div>
             </div>
             <% if (tender.user_id === uid) { %>
@@ -87,6 +90,10 @@
                             <td>
                                 上报中
                             </td>
+                        <% } else if (c.status === auditConst.status.revise && ctx.tender.isTourist) { %>
+                            <td>
+                                修订中
+                            </td>
                         <% } else if (c.auditStatus) { %>
                         <td>
                             <a href="/tender/<%- tender.id %>/change/<%- c.cid %>/information" class="btn <%- auditConst.statusButtonClass[c.status] %> btn-sm">
@@ -112,7 +119,7 @@
                             <span class="<%- auditConst.auditStatusClass[c.changeAudit.status] %>"><%- auditConst.auditStatusString[c.changeAudit.status] %></span>
                         </td>
                         <% } %>
-                        <td><% if ((c.status === auditConst.status.uncheck || ((c.status === auditConst.status.back || (c.status === auditConst.status.revise && c.stageChangeNum === 0)) && c.uid === uid)) && !ctx.tender.isTourist) { %><a href="#del-bg" cid="<%= c.cid %>" data-toggle="modal" data-target="#del-bg" class="btn btn-outline-danger btn-sm delete-cid-modal">删除</a><% } %></td>
+                        <td><% if ((c.status === auditConst.status.uncheck || (((c.status === auditConst.status.back || c.status === auditConst.status.revise) && c.stageChangeNum === 0) && c.uid === uid)) && !ctx.tender.isTourist) { %><a href="#del-bg" cid="<%= c.cid %>" data-toggle="modal" data-target="#del-bg" class="btn btn-outline-danger btn-sm delete-cid-modal">删除</a><% } %></td>
                     </tr>
                     <% } %>
                     </tbody>

+ 1 - 0
app/view/change/information.ejs

@@ -454,6 +454,7 @@
     const auditList2 = JSON.parse(unescape('<%- escape(JSON.stringify(auditList2)) %>'));
     const aidList = _.map(auditList2, 'uid');
     aidList.splice(0, 1);
+    let changeUsedData = JSON.parse(unescape('<%- escape(JSON.stringify(changeUsedData)) %>'));
 </script>
 <script src="/public/js/change_information_approval.js"></script>
 <% } %>

+ 6 - 6
app/view/change/information_modal.ejs

@@ -234,7 +234,7 @@
                                                         <div class="timeline-item-icon bg-success text-light">
                                                             <i class="fa fa-check"></i>
                                                         </div>
-                                                    <% } else if(auditor.status === auditConst.auditStatus.back || auditor.status === auditConst.auditStatus.backnew) {%>
+                                                    <% } else if(auditor.status === auditConst.auditStatus.back || auditor.status === auditConst.auditStatus.backnew || auditor.status === auditConst.auditStatus.revise) {%>
                                                         <div class="timeline-item-icon bg-warning text-light">
                                                             <i class="fa fa-level-up"></i>
                                                         </div>
@@ -364,7 +364,7 @@
                                                     <div class="timeline-item-icon bg-success text-light">
                                                         <i class="fa fa-check"></i>
                                                     </div>
-                                                <% } else if(auditor.status === auditConst.auditStatus.back || auditor.status === auditConst.auditStatus.backnew) {%>
+                                                <% } else if(auditor.status === auditConst.auditStatus.back || auditor.status === auditConst.auditStatus.backnew || auditor.status === auditConst.auditStatus.revise) {%>
                                                     <div class="timeline-item-icon bg-warning text-light">
                                                         <i class="fa fa-level-up"></i>
                                                     </div>
@@ -494,7 +494,7 @@
                                                         <div class="timeline-item-icon bg-success text-light">
                                                             <i class="fa fa-check"></i>
                                                         </div>
-                                                    <% } else if(auditor.status === auditConst.auditStatus.back || auditor.status === auditConst.auditStatus.backnew) {%>
+                                                    <% } else if(auditor.status === auditConst.auditStatus.back || auditor.status === auditConst.auditStatus.backnew || auditor.status === auditConst.auditStatus.revise) {%>
                                                         <div class="timeline-item-icon bg-warning text-light">
                                                             <i class="fa fa-level-up"></i>
                                                         </div>
@@ -583,7 +583,7 @@
                                                         <div class="timeline-item-icon bg-success text-light">
                                                             <i class="fa fa-check"></i>
                                                         </div>
-                                                    <% } else if(auditor.status === auditConst.auditStatus.back || auditor.status === auditConst.auditStatus.backnew) {%>
+                                                    <% } else if(auditor.status === auditConst.auditStatus.back || auditor.status === auditConst.auditStatus.backnew || auditor.status === auditConst.auditStatus.revise) {%>
                                                         <div class="timeline-item-icon bg-warning text-light">
                                                             <i class="fa fa-level-up"></i>
                                                         </div>
@@ -731,7 +731,7 @@
                                                         <div class="timeline-item-icon bg-success text-light">
                                                             <i class="fa fa-check"></i>
                                                         </div>
-                                                    <% } else if(auditor.status === auditConst.auditStatus.back || auditor.status === auditConst.auditStatus.backnew) {%>
+                                                    <% } else if(auditor.status === auditConst.auditStatus.back || auditor.status === auditConst.auditStatus.backnew || auditor.status === auditConst.auditStatus.revise) {%>
                                                         <div class="timeline-item-icon bg-warning text-light">
                                                             <i class="fa fa-level-up"></i>
                                                         </div>
@@ -820,7 +820,7 @@
                                                         <div class="timeline-item-icon bg-success text-light">
                                                             <i class="fa fa-check"></i>
                                                         </div>
-                                                    <% } else if(auditor.status === auditConst.auditStatus.back || auditor.status === auditConst.auditStatus.backnew) {%>
+                                                    <% } else if(auditor.status === auditConst.auditStatus.back || auditor.status === auditConst.auditStatus.backnew || auditor.status === auditConst.auditStatus.revise) {%>
                                                         <div class="timeline-item-icon bg-warning text-light">
                                                             <i class="fa fa-level-up"></i>
                                                         </div>

+ 2 - 3
app/view/layout/layout.ejs

@@ -6,10 +6,9 @@
     <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
     <title><%= ctx.menu.name === undefined ? '主页' : ctx.menu.name %>-计量支付</title>
     <link rel="stylesheet" href="/public/css/bootstrap/bootstrap.min.css">
-    <% if (ctx.request.host.indexOf('jlqa') !== -1 || ctx.request.host.indexOf('jluat') !== -1 || ctx.request.host === '127.0.0.1:7002') { %>
-    <link rel="stylesheet" href="/public/css/main_s.css">
-    <% } else { %>
     <link rel="stylesheet" href="/public/css/main.css">
+    <% if (ctx.request.host.indexOf('jlqa') !== -1 || ctx.request.host.indexOf('jluat') !== -1 || ctx.request.host === '127.0.0.1:7002') { %>
+    <link rel="stylesheet" href="/public/css/qa_side.css">
     <% } %>
     <link rel="stylesheet" href="/public/css/toast.css">
     <link rel="stylesheet" href="/public/css/font-awesome/font-awesome.min.css">

+ 7 - 7
app/view/stage/stage_sub_menu.ejs

@@ -66,13 +66,13 @@
                 </li>
             </ul>
         </div>
-        <div class="nav-box">
-            <ul class="nav-list list-unstyled">
-                <li class="<% if (ctx.url === '/tender/' + ctx.tender.id + '/measure/stage/' + ctx.stage.order + '/archiveReport') { %>active<% } %>">
-                    <a href="/tender/<%- ctx.tender.id %>/measure/stage/<%- ctx.stage.order %>/archiveReport"><span class="ml-3">归档报表</span></a>
-                </li>
-            </ul>
-        </div>
+        <!--<div class="nav-box">-->
+            <!--<ul class="nav-list list-unstyled">-->
+                <!--<li class="<% if (ctx.url === '/tender/' + ctx.tender.id + '/measure/stage/' + ctx.stage.order + '/archiveReport') { %>active<% } %>">-->
+                    <!--<a href="/tender/<%- ctx.tender.id %>/measure/stage/<%- ctx.stage.order %>/archiveReport"><span class="ml-3">归档报表</span></a>-->
+                <!--</li>-->
+            <!--</ul>-->
+        <!--</div>-->
         <% if (ctx.session.sessionUser.is_admin) { %>
         <div class="nav-box">
             <ul class="nav-list list-unstyled">

+ 7 - 0
app/view/stage/stage_sub_mini_menu.ejs

@@ -68,6 +68,13 @@
                 </li>
             </ul>
         </div>
+        <!--<div class="nav-box">-->
+            <!--<ul class="nav-list list-unstyled">-->
+                <!--<li class="<% if (ctx.url === '/tender/' + ctx.tender.id + '/measure/stage/' + ctx.stage.order + '/archiveReport') { %>active<% } %>">-->
+                    <!--<a href="/tender/<%- ctx.tender.id %>/measure/stage/<%- ctx.stage.order %>/archiveReport"><span class="ml-3">归档报表</span></a>-->
+                <!--</li>-->
+            <!--</ul>-->
+        <!--</div>-->
         <% if (ctx.session.sessionUser.is_admin) { %>
             <div class="nav-box">
                 <ul class="nav-list list-unstyled">

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

@@ -107,7 +107,8 @@
                                 <a href="javascript: void(0);" class="btn btn-sm btn-outline-primary" id="copyBtn">拷贝设置</a>
                                 <% if (ctx.session.sessionUser.is_admin) { %>
                                 <a href="/tender/<%- tender.id %>/shenpi" class="btn btn-sm btn-outline-primary">审批流程</a>
-                                    <a href="#bd-set-9" data-toggle="modal" data-target="#bd-set-9" class="btn btn-sm btn-outline-primary">游客账号 <span id="tourist-num" <% if (tourists.length !== 0) { %>class="badge badge-secondary"<% } %>><% if (tourists.length !== 0) { %><%- tourists.length %><% } %></span></a>
+                                <a href="#bd-set-9" data-toggle="modal" data-target="#bd-set-9" class="btn btn-sm btn-outline-primary">游客账号 <span id="tourist-num" <% if (tourists.length !== 0) { %>class="badge badge-secondary"<% } %>><% if (tourists.length !== 0) { %><%- tourists.length %><% } %></span></a>
+                                <a href="#bd-set-10" data-toggle="modal" data-target="#bd-set-10" class="btn btn-sm btn-outline-primary">上报控制</a>
                                 <% } %>
                             </div>
                         </div>

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

@@ -766,6 +766,7 @@
         </div>
     </div>
 </div>
+
 <script>
     let property = JSON.parse(unescape('<%- escape(JSON.stringify(tenderInfo)) %>'));
     let ledgerChecked = <%- (tender.ledger_status === audit.ledger.status.checked) && ((lastStage !== undefined && lastStage !== null) || !revise || !revise.valid || revise.status === audit.revise.status.checked) %>;
@@ -1589,11 +1590,57 @@
         </div>
     </div>
 </div>
+<!--上报控制-->
+<div class="modal fade" id="bd-set-10" data-backdrop="static">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">上报控制</h5>
+            </div>
+            <div class="modal-body">
+                <div class="form-group">
+                    <div class="custom-control custom-checkbox mb-2">
+                        <input type="checkbox" class="custom-control-input" id="lc_same_code" checked="">
+                        <label class="custom-control-label" for="lc_same_code">重复项目节</label>
+                    </div>
+                    <div class="custom-control custom-checkbox mb-2">
+                        <input type="checkbox" class="custom-control-input" id="lc_sibling" checked="">
+                        <label class="custom-control-label" for="lc_sibling">项目节清单同层次</label>
+                    </div>
+                </div>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">取消</button>
+                <button type="button" class="btn btn-sm btn-primary" onclick="post10()">确认修改</button>
+            </div>
+        </div>
+    </div>
+</div>
 <script>
     const accountGroup = JSON.parse(unescape('<%- escape(JSON.stringify(accountGroup)) %>'));
     const accountList = JSON.parse(unescape('<%- escape(JSON.stringify(accountList)) %>'));
     const cur_tender_uid = parseInt('<%- ctx.tender.data.user_id %>');
     const cur_tenderid = parseInt('<%- ctx.tender.id %>');
+    const loadLedgerCheckProperty = function () {
+        $('#lc_same_code')[0].checked = property.ledger_check.same_code;
+        $('#lc_sibling')[0].checked = property.ledger_check.sibling;
+    }
+    $('#bd-set-10').on('show.bs.modal', function () {
+        loadLedgerCheckProperty();
+    });
+    function post10 () {
+        const prop = {
+            ledger_check: {
+                same_code: $('#lc_same_code')[0].checked,
+                sibling: $('#lc_sibling')[0].checked,
+            },
+        };
+        const tenderId = window.location.pathname.split('/')[2];
+        postData('/tender/' + tenderId + '/save', prop, function (data) {
+            property.ledger_check = data.ledger_check;
+            $('#bd-set-10').modal('hide');
+        });
+    }
     $(function () {
         // 形象进度
         let timer2 = null;

+ 2 - 0
sql/update.sql

@@ -404,3 +404,5 @@ CREATE TABLE `zh_tender_tourist` (
   `in_time` datetime DEFAULT NULL COMMENT '添加时间',
   PRIMARY KEY (`id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='标段游客表';
+
+ALTER TABLE `zh_change` ADD `is_revise` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '是否是修订状态' AFTER `tp_decimal`;