瀏覽代碼

投资总控大屏

ellisran 2 天之前
父節點
當前提交
067b3d9f6a

+ 9 - 0
app/const/project_setting.js

@@ -106,10 +106,19 @@ const daPing06Set = {
     cb_value: null,
     cb_show: [],
 };
+const daPing08Set = {
+    tenders: [
+        { id: 1, a: 0, b: 0 },
+        { id: 2, a: 0, b: 0 },
+        { id: 3, a: 0, b: 0 },
+        { id: 4, a: 0, b: 0 },
+    ],
+};
 module.exports = {
     noticeSetting: notice_setting,
     colSet,
     defaultProjectColSet,
     defaultColSet,
     daPing06Set,
+    daPing08Set,
 };

+ 118 - 67
app/controller/datacollect_controller.js

@@ -63,23 +63,33 @@ module.exports = app => {
                 // 默认坐标,否则则取办事处坐标
                 const projectData = await ctx.service.project.getDataById(ctx.session.sessionProject.id);
                 ctx.subProject.data_collect_pages = ctx.subProject.data_collect_pages ? ctx.subProject.data_collect_pages.split(',') : [];
-                // 判断是否只有'7',如果只有7,则不用获取其它数据
-                let only_cost = false;
-                if (ctx.subProject.data_collect_pages.length === 1 && ctx.subProject.data_collect_pages[0] === '7') {
-                    only_cost = true;
-                }
+                // 判断ctx.subProject.data_collect_pages如果只有7或者只有8或者只有7,8,则不用获取其它数据
+                const pages = ctx.subProject.data_collect_pages;
+                const only_cost =
+                    (pages.length === 1 && (pages[0] === '7' || pages[0] === '8')) ||
+                    (pages.length === 2 &&
+                        pages.includes('7') &&
+                        pages.includes('8'));
                 let noticeList = [];
                 if (!only_cost) {
                     noticeList = await ctx.service.noticePush.getNoticeByDataCollect(ctx.session.sessionProject.id, tenderidList);
                 }
                 if (ctx.params.index) {
                     ctx.subProject.data_collect = parseInt(ctx.params.index);
+                    ctx.session.sessionSubProj = {
+                        data_collect: ctx.subProject.data_collect,
+                    };
+                } else {
+                    ctx.session.sessionSubProj = {
+                        data_collect: ctx.subProject.data_collect,
+                    };
                 }
-                const is_cost = ctx.subProject.data_collect_pages.includes('7') && ctx.subProject.data_collect === 7;
+                // const is_cost = ctx.subProject.data_collect_pages.includes('7') && ctx.subProject.data_collect === 7;
                 const is_dz2 = ['P0505', 'P0506', 'P1201', 'P1202', 'GY18Y', 'GYJJ1', 'P1103', 'KLG25', 'I2U5B', 'SEN48'].indexOf(ctx.session.sessionProject.code) !== -1
                     && ctx.subProject.data_collect_pages.includes('6') && ctx.subProject.data_collect === 6;
-                const is_dz3 = ctx.subProject.data_collect_pages.includes('8') && ctx.subProject.data_collect === 8;
-                const shj_url = 'http://112.74.42.187:3300/#/project/viewer?projectId=b03i54j0j8ai';
+                const is_dzcb = ['P0505', 'P0506', 'P1201', 'P1202', 'GY18Y', 'Y3T2Q'].indexOf(ctx.session.sessionProject.code) !== -1 && ctx.subProject.data_collect_pages.includes('7') && ctx.subProject.data_collect === 7;// 成本管理定制大屏
+                const is_dztz = ['P0505', 'P0506', 'P1201', 'P1202', 'GY18Y', 'Y3T2Q'].indexOf(ctx.session.sessionProject.code) !== -1 && ctx.subProject.data_collect_pages.includes('8') && ctx.subProject.data_collect === 8;// 投资总控定制大屏
+                // const shj_url = 'http://112.74.42.187:3300/#/project/viewer?projectId=b03i54j0j8ai';
                 const renderData = {
                     projectData,
                     noticeList,
@@ -93,10 +103,12 @@ module.exports = app => {
                     acAdvance: auditConst.advance,
                     pushType: auditConst.pushType,
                     jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.datacollect.index),
-                    shj_url,
+                    // shj_url,
                 };
-                if (is_cost) {
+                if (is_dzcb) {
                     await this.layout('datacollect/index_cost.ejs', renderData);
+                } else if (is_dztz) {
+                    await this.layout('datacollect/index_tz.ejs', renderData);
                 } else if (is_dz2) {
                     // 判断并更新common_json
                     if (!ctx.subProject.common_json) {
@@ -111,8 +123,8 @@ module.exports = app => {
                     }
                     renderData.dpCategory = dpCategory;
                     await this.layout('datacollect/index4GY18Y.ejs', renderData);
-                } else if (is_dz3) {
-                    ctx.redirect(shj_url);
+                // } else if (is_dz3) {
+                //     ctx.redirect(shj_url);
                 } else {
                     await this.layout('datacollect/index.ejs', renderData);
                 }
@@ -128,67 +140,66 @@ module.exports = app => {
                 const responseData = { err: 0, msg: '', data: {} };
                 // const tenderidList = [];
                 // const noticeList = await ctx.service.noticePush.getNoticeByDataCollect(ctx.session.sessionProject.id, tenderidList);
-                const dcTenders = await ctx.service.datacollectTender.getList(ctx.session.sessionProject.id, ctx.subProject.id);
-                const noTids = ctx.app._.map(dcTenders, 'tid');
-                let tenderList = await ctx.service.tender.getList('', null, 1);
-                // let tenderList = await this.ctx.service.tender.getBuildList('', null, 1);
-                tenderList = ctx.app._.filter(tenderList, function(item) {
-                    return ctx.app._.indexOf(noTids, item.id) === -1;
-                });
-                // 判断是否只有'7',如果只有7,则不用获取其它数据
-                let only_cost = false;
-                if (ctx.subProject.data_collect_pages.length === 1 && ctx.subProject.data_collect_pages[0] === '7') {
-                    only_cost = true;
-                }
-                const have_cost = ctx.subProject.data_collect_pages.includes('7');
+                const have_cost = ctx.session.sessionSubProj.data_collect === 7 || ctx.session.sessionSubProj.data_collect === 8;
                 const thisMonth = new Date();
                 const [startMonth, endMonth] = ctx.helper.getStartEndMonth(thisMonth);
                 // 统计方法总时长
                 // let sumStageByDataCollectTime = 0;
-                for (const t of tenderList) {
-                    // 用标段管理的方法获取t数据
-                    if (!only_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);
+                const only_tz = ctx.session.sessionSubProj.data_collect === 8;
+                if (!only_tz) {
+                    const dcTenders = await ctx.service.datacollectTender.getList(ctx.session.sessionProject.id, ctx.subProject.id);
+                    const noTids = ctx.app._.map(dcTenders, 'tid');
+                    let tenderList = await ctx.service.tender.getList('', null, 1);
+                    // let tenderList = await this.ctx.service.tender.getBuildList('', null, 1);
+                    tenderList = ctx.app._.filter(tenderList, function(item) {
+                        return ctx.app._.indexOf(noTids, item.id) === -1;
+                    });
+                    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);
+                                }
                             }
+                            t.month_stage = month_stage;
+                        }
+                        if (have_cost) {
+                            // 取最新已审批完成的成本管理-成本分析期数据
+                            t.cost_analysis = await ctx.service.costStage.getLastCheckedStage(t.id, 'analysis');
+                            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');
+                            t.cost_book_num = await ctx.service.costStage.getNumByChecked(t.id, 'book');
                         }
-                        t.month_stage = month_stage;
-                    }
-                    if (have_cost) {
-                        // 取最新已审批完成的成本管理-成本分析期数据
-                        t.cost_analysis = await ctx.service.costStage.getLastCheckedStage(t.id, 'analysis');
-                        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');
-                        t.cost_book_num = await ctx.service.costStage.getNumByChecked(t.id, 'book');
                     }
+                    responseData.data.tenderList = tenderList;
                 }
                 if (have_cost) {
                     const data = {};
@@ -206,10 +217,50 @@ module.exports = app => {
                         data.ctrl = await ctx.service.budgetCtrl.getData(budget.id);
                         data.real = await ctx.service.budgetReal.getData(budget.id);
                     }
+                    data.info = budget;
                     responseData.data.budget = data;
                 }
