Browse Source

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

Tony Kang 2 years ago
parent
commit
f96769a5f6

+ 36 - 0
app/controller/payment_controller.js

@@ -0,0 +1,36 @@
+'use strict';
+module.exports = app => {
+
+    class PaymentController extends app.BaseController {
+        /**
+         * 构造函数
+         *
+         * @param {Object} ctx - egg全局变量
+         * @return {void}
+         */
+        constructor(ctx) {
+            super(ctx);
+            ctx.showProject = true;
+            // ctx.showTitle = true;
+        }
+        /**
+         * 支付表单页面
+         *
+         * @param {Object} ctx - egg全局页面
+         * @return {void}
+         */
+        async detail(ctx) {
+            console.log(ctx.params);
+            const id = parseInt(ctx.params.id);
+            if (!id) throw '参数错误';
+            const info = await ctx.service.paymentDetail.getDataById(id);
+
+            const renderData = {
+                info,
+            };
+            await this.layout('payment/detail.ejs', renderData);
+        }
+    }
+
+    return PaymentController;
+};

+ 15 - 0
app/public/css/main.css

@@ -2072,4 +2072,19 @@ animation:shake 1s .2s ease both;}
 }
 .signatureCavans{
   background: transparent!important;
+}
+.span-grey{
+    background: #657798;
+}
+.span-red{
+    background: #EE6666;
+}
+.span-blue{
+    background: #74CBED;
+}
+.span-yellow{
+    background: #FAC858;
+}
+.span-green{
+    background: #62DAAB;
 }

+ 124 - 18
app/public/js/budget_compare.js

