Browse Source

Merge branch 'dev' into uat

MaiXinRong 10 hours ago
parent
commit
3ccb3d89ba

+ 31 - 32
app/controller/datacollect_controller.js

@@ -156,43 +156,42 @@ module.exports = app => {
                     });
                     for (const t of tenderList) {
                         // 用标段管理的方法获取t数据
-                        if (!have_cost) {
-                            await this.ctx.service.tenderCache.loadTenderCache(t, '');
-                            t.total_price = t.ledger_tp && t.ledger_tp.total_price ? t.ledger_tp.total_price : 0;
-                            [t.change_tp, t.change_p_tp, t.change_n_tp, t.change_valuation_tp, t.change_unvaluation_tp] = await ctx.service.change.getChangeTp(t.id);
-                            // t.material_tp = await ctx.service.material.getSumMaterial(t.id);
-                            // 获取本标段 本月计量期审批通过数目,变更令审批通过数目,台账修订通过数目,材料调差通过数目
-                            t.month_stage_num = await ctx.service.stageAudit.getNumByMonth(t.id, startMonth, endMonth);
-                            t.month_change_num = await ctx.service.changeAudit.getNumByMonth(t.id, startMonth, endMonth);
-                            t.month_revise_num = await ctx.service.reviseAudit.getNumByMonth(t.id, startMonth, endMonth);
-                            t.month_material_num = await ctx.service.materialAudit.getNumByMonth(t.id, startMonth, endMonth);
-                            // 获取标段计量月统计及截止月累计计量
-                            // 这个慢,统计下面这个方法时长
-                            const stageList = await ctx.service.stage.getStageByDataCollect(t.id, t.stage_tp);
-                            // const stageList = [];
-                            const month_stage = [];
-                            for (const s of stageList) {
-                                const monthOneStage = ctx.app._.find(month_stage, { yearmonth: s.s_time });
-                                if (monthOneStage) {
-                                    monthOneStage.tp = ctx.helper.add(monthOneStage.tp, s.tp);
-                                    monthOneStage.end_yf_tp = ctx.helper.add(monthOneStage.end_yf_tp, s.yf_tp);
-                                    monthOneStage.end_sf_tp = ctx.helper.add(monthOneStage.end_sf_tp, s.sf_tp);
-                                } else {
-                                    const data = {
-                                        yearmonth: s.s_time,
-                                        tp: s.tp,
-                                        end_tp: s.end_tp,
-                                        end_yf_tp: s.yf_tp,
-                                        end_sf_tp: s.sf_tp,
-                                    };
-                                    month_stage.push(data);
-                                }
+                        await this.ctx.service.tenderCache.loadTenderCache(t, '');
+                        t.total_price = t.ledger_tp && t.ledger_tp.total_price ? t.ledger_tp.total_price : 0;
+                        [t.change_tp, t.change_p_tp, t.change_n_tp, t.change_valuation_tp, t.change_unvaluation_tp] = await ctx.service.change.getChangeTp(t.id);
+                        // t.material_tp = await ctx.service.material.getSumMaterial(t.id);
+                        // 获取本标段 本月计量期审批通过数目,变更令审批通过数目,台账修订通过数目,材料调差通过数目
+                        t.month_stage_num = await ctx.service.stageAudit.getNumByMonth(t.id, startMonth, endMonth);
+                        t.month_change_num = await ctx.service.changeAudit.getNumByMonth(t.id, startMonth, endMonth);
+                        t.month_revise_num = await ctx.service.reviseAudit.getNumByMonth(t.id, startMonth, endMonth);
+                        t.month_material_num = await ctx.service.materialAudit.getNumByMonth(t.id, startMonth, endMonth);
+                        // 获取标段计量月统计及截止月累计计量
+                        // 这个慢,统计下面这个方法时长
+                        const stageList = await ctx.service.stage.getStageByDataCollect(t.id, t.stage_tp);
+                        // const stageList = [];
+                        const month_stage = [];
+                        for (const s of stageList) {
+                            const monthOneStage = ctx.app._.find(month_stage, { yearmonth: s.s_time });
+                            if (monthOneStage) {
+                                monthOneStage.tp = ctx.helper.add(monthOneStage.tp, s.tp);
+                                monthOneStage.end_yf_tp = ctx.helper.add(monthOneStage.end_yf_tp, s.yf_tp);
+                                monthOneStage.end_sf_tp = ctx.helper.add(monthOneStage.end_sf_tp, s.sf_tp);
+                            } else {
+                                const data = {
+                                    yearmonth: s.s_time,
+                                    tp: s.tp,
+                                    end_tp: s.end_tp,
+                                    end_yf_tp: s.yf_tp,
+                                    end_sf_tp: s.sf_tp,
+                                };
+                                month_stage.push(data);
                             }
-                            t.month_stage = month_stage;
                         }
+                        t.month_stage = month_stage;
                         if (have_cost) {
                             // 取最新已审批完成的成本管理-成本分析期数据
                             t.cost_analysis = await ctx.service.costStage.getLastCheckedStage(t.id, 'analysis');
+                            t.cost_duty = await ctx.service.costStage.getStageByOrder(t.id, 'duty', 1);
                             t.stage_num = await ctx.service.stage.getNumByChecked(t.id);
                             t.cost_ledger_num = await ctx.service.costStage.getNumByChecked(t.id, 'ledger');
                             t.cost_analysis_num = await ctx.service.costStage.getNumByChecked(t.id, 'analysis');

+ 8 - 7
app/controller/pay_controller.js

@@ -47,7 +47,7 @@ module.exports = app => {
                     phasePays,
                     validStages,
                     auditConst: audit.common,
-                    jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.phasePay.list)
+                    jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.phasePay.list),
                 };
                 await this.layout('phase_pay/index.ejs', renderData, 'phase_pay/modal.ejs');
             } catch (err) {
@@ -68,7 +68,7 @@ module.exports = app => {
 
                 const pays = await ctx.service.phasePay.getAllPhasePay(ctx.tender.id, 'DESC');
                 const unCompleteCount = pays.filter(s => { return s.status !== audit.common.status.checked; }).length;
-                if (unCompleteCount.length > 0) throw `最新一起未审批通过,请审批通过后再新增`;
+                if (unCompleteCount.length > 0) throw '最新一起未审批通过,请审批通过后再新增';
                 const stages = stage ? await ctx.service.stage.getAllDataByCondition({ where: { tid: ctx.tender.id, order: stage } }) : [];
 
                 const newPhase = await ctx.service.phasePay.add(ctx.tender.id, stages, date, memo);
@@ -177,6 +177,7 @@ module.exports = app => {
                     shenpiConst,
                     auditType: audit.auditType,
                     authMobile: pa.auth_mobile,
+                    showAudit: true,
                 };
                 await this.layout('phase_pay/detail.ejs', renderData, 'phase_pay/detail_modal.ejs');
             } catch (err) {
@@ -194,7 +195,7 @@ module.exports = app => {
 
                 const result = {};
                 for (const f of filter) {
-                    switch(f) {
+                    switch (f) {
                         case 'pay':
                             result.pay = await this.ctx.service.phasePayDetail.getDetailData(ctx.phasePay);
                             break;
@@ -269,7 +270,7 @@ module.exports = app => {
         async uploadFile(ctx) {
             let stream;
             try {
-                const parts = ctx.multipart({autoFields: true});
+                const parts = ctx.multipart({ autoFields: true });
 
                 let index = 0;
                 const create_time = Date.parse(new Date()) / 1000;
@@ -306,7 +307,7 @@ module.exports = app => {
                 }
 
                 const result = await ctx.service.phasePayFile.addFiles(ctx.phasePay, 'pay', uploadfiles, user);
-                ctx.body = {err: 0, msg: '', data: result};
+                ctx.body = { err: 0, msg: '', data: result };
             } catch (error) {
                 ctx.log(error);
                 // 失败需要消耗掉stream 以防卡死
@@ -315,12 +316,12 @@ module.exports = app => {
             }
         }
         async deleteFile(ctx) {
-            try{
+            try {
                 const data = JSON.parse(ctx.request.body.data);
                 if (!data && !data.id) throw '缺少参数';
                 const result = await ctx.service.phasePayFile.delFiles(data.id);
                 ctx.body = { err: 0, msg: '', data: result };
-            } catch(error) {
+            } catch (error) {
                 ctx.log(error);
                 ctx.ajaxErrorBody(error, '删除附件失败');
             }

+ 1 - 0
app/controller/report_controller.js

@@ -1022,6 +1022,7 @@ module.exports = app => {
                     otherHintName: '',
                     bizId: bglObj.BUSINESS_ID,
                     permissions: '[]',
+                    showAudit: false,
                 };
                 await this.layout('report/index.ejs', renderData, 'report/rpt_all_popup.ejs');
             } catch (err) {

BIN
app/public/images/juecedaping07.png


BIN
app/public/images/juecedaping08.png


+ 370 - 276
app/view/datacollect/index_cost.ejs

@@ -62,165 +62,142 @@
         </div>
         <div class="c-body" style="background:#2c3237 !important">
             <div class="flex-content">
-                <div class="row mx-2" style="height: 63.5vh">
-                    <div class="col-3 px-0 height-100">
-                        <div class="left-content height-100">
-                            <div class="left-card-content height-100">
-                                <div class="height-25 mb-2">
-                                    <div class="card text-center bg-dark text-white mr-2 py-2 height-100">
-                                        <div class="height-100" style="display: grid;place-items: center;">
-                                            <div style="line-height: 3;">
-                                                <div style="font-size: 1.5rem" class="data_total_in_tp">0.00</div>
-                                                <div style="font-size: .9rem;">
-                                                    <span style="background-color: #42474c;border-radius: 1rem;padding: .25rem .75rem">项目收入</span>
-                                                </div>
-                                            </div>
-                                        </div>
-                                    </div>
+                <div class="row mx-2" style="height: 95.5vh">
+                    <div class="col-9 px-0 height-100">
+                        <div class="row m-0 px-0 mb-2" style="height: 50%;">
+                            <div class="col-4 px-0 bg-dark height-100">
+                                <div class="col-12 text-white pt-2">
+                                    <div class="card-big-htext">|  金额对比<span class="float-right mr-2">万元&nbsp;</span></div>
                                 </div>
-                                <div class="height-25 mb-2">
-                                    <div class="card text-center bg-dark text-white mr-2 py-2 height-100">
-                                        <div class="height-100" style="display: grid;place-items: center;">
-                                            <div style="line-height: 3;">
-                                                <div style="font-size: 1.5rem" class="data_total_out_tp">0.00</div>
-                                                <div style="font-size: .9rem;">
-                                                    <span style="background-color: #42474c;border-radius: 1rem;padding: .25rem .75rem">项目支出</span>
-                                                </div>
-                                            </div>
-                                        </div>
-                                    </div>
+                                <div class="col-12 pb-2 text-white m-0 mt-2 bg-dark" style="height: 89%;overflow: auto;">
+                                    <style>
+                                        .level1-table tbody tr td {
+                                            padding: 6px 10px; /* 默认一般是 8~16px,可根据需要继续调小 */
+                                            line-height: 1.2;
+                                            border-bottom: 1px solid rgba(255,255,255,0.2);
+                                        }
+                                        .level1-table tbody tr:last-child td {
+                                            border-bottom: none;
+                                        }
+                                    </style>
+                                    <table class="level1-table" style="width: 100%; height: 100%;">
+                                        <thead style="height: 50px;border-bottom: 1px solid rgba(255,255,255,0.2);background-color: #2C3034;">
+                                        <tr class="text-center">
+                                            <th>分类</th>
+                                            <th>责任成本</th>
+                                            <th>实际成本</th>
+                                        </tr>
+                                        </thead>
+                                        <tbody>
+                                        <tr>
+                                            <td>项目收入</td>
+                                            <td class="text-center data_duty_total_in_tp"></td>
+                                            <td class="text-center data_total_in_tp"></td>
+                                        </tr>
+                                        <tr>
+                                            <td>项目成本</td>
+                                            <td class="text-center data_duty_total_out_tp"></td>
+                                            <td class="text-center data_total_out_tp"></td>
+                                        </tr>
+                                        <tr>
+                                            <td>利润</td>
+                                            <td class="text-center data_duty_total_profit"></td>
+                                            <td class="text-center data_total_profit"></td>
+                                        </tr>
+                                        <tr>
+                                            <td>利润率</td>
+                                            <td class="text-center data_duty_total_profit_percent"></td>
+                                            <td class="text-center data_total_profit_percent"></td>
+                                        </tr>
+                                        </tbody>
+                                    </table>
                                 </div>
-                                <div class="height-25 mb-2">
-                                    <div class="card text-center bg-dark text-white mr-2 py-2 height-100">
-                                        <div class="height-100" style="display: grid;place-items: center;">
-                                            <div style="line-height: 3;">
-                                                <div style="font-size: 1.5rem" class="data_total_profit">0.00</div>
-                                                <div style="font-size: .9rem;">
-                                                    <span style="background-color: #42474c;border-radius: 1rem;padding: .25rem .75rem">利润</span>
-                                                </div>
-                                            </div>
-                                        </div>
+                            </div>
+                            <div class="col-8 px-0 height-100">
+                                <div class="row mx-2 mb-2 height-100 bg-dark">
+                                    <div class="col-12 text-white pt-2 pl-3">
+                                        <div class="card-big-htext">|  标段利润及利润率<span class="float-right mr-2">万元&nbsp;</span></div>
                                     </div>
-                                </div>
-                                <div class="height-25" style="height: 24.3%">
-                                    <div class="card text-center bg-dark text-white mr-2 py-2 height-100">
-                                        <div class="height-100" style="display: grid;place-items: center;">
-                                            <div style="line-height: 3;">
-                                                <div style="font-size: 1.5rem" class="data_total_profit_percent">0%</div>
-                                                <div style="font-size: .9rem;">
-                                                    <span style="background-color: #42474c;border-radius: 1rem;padding: .25rem .75rem">利润率</span>
-                                                </div>
-                                            </div>
-                                        </div>
+                                    <div class="col-12 m-0" style="height: 88%">
+                                        <div class="jlchart" data-chart-num="1" id="jlchart" style="height: 100%; width: 100%;"></div>
                                     </div>
                                 </div>
                             </div>
                         </div>
-                    </div>
-                    <div class="col-6 px-0 height-100">
-                        <div class="center-content height-100 mr-2">
-                            <div class="center-chart-content height-100">
-                                <div class="center-di">
-                                    <div class="card bg-dark height-100">
-                                        <div class="jlchart" data-chart-num="1" id="jlchart" style="height: 100%; width: 100%;"></div>
-                                    </div>
-                                </div>
-                                <div class="center-chart">
-                                    <div class="card height-100 bg-dark mt-2">
-                                        <div class="di-content mb-2">
-                                            <div class="jldbchart" data-chart-num="1" id="jldbchart" style="height: 100%; width: 100%;"></div>
-                                        </div>
-                                    </div>
-                                </div>
+                        <div class="row m-0 px-0 mr-2 bg-dark" style="height: 49%;">
+                            <div class="col-12 text-white pt-2 pl-3">
+                                <div class="card-big-htext">|  累计计量<span class="float-right mr-2">万元&nbsp;</span></div>
+                            </div>
+                            <div class="col-12 m-0" style="height: 88%">
+                                <div class="jldbchart" id="jldbchart" style="height: 100%; width: 100%;"></div>
                             </div>
                         </div>
                     </div>
                     <div class="col-3 px-0 height-100">
-                        <div class="right-content height-100">
-                            <div class="right-chart-content height-100">
-                                <div class="right-month">
-                                    <h6 class="card bg-dark text-center text-white m-0 pt-2 pb-3">期数统计</h6>
-                                    <div class="row right-month-height">
-                                        <div class="col-6 pr-0 height-50">
-                                            <div class="card text-center bg-dark text-white border-right-0 border-botton-0 height-100">
-                                                <div class="card-body card-small-body height-100">
-                                                    <h5 class="card-title text-center height-50" style="font-size: 2.80rem;line-height: 200%"><span class="stage_num">0</span></h5>
-                                                    <p class="card-text text-muted height-50">计量期</p>
-                                                </div>
+                        <div class="row mb-2 bg-dark m-0 p-0" style="height: 31.2vh">
+                            <div class="col-12 text-white pt-2 pl-3">
+                                <div class="card-big-htext">|  期数统计<span class="float-right mr-2">&nbsp;</span></div>
+                            </div>
+<!--                                    <h6 class="card bg-dark text-center text-white m-0 pt-2 pb-3">期数统计</h6>-->
+                            <div class="col-12 p-0 m-0 right-month-height">
+                                <div class="row p-0 m-0 height-100">
+                                    <div class="col-6 px-0 height-50">
+                                        <div class="card text-center bg-dark text-white border-0 height-100">
+                                            <div class="card-body card-small-body height-100">
+                                                <h5 class="card-title text-center height-50" style="font-size: 2.80rem;line-height: 200%"><span class="stage_num">0</span></h5>
+                                                <p class="card-text text-muted height-50">计量期</p>
                                             </div>
                                         </div>
-                                        <div class="col-6 pl-0 height-50">
-                                            <div class="card text-center bg-dark text-white border-botton-0 height-100">
-                                                <div class="card-body card-small-body height-100">
-                                                    <h5 class="card-title text-center height-50" style="font-size: 2.80rem;line-height: 200%"><span class="cost_ledger_num">0</span></h5>
-                                                    <p class="card-text text-muted height-50">成本报审</p>
-                                                </div>
+                                    </div>
+                                    <div class="col-6 px-0 height-50">
+                                        <div class="card text-center bg-dark text-white border-0 height-100">
+                                            <div class="card-body card-small-body height-100">
+                                                <h5 class="card-title text-center height-50" style="font-size: 2.80rem;line-height: 200%"><span class="cost_ledger_num">0</span></h5>
+                                                <p class="card-text text-muted height-50">成本报审</p>
                                             </div>
                                         </div>
-                                        <div class="col-6 pr-0 height-50">
-                                            <div class="card text-center bg-dark text-white border-right-0 border-top-0 height-100">
-                                                <div class="card-body card-small-body height-100">
-                                                    <h5 class="card-title text-center height-50" style="font-size: 2.80rem;line-height: 200%"><span class="cost_book_num">0</span></h5>
-                                                    <p class="card-text text-muted height-50">财务账面</p>
-                                                </div>
+                                    </div>
+                                    <div class="col-6 px-0 height-50">
+                                        <div class="card text-center bg-dark text-white border-0 border-top-0 height-100">
+                                            <div class="card-body card-small-body height-100">
+                                                <h5 class="card-title text-center height-50" style="font-size: 2.80rem;line-height: 200%"><span class="cost_book_num">0</span></h5>
+                                                <p class="card-text text-muted height-50">财务账面</p>
                                             </div>
                                         </div>
-                                        <div class="col-6 pl-0 height-50">
-                                            <div class="card text-center bg-dark text-white border-top-0 height-100">
-                                                <div class="card-body card-small-body height-100">
-                                                    <h5 class="card-title text-center height-50" style="font-size: 2.80rem;line-height: 200%"><span class="cost_analysis_num">0</span></h5>
-                                                    <p class="card-text text-muted height-50">成本分析</p>
-                                                </div>
+                                    </div>
+                                    <div class="col-6 px-0 height-50">
+                                        <div class="card text-center bg-dark text-white border-0 height-100">
+                                            <div class="card-body card-small-body height-100">
+                                                <h5 class="card-title text-center height-50" style="font-size: 2.80rem;line-height: 200%"><span class="cost_analysis_num">0</span></h5>
+                                                <p class="card-text text-muted height-50">成本分析</p>
                                             </div>
                                         </div>
                                     </div>
                                 </div>
-                                <div class="right-chart">
-                                    <div class="card height-100 bg-dark">
-                                        <div class="jlwcdchart" id="jlwcdchart" style="height: 100%; width: 100%;"></div>
-                                    </div>
-                                </div>
                             </div>
                         </div>
-                    </div>
-                </div>
-                <div class="row mx-2" style="height: 32vh">
-                    <div class="col-9 px-0 pt-1 height-100">
-                        <div class="center-table height-100" style="padding-right: .5rem !important;">
-                            <div class="card height-100 bg-dark mt-2">
-                                <h6 class="bg-dark text-center text-white m-0 py-3">投资控制(万元)</h6>
-                                <div class="tablebox">
-                                    <table id="tableId">
-                                        <thead>
-                                        <tr class="text-center">
-                                            <th></th>
-                                            <th>投资估算</th>
-                                            <th>设计概算</th>
-                                            <th>施工图预算</th>
-                                            <th>控制目标</th>
-                                            <th>已完成</th>
-                                            <th>完成比例(%)</th>
-                                        </tr>
-                                        </thead>
-                                        <tbody class="stage-data">
-                                        </tbody>
-                                    </table>
-                                    <table id="tableId1"></table>
+                        <div class="m-0 mb-2 bg-dark p-0" style="height: 31.2vh">
+                            <div class="row mx-0 mb-2 height-100">
+                                <div class="col-12 text-white pt-2 pl-3">
+                                    <div class="card-big-htext">|  利润占比<span class="float-right mr-2">万元&nbsp;</span></div>
+                                </div>
+                                <div class="col-12 m-0" style="height: 88%">
+                                    <div class="jlwcdchart" id="jlwcdchart" style="height: 100%; width: 100%;"></div>
                                 </div>
                             </div>
                         </div>
-                    </div>
-                    <div class="col-3 px-0 pt-1 height-100">
-                        <div class="right-biaoduan height-100">
-                            <div class="card height-100 bg-dark mt-2">
-                                <h6 class="bg-dark text-center text-white m-0 py-3">利润率排名</h6>
-                                <div class="tablebox">
+                        <div class="m-0 mb-2 bg-dark p-0" style="height: 31.3vh">
+                            <div class="height-100">
+                                <div class="col-12 text-white pt-2 pl-3">
+                                    <div class="card-big-htext">|  利润率排名<span class="float-right mr-2">&nbsp;</span></div>
+                                </div>
+                                <div class="tablebox mt-2" style="height: 80%">
                                     <table id="profit_tableId">
                                         <thead>
                                         <tr class="text-center">
-                                            <th></th>
+                                            <th width="50">排名</th>
                                             <th>标段</th>
-                                            <th>利润率</th>
+                                            <th width="80">利润率</th>
                                         </tr>
                                         </thead>
                                         <tbody class="tender-data">
@@ -250,9 +227,6 @@
             // position: 'top',
         },
         title: {
-            text: '利润排名占比',
-            left: 'center',
-            top:'7%'
         },
         color: ['rgba(38, 217, 217,0.7)','rgba(78, 139, 229,0.7)',
             'rgba(78, 229, 139,0.7)','rgba(108, 78, 229,0.7)',
@@ -272,8 +246,8 @@
             {
                 name: '利润金额',
                 type: 'pie',
-                radius: '60%',
-                top:'15%',
+                radius: '65%',
+                top:'2%',
                 formatter: function(name){
                     return name.length>10?name.substr(0,10)+"...":name;
                 },
@@ -293,9 +267,6 @@
     // 利润统计状图表
     option2 = {
         title: {
-            text: '利润统计',
-            left: 'center',
-            top:'5%'
         },
         color: ['rgba(38, 217, 217,0.7)','rgba(78, 139, 229,0.7)',
             'rgba(78, 229, 139,0.7)','rgba(108, 78, 229,0.7)',
@@ -309,6 +280,28 @@
             axisPointer: {            // 坐标轴指示器,坐标轴触发有效
                 type: 'shadow'        // 默认为直线,可选为:'line' | 'shadow'
             },
+            formatter: function (params) {
+
+                let html = params[0].axisValue + '<br/>';
+
+                params.forEach(function (item) {
+
+                    let value = item.value;
+
+                    if (item.seriesName === '利润率') {
+                        value += '%';
+                    }
+
+                    html += `
+            <div style="display:flex;justify-content:space-between;min-width:150px;">
+                <span>${item.marker}${item.seriesName}</span>
+                <span style="font-weight:bold;">${value}</span>
+            </div>
+        `;
+                });
+
+                return html;
+            }
         },
 
         dataZoom: [
@@ -327,25 +320,17 @@
                 height: 10,
                 bottom: '10%',
             },
-            // {
-            //     // realtime: true,
-            //     type: 'slider',
-            //     show: true,
-            //     realtime: true,
-            //     showdetail: false,
-            //     showDataShadow: false,
-            //     // dataZoomIndex: 10,
-            //     start: 0,
-            //     end: 8,
-            //     handleSize: 0,
-            //     bottom:30,
-            //     height:10,
-            // }
         ],
-        // legend: {
-        //     data: ['利润'],
-        //     top:'17%'
-        // },
+        legend: {
+            top: '5%',
+            left: 'center',
+            data: ['利润', '利润率'],
+            textStyle: {
+                color: '#fff',
+                fontSize: 14
+            },
+            icon: 'roundRect' // 可选:rect、circle、roundRect
+        },
         grid: {
             top:'25%',
             left: '3%',
@@ -377,7 +362,7 @@
         yAxis: [
             {
                 type: 'value',
-                name:'金额',
+                name:'',
                 position: 'left',
                 axisLabel : {
                     formatter: function (value, index) {
@@ -398,19 +383,28 @@
                         return value;
                     }
                 },
-                splitArea : {show : true}
+                splitLine: {
+                    show: true,
+                    lineStyle: {
+                        color: 'rgba(255,255,255,0.5)',
+                        type: 'dashed',   // 虚线
+                        width: 1
+                    }
+                }
             },
-            // {
-            //     type: 'value',
-            //     name:'完成度',
-            //     position: 'right',
-            //     min:0,
-            //     max:100,
-            //     axisLabel : {
-            //         formatter: '{value} %'
-            //     },
-            //     splitArea : {show : true}
-            // }
+            {
+                type: 'value',
+                name: '',
+                position: 'right',
+
+                axisLabel: {
+                    formatter: '{value}%'
+                },
+
+                splitLine: {
+                    show: false      // 不显示右侧网格线
+                }
+            }
         ],
         series: [
             {
@@ -421,19 +415,35 @@
                 },
                 data: []
             },
+            {
+                name: '利润率',
+                type: 'line',
+                yAxisIndex: 1,     // 使用右侧坐标轴
+
+                smooth: true,
+
+                symbol: 'circle',
+                symbolSize: 8,
+
+                lineStyle: {
+                    width: 3
+                },
+
+                itemStyle: {
+                    color: '#fea844'
+                },
+
+                data: []
+            }
         ]
     };
     var chart2 = document.getElementsByClassName('jlchart');
     var myChart2_1 = echarts.init(chart2[0], 'dark');
     myChart2_1.setOption(option2);
     // myChart2.setOption(option);
-    // 利润率统计柱状图表
-    // var myChart3 = echarts.init(document.getElementsByClassName('jlwcdchart')[0], 'dark');
-    option3 = {
+
+    const option4_default = {
         title: {
-            text: '利润率统计',
-            left: 'center',
-            top:'5%'
         },
         color: ['rgba(38, 217, 217,0.7)','rgba(78, 139, 229,0.7)',
             'rgba(78, 229, 139,0.7)','rgba(108, 78, 229,0.7)',
@@ -444,34 +454,23 @@
         backgroundColor: '#343a40 ',
         tooltip: {
             trigger: 'axis',
-            axisPointer: {            // 坐标轴指示器,坐标轴触发有效
-                type: 'shadow'        // 默认为直线,可选为:'line' | 'shadow'
-            },
+            axisPointer: {
+                type: 'cross',
+                label: {
+                    backgroundColor: '#6a7985'
+                }
+            }
+        },
+        legend: {
+            type: 'scroll',
+            bottom: '2%',
+            data: [],
+            textStyle: {
+                color: '#fff'
+            }
         },
-
-        dataZoom: [
-            {
-                brushSelect:false,
-                // zoomLock: false,
-                type: 'slider',
-                show: true,
-                realtime: true,
-                showdetail: false,
-                showDataShadow: false,
-                // dataZoomIndex: 10,
-                start: 0,
-                end: 8,
-                handleSize: 0,
-                height: 10,
-                bottom: '10%',
-            },
-        ],
-        // legend: {
-        //     data: ['利润率'],
-        //     top:'17%'
-        // },
         grid: {
-            top:'25%',
+            top:'10%',
             left: '3%',
             right: '4%',
             bottom: '15%',
@@ -480,81 +479,66 @@
         xAxis: [
             {
                 type: 'category',
-                data: [],
-                axisLabel: {
-                    show: true,
-                    interval: 0,
-                    textStyle: {
-                        color: "#fff",
-                        fontSize: 14
-                    },
-                    formatter: function(value) {
-                        var res = value;
-                        if(res.length > 6) {
-                            res = res.substring(0, 5) + "..";
-                        }
-                        return res;
-                    }
-                }
+                boundaryGap: false,
+                data: []
             }
         ],
         yAxis: [
-            // {
-            //     type: 'value',
-            //     name:'利润率',
-            //     position: 'left',
-            //     axisLabel : {
-            //         formatter: function (value, index) {
-            //             if (value < 0) {
-            //                 let newValue = Math.abs(value);
-            //                 if (newValue >= 10000 && newValue < 10000000) {
-            //                     newValue = newValue / 10000 + "万";
-            //                 } else if (newValue >= 10000000) {
-            //                     newValue = newValue / 10000000 + "千万";
-            //                 }
-            //                 value = '-' + newValue;
-            //             }
-            //             if (value >= 10000 && value < 10000000) {
-            //                 value = value / 10000 + "万";
-            //             } else if (value >= 10000000) {
-            //                 value = value / 10000000 + "千万";
-            //             }
-            //             return value;
-            //         }
-            //     },
-            //     splitArea : {show : true}
-            // },
             {
                 type: 'value',
-                name:'利润率',
-                position: 'left',
-                min:0,
-                max:100,
                 axisLabel : {
-                    formatter: '{value} %'
+                    formatter: function (value, index) {
+                        if (value < 0) {
+                            let newValue = Math.abs(value);
+                            if (newValue >= 10000 && newValue < 10000000) {
+                                newValue = newValue / 10000 + "万";
+                            } else if (newValue >= 10000000) {
+                                newValue = newValue / 10000000 + "千万";
+                            }
+                            value = '-' + newValue;
+                        }
+                        if (value >= 10000 && value < 10000000) {
+                            value = value / 10000 + "万";
+                        } else if (value >= 10000000) {
+                            value = value / 10000000 + "千万";
+                        }
+                        return value;
+                    }
                 },
-                splitArea : {show : true}
+                splitLine: {
+                    show: true,
+                    lineStyle: {
+                        color: 'rgba(255,255,255,0.5)',
+                        type: 'dashed',   // 虚线
+                        width: 1
+                    }
+                }
             }
         ],
-        series: [
+        dataZoom: [
             {
-                name: '利润率',
-                type: 'bar',
-                emphasis: {
-                    focus: 'series'
-                },
-                data: []
+                brushSelect: false,
+                showdetail: false,
+                show: true,
+                realtime: true,
+                dataZoomIndex: 10,
+                start: 0,
+                end: 5,
+                handleSize: 0,
+                height: 10,
+                bottom: '10%'
             },
-        ]
+        ],
+        series: [],
     };
-    var chart3 = document.getElementsByClassName('jldbchart');
-    var myChart3_1 = echarts.init(chart3[0], 'dark');
-    myChart3_1.setOption(option3);
+    var chart4 = document.getElementsByClassName('jldbchart');
+    var myChart4_1 = echarts.init(chart4[0], 'dark');
+    myChart4_1.setOption(option4_default);
 
     function echartsReset() {
         myChart1_1.resize();
         myChart2_1.resize();
-        myChart3_1.resize();
+        myChart4_1.resize();
     }
     $(function () {
         $('#showFull').click(function () {
@@ -850,6 +834,9 @@
         }
 
         function setData(tenderList, categoryIndex = 0) {
+            let total_duty_in_tp = 0;
+            let total_duty_out_tp = 0;
+            let total_duty_profit = 0;
             let total_in_tp = 0;
             let total_out_tp = 0;
             let total_profit = 0;
@@ -879,17 +866,26 @@
             // } else {
             //     option1_is_tender = true;
             // }
-
+            const chart_option4_data = [];
             for(const t of tenderList) {
                 const stage_tp = t.cost_analysis ? t.cost_analysis.stage_tp : null;
                 if (stage_tp) {
                     total_in_tp = ZhCalc.add(total_in_tp, stage_tp.in_tp);
                     total_out_tp = ZhCalc.add(total_out_tp, stage_tp.out_tp);
                     total_profit = ZhCalc.add(total_profit, stage_tp.profit);
-                    chart_option2_data.push(stage_tp.profit ? stage_tp.profit : 0);
+                    chart_option2_data.push(stage_tp.profit ? ZhCalc.round(ZhCalc.div(stage_tp.profit, 10000), 0) : 0);
                     chart_option3_data.push(stage_tp.profit_percent ? stage_tp.profit_percent : 0);
                     chart_option_name.push(t.name);
-                    chart_option1_data.push({ value: stage_tp.profit, name: t.name});
+                    chart_option1_data.push({ value: stage_tp.profit ? ZhCalc.round(ZhCalc.div(stage_tp.profit, 10000), 0) : 0, name: t.name});
+                }
+                const dutyInfo = t.cost_duty ? t.cost_duty : null;
+                if (dutyInfo) {
+                    const duty_in_tp = dutyInfo.extra_info ? dutyInfo.extra_info.in_tp : 0;
+                    const duty_out_tp = dutyInfo.stage_tp ? dutyInfo.stage_tp.total_price : 0;
+                    total_duty_in_tp = ZhCalc.add(total_duty_in_tp, duty_in_tp);
+                    total_duty_out_tp = ZhCalc.add(total_duty_out_tp, duty_out_tp);
+                    const profit = ZhCalc.sub(duty_in_tp, duty_out_tp);
+                    total_duty_profit = ZhCalc.add(total_duty_profit, profit);
                 }
                 stage_num = ZhCalc.add(stage_num, t.stage_num);
                 cost_ledger_num = ZhCalc.add(cost_ledger_num, t.cost_ledger_num);
@@ -904,6 +900,25 @@
                 //         chart_option1_data[index].value = ZhCalc.add(chart_option1_data[index].value, (stage_tp.profit ? stage_tp.profit : 0));
                 //     }
                 // }
+                const one_option4_data = {
+                    id: t.id,
+                    name: t.name,
+                    list: [],
+                };
+                for (const s of t.month_stage) {
+                    const index = _.findIndex(one_option4_data.list, { yearmonth: s.yearmonth });
+                    if (index === -1) {
+                        one_option4_data.list.push({
+                            yearmonth: s.yearmonth,
+                            tp: s.tp,
+                            end_tp: s.end_tp,
+                        })
+                    } else {
+                        one_option4_data.list[index].tp = ZhCalc.add(one_option4_data.list[index].tp, s.tp);
+                        one_option4_data.list[index].end_tp = ZhCalc.add(one_option4_data.list[index].end_tp, s.end_tp);
+                    }
+                }
+                chart_option4_data.push(one_option4_data);
             }
             // 根据利润率排行并只显示前5位
             let index = 1;
@@ -923,17 +938,22 @@
                     tender_html += `<tr class="bg-dark">
                     <td class="text-center py-2">${rankDisplay}</td>
                     <td class="py-2">${t.name}</td>
-                    <td class="text-center py-2">${stage_tp.profit_percent}</td>
+                    <td class="text-center py-2">${stage_tp.profit_percent}%</td>
                 </tr>`;
                     index++;
                 }
             }
             // console.log(tenderList);
             const profit_percent = total_in_tp && total_profit ? ZhCalc.round(ZhCalc.div(total_profit, total_in_tp) * 100, 2) : 0;
+            const profit_duty_percent = total_duty_in_tp && total_duty_profit ? ZhCalc.round(ZhCalc.div(total_duty_profit, total_duty_in_tp) * 100, 2) : 0;
             $('.data_total_profit_percent').text(profit_percent ? profit_percent + '%' : '0%');
-            $('.data_total_in_tp').text(formatMoney(total_in_tp));
-            $('.data_total_out_tp').text(formatMoney(total_out_tp));
-            $('.data_total_profit').text(formatMoney(total_profit));
+            $('.data_total_in_tp').text(ZhCalc.round(ZhCalc.div(total_in_tp, 10000), 0));
+            $('.data_total_out_tp').text(ZhCalc.round(ZhCalc.div(total_out_tp, 10000), 0));
+            $('.data_total_profit').text(ZhCalc.round(ZhCalc.div(total_profit, 10000), 0));
+            $('.data_duty_total_profit_percent').text(profit_duty_percent ? profit_duty_percent + '%' : '0%');
+            $('.data_duty_total_in_tp').text(ZhCalc.round(ZhCalc.div(total_duty_in_tp, 10000), 0));
+            $('.data_duty_total_out_tp').text(ZhCalc.round(ZhCalc.div(total_duty_out_tp, 10000), 0));
+            $('.data_duty_total_profit').text(ZhCalc.round(ZhCalc.div(total_duty_profit, 10000), 0));
             $('.stage_num').text(stage_num);
             $('.cost_ledger_num').text(cost_ledger_num);
             $('.cost_analysis_num').text(cost_analysis_num);
@@ -952,6 +972,7 @@
             option2.dataZoom[0].end = computedPosition(analysis_num);
             option2.xAxis[0].data = chart_option_name;
             option2.series[0].data = chart_option2_data;
+            option2.series[1].data = chart_option3_data;
             if (analysis_num >= 8) {
                 option2.dataZoom[0].show = true;
             } else {
@@ -959,24 +980,97 @@
             }
             myChart2_1.setOption(option2);
 
-            const option3 = myChart3_1.getOption();
-            option3.dataZoom[0].start = 0;
-            option3.dataZoom[0].end = computedPosition(analysis_num);
-            option3.xAxis[0].data = chart_option_name;
-            option3.series[0].data = chart_option3_data;
-            if (analysis_num >= 8) {
-                option3.dataZoom[0].show = true;
+            const option4_data = {
+                yearmonth: [],
+                series: [],
+                names: [],
+                totalMap: {},
+            }
+            console.log(chart_option4_data);
+            if (chart_option4_data.length > 0) {
+                const monthSet = new Set();
+                const namesSet = new Set();
+                chart_option4_data.forEach(tender => {
+                    namesSet.add(tender.name);
+                    tender.list.forEach(item => {
+                        monthSet.add(item.yearmonth);
+                    });
+                });
+                option4_data.names = [...namesSet];
+                option4_data.yearmonth = [...monthSet].sort();
+                chart_option4_data.forEach(tender => {
+                    const data = [];
+                    let total = 0; // 当前标段累计
+
+                    option4_data.yearmonth.forEach(month => {
+
+                        const item = tender.list.find(v => v.yearmonth === month);
+
+                        // const value = item ? ZhCalc.round(ZhCalc.div(item.tp, 10000), 0) : 0;
+
+                        const endtp = item ? ZhCalc.round(ZhCalc.div(item.end_tp, 10000), 0) : 0;
+
+                        total = endtp ? endtp : total;   // 累计
+
+                        data.push(total);
+                        option4_data.totalMap[month] = ZhCalc.add((option4_data.totalMap[month] || 0), total);
+                    });
+
+                    option4_data.series.push({
+                        name: tender.name,
+                        type: 'line',
+                        smooth: true,
+                        // itemStyle: {
+                        //     color: option4_default.color[index % option4_default.color.length]
+                        // },
+                        // lineStyle: {
+                        //     color: option4_default.color[index % option4_default.color.length]
+                        // },
+                        data
+                    });
+                });
+                option4_data.names.push('合计');
+                option4_data.series.push({
+                    name: '合计',
+
+                    type: 'line',
+
+                    smooth: true,
+
+                    lineStyle: {
+                        width: 4,
+                        color: '#FFD54F'
+                    },
+                    itemStyle: {
+                        color: '#FFD54F'
+                    },
+
+                    symbolSize: 8,
+
+                    data: option4_data.yearmonth.map(month => option4_data.totalMap[month] || 0)
+                })
+            }
+            console.log(option4_data);
+            const option4 = _.cloneDeep(option4_default);
+            option4.dataZoom[0].start = 0;
+            option4.dataZoom[0].end = computedPosition(option4_data.yearmonth.length);
+            option4.xAxis[0].data = option4_data.yearmonth;
+            option4.series = option4_data.series;
+            option4.legend.data = option4_data.names;
+            if (option4_data.yearmonth.length >= 8) {
+                option4.dataZoom[0].show = true;
             } else {
-                option3.dataZoom[0].show = false;
+                option4.dataZoom[0].show = false;
             }
-            myChart3_1.setOption(option3);
+            console.log(option4);
+            myChart4_1.setOption(option4, true);
 
             const option1 = myChart1_1.getOption();
             option1.series[0].data = _.filter(chart_option1_data, function (item) {
                 return item.value !== 0;
             });
             myChart1_1.setOption(option1);
-            $('#profit_tableId').css({'margin-top': 0});
+            // $('#profit_tableId').css({'margin-top': 0});
         }
         // 第一层分类选择
         $("body").on('click', '#first-category .select-cate', function () {

+ 42 - 3
app/view/datacollect/index_tz.ejs

@@ -62,7 +62,30 @@
                                 <div class="col-12 text-white pt-2 pl-3">
                                     <div class="card-big-htext">|  金额对比<span class="float-right mr-2">万元&nbsp;</span></div>
                                 </div>
-                                <div class="col-12 pb-2 text-white m-0 bg-dark" style="height: 89%;overflow: auto;">
+                                <style>
+                                    .table-scroll::-webkit-scrollbar {
+                                        width: 6px;
+                                        height: 6px;
+                                    }
+
+                                    .table-scroll::-webkit-scrollbar-track {
+                                        background: transparent;
+                                    }
+
+                                    .table-scroll::-webkit-scrollbar-thumb {
+                                        background: rgba(255,255,255,.25);
+                                        border-radius: 3px;
+                                    }
+
+                                    .table-scroll::-webkit-scrollbar-thumb:hover {
+                                        background: rgba(255,255,255,.45);
+                                    }
+
+                                    .table-scroll::-webkit-scrollbar-corner {
+                                        background: transparent;
+                                    }
+                                </style>
+                                <div class="col-12 pb-2 text-white m-0 bg-dark table-scroll" style="height: 89%;overflow: auto;">
                                     <style>
                                         .level1-table tbody tr td {
                                             padding: 6px 10px; /* 默认一般是 8~16px,可根据需要继续调小 */
@@ -98,7 +121,7 @@
                             </div>
                         </div>
                     </div>
-                    <div class="col-3 m-0 px-0 height-100">
+                    <div class="col-3 m-0 px-0 height-100" id="tender-chart">
                         <style>
                             #tender-chart .card-big-htext {
                                 display: flex;
@@ -116,7 +139,7 @@
                                 flex-shrink: 0;
                             }
                         </style>
-                        <div class="row m-0 px-0 pb-2" id="tender-chart" style="height: 23.85vh">
+                        <div class="row m-0 px-0 pb-2" style="height: 23.85vh">
                             <div class="row mx-0 w-100 height-100 bg-dark">
                                 <div class="col-12 text-white pt-2 pl-3">
                                     <div class="card-big-htext"><span id="tender1_name" data-toggle="tooltip" data-original-title="">标段1</span><span class="float-right mr-2">万元&nbsp;</span></div>
@@ -830,6 +853,10 @@
                 realData: [],
             };
             const table_data = [];
+            const totalLevel1_table_data = {
+                ctrl_tp: 0,
+                real_tp: 0,
+            };
             if (tree.children.length > 0) {
                 // 分析第一层结构,获取各个部分金额非全0的及除了回收金额层
                 const level1List = _.filter(tree.children, function (item) {
@@ -874,6 +901,9 @@
                         ]
                     });
 
+                    totalLevel1_table_data.ctrl_tp = ZhCalc.add(totalLevel1_table_data.ctrl_tp, level1.ctrl_tp ? ZhCalc.round(ZhCalc.div(level1.ctrl_tp, 10000), 0) : 0);
+                    totalLevel1_table_data.real_tp = ZhCalc.add(totalLevel1_table_data.real_tp, level1.real_tp ? ZhCalc.round(ZhCalc.div(level1.real_tp, 10000), 0) : 0);
+
                     table_data.push(`
                     <tr>
                         <td>${level1.name}</td>
@@ -887,6 +917,12 @@
             }
             table_data.push(`
                 <tr>
+                    <td>公路总造价</td>
+                    <td class="text-center">${totalLevel1_table_data.ctrl_tp}</td>
+                    <td class="text-center">${totalLevel1_table_data.real_tp}</td>
+                </tr>`);
+            table_data.push(`
+                <tr>
                     <td>设计优化率(%)</td>
                     <td class="text-center">${info.ctrl_optimize_rate}</td>
                     <td class="text-center">${info.real_optimize_rate}</td>
@@ -916,6 +952,9 @@
             $('#level1-data').html(table_data.join(''));
 
             const mbsjOption1 = mbsjChart1.getOption();
+            chart_mbsj_data.xData.push('收益金额');
+            chart_mbsj_data.ctrlData.push(info.ctrl_profit ? ZhCalc.round(ZhCalc.div(info.ctrl_profit, 10000), 0) : 0);
+            chart_mbsj_data.realData.push(info.real_profit ? ZhCalc.round(ZhCalc.div(info.real_profit, 10000), 0) : 0);
             mbsjOption1.xAxis[0].data = chart_mbsj_data.xData;
             mbsjOption1.series[0].data = chart_mbsj_data.ctrlData;
             mbsjOption1.series[1].data = chart_mbsj_data.realData;

+ 3 - 1
app/view/phase_pay/sub_menu_list.ejs

@@ -1,4 +1,6 @@
 <nav-menu title="返回" url="/tender/<%= ctx.tender.id %>/pay" tclass="text-primary" ml="1" icon="fa-chevron-left"></nav-menu>
 <nav-menu title="支付明细" url="/tender/<%= ctx.tender.id %>/pay/<%= ctx.phasePay.phase_order + '/detail'%>" ml="3" active="<%= (ctx.url.indexOf('detail') >= 0 ? 1 : -1) %>"></nav-menu>
 <nav-menu title="输出报表" url="/tender/<%= ctx.tender.id %>/pay/<%= ctx.phasePay.phase_order + '/report'%>" ml="3" active="<%= (ctx.url.indexOf('report') >= 0 ? 1 : -1) %>"></nav-menu>
-<% include ./audit_btn.ejs %>
+<% if (showAudit) { %>
+    <% include ./audit_btn.ejs %>
+<% } %>

+ 3 - 1
app/view/template/cost.ejs

@@ -13,9 +13,11 @@
                     <div id="detail-ctrl" style="display: none;">
                         <a href="javascript: void(0);" class="btn btn-sm btn-light text-primary" id="reset"> 重置</a>
                         <a href="javascript: void(0);" class="btn btn-sm btn-light text-primary" id="save"> 保存</a>
-                        <a href="javascript: void(0);" class="btn btn-sm btn-light text-primary" id="export"> 导出</a>
                         <a href="javascript: void(0);" class="btn btn-sm btn-light text-primary" id="import"> 导入</a>
                     </div>
+                    <div>
+                        <a href="javascript: void(0);" class="btn btn-sm btn-light text-primary" id="export"> 导出</a>
+                    </div>
                 </div>
             </div>
         </div>

+ 3 - 1
app/view/template/pos_calc.ejs

@@ -23,9 +23,11 @@
                     <div id="detail-ctrl" style="display: none;">
                         <a href="javascript: void(0);" class="btn btn-sm btn-light text-primary" id="reset"> 重置</a>
                         <a href="javascript: void(0);" class="btn btn-sm btn-light text-primary" id="save"> 保存</a>
-                        <a href="javascript: void(0);" class="btn btn-sm btn-light text-primary" id="export"> 导出</a>
                         <a href="javascript: void(0);" class="btn btn-sm btn-light text-primary" id="import"> 导入</a>
                     </div>
+                    <div>
+                        <a href="javascript: void(0);" class="btn btn-sm btn-light text-primary" id="export"> 导出</a>
+                    </div>
                     <div id="detail-user-info" class="ml-auto"></div>
                 </div>
             </div>