+                if (only_tz) {
+                    const commonJson = ctx.subProject.common_json ? JSON.parse(ctx.subProject.common_json) : null;
+                    const daping08Set = commonJson && commonJson.daPing08_set ? commonJson.daPing08_set : ctx.helper._.cloneDeep(projectSettingConst.daPing08Set);
+                    const tenderList = {
+                        1: {
+                            a: null,
+                            b: null,
+                            // name: '',
+                            // contract_price: 0,
+                            // end_gather_tp: 0,
+                            // end_profit: 0,
+                        },
+                        2: {
+                            a: null,
+                            b: null,
+                        },
+                        3: {
+                            a: null,
+                            b: null,
+                        },
+                        4: {
+                            a: null,
+                            b: null,
+                        },
+                    };
+                    for (const t of daping08Set.tenders) {
+                        tenderList[t.id] = {};
+                        const tendera = t.a ? await ctx.service.tender.getDataById(t.a) : null;
+                        if (tendera) {
+                            await this.ctx.service.tenderCache.loadTenderCache(tendera, '');
+                            tenderList[t.id].a = tendera;
+                            const tenderb = t.b ? await ctx.service.tender.getDataById(t.b) : null;
+                            if (tenderb) {
+                                await this.ctx.service.tenderCache.loadTenderCache(tenderb, '');
+                                tenderList[t.id].b = tenderb;
+                            }
+                        }
+                    }
+                    responseData.data.tenderList = tenderList;
+                }
                 // const tenderMapList = await ctx.service.tenderMap.getAllDataByCondition({ where: { tid: tender.id } });
