Procházet zdrojové kódy

材料调差wap页审批及待办页功能

ellisran před 1 měsícem
rodič
revize
dab29b1313

+ 84 - 0
app/controller/wap_controller.js

@@ -10,8 +10,10 @@
 const URL = require('url');
 const maintainConst = require('../const/maintain');
 const auditConst = require('../const/audit');
+const tenderConst = require('../const/tender');
 const changeConst = require('../const/change');
 const advanceConst = require('../const/advance');
+const materialConst = require('../const/material');
 const fs = require('fs');
 const path = require('path');
 const sendToWormhole = require('stream-wormhole');
@@ -221,12 +223,33 @@ module.exports = app => {
             }
             // 获取待审批的预付款
             const auditAdvance = await ctx.service.advanceAudit.getAuditAdvanceByWap(ctx.session.sessionUser.accountId);
+            const materialList = await ctx.service.materialAudit.getAuditMaterialByWap(ctx.session.sessionUser.accountId);
+            const auditMaterials = [];
+            for (const audit of materialList) {
+                audit.decimal = audit.decimal ? JSON.parse(audit.decimal) : materialConst.decimal;
+                let sp = null;
+                if (audit.spid) {
+                    if (ctx.helper._.findIndex(subProjects, { id: audit.spid }) !== -1) {
+                        sp = ctx.helper._.find(subProjects, { id: audit.spid });
+                    } else {
+                        sp = await ctx.service.subProject.getDataById(audit.spid);
+                        subProjects.push(sp);
+                    }
+                }
+                if (sp) {
+                    const pageShow = JSON.parse(sp.page_show);
+                    if (pageShow.openMaterial) {
+                        auditMaterials.push(audit);
+                    }
+                }
+            }
             const renderData = {
                 auditStages,
                 auditChanges,
                 auditChangeProjects,
                 auditChangeApplys,
                 auditChangePlans,
+                auditMaterials,
                 auditRevise,
                 auditAdvance,
                 changeConst,
@@ -362,13 +385,43 @@ module.exports = app => {
                     advanceList.push(advance);
                 }
 
+                // 材料调差
+                const materials = await ctx.service.material.getValidMaterials(ctx.tender.id);
+                let openMaterialTax = ctx.subProject.page_show.openMaterialTax;
+                const tenderMsg = await ctx.service.tender.getTender(ctx.tender.id, ['material_col_show']);
+                const material_col_show = tenderMsg.material_col_show ? JSON.parse(tenderMsg.material_col_show) : ctx.helper._.cloneDeep(tenderConst.materialColShow);
+                let allMaterialTax = true;
+                for (const s of materials) {
+                    if (!s.final_auditor_str || s.status !== auditConst.material.status.checked) {
+                        // 根据期状态返回展示用户
+                        s.curAuditors = await ctx.service.materialAudit.getAuditorsByStatus(s.id, s.status, s.times);
+                        if (s.status === auditConst.material.status.checked && s.curAuditors.length > 0) {
+                            const final_auditor_str = (s.curAuditors[0].audit_type === auditType.key.common)
+                                ? `${s.curAuditors[0].name}${(s.curAuditors[0].role ? '-' + s.curAuditors[0].role : '')}`
+                                : ctx.helper.transFormToChinese(s.curAuditors[0].audit_order) + '审';
+                            await ctx.service.material.defaultUpdate({ id: s.id, final_auditor_str });
+                        }
+                    }
+                    if (allMaterialTax && s.material_tax === 0) {
+                        allMaterialTax = false;
+                    }
+                    if (!openMaterialTax && s.material_tax === 1) {
+                        openMaterialTax = 1;
+                    }
+                    s.decimal = s.decimal ? JSON.parse(s.decimal) : materialConst.decimal;
+                }
                 const renderData = {
                     tender,
                     stages,
                     revises,
                     advanceList,
+                    materials,
+                    openMaterialTax,
+                    allMaterialTax,
+                    materialColShow: material_col_show,
                     auditConst: auditConst.stage,
                     auditReviseConst: auditConst.revise,
+                    auditMaterialConst: auditConst.material,
                     advanceConst,
                     tpUnit: ctx.tender.info.decimal.tp,
                     monthProgress,
@@ -441,6 +494,37 @@ module.exports = app => {
         }
 
         /**
+         * 调差期审批详细页
+         *
+         * @param {Object} ctx - egg全局变量
+         * @return {void}
+         */
+        async material(ctx) {
+            try {
+                const tender = ctx.tender.data;
+                const material = ctx.material;
+                await ctx.service.material.loadMaterialAuditViewData(material);
+                const renderData = {
+                    moment,
+                    tender,
+                    material,
+                    auditConst: auditConst.material,
+                    auditType,
+                };
+                renderData.material.m_tax_tp = renderData.material.m_tax_tp ? renderData.material.m_tax_tp : renderData.material.m_tp;
+                renderData.pre_tp_hs = await ctx.service.material.getPreTpHs(ctx.tender.id, ctx.material.order, ctx.material.decimal.tp);
+                renderData.ex_pre_tp_hs = await ctx.service.material.getExPreTpHs(ctx.tender.id, ctx.material.order, ctx.material.decimal.tp);
+                renderData.months = ctx.material.months ? ctx.material.months.split(',') : [];
+                renderData.material.lastAuditors = await ctx.service.materialAudit.getAuditorsByStatus(material.id, material.status, material.times);
+                renderData.old_had_tax = await ctx.service.material.getOldMaterialTax(ctx.tender.id, ctx.material.order);
+                await ctx.render('wap/shenpi_material.ejs', renderData);
+            } catch (err) {
+                this.log(err);
+                ctx.redirect('/wap/sp/' + ctx.subProject.id + '/list');
+            }
+        }
+
+        /**
          * 工程变更列表页
          *
          * @param {Object} ctx - egg全局变量

+ 2 - 2
app/lib/wechat.js

@@ -141,8 +141,8 @@ class WX {
                         break;
                     case wxConst.template.material:
                         templateId = wxConst.templateId.material;
-                        // url = origin_url + '/wx/url2wap?project=' + data.code + '&url=' + sck + data.wap_url;
-                        remark = data.status === wxConst.status.check ? '微信暂无法在线审批' :
+                        url = origin_url + '/wx/url2wap?project=' + data.code + '&url=' + sck + data.wap_url;
+                        remark = data.status === wxConst.status.check ? '微信可快速审批,如需进行详细审批' :
                             (data.status === wxConst.status.success ? '审批已通过,查看审批结果' : '审批被退回,查看退回结果');
                         msgData = {
                             first: {

+ 67 - 1
app/public/css/wap/main.css

@@ -25,4 +25,70 @@ input.form-control[readonly],textarea.form-control[readonly] {
 	border: none;
 	background: #f1f1f1;
 
-}
+}
+.bg-new-advance{
+    background: rgba(241, 82, 91, 0.08) !important;
+}
+.bg-new-ledger{
+    background: rgba(250, 140, 22, 0.08) !important;
+}
+.bg-new-revise{
+    background: rgba(251, 182, 45, 0.08) !important;
+}
+.bg-new-stage{
+    background: rgba(82, 196, 26, 0.08) !important;
+}
+.bg-new-changeProject{
+    background: rgba(51, 119, 255, 0.08) !important;
+}
+.bg-new-changePlan{
+    background: rgba(114, 46, 209, 0.08) !important;
+}
+.bg-new-change{
+    background: rgba(22, 208, 208, 0.08) !important;
+}
+.bg-new-changeApply{
+    background: rgba(41, 58, 210, 0.08) !important;
+}
+.bg-new-material{
+    background: rgba(187, 41, 210, 0.08) !important;
+}
+.bg-new-payment{
+    background: rgba(128, 128, 0, 0.08) !important;
+}
+.bg-new-financial{
+    background: rgba(58, 88, 50, 0.08) !important;
+}
+.text-new-advance{
+    color: rgba(241, 82, 91, 1) !important;
+}
+.text-new-ledger{
+    color: rgba(250, 140, 22, 1) !important;
+}
+.text-new-revise{
+    color: rgba(251, 182, 45, 1) !important;
+}
+.text-new-stage{
+    color: rgba(82, 196, 26, 1) !important;
+}
+.text-new-changeProject{
+    color: rgba(51, 119, 255, 1) !important;
+}
+.text-new-changePlan{
+    color: rgba(114, 46, 209, 1) !important;
+}
+.text-new-change{
+    color: rgba(22, 208, 208, 1) !important;
+}
+.text-new-changeApply{
+    color: rgba(41, 58, 210, 1) !important;
+}
+.text-new-material{
+    color: rgba(187, 41, 210, 1); !important;
+}
+.text-new-payment{
+    color: rgba(128, 128, 0, 1) !important;
+}
+.text-new-financial{
+    color: rgba(58, 88, 50, 1) !important;
+}

+ 2 - 0
app/router.js

@@ -1012,6 +1012,8 @@ module.exports = app => {
     app.get('/wap/tender/:id/change/project/:cpid/information', sessionAuth, tenderCheck, subProjectCheck, uncheckTenderCheck, changeProjectCheck, changeProjectAuditCheck, 'wapController.changeProject');
     app.get('/wap/tender/:id/change/apply/:caid/information', sessionAuth, tenderCheck, subProjectCheck, uncheckTenderCheck, changeApplyCheck, changeApplyAuditCheck, 'wapController.changeApply');
     app.get('/wap/tender/:id/change/plan/:cpid/information', sessionAuth, tenderCheck, subProjectCheck, uncheckTenderCheck, changePlanCheck, changePlanAuditCheck, 'wapController.changePlan');
+    app.get('/wap/tender/:id/material/:order', sessionAuth, tenderCheck, subProjectCheck, uncheckTenderCheck, materialCheck, 'wapController.material');
+    app.get('/wap/tender/:id/measure/material/:order', sessionAuth, tenderCheck, subProjectCheck, uncheckTenderCheck, materialCheck, 'wapController.material');
 
     // 微信
     app.get('/wx', 'wechatController.index');

+ 41 - 0
app/service/material_audit.js

@@ -297,9 +297,11 @@ module.exports = app => {
 
                 // 微信模板通知
                 const materialInfo = await this.ctx.service.material.getDataById(materialId);
+                const shenpiUrl = await this.ctx.helper.urlToShort(this.ctx.protocol + '://' + this.ctx.host + '/wap/tender/' + this.ctx.tender.id + '/measure/material/' + materialInfo.order);
                 const material_decimal = materialInfo && materialInfo.decimal ? JSON.parse(materialInfo.decimal) : materialConst.decimal;
                 const users = this._.map(audits, 'aid');
                 const wechatData = {
+                    wap_url: shenpiUrl,
                     qi: materialInfo.order,
                     status: wxConst.status.check,
                     tips: wxConst.tips.check,
@@ -408,8 +410,10 @@ module.exports = app => {
                             mid: materialId,
                             order: 1,
                         });
+                        const shenpiUrl = await this.ctx.helper.urlToShort(this.ctx.protocol + '://' + this.ctx.host + '/wap/tender/' + this.ctx.tender.id + '/measure/material/' + materialInfo.order);
                         // 微信模板通知
                         const wechatData = {
+                            wap_url: shenpiUrl,
                             qi: materialInfo.order,
                             status: wxConst.status.check,
                             tips: wxConst.tips.check,
@@ -506,7 +510,9 @@ module.exports = app => {
                             order: 1,
                         });
                         const users = this._.uniq(this._.concat(this._.map(auditors, 'aid'), materialInfo.user_id));
+                        const shenpiUrl = await this.ctx.helper.urlToShort(this.ctx.protocol + '://' + this.ctx.host + '/wap/tender/' + this.ctx.tender.id + '/measure/material/' + materialInfo.order);
                         const wechatData = {
+                            wap_url: shenpiUrl,
                             qi: materialInfo.order,
                             status: wxConst.status.success,
                             tips: wxConst.tips.success,
@@ -590,7 +596,9 @@ module.exports = app => {
                 const materialInfo = await this.ctx.service.material.getDataById(materialId);
                 const material_decimal = materialInfo && materialInfo.decimal ? JSON.parse(materialInfo.decimal) : materialConst.decimal;
                 const users = this._.uniq(this._.concat(this._.map(auditors, 'aid'), materialInfo.user_id));
+                const shenpiUrl = await this.ctx.helper.urlToShort(this.ctx.protocol + '://' + this.ctx.host + '/wap/tender/' + this.ctx.tender.id + '/measure/material/' + materialInfo.order);
                 const wechatData = {
+                    wap_url: shenpiUrl,
                     qi: materialInfo.order,
                     status: wxConst.status.back,
                     tips: wxConst.tips.back,
@@ -681,7 +689,9 @@ module.exports = app => {
                 });
                 const materialInfo = await this.ctx.service.material.getDataById(materialId);
                 const material_decimal = materialInfo && materialInfo.decimal ? JSON.parse(materialInfo.decimal) : materialConst.decimal;
+                const shenpiUrl = await this.ctx.helper.urlToShort(this.ctx.protocol + '://' + this.ctx.host + '/wap/tender/' + this.ctx.tender.id + '/measure/material/' + materialInfo.order);
                 const wechatData = {
+                    wap_url: shenpiUrl,
                     qi: materialInfo.order,
                     status: wxConst.status.check,
                     tips: wxConst.tips.check,
@@ -821,7 +831,9 @@ module.exports = app => {
                 });
 
                 // 微信模板通知
+                const shenpiUrl = await this.ctx.helper.urlToShort(this.ctx.protocol + '://' + this.ctx.host + '/wap/tender/' + this.ctx.tender.id + '/measure/material/' + materialInfo.order);
                 const wechatData = {
+                    wap_url: shenpiUrl,
                     qi: materialInfo.order,
                     status: wxConst.status.check,
                     tips: wxConst.tips.check,
@@ -1117,6 +1129,35 @@ module.exports = app => {
             return this.db.query(sql, sqlParam);
         }
 
+        /**
+         * 取待审批期列表(wap用)
+         *
+         * @param auditorId
+         * @return {Promise<*>}
+         */
+        async getAuditMaterialByWap(auditorId) {
+            const sql =
+                'SELECT sa.`aid`, sa.`times`, sa.`begin_time`, sa.`end_time`, sa.`tid`, sa.`mid`,' +
+                // '    s.`order` As `sorder`, s.`status` As `sstatus`, s.`s_time`, s.`contract_tp`, s.`qc_tp`, s.`pre_contract_tp`, s.`pre_qc_tp`, s.`yf_tp`, s.`pre_yf_tp`, ' +
+                '    s.*,' +
+                '    t.`name`, t.`project_id`, t.`type`, t.`user_id`, t.`spid`,' +
+                '    ti.`deal_info` ' +
+                '  FROM ?? AS sa' +
+                '    Left Join ?? AS s On sa.`mid` = s.`id`' +
+                '    Left Join ?? As t On sa.`tid` = t.`id`' +
+                '    Left Join ?? AS ti ON ti.`tid` = t.`id`' +
+                '  WHERE sa.`aid` = ? and sa.`status` = ?';
+            const sqlParam = [
+                this.tableName,
+                this.ctx.service.material.tableName,
+                this.ctx.service.tender.tableName,
+                this.ctx.service.tenderInfo.tableName,
+                auditorId,
+                auditConst.status.checking,
+            ];
+            return await this.db.query(sql, sqlParam);
+        }
+
         async updateNewAuditList(material, newList) {
             const transaction = await this.db.beginTransaction();
             try {

+ 36 - 8
app/view/wap/dashboard.ejs

@@ -40,12 +40,12 @@
         </nav>
         <!--待审批期列表-->
         <div class="py-6">
-            <% if (auditStages.length !== 0 || auditChanges.length !== 0 || auditRevise.length !== 0 || auditAdvance.length !== 0 || auditChangeProjects.length !== 0|| auditChangeApplys.length !== 0 || auditChangePlans.length !== 0) { %>
+            <% if (auditStages.length !== 0 || auditChanges.length !== 0 || auditRevise.length !== 0 || auditAdvance.length !== 0 || auditChangeProjects.length !== 0|| auditChangeApplys.length !== 0 || auditChangePlans.length !== 0 || auditMaterials.length !== 0) { %>
                 <% for (const audit of auditStages) { %>
                 <div class="card mb-3">
                     <div class="card-header d-flex justify-content-between">
                         <span><%- JSON.parse(audit.deal_info).buildName %></span>
-                        <span class="badge badge-pill badge-info">计量期</span>
+                        <span class="badge badge-pill bg-new-stage text-new-stage">计量期</span>
                     </div>
                     <div class="bg-light p-2 px-3"><b><%- audit.name %></b></div>
                     <div class="card-body">
@@ -73,7 +73,7 @@
                     <div class="card mb-3">
                         <div class="card-header d-flex justify-content-between">
                             <span><%- JSON.parse(revise.deal_info).buildName %></span>
-                            <span class="badge badge-pill badge-info">台账修订</span>
+                            <span class="badge badge-pill bg-new-revise text-new-revise">台账修订</span>
                         </div>
                         <div class="bg-light p-2 px-3"><b><%- revise.t_name %></b></div>
                         <div class="card-body">
@@ -95,7 +95,7 @@
                     <div class="card mb-3">
                         <div class="card-header d-flex justify-content-between">
                             <span><%- JSON.parse(change.deal_info).buildName %></span>
-                            <span class="badge badge-pill badge-danger">工程变更</span>
+                            <span class="badge badge-pill bg-new-change text-new-change">工程变更</span>
                         </div>
                         <div class="bg-light p-2 px-3"><b><%- change.name %></b></div>
                         <div class="card-body">
@@ -118,7 +118,7 @@
                     <div class="card mb-3">
                         <div class="card-header d-flex justify-content-between">
                             <span><%- JSON.parse(change.deal_info).buildName %></span>
-                            <span class="badge badge-pill badge-danger">变更立项</span>
+                            <span class="badge badge-pill bg-new-changeProject text-new-changeProject">变更立项</span>
                         </div>
                         <div class="bg-light p-2 px-3"><b><%- change.t_name %></b></div>
                         <div class="card-body">
@@ -140,7 +140,7 @@
                     <div class="card mb-3">
                         <div class="card-header d-flex justify-content-between">
                             <span><%- JSON.parse(change.deal_info).buildName %></span>
-                            <span class="badge badge-pill badge-danger">变更申请</span>
+                            <span class="badge badge-pill bg-new-changeApply text-new-changeApply">变更申请</span>
                         </div>
                         <div class="bg-light p-2 px-3"><b><%- change.t_name %></b></div>
                         <div class="card-body">
@@ -162,7 +162,7 @@
                     <div class="card mb-3">
                         <div class="card-header d-flex justify-content-between">
                             <span><%- JSON.parse(change.deal_info).buildName %></span>
-                            <span class="badge badge-pill badge-danger">变更方案</span>
+                            <span class="badge badge-pill bg-new-changePlan text-new-changePlan">变更方案</span>
                         </div>
                         <div class="bg-light p-2 px-3"><b><%- change.t_name %></b></div>
                         <div class="card-body">
@@ -184,7 +184,7 @@
                     <div class="card mb-3">
                         <div class="card-header d-flex justify-content-between">
                             <span><%- JSON.parse(advance.deal_info).buildName %></span>
-                            <span class="badge badge-pill badge-warning">预付款</span>
+                            <span class="badge badge-pill bg-new-advance text-new-advance">预付款</span>
                         </div>
                         <div class="bg-light p-2 px-3"><b><%- advance.name %></b></div>
                         <div class="card-body">
@@ -204,6 +204,34 @@
                         </div>
                     </div>
                 <% } %>
+                <% for (const audit of auditMaterials) { %>
+                    <div class="card mb-3">
+                        <div class="card-header d-flex justify-content-between">
+                            <span><%- JSON.parse(audit.deal_info).buildName %></span>
+                            <span class="badge badge-pill bg-new-material text-new-material">材料调差</span>
+                        </div>
+                        <div class="bg-light p-2 px-3"><b><%- audit.name %></b></div>
+                        <div class="card-body">
+                            <div class="d-flex justify-content-between"><span>第<%- audit.order %>期</span></div>
+                            <div class="my-2">
+                                <table class="table table-sm table-bordered">
+                                    <tr><th>计量期</th><td class="text-right">第<%- audit.s_order %>期</td></tr>
+                                    <tr><th>信息价价差费用</th><td class="text-right"><%- audit.m_tp !== null ? ctx.helper.round(audit.m_tp, audit.decimal.tp) : 0 %></td></tr>
+                                    <% if (audit.material_tax) { %>
+                                        <tr><th>信息价(含材料税)</th><td class="text-right"><%- audit.m_tax_tp !== null ? audit.m_tax_tp : 0 %></td></tr>
+                                    <% } else { %>
+                                        <tr><th>信息价(含建筑税)</th><td class="text-right"><%- audit.rate_tp !== null ? audit.rate_tp : 0 %></td></tr>
+                                    <% } %>
+                                    <tr><th>指数法价差费用</th><td class="text-right"><%- audit.ex_tp !== null ? ctx.helper.round(audit.ex_tp, audit.decimal.tp) : 0 %></td></tr>
+                                    <tr><th>指数法(含建筑税)</th><td class="text-right"><%- audit.ex_tp !== null ? ctx.helper.round(ctx.helper.mul(audit.ex_tp, 1+audit.exponent_rate/100), audit.decimal.tp) : 0 %></td></tr>
+                                </table>
+                            </div>
+                            <div class="">
+                                <a href="/wap/tender/<%- audit.tid %>/measure/material/<%- audit.order %>" class="btn btn-block btn-success">审批</a>
+                            </div>
+                        </div>
+                    </div>
+                <% } %>
             <% } else { %>
                 <h3 class="text-center text-muted">暂无待审批期计量</h3>
             <% } %>

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 296 - 0
app/view/wap/shenpi_material.ejs


+ 124 - 29
app/view/wap/tender.ejs

@@ -25,6 +25,16 @@
         .tab-content > .active,.pill-content > .active {
             height: auto;
         }
+        .nav-tabs-scrollable {
+            overflow-x: auto;
+            white-space: nowrap;
+            -webkit-overflow-scrolling: touch; /* 平滑滚动 */
+            scrollbar-width: none; /* Firefox 隐藏滚动条 */
+        }
+
+        .nav-tabs-scrollable::-webkit-scrollbar {
+            display: none; /* Chrome / Safari 隐藏滚动条 */
+        }
     </style>
 </head>
 <body>
@@ -50,24 +60,32 @@
     </nav>
     <!--标段概况-->
     <div class="py-6">
-        <!--标签-->
-        <ul class="nav nav-tabs nav-fill">
-            <li class="nav-item">
-                <a class="px-1 nav-link active" data-toggle="tab" href="#gaikuang" role="tab">概况</a>
-            </li>
-            <li class="nav-item">
-                <a class="px-1 nav-link" data-toggle="tab" href="#yufukuan" role="tab">预付款</a>
-            </li>
-            <li class="nav-item">
-                <a class="px-1 nav-link" data-toggle="tab" href="#tzxiuding" role="tab">台账修订</a>
-            </li>
-            <li class="nav-item">
-                <a class="px-1 nav-link" data-toggle="tab" href="#jlqi" role="tab">计量期</a>
-            </li>
-            <li class="nav-item">
-                <a class="px-1 nav-link" data-toggle="tab" href="#biangeng" role="tab">工程变更</a>
-            </li>
-        </ul>
+        <div class="nav-tabs-scrollable">
+            <!--标签-->
+            <ul class="nav nav-tabs nav-fill" style="flex-wrap: nowrap;min-width: max-content;">
+                <li class="nav-item">
+                    <a class="px-2 nav-link active" data-toggle="tab" href="#gaikuang" role="tab">概况</a>
+                </li>
+                <li class="nav-item">
+                    <a class="px-2 nav-link" data-toggle="tab" href="#yufukuan" role="tab">预付款</a>
+                </li>
+<!--                <li class="nav-item">-->
+<!--                    <a class="px-2 nav-link" data-toggle="tab" href="#ledger" role="tab">台账分解</a>-->
+<!--                </li>-->
+                <li class="nav-item">
+                    <a class="px-2 nav-link" data-toggle="tab" href="#tzxiuding" role="tab">台账修订</a>
+                </li>
+                <li class="nav-item">
+                    <a class="px-2 nav-link" data-toggle="tab" href="#jlqi" role="tab">计量期</a>
+                </li>
+                <li class="nav-item">
+                    <a class="px-2 nav-link" data-toggle="tab" href="#biangeng" role="tab">工程变更</a>
+                </li>
+                <li class="nav-item">
+                    <a class="px-2 nav-link" data-toggle="tab" href="#material" role="tab">材料调差</a>
+                </li>
+            </ul>
+        </div>
         <div class="tab-content">
             <div class="tab-pane active" id="gaikuang">
                 <!--图表-->
@@ -101,6 +119,8 @@
                 </div>
                 <% } %>
             </div>
+            <div class="tab-pane" id="ledger">
+            </div>
             <div class="tab-pane" id="tzxiuding">
                 <dl class="mb-2 mt-3">
                     <% for (const lr of revises) { %>
@@ -235,6 +255,76 @@
                     </div>
                 </div>
             </div>
+            <div class="tab-pane" id="material">
+                <!--期列表-->
+                <dl class="mb-2 mt-3">
+                    <% for (const m of materials) { %>
+                        <dt class="bg-light p-2 d-flex justify-content-between"><span>第<%- m.order %>期</span>
+                            <span class="<%- auditMaterialConst.auditStringClass[m.status] %>">
+                                <% if (m.curAuditors && m.curAuditors.length > 0 && m.status !== auditMaterialConst.status.checked) { %>
+                                    <% if (m.curAuditors[0].audit_type === auditType.key.common) { %>
+                                        <%- m.curAuditors[0].name %><%if (m.curAuditors[0].role !== '' && m.curAuditors[0].role !== null) { %>-<%- m.curAuditors[0].role %><% } %>
+                                    <% } else { %>
+                                        <%- ctx.helper.transFormToChinese(m.curAuditors[0].audit_order) + '审' %>
+                                    <% } %>
+                                <% } %>
+                                <%- m.status === auditMaterialConst.status.checked ? '审批完成' : auditMaterialConst.auditProgress[m.status] %>
+                        </span>
+                        </dt>
+                        <dd>
+                            <table class="table table-hover">
+                                <tbody><tr>
+                                    <td>
+                                        <p class="mb-0">计量期</p>
+                                        <b>第<%- m.s_order %>期</b>
+                                    </td>
+                                    <% if (materialColShow[0].checked) { %>
+                                    <td>
+                                        <p class="mb-0">信息价价差费用</p>
+                                        <b>¥<%= m.m_tp !== null ? ctx.helper.round(m.m_tp, m.decimal.tp) : 0 %></b>
+                                    </td>
+                                    <% } %>
+                                </tr>
+                                <% if (materialColShow[0].checked) { %>
+                                <tr>
+                                    <% if (openMaterialTax) { %>
+                                    <td>
+                                        <p class="mb-0">信息价(含材料税)</p>
+                                        <b>¥<% if (m.material_tax) { %><% if (m.m_tax_tp) { %><%- m.m_tax_tp || 0 %><% } else { %><%- m.m_tp || 0 %><% } %><% } else { %>0<% } %></b>
+                                    </td>
+                                    <% } %>
+                                    <% if ((openMaterialTax && !allMaterialTax) || !openMaterialTax) { %>
+                                    <td>
+                                        <p class="mb-0">信息价(含建筑税)</p>
+                                        <b>¥<% if (!m.material_tax) { %><%- m.rate_tp || 0 %><% } else { %>0<% } %></b>
+                                    </td>
+                                    <% } %>
+                                </tr>
+                                <% } %>
+                                <% if (materialColShow[1].checked) { %>
+                                <tr>
+                                    <td>
+                                        <p class="mb-0">指数法价差费用</p>
+                                        <b>¥<%= m.ex_tp !== null ? ctx.helper.round(m.ex_tp, m.decimal.tp) : 0 %></b>
+                                    </td>
+                                    <td>
+                                        <p class="mb-0">指数法(含建筑税)</p>
+                                        <b>¥<%= m.ex_tp !== null ? ctx.helper.round(ctx.helper.mul(m.ex_tp, 1+m.exponent_rate/100), m.decimal.tp) : 0 %></b>
+                                    </td>
+                                </tr>
+                                <% } %>
+                                <% if (m.curAuditors && m.curAuditors.length > 0 && m.status == auditMaterialConst.status.checking && m.curAuditors.find(x => { return x.aid === ctx.session.sessionUser.accountId})) { %>
+                                    <tr>
+                                        <td colspan="2">
+                                            <a class="btn btn-block btn-success" href="/wap/tender/<%- m.tid %>/measure/material/<%- m.order %>">审批本期</a>
+                                        </td>
+                                    </tr>
+                                <% } %>
+                                </tbody></table>
+                        </dd>
+                    <% } %>
+                </dl>
+            </div>
         </div>
     </div>
     <!--底栏菜单-->
@@ -482,36 +572,41 @@
 </script>
 <script>
     $(document).ready(function () {
-        if (window.location.hash && window.location.hash === '#yufukuan') {
+        if (window.location.hash && window.location.hash !== '#gaikuang') {
             $('#gaikuang').removeClass('active');
             $('.nav-item a[href="#gaikuang"]').removeClass('active');
-
+        }
+        if (window.location.hash && window.location.hash === '#yufukuan') {
             $('#yufukuan').addClass('active');
             $('.nav-item a[href="#yufukuan"]').addClass('active');
+        } else if (window.location.hash && window.location.hash === '#ledger') {
+            $('#ledger').addClass('active');
+            $('.nav-item a[href="#ledger"]').addClass('active');
         } else if (window.location.hash && window.location.hash === '#tzxiuding') {
-            $('#gaikuang').removeClass('active');
-            $('.nav-item a[href="#gaikuang"]').removeClass('active');
-
             $('#tzxiuding').addClass('active');
             $('.nav-item a[href="#tzxiuding"]').addClass('active');
         } else if (window.location.hash && window.location.hash === '#jlqi') {
-            $('#gaikuang').removeClass('active');
-            $('.nav-item a[href="#gaikuang"]').removeClass('active');
-
             $('#jlqi').addClass('active');
             $('.nav-item a[href="#jlqi"]').addClass('active');
         } else if (window.location.hash && window.location.hash === '#biangeng') {
-            $('#gaikuang').removeClass('active');
-            $('.nav-item a[href="#gaikuang"]').removeClass('active');
-
             $('#biangeng').addClass('active');
             $('.nav-item a[href="#biangeng"]').addClass('active');
+        } else if (window.location.hash && window.location.hash === '#material') {
+            $('#material').addClass('active');
+            $('.nav-item a[href="#material"]').addClass('active');
         }
 
         $('.show-content').on('click', function () {
             $(this).parents('td').html($(this).data('content'));
         });
 
+        const $container = $('.nav-tabs-scrollable');
+        const $activeTab = $container.find('.nav-tabs .nav-link.active');
+        if ($activeTab) {
+            $container.animate({
+                scrollLeft: $activeTab.position().left + $container.scrollLeft() - 20
+            }, 300); // 300 毫秒平滑滚动
+        }
     });
 </script>
 </body>