Sfoglia il codice sorgente

feat: 标段概括-拷贝设置功能

lanjianrong 4 anni fa
parent
commit
3bb1e429c7

+ 9 - 5
app/controller/tender_controller.js

@@ -33,7 +33,7 @@ module.exports = app => {
             ctx.showTitle = true;
         }
 
-        async _getLedgerAuditInfo (tender) {
+        async _getLedgerAuditInfo(tender) {
             tender.cur_flow = {
                 title: '台账',
                 status: auditConst.ledger.tiStatusString[tender.ledger_status],
@@ -59,7 +59,7 @@ module.exports = app => {
             }
         }
 
-        async _getStageAuditInfo (tender, stage) {
+        async _getStageAuditInfo(tender, stage) {
             tender.cur_flow = {
                 title: '第' + stage.order + '期',
                 status: auditConst.stage.tiStatusString[stage.status],
@@ -73,11 +73,11 @@ module.exports = app => {
                     tender.cur_flow.name = user.name;
                 }
                 if (stage.order > 1) {
-                    const preStage = await this.ctx.service.stage.getDataByCondition({ tid: tender.id, order: stage.order - 1});
+                    const preStage = await this.ctx.service.stage.getDataByCondition({ tid: tender.id, order: stage.order - 1 });
                     if (!preStage) return;
 
                     const pre = await this.ctx.service.stageAudit.getLastestAuditor(preStage.id, preStage.times, auditConst.stage.status.checked);
-                    if (pre) tender.pre_flow = { name: pre.name, time: pre.end_time};
+                    if (pre) tender.pre_flow = { name: pre.name, time: pre.end_time };
                 }
             } else {
                 let cur;
@@ -120,7 +120,7 @@ module.exports = app => {
 
                 for (const t of tenderList) {
                     if (t.user_id === this.ctx.session.sessionUser.accountId && (
-                            t.ledger_status === auditConst.ledger.status.checkNo || t.ledger_status === auditConst.ledger.status.uncheck)) {
+                        t.ledger_status === auditConst.ledger.status.checkNo || t.ledger_status === auditConst.ledger.status.uncheck)) {
                         const sum = await this.ctx.service.ledger.addUp({ tender_id: t.id/* , is_leaf: true*/ });
                         t.total_price = sum.total_price;
                         t.deal_tp = sum.deal_tp;
@@ -426,7 +426,11 @@ module.exports = app => {
                     p.end_ratio = ctx.helper.mul(ctx.helper.div(p.end_tp, tender.sum, 4), 100);
                 }
                 const revise = await ctx.service.ledgerRevise.getLastestRevise(tender.id);
+                const tenders = await ctx.service.tender.getList('', null, 1);
+                const categoryData = await ctx.service.category.getAllCategory(ctx.session.sessionProject.id);
                 const renderData = {
+                    tenders,
+                    categoryData,
                     tender,
                     revise,
                     tenderInfo: ctx.tender.info,

+ 153 - 0
app/public/js/tender_copy_setting.js

@@ -0,0 +1,153 @@
+'use strict';
+
+/**
+ *
+ * @author LanJianRong
+ * @date 2020/11/13
+ * @version
+ */
+const tenderTree = [];
+let parentId = 0;
+// 查询方法
+function findNode (key, value, arr) {
+    for (const a of arr) {
+        if (a[key] && a[key] === value) {
+            return a;
+        }
+    }
+}
+// 初始化TenderTree数据
+function initTenderTree () {
+    const levelCategory = category.filter(function (c) {
+        return c.level && c.level > 0;
+    });
+    function findCategoryNode(cid, value, array) {
+        for (const a of array) {
+            if (a.cid === cid && a.vid === value) {
+                return a;
+            }
+        }
+    }
+    function getCategoryNode(category, value, parent, i = null) {
+        const array = parent ?  parent.children : tenderTree;
+        let cate = findCategoryNode(category.id, value, array);
+        if (!cate) {
+            const cateValue = findNode('id', value, category.value);
+            if (!cateValue) return null;
+            cate = {
+                cid: category.id,
+                vid: value,
+                name: cateValue.value,
+                children: [],
+                level: i ? i : category.level,
+                sort_id: ++parentId,
+                sort: cateValue.sort,
+            };
+            array.push(cate);
+        }
+        return cate;
+    }
+    function loadTenderCategory (tender) {
+        let tenderCategory = null;
+        for (const [index,lc] of levelCategory.entries()) {
+            const tenderCate = findNode('cid', lc.id, tender.category);
+            if (tenderCate) {
+                tenderCategory = getCategoryNode(lc, tenderCate.value, tenderCategory);
+            } else {
+                if (index === 0 && tender.category) {
+                    for (const [i,c] of tender.category.entries()) {
+                        const cate = findNode('id', c.cid, category);
+                        tenderCategory = getCategoryNode(cate, c.value, tenderCategory, i+1);
+                    }
+                }
+                return tenderCategory;
+            }
+        }
+        return tenderCategory;
+    }
+    function calculateTender(tender) {
+        if (tender.lastStage) {
+            tender.gather_tp = ZhCalc.add(tender.lastStage.contract_tp, tender.lastStage.qc_tp);
+            tender.end_contract_tp = ZhCalc.add(tender.lastStage.pre_contract_tp, tender.lastStage.contract_tp);
+            tender.end_qc_tp = ZhCalc.add(tender.lastStage.pre_qc_tp, tender.lastStage.qc_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);
+        }
+    }
+    tenderTree.splice(0, tenderTree.length);
+    for (const t of tenders) {
+        calculateTender(t);
+        t.valid = true;
+        delete t.level;
+        if (t.category && levelCategory.length > 0) {
+            const parent = loadTenderCategory(t);
+            if (parent) {
+                t.level = parent.level + 1;
+                parent.children.push(t);
+            } else {
+                tenderTree.push(t);
+            }
+        } else {
+            tenderTree.push(t);
+        }
+    }
+}
+function recursiveGetTenderNodeHtml (node, arr, pid) {
+    const html = [];
+    html.push('<tr pid="' + pid + '">');
+    // 名称
+    html.push('<td class="in-' + node.level + '">');
+    if (node.cid) {
+        html.push('<i class="fa fa-folder-o"></i> ', node.name);
+    } else {
+        html.push('<span class="text-muted mr-2">');
+        html.push(arr.indexOf(node) === arr.length - 1 ? '└' : '├');
+        html.push('</span>');
+        //html.push('<a href="/tender/' + node.id + '">', node[c.field], '</a>');
+        html.push('<a href="javascript: void(0)" id="' + node.id + '">', node.name, '</a>');
+    }
+    html.push('</td>');
+    // 创建人
+    html.push('<td>');
+    if (!node.cid) {
+        html.push('<input data-tid="'+ node.id +'" type="radio">');
+    }
+    html.push('</td>');
+    html.push('</tr>');
+    if (node.children) {
+        for (const c of node.children) {
+            html.push(recursiveGetTenderNodeHtml(c, node.children, node.sort_id));
+        }
+    }
+    return html.join('');
+}
+// 根据TenderTree数据获取Html代码
+function getTenderTreeHtml () {
+    if (tenderTree.length > 0) {
+        const html = [];
+        html.push('<table class="table table-hover table-bordered">');
+        html.push('<thead>', '<tr>');
+        html.push('<th>名称</th>');
+        html.push('<th width="40">选择</th>');
+        html.push('</tr>', '</thead>');
+        parentId = 0;
+        for (const t of tenderTree) {
+            html.push(recursiveGetTenderNodeHtml(t, tenderTree, ''));
+        }
+        html.push('</table>');
+        return html.join('');
+    } else {
+        return EmptyTenderHtml.join('');
+    }
+}
+$(document).ready(function () {
+    initTenderTree()
+    $('#copyBtn').click(() => {
+        console.log('1111')
+        const html = getTenderTreeHtml();
+        $('#copyModalContent').html(html)
+        $('#bd-set-8').modal('show')
+    })
+})

+ 4 - 0
app/view/tender/detail.ejs

@@ -100,6 +100,8 @@
                                 <a href="#bd-set-5" data-toggle="modal" data-target="#bd-set-5" class="btn btn-sm btn-outline-primary">显示设置</a>
                                 <a href="#bd-set-6" data-toggle="modal" data-target="#bd-set-6" class="btn btn-sm btn-outline-primary">章节设置</a>
                                 <a href="#bd-set-7" data-toggle="modal" data-target="#bd-set-7" class="btn btn-sm btn-outline-primary">付款账号</a>
+                                <i class="mx-2">|</i>
+                                <a href="javascript: void(0);" class="btn btn-sm btn-outline-primary" id="copyBtn">拷贝设置</a>
                                 <% if (ctx.session.sessionUser.is_admin) { %>
                                 <a href="/tender/<%- tender.id %>/shenpi" class="btn btn-sm btn-outline-primary">审批流程</a>
                                 <% } %>
@@ -147,6 +149,8 @@
     });
 </script>
 <script type="text/javascript">
+    const category = JSON.parse('<%- JSON.stringify(categoryData) %>');
+    const tenders = JSON.parse('<%- JSON.stringify(tenders) %>');
     //4 标段期数计量进度//
     var myChart = echarts.init(document.getElementById('chartContainer4'));
     var option = {

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

@@ -614,6 +614,45 @@
         </div>
     </div>
 </div>
+<!--批量设置-->
+<div class="modal fade" id="bd-set-8" data-backdrop="static">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">从其他标段拷贝设置</h5>
+            </div>
+            <div class="modal-body">
+                <div class="alert alert-warning mb-1">从以下标段拷贝设置</div>
+                <div class=" mb-1">
+                <a class="btn btn-sm btn-light">
+                    <div class="custom-control custom-checkbox">
+                    <input type="checkbox" class="custom-control-input" id="customCheckDisabld" checked="">
+                    <label class="custom-control-label text-primary" for="customCheckDisabld">标段属性</label>
+                    </div>
+                </a>
+                <a class="btn btn-sm btn-light">
+                    <div class="custom-control custom-checkbox">
+                    <input type="checkbox" class="custom-control-input" id="customCheckDisabld2" checked="">
+                    <label class="custom-control-label text-primary" for="customCheckDisabld2">章节设置</label>
+                    </div>
+                </a>
+                <a class="btn btn-sm btn-light">
+                    <div class="custom-control custom-checkbox">
+                    <input type="checkbox" class="custom-control-input" id="customCheckDisabld3" checked="">
+                    <label class="custom-control-label text-primary" for="customCheckDisabld3">付款账号</label>
+                    </div>
+                </a>
+                </div>
+                <div class="modal-height-300" id="copyModalContent">
+                </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">确认</button>
+            </div>
+        </div>
+    </div>
+</div>
 <script>
     let property = JSON.parse(unescape('<%- escape(JSON.stringify(tenderInfo)) %>'));
     let ledgerChecked = <%- (tender.ledger_status === audit.ledger.status.checked) && ((lastStage !== undefined && lastStage !== null) || !revise || !revise.valid || revise.status === audit.revise.status.checked) %>;

+ 3 - 1
config/web.js

@@ -102,6 +102,8 @@ const JsFiles = {
                 mergeFiles: [
                     '/public/js/spreadjs_rela/spreadjs_zh.js',
                     '/public/js/zh_calc.js',
+                    '/public/js/tender_showhide.js',
+                    '/public/js/tender_copy_setting.js',
                     // "/public/js/tender.js",
                 ],
                 mergeFile: 'tender',
@@ -278,7 +280,7 @@ const JsFiles = {
                     '/public/js/revise_gcl_compare.js',
                 ],
                 mergeFile: 'revise_gcl_compare',
-            }
+            },
         },
         stage: {
             // 本期计量台账

+ 2 - 27
sql/update.sql

@@ -1,29 +1,2 @@
-ALTER TABLE `zh_s2b_proj`
-ADD COLUMN `common_option`  text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '通用配置' AFTER `dagl_option`;
-
-ALTER TABLE `zh_tender_info` ADD `shenpi` VARCHAR(1000) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '审批流程设置' AFTER `pay_account`;
-
-ALTER TABLE `zh_material_file`
-ADD COLUMN `extra_upload` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否是审核完成后上传的,0:否、1:是' AFTER `fileext`;
-
-ALTER TABLE `zh_pos`
-MODIFY COLUMN `gxby_status`  int(4) NULL DEFAULT -1 COMMENT '工序报验-状态' AFTER `real_qty`,
-MODIFY COLUMN `dagl_status`  int(4) NULL DEFAULT -1 COMMENT '档案管理-状态' AFTER `gxby_status`;
-
-ALTER TABLE `zh_stage_attachment`
-CHANGE COLUMN `re_upload` `extra_upload` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '是否为审核通过后再次上传的文件,0为否' ;
-
-ALTER TABLE `zh_change_attachment`
-ADD COLUMN `extra_upload` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否为审核通过后再次上传的文件,0为否' AFTER `in_time`;
-
-CREATE TABLE `zh_shenpi_audit` (
-  `id` int(11) NOT NULL AUTO_INCREMENT,
-  `tid` int(11) NOT NULL COMMENT '标段id',
-  `sp_type` tinyint(4) NOT NULL COMMENT '审批流程类型',
-  `sp_status` tinyint(4) NOT NULL COMMENT '所选审批流程状态',
-  `audit_id` int(11) NOT NULL COMMENT '审批人id',
-  PRIMARY KEY (`id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='审批流程人设置表';
-
+ALTER TABLE `zh_tender`
+ADD COLUMN `copy_id` INT(10) NULL COMMENT '被拷贝标段id' AFTER `uuid`;

+ 29 - 0
sql/update20201105.sql

@@ -0,0 +1,29 @@
+ALTER TABLE `zh_s2b_proj`
+ADD COLUMN `common_option`  text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '通用配置' AFTER `dagl_option`;
+
+ALTER TABLE `zh_tender_info` ADD `shenpi` VARCHAR(1000) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '审批流程设置' AFTER `pay_account`;
+
+ALTER TABLE `zh_material_file`
+ADD COLUMN `extra_upload` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否是审核完成后上传的,0:否、1:是' AFTER `fileext`;
+
+ALTER TABLE `zh_pos`
+MODIFY COLUMN `gxby_status`  int(4) NULL DEFAULT -1 COMMENT '工序报验-状态' AFTER `real_qty`,
+MODIFY COLUMN `dagl_status`  int(4) NULL DEFAULT -1 COMMENT '档案管理-状态' AFTER `gxby_status`;
+
+ALTER TABLE `zh_stage_attachment`
+CHANGE COLUMN `re_upload` `extra_upload` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '是否为审核通过后再次上传的文件,0为否' ;
+
+ALTER TABLE `zh_change_attachment`
+ADD COLUMN `extra_upload` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否为审核通过后再次上传的文件,0为否' AFTER `in_time`;
+
+CREATE TABLE `zh_shenpi_audit` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `tid` int(11) NOT NULL COMMENT '标段id',
+  `sp_type` tinyint(4) NOT NULL COMMENT '审批流程类型',
+  `sp_status` tinyint(4) NOT NULL COMMENT '所选审批流程状态',
+  `audit_id` int(11) NOT NULL COMMENT '审批人id',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='审批流程人设置表';
+
+-- 2020/11/4 更新到uat
+-- 2020/11/5 更新到prod