-                responseData.data.tenderList = tenderList;
                 ctx.body = responseData;
             } catch (err) {
                 this.log(err);

+ 11 - 1
app/controller/sub_proj_setting_controller.js

@@ -444,6 +444,8 @@ module.exports = app => {
                 const tenders = await ctx.service.tender.getList('', null, 1);
                 const dcTenders = await ctx.service.datacollectTender.getList(ctx.subProject.project_id, ctx.subProject.id);
                 const is_dz2 = ['P0505', 'P0506', 'P1201', 'P1202', 'GY18Y', 'GYJJ1', 'P1103', 'KLG25', 'I2U5B', 'SEN48'].indexOf(ctx.session.sessionProject.code) !== -1 ? 6 : false;
+                const is_dzcb = ['P0505', 'P0506', 'P1201', 'P1202', 'GY18Y', 'Y3T2Q'].indexOf(ctx.session.sessionProject.code) !== -1 ? 7 : false;// 成本管理定制大屏
+                const is_dztz = ['P0505', 'P0506', 'P1201', 'P1202', 'GY18Y', 'Y3T2Q'].indexOf(ctx.session.sessionProject.code) !== -1 ? 8 : false;// 投资总控定制大屏
                 const renderData = {
                     dataCollectAudits,
                     accountList,
@@ -453,7 +455,8 @@ module.exports = app => {
                     dcTenders,
                     is_dz1: ['P0505', 'MI22U'].indexOf(ctx.session.sessionProject.code) !== -1 ? 5 : false,
                     is_dz2,
-                    is_dz3: 8,
+                    is_dzcb,
+                    is_dztz,
                     selfCategoryLevel: await ctx.service.projectAccount.getSelfCategoryLevel(this.ctx.session.sessionUser.accountId),
                 };
                 if (is_dz2) {
@@ -465,6 +468,10 @@ module.exports = app => {
                     const commonJson = ctx.subProject.common_json ? JSON.parse(ctx.subProject.common_json) : null;
                     renderData.daPing06Set = commonJson && commonJson.daPing06_set ? commonJson.daPing06_set : ctx.helper._.cloneDeep(projectSettingConst.daPing06Set);
                 }
+                if (is_dztz) {
+                    const commonJson = ctx.subProject.common_json ? JSON.parse(ctx.subProject.common_json) : null;
+                    renderData.daPing08Set = commonJson && commonJson.daPing08_set ? commonJson.daPing08_set : ctx.helper._.cloneDeep(projectSettingConst.daPing08Set);
+                }
                 await this.layout('sp_setting/datacollect.ejs', renderData, 'sp_setting/datacollect_modal.ejs');
             } catch (error) {
                 ctx.log(error);
@@ -530,6 +537,9 @@ module.exports = app => {
                     case 'save-dp06':
                         responseData.data = await ctx.service.subProject.saveCommonJson(ctx.subProject.id, 'daPing06_set', data.daPing06Set);
                         break;
+                    case 'save-dp08':
+                        responseData.data = await ctx.service.subProject.saveCommonJson(ctx.subProject.id, 'daPing08_set', data.daPing08Set);
+                        break;
                     default:
                         throw '参数有误';
                 }

二進制
app/public/images/juecedaping08.png


+ 2 - 4
app/view/datacollect/index.ejs

@@ -43,10 +43,8 @@
                     <button type="button" class="btn btn-sm btn-outline-dark text-white dropdown-toggle" data-toggle="dropdown" id="zhankai">决策大屏<span><%- ctx.subProject.data_collect %></span></button>
                     <div class="dropdown-menu" aria-labelledby="zhankai">
                         <% for (const i of ctx.subProject.data_collect_pages) { %>
-                        <% if (['6', '7'].includes(i)) { %>
-                            <a class="dropdown-item" href="/sp/<%- ctx.subProject.id %>/datacollect/index/<%- i %>">决策大屏<%- i %></a>
-                        <% } else if (['8'].includes(i)) { %>
-                            <a class="dropdown-item" target="_blank" href="<%- shj_url %>">决策大屏<%- i %></a>
+                        <% if (['6', '7', '8'].includes(i)) { %>
+                            <a class="dropdown-item" href="/sp/<%- ctx.subProject.id %>/datacollect/index/<%- i %>"><% if (i === '7') { %>成本管理<% } else if (i === '8')  { %>投资总控<% } else { %>决策大屏<%- i %><% } %></a>
                         <% } else { %>
                             <a class="dropdown-item change-collect" href="javascript:void(0)" data-collect="<%- i %>">决策大屏<%- i %></a>
                         <% } %>

+ 1 - 5
app/view/datacollect/index4GY18Y.ejs

@@ -61,11 +61,7 @@
                     <button type="button" class="btn btn-sm btn-outline-dark text-white dropdown-toggle" data-toggle="dropdown" id="zhankai">决策大屏<span>6</span></button>
                     <div class="dropdown-menu" aria-labelledby="zhankai">
                         <% for (const i of ctx.subProject.data_collect_pages) { %>
-                            <% if (['8'].includes(i)) { %>
-                                <a class="dropdown-item" target="_blank" href="<%- shj_url %>">决策大屏<%- i %></a>
-                            <% } else { %>
-                                <a class="dropdown-item" href="/sp/<%- ctx.subProject.id %>/datacollect/index/<%- i %>">决策大屏<%- i %></a>
-                            <% } %>
+                            <a class="dropdown-item" href="/sp/<%- ctx.subProject.id %>/datacollect/index/<%- i %>"><% if (i === '7') { %>成本管理<% } else if (i === '8')  { %>投资总控<% } else { %>决策大屏<%- i %><% } %></a>
                         <% } %>
                     </div>
                 </div>

+ 2 - 6
app/view/datacollect/index_cost.ejs

@@ -40,14 +40,10 @@
             <div>
                 <a href="javascript:void(0)"  title="全屏显示" id="showFull" class="text-white"><i class="fa fa-arrows-alt"></i></a>
                 <div class="btn-group">
-                    <button type="button" class="btn btn-sm btn-outline-dark text-white dropdown-toggle" data-toggle="dropdown" id="zhankai">决策大屏<span>7</span></button>
+                    <button type="button" class="btn btn-sm btn-outline-dark text-white dropdown-toggle" data-toggle="dropdown" id="zhankai">成本管理</button>
                     <div class="dropdown-menu" aria-labelledby="zhankai">
                         <% for (const i of ctx.subProject.data_collect_pages) { %>
-                            <% if (['8'].includes(i)) { %>
-                                <a class="dropdown-item" target="_blank" href="<%- shj_url %>">决策大屏<%- i %></a>
-                            <% } else { %>
-                                <a class="dropdown-item" href="/sp/<%- ctx.subProject.id %>/datacollect/index/<%- i %>">决策大屏<%- i %></a>
-                            <% } %>
+                            <a class="dropdown-item" href="/sp/<%- ctx.subProject.id %>/datacollect/index/<%- i %>"><% if (i === '7') { %>成本管理<% } else if (i === '8')  { %>投资总控<% } else { %>决策大屏<%- i %><% } %></a>
                         <% } %>
                     </div>
                 </div>

+ 984 - 0
app/view/datacollect/index_tz.ejs

@@ -0,0 +1,984 @@
+<link href="/public/css/bootstrap/bootstrap-colorpicker.min.css" rel="stylesheet">
+<div class="panel-content">
+    <div class="panel-title fluid border-top-0" style="background:linear-gradient(#ccc, '2%', '#ffffff') !important">
+        <div class="title-main d-flex justify-content-between">
+            <div class="d-inline-block mr-2"></div>
+            <div>
+                <a href="javascript:void(0)"  title="全屏显示" id="showFull"><i class="fa fa-arrows-alt"></i></a>
+                <div class="btn-group">
+                    <button type="button" class="btn btn-sm dropdown-toggle" data-toggle="dropdown" id="zhankai">投资总控</button>
+                    <div class="dropdown-menu" aria-labelledby="zhankai">
+                        <% for (const i of ctx.subProject.data_collect_pages) { %>
+                            <a class="dropdown-item" href="/sp/<%- ctx.subProject.id %>/datacollect/index/<%- i %>"><% if (i === '7') { %>成本管理<% } else if (i === '8')  { %>投资总控<% } else { %>决策大屏<%- i %><% } %></a>
+                        <% } %>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+    <div class="content-wrap" id="big-data">
+        <div style="height: 30px;background-color: #d8d8d8; display: none" id="exitfull-div">
+            <div class="title-main d-flex">
+                <div class="ml-auto">
+                    <div class="dropdown d-flex float-left mt-1 mr-2">
+                        <button id="exitFull" class="btn btn-sm btn-secondary ml-auto">退出全屏</button>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <div class="c-body" style="background-color: #d8d8d8 !important;">
+            <div class="flex-content">
+                <div class="row m-2">
+                    <div class="col-9 m-0 px-0 height-100">
+                        <div class="row m-0 px-0 mb-2 mr-2" style="height: 31vh;background-color: #031c59;">
+                            <div class="col-12 text-white pt-2 pl-3">
+                                <div class="card-big-htext">|  公路总造价占比</div>
+                            </div>
+                            <div class="col-12 row ml-0 mr-2 px-0" style="height: 88%">
+                                <div class="col-3 m-0 px-0 height-100">
+                                    <div class="guchart" id="guchart" style="height: 100%; width: 100%;"></div>
+                                </div>
+                                <div class="col-3 m-0 px-0 height-100">
+                                    <div class="gaichart" id="gaichart" style="height: 100%; width: 100%;"></div>
+                                </div>
+                                <div class="col-3 m-0 px-0 height-100">
+                                    <div class="yuchart" id="yuchart" style="height: 100%; width: 100%;"></div>
+                                </div>
+                                <div class="col-3 m-0 px-0 height-100">
+                                    <div class="ctrlchart" id="ctrlchart" style="height: 100%; width: 100%;"></div>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="row m-0 px-0 mb-2 mr-2" style="height: 31vh;background-color: #031c59;">
+                            <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="quanchart" id="quanchart" style="height: 100%; width: 100%;"></div>
+                            </div>
+                        </div>
+                        <div class="row m-0 px-0 mb-2 mr-2" style="height: 31vh;">
+                            <div class="col-5 px-0 pb-1 height-100" style="background-color: #031c59;">
+                                <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" style="height: 89%;background-color: #031c59;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: 27px;border-bottom: 1px solid rgba(255,255,255,0.2);background-color: #122b69;">
+                                            <tr class="text-center">
+                                                <th>分类</th>
+                                                <th>控制目标</th>
+                                                <th>实际投资</th>
+                                            </tr>
+                                        </thead>
+                                        <tbody id="level1-data">
+                                        </tbody>
+                                    </table>
+                                </div>
+                            </div>
+                            <div class="col-7 m-0 px-0 height-100">
+                                <div class="row ml-2 mr-0 mb-2 height-100" style="background-color: #031c59;">
+                                    <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="mbsjchart" id="mbsjchart" style="height: 100%; width: 100%;"></div>
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                    <div class="col-3 m-0 px-0 height-100">
+                        <div class="row m-0 px-0 pb-2" style="height: 23.85vh">
+                            <div class="row mx-0 w-100 height-100" style="background-color: #031c59;">
+                                <div class="col-12 text-white pt-2 pl-3">
+                                    <div class="card-big-htext" id="tender1_name">标段1</div>
+                                </div>
+                                <div class="col-12 m-0" style="height: 80%">
+                                    <div class="tender1chart" id="tender1chart" style="height: 100%; width: 100%;"></div>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="row m-0 px-0 pb-2" style="height: 23.85vh">
+                            <div class="row mx-0 w-100 height-100" style="background-color: #031c59;">
+                                <div class="col-12 text-white pt-2 pl-3">
+                                    <div class="card-big-htext" id="tender2_name">标段2</div>
+                                </div>
+                                <div class="col-12 m-0" style="height: 80%">
+                                    <div class="tender2chart" id="tender2chart" style="height: 100%; width: 100%;"></div>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="row m-0 px-0 pb-2" style="height: 23.85vh">
+                            <div class="row mx-0 w-100 height-100" style="background-color: #031c59;">
+                                <div class="col-12 text-white pt-2 pl-3">
+                                    <div class="card-big-htext" id="tender3_name">标段3</div>
+                                </div>
+                                <div class="col-12 m-0" style="height: 80%">
+                                    <div class="tender3chart" id="tender3chart" style="height: 100%; width: 100%;"></div>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="row m-0 pb-2 px-0" style="height: 23.85vh">
+                            <div class="row mx-0 w-100 height-100" style="background-color: #031c59;">
+                                <div class="col-12 text-white pt-2 pl-3">
+                                    <div class="card-big-htext" id="tender4_name">标段4</div>
+                                </div>
+                                <div class="col-12 m-0" style="height: 80%">
+                                    <div class="tender4chart" id="tender4chart" style="height: 100%; width: 100%;"></div>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+<script src="/public/js/path_tree.js"></script>
+<script src="/public/js/shares/tenders2tree.js"></script>
+<script src="/public/js/datacollect_scroll.js"></script>
+<script type="text/javascript">  autoFlashHeight();</script>
+<script type="text/javascript">
+    // 利润排名占比饼图表
+    const guchart = document.getElementsByClassName('guchart');
+    const gaichart = document.getElementsByClassName('gaichart');
+    const yuchart = document.getElementsByClassName('yuchart');
+    const ctrlchart = document.getElementsByClassName('ctrlchart');
+    const guOption = {
+        tooltip : {
+            trigger: 'item',
+            formatter: "{a} <br/>{b} : {c} ({d}%)",
+            // 当前鼠标位置
+            position: 'right',
+        },
+        title: {
+            text: '投资估算',
+            left: 'center',
+            bottom: '5%',
+            textStyle: {
+                fontSize: 14,
+                fontWeight: 'normal',
+                color: '#fff',
+            }
+        },
+        color: ['#009DFF', '#22E4FF',   '#3BFFD0', '#04E38A',
+            '#00FFBB', '#9DFF86', '#6FFFEC', '#5AD2FF',
+            '#00BFFF', '#66FFB2', '#29FFC9', '#7BE7FF',
+            '#1EE8B6', '#8CF7FF',
+        ],
+        backgroundColor: '#031c59',
+        series: [
+            {
+                name: '金额',
+                type: 'pie',
+                radius: '52%',
+                center: ['50%', '42%'],
+                // formatter: function(name){
+                //     return name.length>10?name.substr(0,10)+"...":name;
+                // },
+                data: [],
+                emphasis: {
+                    itemStyle: {
+                        shadowBlur: 10,
+                        shadowOffsetX: 0,
+                        shadowColor: 'rgba(0, 0, 0, 0.5)'
+                    }
+                }
+            }
+        ]
+    };
+    const guChart1 = echarts.init(guchart[0]);
+    const gaiChart1 = echarts.init(gaichart[0]);
+    const yuChart1 = echarts.init(yuchart[0]);
+    const ctrlChart1 = echarts.init(ctrlchart[0]);
+    guChart1.setOption(guOption);
+    const gaiOption = _.cloneDeep(guOption);
+    gaiOption.title.text = '设计概算';
+    gaiChart1.setOption(gaiOption);
+    const yuOption = _.cloneDeep(guOption);
+    yuOption.title.text = '施工图预算';
+    yuChart1.setOption(yuOption);
+    const ctrlOption = _.cloneDeep(guOption);
+    ctrlOption.title.text = '控制目标';
+    ctrlChart1.setOption(ctrlOption);
+    // 利润统计状图表
+    const quanoption = {
+        title: {},
+        legend: {
+            type: 'scroll', // 超过一行可滚动
+            top: 10,
+            textStyle: {
+                color: '#fff',
+                overflow: 'truncate'
+            }
+        },
+        color: ['#009DFF', '#22E4FF', '#3BFFD0', '#04E38A',
+            '#00FFBB', '#9DFF86', '#6FFFEC', '#5AD2FF',
+            '#00BFFF', '#66FFB2', '#29FFC9', '#7BE7FF',
+            '#1EE8B6', '#8CF7FF',
+        ],
+        backgroundColor: '#031c59',
+        tooltip: {
+            trigger: 'axis',
+            axisPointer: {            // 坐标轴指示器,坐标轴触发有效
+                type: 'shadow'        // 默认为直线,可选为:'line' | 'shadow'
+            },
+        },
+        grid: {
+            left: '3%',
+            right: '5%',
+            bottom: '3%',
+            containLabel: true
+        },
+        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;
+                    }
+                }
+            }
+        ],
+        yAxis: [
+            {
+                type: 'value',
+                // name:'金额',
+                position: 'left',
+                axisLabel : {
+                    color: '#fff',
+                    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;
+                    }
+                },
+                splitLine: {
+                    show: true,
+                    lineStyle: {
+                        color: 'rgba(255,255,255,0.5)',
+                        type: 'dashed',   // 虚线
+                        width: 1
+                    }
+                }
+            },
+        ],
+        series: []
+    };
+    const quanchart = document.getElementsByClassName('quanchart');
+    const quanChart1 = echarts.init(quanchart[0]);
+    quanChart1.setOption(quanoption);
+
+    const mbsjoption = {
+        title: {},
+        legend: {
+            type: 'scroll', // 超过一行可滚动
+            top: 10,
+            textStyle: {
+                color: '#fff',
+                overflow: 'truncate'
+            }
+        },
+        color: ['#009DFF', '#22E4FF'],
+        backgroundColor: '#031c59',
+        tooltip: {
+            trigger: 'axis',
+            axisPointer: {            // 坐标轴指示器,坐标轴触发有效
+                type: 'shadow'        // 默认为直线,可选为:'line' | 'shadow'
+            },
+        },
+        grid: {
+            left: '3%',
+            right: '5%',
+            bottom: '3%',
+            containLabel: true
+        },
+        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;
+                    }
+                }
+            }
+        ],
+        yAxis: [
+            {
+                type: 'value',
+                // name:'金额',
+                position: 'left',
+                axisLabel : {
+                    color: '#fff',
+                    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;
+                    }
+                },
+                splitLine: {
+                    show: true,
+                    lineStyle: {
+                        color: 'rgba(255,255,255,0.5)',
+                        type: 'dashed',   // 虚线
+                        width: 1
+                    }
+                }
+            },
+        ],
+        series: [
+            {
+                name: '控制目标',
+                type: 'bar',
+                data: [],
+                // barWidth: 18,
+                barGap: '0%',
+                // itemStyle: {
+                //     borderRadius: [4, 4, 0, 0]
+                // }
+            },
+            {
+                name: '实际投资',
+                type: 'bar',
+                data: [],
+                // barWidth: 18,
+                barGap: '0%',
+                // itemStyle: {
+                //     borderRadius: [4, 4, 0, 0]
+                // }
+            }
+        ]
+    };
+    const mbsjchart = document.getElementsByClassName('mbsjchart');
+    const mbsjChart1 = echarts.init(mbsjchart[0]);
+    mbsjChart1.setOption(mbsjoption);
+
+
+    const tenderoption = {
+        title: {},
+        legend: {
+            type: 'scroll', // 超过一行可滚动
+            top: 10,
+            textStyle: {
+                color: '#fff',
+                overflow: 'truncate'
+            }
+        },
+        color: ['#009DFF', '#22E4FF', '#3BFFD0'],
+        backgroundColor: '#031c59',
+        tooltip: {
+            trigger: 'axis',
+            axisPointer: {            // 坐标轴指示器,坐标轴触发有效
+                type: 'shadow'        // 默认为直线,可选为:'line' | 'shadow'
+            },
+        },
+        grid: {
+            left: '3%',
+            right: '5%',
+            bottom: '3%',
+            containLabel: true
+        },
+        xAxis: [
+            {
+                type: 'category',
+                data: [''],
+                axisLabel: {
+                    show: false,
+                    interval: 0,
+                    textStyle: {
+                        color: "#fff",
+                        fontSize: 14
+                    },
+                    formatter: function(value) {
+                        var res = value;
+                        if(res.length > 6) {
+                            res = res.substring(0, 5) + "..";
+                        }
+                        return res;
+                    }
+                }
+            }
+        ],
+        yAxis: [
+            {
+                type: 'value',
+                // name:'金额',
+                position: 'left',
+                axisLabel : {
+                    color: '#fff',
+                    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;
+                    }
+                },
+                splitLine: {
+                    show: true,
+                    lineStyle: {
+                        color: 'rgba(255,255,255,0.5)',
+                        type: 'dashed',   // 虚线
+                        width: 1
+                    }
+                }
+            },
+        ],
+        series: [
+            {
+                name: '合同额',
+                type: 'bar',
+                data: [],
+                // barWidth: 30,
+                barGap: '0%',
+                // itemStyle: {
+                //     borderRadius: [4, 4, 0, 0]
+                // }
+            },
+            {
+                name: '计价',
+                type: 'bar',
+                data: [],
+                // barWidth: 30,
+                barGap: '0%',
+                // itemStyle: {
+                //     borderRadius: [4, 4, 0, 0]
+                // }
+            },
+            {
+                name: '利润',
+                type: 'bar',
+                data: [],
+                // barWidth: 30,
+                barGap: '0%',
+                // itemStyle: {
+                //     borderRadius: [4, 4, 0, 0]
+                // }
+            }
+        ]
+    };
+    const tenderChart = {
+        chart1: null,
+        chart2: null,
+        chart3: null,
+        chart4: null,
+    }
+    for (let i = 1; i <= 4; i++) {
+        tenderChart['chart' + i] = echarts.init(document.getElementsByClassName('tender' + i + 'chart')[0]);
+        tenderChart['chart' + i].setOption(tenderoption);
+    }
+
+    function echartsReset() {
+        guChart1.resize();
+        gaiChart1.resize();
+        yuChart1.resize();
+        ctrlChart1.resize();
+        quanChart1.resize();
+        mbsjChart1.resize();
+        for (let i = 1; i <= 4; i++) {
+            tenderChart['chart' + i].resize();
+        }
+    }
+    $(function () {
+        $('#showFull').click(function () {
+            const full=document.getElementById("big-data");
+            launchIntoFullscreen(full);
+        });
+        $('#exitFull').click(function () {
+            exitFullscreen();
+        })
+    })
+    let resizeTimer = null;
+    $(window).bind('resize', function () {
+        if (resizeTimer) clearTimeout(resizeTimer);
+        resizeTimer = setTimeout(function () {
+            echartsReset();
+            $(".tableid_").find('th').each(function(i) {
+                $(this).css('width', $('#tableId').find('th:eq(' + i + ')').innerWidth());
+            });
+        }, 500);
+    })
+
+    // 数据全屏
+    function launchIntoFullscreen(element) {
+        if(element.requestFullscreen){
+            element.requestFullscreen();
+        }
+        else if(element.mozRequestFullScreen) {
+            element.mozRequestFullScreen();
+        }
+        else if(element.webkitRequestFullscreen) {
+            element.webkitRequestFullscreen();
+        }
+        else if(element.msRequestFullscreen) {
+            element.msRequestFullscreen();
+        }
+    }
+    function exitFullscreen() {
+        if(document.exitFullscreen) {
+            document.exitFullscreen();
+        } else if(document.mozCancelFullScreen) {
+            document.mozCancelFullScreen();
+        } else if(document.webkitExitFullscreen) {
+            document.webkitExitFullscreen();
+        }
+    }
+    document.addEventListener("fullscreenchange", function (event) {
+        if (document.fullscreenElement) {
+            $('#exitfull-div').show();
+            $('#showFull').hide();
+        } else {
+            $('#exitfull-div').hide();
+            $('#showFull').show();
+        }
+    });
+    const originDataCollect = parseInt('<%- ctx.subProject.data_collect %>');
+    $(function () {
+        const compareObj = {
+            curFinalId() {
+                return this.finalInfo ? this.finalInfo.id : undefined;
+            },
+            expand(tree, tag) {
+                switch (tag) {
+                    case "1":
+                    case "2":
+                    case "3":
+                    case "4":
+                    case "5":
+                        tree.expandByLevel(parseInt(tag));
+                        break;
+                    case "last":
+                        tree.expandByCustom(() => { return true; });
+                        break;
+                }
+            },
+            calcStackedBar(tree) {
+                const calcField = this.stackedBarField;
+                const calcFieldColor = { 'gu_tp': '#657798', 'gai_tp': '#EE6666', 'yu_tp': '#74CBED', 'total_price': '#FAC858', 'final_tp': '#62DAAB' };
+                const calcFieldCaption = { 'gu_tp': '估算', 'gai_tp': '概算', 'yu_tp': '预算', 'total_price': '台账', 'final_tp': '决算' };
+                const calc = function(node, base){
+                    // const parent = tree.getParent(node);
+                    // if (!parent) {
+                    //     base = 0;
+                    //     for (const cf of calcField) {
+                    //         base = Math.max(node[cf], base);
+                    //     }
+                    // }
+                    node.stackedBar = [];
+                    node.stackedBarTips = [];
+                    for (const cf of calcField) {
+                        node.stackedBar.push({color: calcFieldColor[cf], percent: ZhCalc.div(node[cf], base), field: cf});
+                        node.stackedBarTips.push(`${calcFieldCaption[cf]}: ${node[cf] || 0}`);
+                    }
+                    if (node.children) {
+                        for (const child of node.children) {
+                            calc(child, base);
+                        }
+                    }
+                };
+                let commonBase = 0;
+                tree.children.forEach(x => {
+                    for (const cf of calcField) {
+                        commonBase = Math.max(x[cf] || 0, commonBase);
+                    }
+                });
+                for (const child of tree.children) {
+                    calc(child, commonBase);
+                }
+            },
+            loadBudgetData(result) {
+                const compareTree = createNewPathTree('final', {
+                    id: 'id',
+                    pid: 'pid',
+                    order: 'order',
+                    level: 'level',
+                    rootId: -1,
+                });
+                const setting = { id: 'tree_id', pid: 'tree_pid', order: 'order', level: 'level', rootId: -1, calcFields: ['total_price'] };
+                const guTree = createNewPathTree('ledger', setting);
+                guTree.loadDatas(result.gu);
+                treeCalc.calculateAll(guTree);
+                compareTree.loadTree(guTree, function (cur, source) {
+                    cur.base = true;
+                    cur.gu_dgn_qty1 = ZhCalc.add(cur.gu_dgn_qty1, source.dgn_qty1);
+                    cur.gu_dgn_qty2 = ZhCalc.add(cur.gu_dgn_qty2, source.dgn_qty2);
+                    cur.gu_tp = ZhCalc.add(cur.gu_tp, source.total_price);
+                });
+                const gaiTree = createNewPathTree('ledger', setting);
+                gaiTree.loadDatas(result.gai);
+                treeCalc.calculateAll(gaiTree);
+                compareTree.loadTree(gaiTree, function (cur, source) {
+                    cur.base = true;
+                    cur.gai_dgn_qty1 = ZhCalc.add(cur.gai_dgn_qty1, source.dgn_qty1);
+                    cur.gai_dgn_qty2 = ZhCalc.add(cur.gai_dgn_qty2, source.dgn_qty2);
+                    cur.gai_tp = ZhCalc.add(cur.gai_tp, source.total_price);
+                });
+                const yuTree = createNewPathTree('ledger', setting);
+                yuTree.loadDatas(result.yu);
+                treeCalc.calculateAll(yuTree);
+                compareTree.loadTree(yuTree, function (cur, source) {
+                    cur.base = true;
+                    cur.yu_dgn_qty1 = ZhCalc.add(cur.yu_dgn_qty1, source.dgn_qty1);
+                    cur.yu_dgn_qty2 = ZhCalc.add(cur.yu_dgn_qty2, source.dgn_qty2);
+                    cur.yu_tp = ZhCalc.add(cur.yu_tp, source.total_price);
+                });
+                compareTree.afterLoad(node => {
+                    node.gu_dgn_price = ZhCalc.div(node.gu_tp, node.gu_dgn_qty1, 2);
+                    node.gu_dgn_qty = node.gu_dgn_qty1
+                        ? (node.gu_dgn_qty2 ? node.gu_dgn_qty1 + '/' + node.gu_dgn_qty2 : node.gu_dgn_qty1)
+                        : (node.gu_dgn_qty2 ? '/' + node.gu_dgn_qty2 : '');
+                    node.gai_dgn_price = ZhCalc.div(node.gai_tp, node.gai_dgn_qty1, 2);
+                    node.gai_dgn_qty = node.gai_dgn_qty1
+                        ? (node.gai_dgn_qty2 ? node.gai_dgn_qty1 + '/' + node.gai_dgn_qty2 : node.gai_dgn_qty1)
+                        : (node.gai_dgn_qty2 ? '/' + node.gai_dgn_qty2 : '');
+                    node.yu_dgn_price = ZhCalc.div(node.yu_tp, node.yu_dgn_qty1, 2);
+                    node.yu_dgn_qty = node.yu_dgn_qty1
+                        ? (node.yu_dgn_qty2 ? node.yu_dgn_qty1 + '/' + node.yu_dgn_qty2 : node.yu_dgn_qty1)
+                        : (node.yu_dgn_qty2 ? '/' + node.yu_dgn_qty2 : '');
+                });
+                compareTree.resortChildrenByCustom(function (x, y) {
+                    const iCode = compareCode(x.code, y.code);
+                    if (iCode) return iCode;
+                    if (!x.name) return -1;
+                    if (!y.name) return 1;
+                    return x.name.localeCompare(y.name);
+                });
+                const expandTag = getLocalCache('revise-compare-level');
+                if (expandTag) compareObj.expand(compareTree, expandTag);
+                this.calcStackedBar(compareTree);
+                // console.log(compareTree);
+                setPageData(compareTree, result.info);
+            },
+            loadFinalData(result, msg) {
+                if (msg) toastr.warning(msg);
+                this.finalInfo = result.finalInfo;
+                const finalTree = createNewPathTree('ledger', {
+                    id: 'tree_id',
+                    pid: 'tree_pid',
+                    order: 'order',
+                    level: 'level',
+                    rootId: -1,
+                });
+                finalTree.loadDatas(result.final);
+                const expandTag = getLocalCache('revise-compare-level');
+                if (expandTag) compareObj.expand(finalTree, expandTag);
+                this.calcStackedBar(finalTree);
+                // console.log(finalTree);
+                setPageData(finalTree, result.info);
+
+            },
+            loadCacheData(){
+                const stackedBarCache = 'gai_tp,total_price,final_tp';
+                this.setStackedBarField(stackedBarCache.split(','));
+            },
+            setStackedBarField(field){
+                this.stackedBarField = field;
+            },
+        };
+        compareObj.loadCacheData();
+
+        function compareCode(str1, str2, symbol = '-') {
+            if (!str1) {
+                return 1;
+            } else if (!str2) {
+                return -1;
+            }
+
+            function compareSubCode(code1, code2) {
+                if (numReg.test(code1)) {
+                    if (numReg.test(code2)) {
+                        return parseInt(code1) - parseInt(code2);
+                    } else {
+                        return -1
+                    }
+                } else {
+                    if (numReg.test(code2)) {
+                        return 1;
+                    } else {
+                        return code1 === code2 ? 0 : (code1 < code2 ? -1 : 1); //code1.localeCompare(code2);
+                    }
+                }
+            }
+            const numReg = /^[0-9]+$/;
+            const aCodes = str1.split(symbol), bCodes = str2.split(symbol);
+            for (let i = 0, iLength = Math.min(aCodes.length, bCodes.length); i < iLength; ++i) {
+                const iCompare = compareSubCode(aCodes[i], bCodes[i]);
+                if (iCompare !== 0) {
+                    return iCompare;
+                }
+            }
+            return aCodes.length - bCodes.length;
+        }
+
+        postData(`/sp/${spid}/datacollect/load`, {}, function (result, msg) {
+            if (result.budget) {
+                if (result.budget.final) {
+                    compareObj.loadFinalData(result.budget, msg);
+                } else {
+                    compareObj.loadBudgetData(result.budget);
+                }
+            }
+            setRightTenderEchart(result.tenderList);
+        });
+
+        function setPageData(tree, info) {
+            console.log(tree);
+            const chart_gu_data = [], chart_gai_data = [], chart_yu_data = [], chart_ctrl_data = [];
+            const chart_quan_data = [];
+            const chart_mbsj_data = {
+                xData: [],
+                ctrlData: [],
+                realData: [],
+            };
+            const table_data = [];
+            if (tree.children.length > 0) {
+                // 分析第一层结构,获取各个部分金额非全0的及除了回收金额层
+                const level1List = _.filter(tree.children, function (item) {
+                    return item.name.indexOf('回收金额') === -1 &&
+                        (item.gu_tp || item.gai_tp || (item.final_tp !== undefined && item.final_tp) || item.yu_tp || (item.ctrl_tp !== undefined && item.ctrl_tp))
+                });
+                console.log(level1List);
+                for (const level1 of level1List) {
+                    level1.name = level1.name.replace(
+                        /^第[一二三四五六七八九十百千万\d]+部分[\s ]+/,
+                        ''
+                    );
+                    chart_gu_data.push({
+                        name: level1.name,
+                        value: level1.gu_tp || 0
+                    });
+                    chart_gai_data.push({
+                        name: level1.name,
+                        value: level1.gai_tp || 0
+                    });
+                    chart_yu_data.push({
+                        name: level1.name,
+                        value: level1.yu_tp || 0
+                    });
+                    chart_ctrl_data.push({
+                        name: level1.name,
+                        value: level1.ctrl_tp || 0
+                    });
+                    chart_quan_data.push({
+                        name: level1.name,
+                        type: 'bar',
+                        stack: 'total',     // 相同 stack 就会堆叠
+                        emphasis: {
+                            focus: 'series'
+                        },
+                        data: [
+                            level1.gu_tp ? ZhCalc.div(level1.gu_tp, 10000) : 0,
+                            level1.gai_tp ? ZhCalc.div(level1.gai_tp, 10000) : 0,
+                            level1.yu_tp ? ZhCalc.div(level1.yu_tp, 10000) : 0,
+                            level1.ctrl_tp ? ZhCalc.div(level1.ctrl_tp, 10000) : 0,
+                            level1.real_tp ? ZhCalc.div(level1.real_tp, 10000) : 0,
+                        ]
+                    });
+
+                    table_data.push(`
+                    <tr>
+                        <td>${level1.name}</td>
+                        <td class="text-center">${level1.ctrl_tp ? ZhCalc.div(level1.ctrl_tp, 10000) : 0}</td>
+                        <td class="text-center">${level1.real_tp ? ZhCalc.div(level1.real_tp, 10000) : 0}</td>
+                    </tr>`);
+                    chart_mbsj_data.xData.push(level1.name);
+                    chart_mbsj_data.ctrlData.push(level1.ctrl_tp ? ZhCalc.div(level1.ctrl_tp, 10000) : 0);
+                    chart_mbsj_data.realData.push(level1.real_tp ? ZhCalc.div(level1.real_tp, 10000) : 0);
+                }
+            }
+            table_data.push(`
+                <tr>
+                    <td>设计优化率(%)</td>
+                    <td class="text-center">${info.ctrl_optimize_rate}</td>
+                    <td class="text-center">${info.real_optimize_rate}</td>
+                </tr>`);
+            table_data.push(`
+                <tr>
+                    <td>收益金额</td>
+                    <td class="text-center">${info.ctrl_profit ? ZhCalc.div(info.ctrl_profit, 10000) : 0}</td>
+                    <td class="text-center">${info.real_profit ? ZhCalc.div(info.real_profit, 10000) : 0}</td>
+                </tr>`);
+            const guOption1 = guChart1.getOption();
+            guOption1.series[0].data = chart_gu_data;
+            guChart1.setOption(guOption1);
+            const gaiOption1 = gaiChart1.getOption();
+            gaiOption1.series[0].data = chart_gai_data;
+            gaiChart1.setOption(gaiOption1);
+            const yuOption1 = yuChart1.getOption();
+            yuOption1.series[0].data = chart_yu_data;
+            yuChart1.setOption(yuOption1);
+            const ctrlOption1 = ctrlChart1.getOption();
+            ctrlOption1.series[0].data = chart_ctrl_data;
+            ctrlChart1.setOption(ctrlOption1);
+            const quanOption1 = quanChart1.getOption();
+            quanOption1.series = chart_quan_data;
+            quanChart1.setOption(quanOption1);
+
+            $('#level1-data').html(table_data.join(''));
+
+            const mbsjOption1 = mbsjChart1.getOption();
+            mbsjOption1.xAxis[0].data = chart_mbsj_data.xData;
+            mbsjOption1.series[0].data = chart_mbsj_data.ctrlData;
+            mbsjOption1.series[1].data = chart_mbsj_data.realData;
+            mbsjChart1.setOption(mbsjOption1);
+        }
+
+        function setRightTenderEchart(tenders) {
+            for (const t in tenders) {
+                const tendera = tenders[t] ? tenders[t].a : null;
+                const chart_data = {
+                    contract_price: [],
+                    end_gather_tp: [],
+                    end_profit_tp: [],
+                };
+                if (tendera) {
+                    $('#tender'+ t + '_name').text(tendera.name);
+                    calculateTender(tendera);
+                    chart_data.contract_price.push(tendera.contract_price || 0);
+                    chart_data.end_gather_tp.push(tendera.end_gather_tp || 0);
+                    // chart_data.end_profit_tp.push(tendera.end_gather_tp || 0);
+                    const tenderb = tenders[t] ? tenders[t].b : null;
+                    if (tenderb) {
+                        calculateTender(tenderb);
+                        chart_data.end_profit_tp.push(ZhCalc.sub(tendera.end_gather_tp, tenderb.end_gather_tp) || 0);
+                    } else {
+                        chart_data.end_profit_tp.push(tendera.end_gather_tp || 0);
+                    }
+                } else {
+                    $('#tender'+ t + '_name').text('');
+                }
+                const chartOption = tenderChart[`chart${t}`].getOption();
+                chartOption.series[0].data = chart_data.contract_price;
+                chartOption.series[1].data = chart_data.end_gather_tp;
+                chartOption.series[2].data = chart_data.end_profit_tp;
+                tenderChart[`chart${t}`].setOption(chartOption);
+            }
+        }
+
+        function calculateTender(tender) {
+            if (tender.stage_tp) {
+                tender.gather_tp = ZhCalc.sum([tender.stage_tp.contract_tp, tender.stage_tp.qc_tp, tender.stage_tp.pc_tp]);
+                tender.end_contract_tp = ZhCalc.sum([tender.stage_tp.pre_contract_tp, tender.stage_tp.contract_tp, tender.stage_tp.contract_pc_tp]);
+                tender.end_qc_tp = ZhCalc.sum([tender.stage_tp.pre_qc_tp, tender.stage_tp.qc_tp, tender.stage_tp.qc_pc_tp]);
+                tender.end_gather_tp = ZhCalc.add(tender.end_contract_tp, tender.end_qc_tp);
+                tender.pre_gather_tp = ZhCalc.add(tender.stage_tp.pre_contract_tp, tender.stage_tp.pre_qc_tp);
+                tender.yf_tp = ZhCalc.add(tender.stage_tp.yf_tp);
+                tender.end_yf_tp = ZhCalc.add(tender.stage_tp.pre_yf_tp, tender.yf_tp);
+                tender.sf_tp = ZhCalc.add(tender.stage_tp.sf_tp);
+                tender.end_sf_tp = ZhCalc.add(tender.stage_tp.pre_sf_tp, tender.sf_tp);
+                tender.wf_tp = ZhCalc.sub(tender.end_yf_tp, tender.end_sf_tp);
+            } else if (tender.lastStage) {
+                tender.gather_tp = ZhCalc.sum([tender.lastStage.contract_tp, tender.lastStage.qc_tp, tender.lastStage.pc_tp]);
+                tender.end_contract_tp = ZhCalc.sum([tender.lastStage.pre_contract_tp, tender.lastStage.contract_tp, tender.lastStage.contract_pc_tp]);
+                tender.end_qc_tp = ZhCalc.sum([tender.lastStage.pre_qc_tp, tender.lastStage.qc_tp, tender.lastStage.qc_pc_tp]);
+                tender.end_gather_tp = ZhCalc.add(tender.end_contract_tp, tender.end_qc_tp);
+                tender.pre_gather_tp = ZhCalc.add(tender.lastStage.pre_contract_tp, tender.lastStage.pre_qc_tp);
+                tender.yf_tp = ZhCalc.add(tender.lastStage.yf_tp);
+                tender.end_yf_tp = ZhCalc.add(tender.lastStage.pre_yf_tp, tender.yf_tp);
+                tender.sf_tp = ZhCalc.add(tender.lastStage.sf_tp);
+                tender.end_sf_tp = ZhCalc.add(tender.lastStage.pre_sf_tp, tender.sf_tp);
+                tender.wf_tp = ZhCalc.sub(tender.end_yf_tp, tender.end_sf_tp);
+            }
+        }
+    })
+    function formatMoney(s, dot = ',', decimal = 2) {
+        if (!s) {
+            s = 0;
+            return s.toFixed(decimal);
+        }
+        console.log(parseFloat((s + '').replace(/[^\d\.-]/g, '')).toFixed(decimal) + '');
+        // 按decimal位数四舍五入方法
+        s = decimal === 0 ? parseFloat((s + '').replace(/[^\d\.-]/g, '')).toFixed(decimal) + '' : (Math.round(parseFloat((s + '').replace(/[^\d\.-]/g, '')) * Math.pow(10, decimal)) / Math.pow(10, decimal)).toFixed(decimal) + '';
+        console.log(s, Math.pow(10, decimal));
+        if (!decimal) {
+            s += '.';
+        }
+        const l = s.split('.')[0].split('').reverse(),
+            r = s.split('.')[1];
+        let t = '';
+        for (let i = 0; i < l.length; i++) {
+            t += l[i] + ((i + 1) % 3 == 0 && (i + 1) != l.length ? dot : '');
+        }
+        const num = t.split('').reverse().join('') + (decimal === 0 ? '' : '.' + r);
+        return num.replace('-,', '-');
+    }
+    // 计算显示滚动条长度
+    function computedPosition(xArrayLength) {
+        if (xArrayLength >= 8) {
+            return Math.floor(8 / xArrayLength * 100) > 100 ? 100 : Math.floor(8 / xArrayLength * 100);
+            // return length <= 10 ? 35 : 100 - Math.floor(35 / length * 100);
+        } else {
+            return 100;
+        }
+    }
+</script>