@@ -9,6 +9,9 @@
  */
 
 $(document).ready(() => {
+    const compareTypeKey = 'budget-compareType';
+    const stackedBarCoverKey = 'budget-stackedBarCover';
+    const stackedBarKey = 'budget-stackedBar';
     autoFlashHeight();
     const compareSpread = SpreadJsObj.createNewSpread($('#cost-compare')[0]);
     const compareSheet = compareSpread.getActiveSheet();
@@ -18,15 +21,16 @@ $(document).ready(() => {
             {title: '项目节编号', colSpan: '1', rowSpan: '2', field: 'code', hAlign: 0, width: 150, formatter: '@', cellType: 'tree'},
             {title: '名称', colSpan: '1', rowSpan: '2', field: 'name', hAlign: 0, width: 230, formatter: '@'},
             {title: '单位', colSpan: '1', rowSpan: '2', field: 'unit', hAlign: 1, width: 50, formatter: '@', cellType: 'unit'},
-            {title: '投资估算|数量1/数量2', colSpan: '3|1', rowSpan: '1|1', field: 'gu_dgn_qty', hAlign: 2, width: 80},
-            {title: '|经济指标', colSpan: '|1', rowSpan: '|1', field: 'gu_dgn_price', hAlign: 2, width: 80, type: 'Number'},
-            {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'gu_tp', hAlign: 2, width: 80, type: 'Number'},
-            {title: '初步概算|数量1/数量2', colSpan: '3|1', rowSpan: '1|1', field: 'gai_dgn_qty', hAlign: 2, width: 80},
-            {title: '|经济指标', colSpan: '|1', rowSpan: '|1', field: 'gai_dgn_price', hAlign: 2, width: 80, type: 'Number'},
-            {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'gai_tp', hAlign: 2, width: 80, type: 'Number'},
-            {title: '施工图预算|数量1/数量2', colSpan: '3|1', rowSpan: '1|1', field: 'yu_dgn_qty', hAlign: 2, width: 80},
-            {title: '|经济指标', colSpan: '|1', rowSpan: '|1', field: 'yu_dgn_price', hAlign: 2, width: 80, type: 'Number'},
-            {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'yu_tp', hAlign: 2, width: 80, type: 'Number'},
+            {title: '投资估算|数量1/数量2', colSpan: '3|1', rowSpan: '1|1', field: 'gu_dgn_qty', hAlign: 2, width: 80, bc_type: 'number'},
+            {title: '|经济指标', colSpan: '|1', rowSpan: '|1', field: 'gu_dgn_price', hAlign: 2, width: 80, type: 'Number', bc_type: 'number'},
+            {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'gu_tp', hAlign: 2, width: 80, type: 'Number', bc_type: 'number'},
+            {title: '初步概算|数量1/数量2', colSpan: '3|1', rowSpan: '1|1', field: 'gai_dgn_qty', hAlign: 2, width: 80, bc_type: 'number'},
+            {title: '|经济指标', colSpan: '|1', rowSpan: '|1', field: 'gai_dgn_price', hAlign: 2, width: 80, type: 'Number', bc_type: 'number'},
+            {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'gai_tp', hAlign: 2, width: 80, type: 'Number', bc_type: 'number'},
+            {title: '施工图预算|数量1/数量2', colSpan: '3|1', rowSpan: '1|1', field: 'yu_dgn_qty', hAlign: 2, width: 80, bc_type: 'number'},
+            {title: '|经济指标', colSpan: '|1', rowSpan: '|1', field: 'yu_dgn_price', hAlign: 2, width: 80, type: 'Number', bc_type: 'number'},
+            {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'yu_tp', hAlign: 2, width: 80, type: 'Number', bc_type: 'number'},
+            {title: '数据对比', colSpan: '1', rowSpan: '2', field: 'stackedBar', hAlign: 0, width: 300, cellType: 'stackedBar', stackedBarCover: false, bc_type: 'grid', visible: false},
         ],
         emptyRows: 0,
         headRows: 2,
@@ -41,28 +45,38 @@ $(document).ready(() => {
 
     };
     sjsSettingObj.setFxTreeStyle(spreadSetting, sjsSettingObj.FxTreeStyle.jz);
-    SpreadJsObj.initSheet(compareSheet, spreadSetting);
-
     let sfSelect;
     const compareObj = {
         curFinalId() {
             return this.finalInfo ? this.finalInfo.id : undefined;
         },
         initFinalCol() {
-            if (spreadSetting.cols.length < 13) {
+            if (spreadSetting.cols.length < 14) {
+                spreadSetting.cols.pop();
                 spreadSetting.cols.push(...[
-                    {title: '台账|数量1/数量2', colSpan: '3|1', rowSpan: '1|1', field: 'dgn_qty', hAlign: 2, width: 80},
-                    {title: '|经济指标', colSpan: '|1', rowSpan: '|1', field: 'dgn_price', hAlign: 2, width: 80, type: 'Number'},
-                    {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'total_price', hAlign: 2, width: 80, type: 'Number'},
-                    {title: '决算|数量1/数量2', colSpan: '3|1', rowSpan: '1|1', field: 'final_dgn_qty', hAlign: 2, width: 80},
-                    {title: '|经济指标', colSpan: '|1', rowSpan: '|1', field: 'final_dgn_price', hAlign: 2, width: 80, type: 'Number'},
-                    {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'final_tp', hAlign: 2, width: 80, type: 'Number'},
+                    {title: '台账|数量1/数量2', colSpan: '3|1', rowSpan: '1|1', field: 'dgn_qty', hAlign: 2, width: 80, bc_type: 'number'},
+                    {title: '|经济指标', colSpan: '|1', rowSpan: '|1', field: 'dgn_price', hAlign: 2, width: 80, type: 'Number', bc_type: 'number'},
+                    {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'total_price', hAlign: 2, width: 80, type: 'Number', bc_type: 'number'},
+                    {title: '决算|数量1/数量2', colSpan: '3|1', rowSpan: '1|1', field: 'final_dgn_qty', hAlign: 2, width: 80, bc_type: 'number'},
+                    {title: '|经济指标', colSpan: '|1', rowSpan: '|1', field: 'final_dgn_price', hAlign: 2, width: 80, type: 'Number', bc_type: 'number'},
+                    {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'final_tp', hAlign: 2, width: 80, type: 'Number', bc_type: 'number'},
+                    {title: '数据对比', colSpan: '1', rowSpan: '2', field: 'stackedBar', hAlign: 0, width: 300, cellType: 'stackedBar', stackedBarCover: false, bc_type: 'grid', visible: false},
                     {title: '增幅%|数量1/数量2', colSpan: '2|1', rowSpan: '1|1', field: 'grow_dgn_qty', hAlign: 2, width: 80},
                     {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'grow_tp', hAlign: 2, width: 80, type: 'Number'},
                 ]);
+                this.initShowType();
                 SpreadJsObj.reLoadSheetHeader(compareSheet);
             };
         },
+        initShowType() {
+            const type = this.compareType;
+            spreadSetting.cols.forEach(x => {
+                if (!x.bc_type) return;
+                x.visible = x.bc_type === type;
+            });
+            const colIndex = spreadSetting.cols.findIndex(x => { return x.field === 'stackedBar'});
+            spreadSetting.cols[colIndex].stackedBarCover = parseInt(this.stackedBarCover);
+        },
         expand(tree, tag) {
             switch (tag) {
                 case "1":
@@ -77,6 +91,37 @@ $(document).ready(() => {
                     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 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 = [];
+                for (const cf of calcField) {
+                    node.stackedBar.push({color: calcFieldColor[cf], percent: ZhCalc.div(node[cf], base), field: cf});
+                }
+                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], commonBase);
+                }
+            });
+            for (const child of tree.children) {
+                calc(child, commonBase);
+            }
+        },
         loadBudgetData(result) {
             const compareTree = createNewPathTree('final', {
                 id: 'id',
@@ -136,6 +181,7 @@ $(document).ready(() => {
             });
             const expandTag = getLocalCache('revise-compare-level');
             if (expandTag) compareObj.expand(compareTree, expandTag);
+            this.calcStackedBar(compareTree);
             SpreadJsObj.loadSheetData(compareSheet, SpreadJsObj.DataType.Tree, compareTree);
         },
         loadFinalData(result, msg) {
@@ -153,10 +199,50 @@ $(document).ready(() => {
             finalTree.loadDatas(result.final);
             const expandTag = getLocalCache('revise-compare-level');
             if (expandTag) compareObj.expand(finalTree, expandTag);
+            this.calcStackedBar(finalTree);
             SpreadJsObj.loadSheetData(compareSheet, SpreadJsObj.DataType.Tree, finalTree);
             if (sfSelect) sfSelect.reloadSelect(this.finalInfo.tender);
         },
+        loadCacheData(){
+            let stackedBarCache = getLocalCache(stackedBarKey);
+            if (stackedBarCache === null) stackedBarCache = 'gai_tp,total_price,final_tp';
+            this.setStackedBarField(stackedBarCache ? stackedBarCache.split(',') : []);
+            this.setCompareType(getLocalCache(compareTypeKey));
+            this.setStackedBarCover(getLocalCache(stackedBarCoverKey));
+            this.initShowType();
+        },
+        setStackedBarField(field){
+            this.stackedBarField = field;
+            setLocalCache(stackedBarKey, field.join(','));
+            if (compareSheet.zh_tree) this.calcStackedBar(compareSheet.zh_tree);
+            const colIndex = spreadSetting.cols.findIndex(x => { return x.field === 'stackedBar'});
+            SpreadJsObj.reloadColData(compareSheet, colIndex);
+        },
+        setCompareType(type) {
+            this.compareType = type;
+            $('[name=showType]').removeClass('active');
+            $(`[tag=${type}]`).addClass('active');
+            if (this.compareType === 'grid') {
+                $('.ml-auto').show();
+            } else {
+                $('.ml-auto').hide();
+            }
+            spreadSetting.cols.forEach(x => {
+                if (!x.bc_type) return;
+                x.visible = x.bc_type === type;
+            });
+            setLocalCache(compareTypeKey, type);
+        },
+        setStackedBarCover(cover){
+            this.stackedBarCover = cover || '1';
+            const colIndex = spreadSetting.cols.findIndex(x => { return x.field === 'stackedBar'});
+            spreadSetting.cols[colIndex].stackedBarCover = parseInt(cover);
+            SpreadJsObj.reloadColData(compareSheet, colIndex);
+            setLocalCache(stackedBarCoverKey, cover);
+        }
     };
+    compareObj.loadCacheData();
+    SpreadJsObj.initSheet(compareSheet, spreadSetting);
 
     function compareCode(str1, str2, symbol = '-') {
         if (!str1) {
@@ -322,4 +408,24 @@ $(document).ready(() => {
     $('#select-final').on('shown.bs.modal', () => {
         if (!sfSelect) sfSelect = new sfObject();
     });
+    $('#stackedBar-ok').click(function() {
+        const checked = $('[name=stackedBar]:checked');
+        const field = [];
+        checked.each((i, x) => { field.push(x.value)});
+        compareObj.setStackedBarField(field);
+    });
+    $('#dp-stackedBar').click(function() {
+        const field = compareObj.stackedBarField;
+        const checked = $('[name=stackedBar]');
+        checked.each((i, x) => { x.checked = field.indexOf(x.value) >= 0; });
+    });
+    $('a[name=showType]').click(function () {
+        const type = this.getAttribute('tag');
+        compareObj.setCompareType(type);
+        SpreadJsObj.refreshColumnVisible(compareSheet);
+    });
+    $('a[name=stackedBarCover]').click(function() {
+        const cover = this.getAttribute('tag');
+        compareObj.setStackedBarCover(cover);
+    })
 });

+ 3 - 1
app/public/js/gcl_gather.js

@@ -131,9 +131,11 @@ const gclGatherModel = (function () {
                 (g.name || node.name ? g.name === node.name : true) &&
                 (g.unit || node.unit ? g.unit === node.unit : true) &&
                 checkZero(ZhCalc.sub(g.unit_price, node.unit_price));
+                // && (g.org_price && node.org_price ? g.org_price === node.org_price : true);
         });
         if (gcl) {
-            return gcl
+            if (node.org_price) gcl.org_price = node.org_price;
+            return gcl;
         } else {
             return newGclNode(node);
         }

+ 72 - 5
app/public/js/spreadjs_rela/spreadjs_zh.js

@@ -307,7 +307,7 @@ const SpreadJsObj = {
         const setting = sheet.zh_setting;
         if (!setting || !setting.cols) { return; }
 
-
+        sheet.setColumnCount(0);
         sheet.setColumnCount(setting.cols.length);
         sheet.setRowCount(setting.headRows, spreadNS.SheetArea.colHeader);
         for (let iRow = 0; iRow < setting.headRowHeight.length; iRow ++) {
@@ -372,7 +372,6 @@ const SpreadJsObj = {
                 const col = _.find(setting.cols, {field: prop});
                 if (col) col.width = setting.localCache.colWidthCache[prop];
             }
-            this._rememberColWidth(sheet);
         }
     },
     /**
@@ -384,6 +383,7 @@ const SpreadJsObj = {
         const self = this;
         this.beginMassOperation(sheet);
         this._loadCacheSetting(sheet, setting);
+        this._rememberColWidth(sheet);
         setting.pos = sheet.getParent().pos;
         if (!setting.tree) setting.tree = {};
         sheet.zh_setting = setting;
@@ -411,6 +411,7 @@ const SpreadJsObj = {
     reLoadSheetHeader: function (sheet) {
         if (sheet.zh_setting) {
             this.beginMassOperation(sheet);
+            this._loadCacheSetting(sheet, sheet.zh_setting);
             this._initSheetHeader(sheet);
             this.endMassOperation(sheet);
         }
@@ -718,6 +719,13 @@ const SpreadJsObj = {
             }
             sheet.getRange(-1, col, -1, 1).cellType(sheet.extendCellType.mouseTouch);
         }
+        if (colSetting.cellType === 'stackedBar') {
+            if (!sheet.extendCellType.stackedBar) {
+                sheet.extendCellType.stackedBar = this.CellType.getStackedBarCellType();
+                SpreadJsObj._addActivePaintEvents(sheet, sheet.extendCellType.stackedBar);
+            }
+            sheet.getRange(-1, col, -1, 1).cellType(sheet.extendCellType.stackedBar);
+        }
         if (colSetting.formatter) {
             sheet.getRange(-1, col, -1, 1).formatter(colSetting.formatter);
             if(colSetting.type === 'Number') {
@@ -918,6 +926,7 @@ const SpreadJsObj = {
      */
     reLoadColsData: function (sheet, cols) {
         const sortData = sheet.zh_dataType === 'tree' ? sheet.zh_tree.nodes : sheet.zh_data;
+        if (!sortData) return;
 
         this.beginMassOperation(sheet);
         try {
@@ -2258,13 +2267,13 @@ const SpreadJsObj = {
                         ctx.save();
                         ctx.rect(x, y, w, h);
                         ctx.clip();
-                        ctx.drawImage(img, x + 2, y + 2)
+                        ctx.drawImage(img, x + 2, y + 2);
                         ctx.restore();
                         cell.tag(null);
                         return;
                     }
                     catch (err) {
-                        GC.Spread.Sheets.CustomCellType.prototype.paint.apply(this, [ctx, "#HTMLError", x, y, w, h, style, context])
+                        GC.Spread.Sheets.CustomCellType.prototype.paint.apply(this, [ctx, "#HTMLError", x, y, w, h, style, context]);
                         cell.tag(null);
                         return;
                     }
@@ -2526,7 +2535,65 @@ const SpreadJsObj = {
                 return false;
             };
             return new mouseTouchCellType();
-        }
+        },
+        getStackedBarCellType: function () {
+            const stackedBarCellType = function(){};
+            stackedBarCellType.prototype = new spreadNS.CellTypes.Text();
+            const indent = 3, defaultR = 3, minHeight = 2;
+            /**
+             * 画一个长条
+             * @param {Object} canvas - 画布
+             * @param {Object} rect - 方框区域
+             * @param {String} lineColor - 画线颜色
+             * @param {String} fillColor - 填充颜色
+             */
+            const drawBar = function (canvas, x, y, w, h, r, color) {
+                canvas.save();
+                // 设置偏移量
+                canvas.translate(0.5, 0.5);
+                canvas.strokeStyle = color;
+                canvas.beginPath();
+                canvas.roundRect(x, y, w, h, r);
+                canvas.stroke();
+                canvas.fillStyle = color;
+                canvas.fill();
+                canvas.restore();
+            };
+            const proto = stackedBarCellType.prototype;
+            /**
+             * 绘制方法
+             * @param {Object} canvas - 画布
+             * @param value - cell.value
+             * @param {Number} x - 单元格左顶点坐标 x
+             * @param {Number} y - 单元格左顶点坐标 y
+             * @param {Number} w - 单元格宽度
+             * @param {Number} h - 单元格高度
+             * @param {Object} style - cell.style
+             * @param {Object} options
+             */
+            proto.paint = function (canvas, value, x, y, w, h, style, options) {
+                // 清理 画布--单元格范围 旧数据
+                canvas.save();
+                canvas.fillStyle = style.backColor || 'white';
+                canvas.fillRect(x, y, w, h);
+                canvas.restore();
+
+                const col = options.sheet.zh_setting.cols[options.col];
+                const barData = value;
+                const left = x + indent;
+                const startTop = y + indent;
+                const validHeight = h - indent - indent - (col.stackedBarCover || barData.length === 1 ? 1 : barData.length / 2 + 1);
+                const height = col.stackedBarCover || barData.length === 0 ? validHeight : Math.max(validHeight/barData.length, minHeight);
+                const validWidth = w - indent - indent - 1;
+                for (const [i, bd] of barData.entries()) {
+                    let width = ZhCalc.mul(validWidth, bd.percent, 2);
+                    if (width < defaultR) continue;
+                    const top = col.stackedBarCover ? startTop : startTop + height * i + i - 1;
+                    drawBar(canvas, left, top, width, height, defaultR, bd.color);
+                }
+            };
+            return new stackedBarCellType();
+        },
     },
 
     RowHeader: {

+ 3 - 0
app/router.js

@@ -695,4 +695,7 @@ module.exports = app => {
     app.post('/budget/:id/:btype/update', sessionAuth, budgetCheck, 'budgetController.detailUpdate');
     app.post('/budget/:id/:btype/upload-excel/:ueType', sessionAuth, budgetCheck, 'budgetController.detailUploadExcel');
     app.post('/budget/:id/decimal', sessionAuth, budgetCheck, 'budgetController.decimal');
+
+    // 支付审批
+    app.get('/payment/:rid/detail/:id', sessionAuth, 'paymentController.detail');
 };

+ 11 - 0
app/service/payment_detail.js

@@ -0,0 +1,11 @@
+'use strict';
+
+module.exports = app => {
+    class PaymentDetail extends app.BaseService {
+        constructor(ctx) {
+            super(ctx);
+            this.tableName = 'payment_detail';
+        }
+    }
+    return PaymentDetail;
+};

+ 63 - 0
app/view/budget/compare.ejs

@@ -4,6 +4,16 @@
         <div class="title-main d-flex">
             <% include ./sub_mini_menu.ejs %>
             <div>
+                <div class="d-inline-block mr-2">
+                    <div class="btn-group group-tab">
+                        <a class="btn btn-sm btn-light" name="showType" tag="grid" href="javascript: void(0)">
+                            图表模式
+                        </a>
+                        <a class="btn btn-sm btn-light" name="showType" tag="number" href="javascript: void(0)">
+                            数据模式
+                        </a>
+                    </div>
+                </div>
                 <div class="d-inline-block">
                     <div class="dropdown">
                         <button class="btn btn-sm btn-light dropdown-toggle text-primary" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
@@ -25,6 +35,59 @@
                 <div class="d-inline-block ml-2" id="final-info">
                 </div>
             </div>
+            <div class="ml-auto">
+                <div class="d-inline-block">
+                    <div class="dropdown">
+                        <button class="btn btn-sm btn-light dropdown-toggle text-primary" type="button" id="dp-stackedBar" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
+                            <i class="fa fa-list"></i> 图表数据
+                        </button>
+                        <div class="dropdown-menu pb-1" aria-labelledby="dp-stackedBar" x-placement="bottom-start" style="position: absolute; transform: translate3d(0px, 26px, 0px); top: 0px; left: 0px; will-change: transform;">
+                            <div class="px-3">
+                                <div class="form-check py-1">
+                                    <input class="form-check-input" name="stackedBar" type="checkbox" id="stackedBarGu" value="gu_tp">
+                                    <label class="form-check-label" for="stackedBarGu">估算</label>
+                                    <span class="ml-1 span-grey px-2">&nbsp;&nbsp;&nbsp;</span>
+                                </div>
+                                <div class="form-check py-1">
+                                    <input class="form-check-input" name="stackedBar" type="checkbox" id="stackedBarGai" value="gai_tp" checked="">
+                                    <label class="form-check-label" for="stackedBarGai">概算</label>
+                                    <span class="ml-1 span-red px-2">&nbsp;&nbsp;&nbsp;</span>
+                                </div>
+                                <div class="form-check py-1">
+                                    <input class="form-check-input" name="stackedBar" type="checkbox" id="stackedBarYu" value="yu_tp">
+                                    <label class="form-check-label" for="stackedBarYu">预算</label>
+                                    <span class="ml-1 span-blue px-2">&nbsp;&nbsp;&nbsp;</span>
+                                </div>
+                                <div class="form-check py-1">
+                                    <input class="form-check-input" name="stackedBar" type="checkbox" id="stackedBarLedger" value="total_price" checked="">
+                                    <label class="form-check-label" for="stackedBarLedger">台账</label>
+                                    <span class="ml-1 span-yellow px-2">&nbsp;&nbsp;&nbsp;</span>
+                                </div>
+                                <div class="form-check py-1">
+                                    <input class="form-check-input" name="stackedBar" type="checkbox" id="stackedBarFinal" value="final_tp" checked="">
+                                    <label class="form-check-label" for="stackedBarFinal">决算</label>
+                                    <span class="ml-1 span-green px-2">&nbsp;&nbsp;&nbsp;</span>
+                                </div>
+                                <hr class="m-1">
+                                <div class="float-right">
+                                    <button type="button" class="btn btn-sm btn-primary" id="stackedBar-ok">确定</button>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                <div class="d-inline-block">
+                    <div class="dropdown">
+                        <button class="btn btn-sm btn-light dropdown-toggle text-primary" type="button" id="dp-cover" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+                            <i class="fa fa-list-ol"></i> 图表样式
+                        </button>
+                        <div class="dropdown-menu" aria-labelledby="dp-cover">
+                            <a class="dropdown-item" name="stackedBarCover" tag="0" href="javascript: void(0);">堆叠</a>
+                            <a class="dropdown-item" name="stackedBarCover" tag="1" href="javascript: void(0);">覆盖</a>
+                        </div>
+                    </div>
+                </div>
+            </div>
         </div>
     </div>
     <div class="content-wrap">

+ 86 - 0
app/view/payment/detail.ejs

@@ -0,0 +1,86 @@
+<div class="panel-content">
+    <div class="panel-title fluid">
+        <div class="title-main  d-flex justify-content-between">
+            <div><a href="payment-approval-detail.html"><i class="fa fa-chevron-left mr-2"></i></a>土建01标 / 报表2 / YFK 003</div>
+            <div>
+                <a href="#add-lot" data-toggle="modal" data-target="#add-lot" class="btn btn-sm btn-warning pull-right">审批退回</a>
+                <a href="#add-lot" data-toggle="modal" data-target="#add-lot" class="btn btn-sm btn-success pull-right mr-2">审批通过</a>
+                <a href="#add-lot" data-toggle="modal" data-target="#add-lot" class="btn btn-sm btn-primary pull-right mr-2">上报审批</a>
+            </div>
+        </div>
+    </div>
+    <div class="content-wrap">
+        <div class="c-body">
+            <div class="sjs-height-0">
+                <div class="row m-0 my-3">
+                    <div class="col-6">
+                        <form>
+                            <h5>表头内容</h5>
+                            <div class="form-group">
+                                <label>编号:</label>
+                                <input type="text" class="form-control form-control-sm" placeholder="请输入">
+                            </div>
+                            <div class="form-group">
+                                <label>合同号:</label>
+                                <input type="text" class="form-control form-control-sm" placeholder="请输入">
+                            </div>
+                            <div class="form-group">
+                                <label>工程名称:</label>
+                                <input type="text" class="form-control form-control-sm" placeholder="请输入">
+                            </div>
+                            <div class="form-group">
+                                <label>项目公司名称:</label>
+                                <input type="text" class="form-control form-control-sm" placeholder="请输入">
+                            </div>
+                            <div class="form-group">
+                                <label>合同价款:</label>
+                                <input type="text" class="form-control form-control-sm" placeholder="请输入">
+                            </div>
+                            <div class="form-group">
+                                <label>已付价款:</label>
+                                <input type="text" class="form-control form-control-sm" placeholder="请输入">
+                            </div>
+                            <div class="form-group">
+                                <label>结算价款:</label>
+                                <input type="text" class="form-control form-control-sm" placeholder="请输入">
+                            </div>
+                            <h5>表单内容</h5>
+                            <div class="form-group">
+                                <label>单位名称:</label>
+                                <input type="text" class="form-control form-control-sm" placeholder="请输入">
+                            </div>
+                            <div class="form-group">
+                                <label>申请内容及金额:</label>
+                                <input type="text" class="form-control form-control-sm" placeholder="请输入">
+                            </div>
+                            <div class="form-group">
+                                <label>开票或者收据编号:</label>
+                                <input type="text" class="form-control form-control-sm" placeholder="请输入">
+                            </div>
+                            <div class="form-group">
+                                <label>开户银行:</label>
+                                <input type="text" class="form-control form-control-sm" placeholder="请输入">
+                            </div>
+                            <div class="form-group">
+                                <label>账号:</label>
+                                <input type="text" class="form-control form-control-sm" placeholder="请输入">
+                            </div>
+                            <div class="form-group">
+                                <label>联系电话:</label>
+                                <input type="text" class="form-control form-control-sm" placeholder="请输入">
+                            </div>
+                        </form>
+                    </div>
+                    <div class="col-5">
+                        <div class="d-flex flex-row">
+                            <a href="#" class="mr-2" >刷新</a>
+                            <a href="#" class="mr-2" >导出pdf</a>
+                            <a href="#">打印</a>
+                        </div>
+                        <div align="center"><img width="600px"  height="800px" src="img/表单审批.png"></div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>