+ 0 - 7
app/view/layout/menu.ejs

@@ -37,17 +37,10 @@
             <% } %>
             <% } else { %>
             <li <% if((ctx.controllerName === menu.controller && (!menu.notIncludedUrl || !menu.notIncludedUrl.some(item => ctx.url.includes(item)))) || (!!menu.controllers && menu.controllers.indexOf(ctx.controllerName) >= 0 && (!menu.includedUrl || !menu.includedUrl[ctx.controllerName] || menu.includedUrl[ctx.controllerName].some(item => ctx.url.includes(item)))) || (menu.url && menu.url === ctx.url)) { %>class="active"<% } %>>
-                <% if (menu.controller === 'datacollect' && ctx.subProject.data_collect_pages.includes('8') && ctx.subProject.data_collect === 8) { %>
-                <a href="<%- menu.url %>" target="_blank" id="<%- 'nav_' + index%>" data-toggle="tooltip" data-placement="right" title="" data-original-title="<%- menu.name %>">
-                    <i class="fa <%- menu.icon %>"></i>
-                    <% if (menu.caption) { %><span class="d-inline-block" style="vertical-align: text-bottom;"><%- menu.caption %></span><% } %>
-                </a>
-                <% } else { %>
                 <a href="<%- menu.url %>" id="<%- 'nav_' + index%>" data-toggle="tooltip" data-placement="right" title="" data-original-title="<%- menu.name %>">
                     <i class="fa <%- menu.icon %>"></i>
                     <% if (menu.caption) { %><span class="d-inline-block" style="vertical-align: text-bottom;"><%- menu.caption %></span><% } %>
                 </a>
-                <% } %>
             </li>
             <% } %>
             <% } %>

+ 62 - 18
app/view/sp_setting/datacollect.ejs

@@ -1,3 +1,42 @@
+<link href="/public/css/bootstrap/select2.min.css" rel="stylesheet" />
+<link rel="stylesheet" href="/public/css/bootstrap/select2-bootstrap4.min.css">
+<script src="/public/js/bootstrap/select2.min.js"></script>
+<style>
+    .select2-container {
+        /*display: inline-block!important;*/
+        /*height: 27px;*/
+        width: 100% !important;
+    }
+    .select2-container--bootstrap4 .select2-selection--single {
+        height: calc(1.1em + .75rem + 2px) !important;
+    }
+    /*.select2-container--bootstrap4 .select2-selection {*/
+    /*    background-color: #f8f9fa;*/
+    /*    !*border-color: #f8f9fa;*!*/
+    /*    border: 1px solid #f8f9fa;*/
+    /*}*/
+    /*.select2-container--bootstrap4 .select2-selection--single .select2-selection__rendered:focus{*/
+    /*    box-shadow: 0 0 0 0.2rem rgba(216,217,219,.5);*/
+    /*}*/
+    /*.select2-container--bootstrap4 .select2-selection--single .select2-selection__rendered:hover {*/
+    /*    background-color: #e2e6ea;*/
+    /*    border-color: #dae0e5;*/
+    /*}*/
+    .select2-container--bootstrap4 .select2-selection--single .select2-selection__rendered {
+        line-height: calc(1.1em + .75rem);
+        /*color: #007bff!important;*/
+        border-radius: 0.2rem;
+        /*background-color: #f8f9fa;*/
+        /*border-color: #f8f9fa;*/
+    }
+    .select2-container--bootstrap4 .select2-selection--single .select2-selection__arrow b {
+        border-color: #007bff transparent transparent transparent;
+        border-width: 4px 3.7px 0;
+    }
+    .select2-search--dropdown .select2-search__field {
+        padding: 0.175rem 0.5rem;
+    }
+</style>
 <% include ./sub_menu.ejs %>
 <div class="panel-content">
     <div class="panel-title">
@@ -24,10 +63,12 @@
                         <a class="nav-item nav-link<% if (ctx.subProject.data_collect === is_dz2) { %> active<% } %>" data-datacollect="<%- is_dz2 %>" data-toggle="tab" href="#shujudaping-<%- is_dz2 %>" role="tab">
                             决策大屏<%- ctx.helper.transFormToChinese(is_dz2) %><% if (ctx.helper._.indexOf(ctx.subProject.data_collect_pages, is_dz2.toString()) !== -1) { %>(已开启<% if (ctx.subProject.data_collect === is_dz2) { %>、默认<% } %>)<% } %></a>
                     <% } %>
-                    <a class="nav-item nav-link<% if (ctx.subProject.data_collect === 7) { %> active<% } %>" data-datacollect="7" data-toggle="tab" href="#shujudaping-7" role="tab">
-                        决策大屏<%- ctx.helper.transFormToChinese(7) %><% if (ctx.helper._.indexOf(ctx.subProject.data_collect_pages, '7') !== -1) { %>(已开启<% if (ctx.subProject.data_collect === 7) { %>、默认<% } %>)<% } %></a>
-                    <a class="nav-item nav-link<% if (ctx.subProject.data_collect === is_dz3) { %> active<% } %>" data-datacollect="<%- is_dz3 %>" data-toggle="tab" href="#shujudaping-<%- is_dz3 %>" role="tab">
-                        决策大屏<%- ctx.helper.transFormToChinese(is_dz3) %><% if (ctx.helper._.indexOf(ctx.subProject.data_collect_pages, is_dz3.toString()) !== -1) { %>(已开启<% if (ctx.subProject.data_collect === is_dz3) { %>、默认<% } %>)<% } %></a>
+                    <% if (is_dzcb) { %>
+                        <a class="nav-item nav-link<% if (ctx.subProject.data_collect === is_dzcb) { %> active<% } %>" data-datacollect="<%- is_dzcb %>" data-toggle="tab" href="#shujudaping-<%- is_dzcb %>" role="tab">
+                            成本管理<% if (ctx.helper._.indexOf(ctx.subProject.data_collect_pages, is_dzcb.toString()) !== -1) { %>(已开启<% if (ctx.subProject.data_collect === is_dzcb) { %>、默认<% } %>)<% } %></a>
+                    <% } %>
+                    <a class="nav-item nav-link<% if (ctx.subProject.data_collect === is_dztz) { %> active<% } %>" data-datacollect="<%- is_dztz %>" data-toggle="tab" href="#shujudaping-<%- is_dztz %>" role="tab">
+                        投资总控<% if (ctx.helper._.indexOf(ctx.subProject.data_collect_pages, is_dztz.toString()) !== -1) { %>(已开启<% if (ctx.subProject.data_collect === is_dztz) { %>、默认<% } %>)<% } %></a>
                     <div class="ml-auto">
                         <!--<div class="form-check form-check-inline">-->
                             <!--<input class="form-check-input" type="checkbox" id="show-datacollect" value="option1" <% if (ctx.subProject.data_collect) { %>checked<% } %>>-->
@@ -61,12 +102,12 @@
                             <span>四川广元路桥集团计量内控管理云平台定制(GY18Y)</span><a class="nav-link" style="display: inline-block;" data-toggle="modal" href="#dpsix-set" data-target="#dpsix-set" title="决策大屏六设置"><i class="fa fa-cog"></i></a><img src="/public/images/juecedaping0<%- is_dz2 %>.png" width="100%">
                         </div>
                     <% } %>
-                    <div id="shujudaping-7" class="tab-pane<% if (ctx.subProject.data_collect === 7) { %> active<% } %>">
-                        成本管理决策大屏数据汇总<img src="/public/images/juecedaping07.png" width="100%">
+                    <div id="shujudaping-<%- is_dzcb %>" class="tab-pane<% if (ctx.subProject.data_collect === is_dzcb) { %> active<% } %>">
+                        <span>成本管理决策大屏定制(Y3T2Q)</span><img src="/public/images/juecedaping0<%- is_dzcb %>.png" width="100%">
                     </div>
-                    <% if (is_dz3) { %>
-                    <div id="shujudaping-<%- is_dz3 %>" class="tab-pane<% if (ctx.subProject.data_collect === is_dz3) { %> active<% } %>">
-                        山海鲸数据大屏平台定制(会打开新标签页跳转)<img src="/public/images/juecedaping0<%- is_dz3 %>.png" width="100%">
+                    <% if (is_dztz) { %>
+                    <div id="shujudaping-<%- is_dztz %>" class="tab-pane<% if (ctx.subProject.data_collect === is_dztz) { %> active<% } %>">
+                        <span>投资总控决策大屏定制(Y3T2Q)</span><a class="nav-link" style="display: inline-block;" data-toggle="modal" href="#dpeight-set" data-target="#dpeight-set" title="决策大屏八设置"><i class="fa fa-cog"></i></a><img src="/public/images/juecedaping0<%- is_dztz %>.png" width="100%">
                     </div>
                     <% } %>
                 </div>
@@ -91,7 +132,8 @@
     let addDataCollect = JSON.parse(unescape('<%- escape(JSON.stringify(ctx.subProject.page_show.addDataCollect)) %>'));
     let is_dz1 = <% if (is_dz1) { %>parseInt('<%- is_dz1 %>');<% } else { %>false;<% } %>
     let is_dz2 = <% if (is_dz2) { %>parseInt('<%- is_dz2 %>');<% } else { %>false;<% } %>
-    let is_dz3 = <% if (is_dz3) { %>parseInt('<%- is_dz3 %>');<% } else { %>false;<% } %>
+    let is_dzcb = <% if (is_dzcb) { %>parseInt('<%- is_dzcb %>');<% } else { %>false;<% } %>
+    let is_dztz = <% if (is_dztz) { %>parseInt('<%- is_dztz %>');<% } else { %>false;<% } %>
     $(function () {
         autoFlashHeight();
         // 开启及关闭展示
@@ -168,17 +210,19 @@
                 }
                 $('#tablist a').eq(is_dz2-3).text('决策大屏' + transFormToChinese(is_dz2) + msg);
             }
-            let msg = '';
-            if (_.indexOf(dataCollectPages, '7') !== -1) {
-                msg = '(已开启' + (7 === dataCollect ? '、默认' : '') + ')' ;
+            if (is_dzcb) {
+                let msg = '';
+                if (_.indexOf(dataCollectPages, is_dzcb.toString()) !== -1) {
+                    msg = '(已开启' + (is_dzcb === dataCollect ? '、默认' : '') + ')' ;
+                }
+                $('#tablist a').eq(is_dzcb-3).text('成本管理' + msg);
             }
-            $('#tablist a').eq(7-3).text('决策大屏' + transFormToChinese(7) + msg);
-            if (is_dz3) {
+            if (is_dztz) {
                 let msg = '';
-                if (_.indexOf(dataCollectPages, is_dz3.toString()) !== -1) {
-                    msg = '(已开启' + (is_dz3=== dataCollect ? '、默认' : '') + ')' ;
+                if (_.indexOf(dataCollectPages, is_dztz.toString()) !== -1) {
+                    msg = '(已开启' + (is_dztz=== dataCollect ? '、默认' : '') + ')' ;
                 }
-                $('#tablist a').eq(is_dz3-3).text('决策大屏' + transFormToChinese(is_dz3) + msg);
+                $('#tablist a').eq(is_dztz-3).text('投资总控' + msg);
             }
         }
         $('#tablist a').click(function () {

+ 204 - 3
app/view/sp_setting/datacollect_modal.ejs

@@ -285,6 +285,207 @@
     })
 </script>
 <% } %>
+<% if (is_dzcb) { %>
+    <!--决策大屏七设置-->
+    <div class="modal fade" id="dpeight-set" data-backdrop="static">
+        <div class="modal-dialog" role="document">
+            <div class="modal-content">
+                <div class="modal-header">
+                    <h5 class="modal-title">指定标段展示设置</h5>
+                </div>
+                <div class="modal-body">
+                    <ul class="list-unstyled">
+                        <li class="mb-4">
+                            <h6 class="mb-3">标段一设置</h6>
+                            <!-- 总包 -->
+                            <div class="form-group row">
+                                <label class="col-sm-2 col-form-label">总包</label>
+                                <div class="col-sm-10">
+                                    <select class="form-control form-control-sm" id="tender1a_select">
+                                        <option value="0">请选择标段</option>
+                                        <% for (const t of tenders) { %>
+                                            <option value="<%= t.id %>"
+                                                    <% if (ctx.helper._.find(daPing08Set.tenders, { id: 1 }).a === t.id) { %>selected<% } %>>
+                                                <%= t.name %>(ID=<%= t.id %>)
+                                            </option>
+                                        <% } %>
+                                    </select>
+                                </div>
+                            </div>
+
+                            <!-- 分包 -->
+                            <div class="form-group row mb-0">
+                                <label class="col-sm-2 col-form-label">分包</label>
+                                <div class="col-sm-10">
+                                    <select class="form-control form-control-sm" id="tender1b_select">
+                                        <option value="0">请选择标段</option>
+                                        <% for (const t of tenders) { %>
+                                            <option value="<%= t.id %>"
+                                                    <% if (ctx.helper._.find(daPing08Set.tenders, { id: 1 }).b === t.id) { %>selected<% } %>>
+                                                <%= t.name %>(ID=<%= t.id %>)
+                                            </option>
+                                        <% } %>
+                                    </select>
+                                </div>
+                            </div>
+                        </li>
+                        <li class="mb-4">
+                            <h6 class="mb-3">标段二设置</h6>
+
+                            <!-- 总包 -->
+                            <div class="form-group row">
+                                <label class="col-sm-2 col-form-label">总包</label>
+                                <div class="col-sm-10">
+                                    <select class="form-control form-control-sm" id="tender2a_select">
+                                        <option value="0">请选择标段</option>
+                                        <% for (const t of tenders) { %>
+                                            <option value="<%= t.id %>"
+                                                    <% if (ctx.helper._.find(daPing08Set.tenders, { id: 2 }).a === t.id) { %>selected<% } %>>
+                                                <%= t.name %>(ID=<%= t.id %>)
+                                            </option>
+                                        <% } %>
+                                    </select>
+                                </div>
+                            </div>
+
+                            <!-- 分包 -->
+                            <div class="form-group row mb-0">
+                                <label class="col-sm-2 col-form-label">分包</label>
+                                <div class="col-sm-10">
+                                    <select class="form-control form-control-sm" id="tender2b_select">
+                                        <option value="0">请选择标段</option>
+                                        <% for (const t of tenders) { %>
+                                            <option value="<%= t.id %>"
+                                                    <% if (ctx.helper._.find(daPing08Set.tenders, { id: 2 }).b === t.id) { %>selected<% } %>>
+                                                <%= t.name %>(ID=<%= t.id %>)
+                                            </option>
+                                        <% } %>
+                                    </select>
+                                </div>
+                            </div>
+                        </li>
+                        <li class="mb-4">
+                            <h6 class="mb-3">标段三设置</h6>
+
+                            <!-- 总包 -->
+                            <div class="form-group row">
+                                <label class="col-sm-2 col-form-label">总包</label>
+                                <div class="col-sm-10">
+                                    <select class="form-control form-control-sm" id="tender3a_select">
+                                        <option value="0">请选择标段</option>
+                                        <% for (const t of tenders) { %>
+                                            <option value="<%= t.id %>"
+                                                    <% if (ctx.helper._.find(daPing08Set.tenders, { id: 3 }).a === t.id) { %>selected<% } %>>
+                                                <%= t.name %>(ID=<%= t.id %>)
+                                            </option>
+                                        <% } %>
+                                    </select>
+                                </div>
+                            </div>
+
+                            <!-- 分包 -->
+                            <div class="form-group row mb-0">
+                                <label class="col-sm-2 col-form-label">分包</label>
+                                <div class="col-sm-10">
+                                    <select class="form-control form-control-sm" id="tender3b_select">
+                                        <option value="0">请选择标段</option>
+                                        <% for (const t of tenders) { %>
+                                            <option value="<%= t.id %>"
+                                                    <% if (ctx.helper._.find(daPing08Set.tenders, { id: 3 }).b === t.id) { %>selected<% } %>>
+                                                <%= t.name %>(ID=<%= t.id %>)
+                                            </option>
+                                        <% } %>
+                                    </select>
+                                </div>
+                            </div>
+                        </li>
+                        <li class="mb-4">
+                            <h6 class="mb-3">标段四设置</h6>
+
+                            <!-- 总包 -->
+                            <div class="form-group row">
+                                <label class="col-sm-2 col-form-label">总包</label>
+                                <div class="col-sm-10">
+                                    <select class="form-control form-control-sm" id="tender4a_select">
+                                        <option value="0">请选择标段</option>
+                                        <% for (const t of tenders) { %>
+                                            <option value="<%= t.id %>"
+                                                    <% if (ctx.helper._.find(daPing08Set.tenders, { id: 4 }).a === t.id) { %>selected<% } %>>
+                                                <%= t.name %>(ID=<%= t.id %>)
+                                            </option>
+                                        <% } %>
+                                    </select>
+                                </div>
+                            </div>
+
+                            <!-- 分包 -->
+                            <div class="form-group row mb-0">
+                                <label class="col-sm-2 col-form-label">分包</label>
+                                <div class="col-sm-10">
+                                    <select class="form-control form-control-sm" id="tender4b_select">
+                                        <option value="0">请选择标段</option>
+                                        <% for (const t of tenders) { %>
+                                            <option value="<%= t.id %>"
+                                                    <% if (ctx.helper._.find(daPing08Set.tenders, { id: 4 }).b === t.id) { %>selected<% } %>>
+                                                <%= t.name %>(ID=<%= t.id %>)
+                                            </option>
+                                        <% } %>
+                                    </select>
+                                </div>
+                            </div>
+                        </li>
+                    </ul>
+                    <div class="mt-2">提示:利润等于 总包-分包</div>
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">取消</button>
+                    <button type="button" class="btn btn-sm btn-primary" id="dp08_save_btn">确定</button>
+                </div>
+            </div>
+        </div>
+    </div>
+    <script>
+        const daPing08Set = JSON.parse(unescape('<%- escape(JSON.stringify(daPing08Set)) %>'));
+        console.log(daPing08Set);
+        $(function () {
+            for (const t of daPing08Set.tenders) {
+                $(`#tender${t.id}a_select`).select2({
+                    language: 'zh-CN',
+                    theme: 'bootstrap4',
+                    selectOnClose: true,
+                    // width: '150',
+                });
+                $(`#tender${t.id}b_select`).select2({
+                    language: 'zh-CN',
+                    theme: 'bootstrap4',
+                    selectOnClose: true,
+                    // width: '150',
+                });
+            }
+            $('#dpeight-set').on('show.bs.modal', function (e) {
+                console.log(daPing08Set);
+                for (const t of daPing08Set.tenders) {
+                    $(`#tender${t.id}a_select`).val(t.a);
+                    $(`#tender${t.id}b_select`).val(t.b);
+                }
+            });
+            $('#dp08_save_btn').click(function () {
+                let tenders = [];
+                for (let i = 1; i <= 4; i++) {
+                    const a = parseInt($(`#tender${i}a_select`).val());
+                    const b = parseInt($(`#tender${i}b_select`).val());
+                    tenders.push({ id: i, a: a, b: b });
+                }
+                daPing08Set.tenders = tenders;
+                console.log(daPing08Set);
+                postData('/sp/' + spid + '/setting/datacollect/save', { type: 'save-dp08', daPing08Set }, function (result) {
+                    toastr.success('设置成功');
+                    $('#dpeight-set').modal('hide');
+                })
+            });
+        })
+    </script>
+<% } %>
 <script>
     $(function () {
         let timer = null
@@ -427,8 +628,8 @@
 
             const selectedIds = dataCollectAudits.map(audit => {
                 const id = parseInt(audit.uid, 10);
-                return isNaN(id) ? null : id; 
-            }).filter(id => id !== null); 
+                return isNaN(id) ? null : id;
+            }).filter(id => id !== null);
 
             $('.user-item').each(function() {
                 const userIdStr = $(this).data('id');
@@ -440,7 +641,7 @@
                     $(this).addClass('bg-light');
                 } else {
                     $mark.hide();
-                    $(this).removeClass('bg-light'); 
+                    $(this).removeClass('bg-light');
                 }
             });
         }