Sfoglia il codice sorgente

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

Conflicts:
	sql/update.sql
MaiXinRong 2 settimane fa
parent
commit
dc3b236179

+ 11 - 2
app/controller/contract_controller.js

@@ -203,6 +203,13 @@ module.exports = app => {
                     case 'list':
                     case 'list':
                         responseData.data = await ctx.service.contractAudit.getList(options);
                         responseData.data = await ctx.service.contractAudit.getList(options);
                         break;
                         break;
+                    case 'get-contract-type':
+                        const commonJson = ctx.subProject.common_json ? JSON.parse(ctx.subProject.common_json) : null;
+                        responseData.data = commonJson && commonJson[(data.is_tender ? 'tender_' : '') + 'contract_type'] ? commonJson[(data.is_tender ? 'tender_' : '') + 'contract_type'] : [];
+                        break;
+                    case 'set-contract-type':
+                        result = await ctx.service.subProject.saveCommonJson(ctx.subProject.id, (data.is_tender ? 'tender_' : '') + 'contract_type', data.contract_type);
+                        break;
                     default: throw '参数有误';
                     default: throw '参数有误';
                 }
                 }
                 ctx.body = responseData;
                 ctx.body = responseData;
@@ -251,7 +258,7 @@ module.exports = app => {
                     incomePayList,
                     incomePayList,
                     thisUrl: `/sp/${ctx.subProject.id}` + (ctx.contract_tender ? `/contract/tender/${ctx.contract.id}/detail` : '/contract/detail'),
                     thisUrl: `/sp/${ctx.subProject.id}` + (ctx.contract_tender ? `/contract/tender/${ctx.contract.id}/detail` : '/contract/detail'),
                 };
                 };
-                await this.layout('contract/panel.ejs', renderData);
+                await this.layout('contract/panel.ejs', renderData, 'contract/setting_modal.ejs');
             } catch (err) {
             } catch (err) {
                 ctx.log(err);
                 ctx.log(err);
                 ctx.session.postError = err.toString();
                 ctx.session.postError = err.toString();
@@ -267,6 +274,8 @@ module.exports = app => {
                 const contractTreeAudits = await ctx.service.contractTreeAudit.getAllDataByCondition({ where: contractOptions });
                 const contractTreeAudits = await ctx.service.contractTreeAudit.getAllDataByCondition({ where: contractOptions });
                 const [stdBills, stdChapters] = ctx.contract.tender ? await this.ctx.service.valuation.getValuationStdList(
                 const [stdBills, stdChapters] = ctx.contract.tender ? await this.ctx.service.valuation.getValuationStdList(
                     ctx.contract.valuation, ctx.contract.measure_type) : await ctx.service.budgetStd.getStdList(ctx.subProject.std_id, 'yu');
                     ctx.contract.valuation, ctx.contract.measure_type) : await ctx.service.budgetStd.getStdList(ctx.subProject.std_id, 'yu');
+                const commonJson = ctx.subProject.common_json ? JSON.parse(ctx.subProject.common_json) : null;
+                const types = commonJson && commonJson[(ctx.contract_tender ? 'tender_' : '') + 'contract_type'] ? commonJson[(ctx.contract_tender ? 'tender_' : '') + 'contract_type'] : [];
 
 
                 const renderData = {
                 const renderData = {
                     contractTreeAudits,
                     contractTreeAudits,
@@ -276,6 +285,7 @@ module.exports = app => {
                     contract_type: ctx.contract_type,
                     contract_type: ctx.contract_type,
                     contractConst,
                     contractConst,
                     whiteList,
                     whiteList,
+                    types,
                     thisUrl: `/sp/${ctx.subProject.id}` + (ctx.contract_tender ? `/contract/tender/${ctx.contract.id}/detail` : '/contract/detail'),
                     thisUrl: `/sp/${ctx.subProject.id}` + (ctx.contract_tender ? `/contract/tender/${ctx.contract.id}/detail` : '/contract/detail'),
                     stdChapters,
                     stdChapters,
                 };
                 };
@@ -357,7 +367,6 @@ module.exports = app => {
         async updateBills(ctx) {
         async updateBills(ctx) {
             try {
             try {
                 const data = JSON.parse(ctx.request.body.data);
                 const data = JSON.parse(ctx.request.body.data);
-                console.log('data', data);
                 if (!data.postType || !data.postData) throw '数据错误';
                 if (!data.postType || !data.postData) throw '数据错误';
                 const responseData = { err: 0, msg: '', data: {} };
                 const responseData = { err: 0, msg: '', data: {} };
                 const options = ctx.helper._.cloneDeep(ctx.contractOptions);
                 const options = ctx.helper._.cloneDeep(ctx.contractOptions);

+ 11 - 1
app/public/js/contract_detail.js

@@ -10,6 +10,7 @@ $(document).ready(function() {
             {title: '项目名称/合同名称', colSpan: '1', rowSpan: '2', field: 'name', hAlign: 0, width: 360, formatter: '@', readOnly: 'readOnly.code', wordWrap: true},
             {title: '项目名称/合同名称', colSpan: '1', rowSpan: '2', field: 'name', hAlign: 0, width: 360, formatter: '@', readOnly: 'readOnly.code', wordWrap: true},
             {title: '创建人', colSpan: '1', rowSpan: '2', field: 'username', hAlign: 1, width: 80, formatter: '@', readOnly: true},
             {title: '创建人', colSpan: '1', rowSpan: '2', field: 'username', hAlign: 1, width: 80, formatter: '@', readOnly: true},
             {title: '合同金额', colSpan: '1', rowSpan: '2', field: 'total_price', hAlign: 2, width: 120, formatter: '@', readOnly: true},
             {title: '合同金额', colSpan: '1', rowSpan: '2', field: 'total_price', hAlign: 2, width: 120, formatter: '@', readOnly: true},
+            {title: '合同类型', colSpan: '1', rowSpan: '2', field: 'type', hAlign: 0, width: 120, readOnly: 'readOnly.type', cellType: 'customizeCombo', comboItems: types, cellTypeKey: 1},
             {title: '合同状态', colSpan: '1', rowSpan: '2', field: 'status', hAlign: 1, width: 100, formatter: '@', readOnly: true, getValue:'getValue.status', foreColor:'foreColor.status'},
             {title: '合同状态', colSpan: '1', rowSpan: '2', field: 'status', hAlign: 1, width: 100, formatter: '@', readOnly: true, getValue:'getValue.status', foreColor:'foreColor.status'},
         ],
         ],
         emptyRows: 0,
         emptyRows: 0,
@@ -59,6 +60,9 @@ $(document).ready(function() {
             calc: function (data) {
             calc: function (data) {
                 return !permission_edit || (data && data.children && data.children.length > 0);
                 return !permission_edit || (data && data.children && data.children.length > 0);
             },
             },
+            type: function (data) {
+                return !(data && data.c_code && !data.settle_code && (data.uid === user_id || permission_edit_contract));
+            }
         },
         },
     }
     }
     const getStackedBarTip = function (data) {
     const getStackedBarTip = function (data) {
@@ -597,6 +601,10 @@ $(document).ready(function() {
                 const col = info.sheet.zh_setting.cols[info.col];
                 const col = info.sheet.zh_setting.cols[info.col];
                 const sortData = info.sheet.zh_dataType === 'tree' ? info.sheet.zh_tree.nodes : info.sheet.zh_data;
                 const sortData = info.sheet.zh_dataType === 'tree' ? info.sheet.zh_tree.nodes : info.sheet.zh_data;
                 const node = sortData[info.row];
                 const node = sortData[info.row];
+                if (col.field === 'type' && contractCol.readOnly.type(node)) {
+                    SpreadJsObj.reLoadRowData(info.sheet, info.row);
+                    return;
+                }
 
 
                 const data = {
                 const data = {
                     id: node.id,
                     id: node.id,
@@ -928,7 +936,7 @@ $(document).ready(function() {
     };
     };
     if (permission_edit) {
     if (permission_edit) {
         contractSpread.bind(spreadNS.Events.EditStarting, contractTreeSpreadObj.editStarting);
         contractSpread.bind(spreadNS.Events.EditStarting, contractTreeSpreadObj.editStarting);
-        contractSpread.bind(spreadNS.Events.EditEnded, contractTreeSpreadObj.editEnded);
+        // contractSpread.bind(spreadNS.Events.EditEnded, contractTreeSpreadObj.editEnded);
         contractSpread.bind(spreadNS.Events.ButtonClicked, contractTreeSpreadObj.buttonClicked);
         contractSpread.bind(spreadNS.Events.ButtonClicked, contractTreeSpreadObj.buttonClicked);
         contractSpread.bind(spreadNS.Events.ClipboardPasting, contractTreeSpreadObj.clipboardPasting);
         contractSpread.bind(spreadNS.Events.ClipboardPasting, contractTreeSpreadObj.clipboardPasting);
         contractSpread.bind(spreadNS.Events.ClipboardChanging, function (e, info) {
         contractSpread.bind(spreadNS.Events.ClipboardChanging, function (e, info) {
@@ -985,6 +993,7 @@ $(document).ready(function() {
             }
             }
         };
         };
     }
     }
+    contractSpread.bind(spreadNS.Events.EditEnded, contractTreeSpreadObj.editEnded);
     if (permission_add) {
     if (permission_add) {
         contractContextMenuOptions.items.create2 = {
         contractContextMenuOptions.items.create2 = {
             name: '新增合同',
             name: '新增合同',
@@ -1765,6 +1774,7 @@ $(document).ready(function() {
                 total_price: $('#cons-add input[name="total_price"]').val(),
                 total_price: $('#cons-add input[name="total_price"]').val(),
                 party_b: $('#cons-add input[name="party_b"]').val(),
                 party_b: $('#cons-add input[name="party_b"]').val(),
                 remark: $('#cons-add textarea[name="remark"]').val(),
                 remark: $('#cons-add textarea[name="remark"]').val(),
+                type: $('#cons-add select[name="type"]').val(),
             }
             }
             if (!data.code) {
             if (!data.code) {
                 toastr.error('请输入合同编号');
                 toastr.error('请输入合同编号');

+ 1 - 0
app/service/contract.js

@@ -57,6 +57,7 @@ module.exports = app => {
                     total_price: data.total_price ? parseFloat(data.total_price) : 0,
                     total_price: data.total_price ? parseFloat(data.total_price) : 0,
                     party_b: data.party_b,
                     party_b: data.party_b,
                     remark: data.remark,
                     remark: data.remark,
+                    type: data.type,
                     create_time: new Date(),
                     create_time: new Date(),
                 };
                 };
                 insertData[this.setting.fullPath] = !node.c_code
                 insertData[this.setting.fullPath] = !node.c_code

+ 2 - 2
app/service/material_exponent.js

@@ -543,12 +543,12 @@ module.exports = app => {
             const stage_list = await ctx.service.stage.getStageMsgByStageId(stage_id);
             const stage_list = await ctx.service.stage.getStageMsgByStageId(stage_id);
             const calcBase = await ctx.service.stage.getMaterialCalcBase(stage_list, ctx.tender.info);
             const calcBase = await ctx.service.stage.getMaterialCalcBase(stage_list, ctx.tender.info);
             const old_ex_calc = ex_calc ? JSON.parse(ex_calc) : null;
             const old_ex_calc = ex_calc ? JSON.parse(ex_calc) : null;
-            const new_ex_calc = materialConst.ex_calc;
+            const new_ex_calc = this._.cloneDeep(materialConst.ex_calc);
             for (const bq of new_ex_calc) {
             for (const bq of new_ex_calc) {
                 const calc = this._.find(calcBase, { code: bq.code }) || this._.find(calcBase, { code: 'bqwc' });
                 const calc = this._.find(calcBase, { code: bq.code }) || this._.find(calcBase, { code: 'bqwc' });
                 const oldcalc = old_ex_calc ? this._.find(old_ex_calc, { code: bq.code }) : null;
                 const oldcalc = old_ex_calc ? this._.find(old_ex_calc, { code: bq.code }) : null;
                 bq.value = calc.value;
                 bq.value = calc.value;
-                bq.select = oldcalc ? oldcalc.select : false;
+                bq.select = oldcalc ? oldcalc.select : bq.select;
             }
             }
             await this.calcMaterialExTp(transaction, new_ex_calc, mid, decimal, rate);
             await this.calcMaterialExTp(transaction, new_ex_calc, mid, decimal, rate);
             return new_ex_calc;
             return new_ex_calc;

+ 4 - 4
app/service/material_exponent_shard.js

@@ -229,12 +229,12 @@ module.exports = app => {
             const stage_list = await ctx.service.stage.getStageMsgByStageId(stage_id);
             const stage_list = await ctx.service.stage.getStageMsgByStageId(stage_id);
             const calcBase = await ctx.service.stage.getMaterialCalcBase(stage_list, ctx.tender.info);
             const calcBase = await ctx.service.stage.getMaterialCalcBase(stage_list, ctx.tender.info);
             const old_ex_calc = ex_calc ? JSON.parse(ex_calc) : null;
             const old_ex_calc = ex_calc ? JSON.parse(ex_calc) : null;
-            const new_ex_calc = materialConst.ex_calc;
+            const new_ex_calc = this._.cloneDeep(materialConst.ex_calc);
             for (const bq of new_ex_calc) {
             for (const bq of new_ex_calc) {
                 const calc = this._.find(calcBase, { code: bq.code }) || this._.find(calcBase, { code: 'bqwc' });
                 const calc = this._.find(calcBase, { code: bq.code }) || this._.find(calcBase, { code: 'bqwc' });
                 const oldcalc = old_ex_calc ? this._.find(old_ex_calc, { code: bq.code }) : null;
                 const oldcalc = old_ex_calc ? this._.find(old_ex_calc, { code: bq.code }) : null;
                 bq.value = calc.value;
                 bq.value = calc.value;
-                bq.select = oldcalc ? oldcalc.select : false;
+                bq.select = oldcalc ? oldcalc.select : bq.select;
             }
             }
             await this.calcMaterialExTp(transaction, new_ex_calc, mid, msid, null, decimal, rate);
             await this.calcMaterialExTp(transaction, new_ex_calc, mid, msid, null, decimal, rate);
             return new_ex_calc;
             return new_ex_calc;
@@ -319,12 +319,12 @@ module.exports = app => {
                         old_ex_calc = JSON.parse(preMs.ex_calc);
                         old_ex_calc = JSON.parse(preMs.ex_calc);
                     }
                     }
                 }
                 }
-                const new_ex_calc = materialConst.ex_calc;
+                const new_ex_calc = this._.cloneDeep(materialConst.ex_calc);
                 for (const bq of new_ex_calc) {
                 for (const bq of new_ex_calc) {
                     const calc = this._.find(calcBase, { code: bq.code }) || this._.find(calcBase, { code: 'bqwc' });
                     const calc = this._.find(calcBase, { code: bq.code }) || this._.find(calcBase, { code: 'bqwc' });
                     const oldcalc = old_ex_calc ? this._.find(old_ex_calc, { code: bq.code }) : null;
                     const oldcalc = old_ex_calc ? this._.find(old_ex_calc, { code: bq.code }) : null;
                     bq.value = calc.value;
                     bq.value = calc.value;
-                    bq.select = oldcalc ? oldcalc.select : false;
+                    bq.select = oldcalc ? oldcalc.select : bq.select;
                 }
                 }
                 await this.calcMaterialExTp(transaction, new_ex_calc, mid, ms.id, null, decimal, rate);
                 await this.calcMaterialExTp(transaction, new_ex_calc, mid, ms.id, null, decimal, rate);
             }
             }

+ 1 - 1
app/view/change/information.ejs

@@ -615,7 +615,7 @@
         }
         }
     }
     }
     const openChangeState = <%- ctx.subProject.page_show.openChangeState ? true : false %>;
     const openChangeState = <%- ctx.subProject.page_show.openChangeState ? true : false %>;
-    const startLimit = 9;
+    const startLimit = 10;
     const settleStatus = JSON.parse('<%- JSON.stringify(settleStatus) %>');
     const settleStatus = JSON.parse('<%- JSON.stringify(settleStatus) %>');
     const removeSettleNum = <%- removeSettleNum %>;
     const removeSettleNum = <%- removeSettleNum %>;
     if (removeSettleNum > 0) {
     if (removeSettleNum > 0) {

+ 3 - 1
app/view/contract/detail.ejs

@@ -222,8 +222,10 @@
     const contractConst = JSON.parse(unescape('<%- escape(JSON.stringify(contractConst)) %>'));
     const contractConst = JSON.parse(unescape('<%- escape(JSON.stringify(contractConst)) %>'));
     let contractTreeAudits = JSON.parse(unescape('<%- escape(JSON.stringify(contractTreeAudits)) %>'));
     let contractTreeAudits = JSON.parse(unescape('<%- escape(JSON.stringify(contractTreeAudits)) %>'));
     const colSet = JSON.parse(unescape('<%- escape(JSON.stringify(colSet)) %>'));
     const colSet = JSON.parse(unescape('<%- escape(JSON.stringify(colSet)) %>'));
-    
+
     const thisUrl = JSON.parse(unescape('<%- escape(JSON.stringify(thisUrl)) %>'));
     const thisUrl = JSON.parse(unescape('<%- escape(JSON.stringify(thisUrl)) %>'));
     const stdChapters = JSON.parse(unescape('<%- escape(JSON.stringify(stdChapters)) %>'));
     const stdChapters = JSON.parse(unescape('<%- escape(JSON.stringify(stdChapters)) %>'));
+    let types = JSON.parse(unescape('<%- escape(JSON.stringify(types)) %>'));
+    types.push('');
     let contractPays = [];
     let contractPays = [];
 </script>
 </script>

+ 10 - 1
app/view/contract/detail_modal.ejs

@@ -23,6 +23,15 @@
                     <div class="invalid-feedback">合同金额不能为0。</div>
                     <div class="invalid-feedback">合同金额不能为0。</div>
                 </div>
                 </div>
                 <div class="form-group">
                 <div class="form-group">
+                    <label>合同类型</label>
+                    <select class="form-control form-control-sm" name="type">
+                        <option value=""></option>
+                        <% for (const t of types) { %>
+                        <option value="t"><%- t %></option>
+                        <% } %>
+                    </select>
+                </div>
+                <div class="form-group">
                     <label>签订单位(乙方)<b class="text-danger">*</b></label>
                     <label>签订单位(乙方)<b class="text-danger">*</b></label>
                     <input class="form-control form-control-sm" placeholder="请输入签订单位" type="text" name="party_b">
                     <input class="form-control form-control-sm" placeholder="请输入签订单位" type="text" name="party_b">
                 </div>
                 </div>
@@ -202,7 +211,7 @@
             </div>
             </div>
             <div class="modal-body">
             <div class="modal-body">
                 <div class="form-group upload-permission">
                 <div class="form-group upload-permission">
-                    <label for="formGroupExampleInput">单个文件大小限制:50MB,支持<span data-toggle="tooltip" data-placement="bottom" title="doc,docx,xls,xlsx,ppt,pptx,pdf">office等文档格式</span>、<span data-toggle="tooltip" data-placement="bottom" title="jpg,png,bmp">图片格式</span>、<span data-toggle="tooltip" data-placement="bottom" title="rar,zip">压缩包格式</span></label>
+                    <label>单个文件大小限制:50MB,支持<span data-toggle="tooltip" data-placement="bottom" title="doc,docx,xls,xlsx,ppt,pptx,pdf">office等文档格式</span>、<span data-toggle="tooltip" data-placement="bottom" title="jpg,png,bmp">图片格式</span>、<span data-toggle="tooltip" data-placement="bottom" title="rar,zip">压缩包格式</span></label>
                     <br>
                     <br>
                     <input type="file" class="" multiple>
                     <input type="file" class="" multiple>
                 </div>
                 </div>

+ 7 - 6
app/view/contract/modal.ejs

@@ -133,7 +133,7 @@
                         html += `<dd class="border-bottom p-2 mb-0 " data-id="${item.id}" >
                         html += `<dd class="border-bottom p-2 mb-0 " data-id="${item.id}" >
                         <p class="mb-0 d-flex"><span class="text-primary">${item.name}</span><span
                         <p class="mb-0 d-flex"><span class="text-primary">${item.name}</span><span
                                 class="ml-auto">${item.mobile || ''}</span>
                                 class="ml-auto">${item.mobile || ''}</span>
-                        <span class="selected-mark text-success ml-2" style="display:none;"><i class="fa fa-check"></i></span>         
+                        <span class="selected-mark text-success ml-2" style="display:none;"><i class="fa fa-check"></i></span>
                         </p>
                         </p>
                         <span class="text-muted">${item.role || ''}</span>
                         <span class="text-muted">${item.role || ''}</span>
                     </dd>`
                     </dd>`
@@ -152,7 +152,7 @@
                                 html += `<dd class="border-bottom p-2 mb-0 " data-id="${item.id}" >
                                 html += `<dd class="border-bottom p-2 mb-0 " data-id="${item.id}" >
                                     <p class="mb-0 d-flex"><span class="text-primary">${item.name}</span><span
                                     <p class="mb-0 d-flex"><span class="text-primary">${item.name}</span><span
                                             class="ml-auto">${item.mobile || ''}</span>
                                             class="ml-auto">${item.mobile || ''}</span>
-                                        <span class="selected-mark text-success ml-2" style="display:none;"><i class="fa fa-check"></i></span>        
+                                        <span class="selected-mark text-success ml-2" style="display:none;"><i class="fa fa-check"></i></span>
                                     </p>
                                     </p>
                                     <span class="text-muted">${item.role || ''}</span>
                                     <span class="text-muted">${item.role || ''}</span>
                                 </dd>`
                                 </dd>`
@@ -258,7 +258,7 @@
         }
         }
 
 
         function syncSelectedMarks() {
         function syncSelectedMarks() {
-            const tableUids = new Set(); 
+            const tableUids = new Set();
             $('#contract-audit-list tr').each(function() {
             $('#contract-audit-list tr').each(function() {
                 const $firstCheckbox = $(this).find('.permission-checkbox').first();
                 const $firstCheckbox = $(this).find('.permission-checkbox').first();
                 if ($firstCheckbox.length) {
                 if ($firstCheckbox.length) {
@@ -269,8 +269,8 @@
                 }
                 }
             });
             });
             $('.dropdown-menu .book-list dd[data-id]').each(function() {
             $('.dropdown-menu .book-list dd[data-id]').each(function() {
-                const userId = parseInt($(this).data('id'), 10); 
-                const $mark = $(this).find('.selected-mark'); 
+                const userId = parseInt($(this).data('id'), 10);
+                const $mark = $(this).find('.selected-mark');
 
 
                 if (!isNaN(userId) && $mark.length > 0) {
                 if (!isNaN(userId) && $mark.length > 0) {
                     if (tableUids.has(userId)) {
                     if (tableUids.has(userId)) {
@@ -282,7 +282,7 @@
             });
             });
         }
         }
 
 
-        
+
         $('body').on('click', '.del-contract-audit-a', function () {
         $('body').on('click', '.del-contract-audit-a', function () {
             $('#del-audit-ids').val($(this).attr('data-id'));
             $('#del-audit-ids').val($(this).attr('data-id'));
             $('#del-contract-audit').modal('show');
             $('#del-contract-audit').modal('show');
@@ -311,3 +311,4 @@
     });
     });
 </script>
 </script>
 <% } %>
 <% } %>
+<% include ./setting_modal.ejs %>

+ 5 - 0
app/view/contract/panel.ejs

@@ -4,6 +4,11 @@
         <div class="title-main  d-flex">
         <div class="title-main  d-flex">
             <% include ./sub_mini_menu.ejs %>
             <% include ./sub_mini_menu.ejs %>
             <h2>合同概况</h2>
             <h2>合同概况</h2>
+            <div class="ml-auto">
+                <% if (ctx.session.sessionUser.is_admin) { %>
+                    <a class="btn btn-sm btn-primary pull-right" href="#bd-set-1" data-toggle="modal" data-target="#bd-set-1">合同设置</a>
+                <% } %>
+            </div>
         </div>
         </div>
     </div>
     </div>
     <div class="content-wrap">
     <div class="content-wrap">

+ 106 - 0
app/view/contract/setting_modal.ejs

@@ -0,0 +1,106 @@
+<% if (ctx.session.sessionUser.is_admin) { %>
+<!--标段设置-标段属性-->
+<div class="modal fade" id="bd-set-1" 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-height-500" style="overflow-y: auto">
+                <div class="modal-body">
+                    <ul class="nav nav-tabs nav-item mb-2">
+                        <li class="nav-item">
+                            <a class="nav-link active" data-toggle="tab" href="#htxx" role="tab" aria-selected="true">合同类型</a>
+                        </li>
+                    </ul>
+                    <div class="tab-content">
+                        <div class="tab-pane active" id="htxx">
+                            <div class="my-2">
+                                <a href="javascript:void(0);" class="" id="addType">新增类型</a>
+                            </div>
+                            <table class="table table-bordered">
+                                <thead><tr class="text-center">
+                                    <th width="60%">名称</th>
+                                    <th>操作</th>
+                                </tr>
+                                </thead>
+                                <tbody class="text-center" id="type-table">
+                                </tbody>
+                            </table>
+                        </div>
+                    </div>
+                </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="set-type-btn">确认</button>
+            </div>
+        </div>
+    </div>
+</div>
+<script>
+    $(function () {
+        function setTypeTable(types) {
+            $('#type-table').empty();
+            types.forEach(type => {
+                const typeRow = `<tr>
+                                    <td><input class="form-control form-control-sm" name="value" placeholder="请输入值" value="${type}"></td>
+                                    <td>
+                                        <a href="javascript:void(0);" class="btn btn-sm text-danger remove-type-btn"><i class="fa fa-remove"></i></a>
+                                    </td>
+                                </tr>`;
+                $('#type-table').append(typeRow);
+            });
+        }
+        $('#bd-set-1').on('show.bs.modal', function () {
+            $('#type-table').empty();
+            // 看url上是否带有tender
+            const is_tender = window.location.pathname.includes('tender') ? 1 : 0;
+            console.log(window.location, is_tender);
+            postData(`/sp/${spid}/contract/audit/save`, { type: 'get-contract-type', is_tender }, function (types) {
+                setTypeTable(types);
+            });
+        });
+        $('#addType').click(function(){
+            const newType = `<tr>
+                                    <td><input class="form-control form-control-sm" name="value" placeholder="请输入值" value=""></td>
+                                    <td>
+                                        <a href="javascript:void(0);" class="btn btn-sm text-danger remove-type-btn"><i class="fa fa-remove"></i></a>
+                                    </td>
+                                </tr>`;
+            $('#type-table').append(newType);
+        });
+
+        $('body').on('click', '.remove-type-btn', function() {
+            const input = $(this).parents('td').siblings('td').eq(0).children('input');
+            input.attr('disabled', true);
+            // 文字加删除线并移除foucs
+            if (input.val() === '') {
+                input.removeAttr('placeholder');
+            }
+            input.css('text-decoration', 'line-through');
+            input.blur();
+            $(this).remove();
+        });
+
+        $('#set-type-btn').click(function() {
+            const types = [];
+            $('#type-table tr').each(function () {
+                const input = $(this).find('input[name="value"]');
+                if (!input.prop('disabled')) {
+                    const value = input.val().trim();
+                    if (value) {
+                        types.push(value);
+                    }
+                }
+            });
+            console.log(types);
+            const is_tender = window.location.pathname.includes('tender') ? 1 : 0;
+            postData(`/sp/${spid}/contract/audit/save`, { type: 'set-contract-type', contract_type: types, is_tender }, function (res) {
+                toastr.success('设置成功');
+                $('#bd-set-1').modal('hide');
+            });
+        });
+    })
+</script>
+<% } %>

+ 5 - 0
app/view/contract/tender.ejs

@@ -2,6 +2,11 @@
     <div class="panel-title fluid">
     <div class="panel-title fluid">
         <div class="title-main d-flex justify-content-between">
         <div class="title-main d-flex justify-content-between">
             <div id="show-level"></div>
             <div id="show-level"></div>
+            <div class="ml-auto">
+                <% if (ctx.session.sessionUser.is_admin) { %>
+                <a class="btn btn-sm btn-primary pull-right" href="#bd-set-1" data-toggle="modal" data-target="#bd-set-1">合同设置</a>
+                <% } %>
+            </div>
         </div>
         </div>
     </div>
     </div>
     <div class="content-wrap">
     <div class="content-wrap">

+ 4 - 1
sql/update.sql

@@ -7,6 +7,9 @@
 -- 表结构
 -- 表结构
 ------------------------------------
 ------------------------------------
 
 
+ALTER TABLE `zh_contract`
+ADD COLUMN `type` varchar(255) NULL DEFAULT '' COMMENT '合同类型(筛选的字段)' AFTER `name`;
+
 ALTER TABLE `zh_shenpi_audit`
 ALTER TABLE `zh_shenpi_audit`
 ADD COLUMN `audit_group` varchar(20) NOT NULL DEFAULT '' COMMENT '审批分组' AFTER `audit_ledger_id`,
 ADD COLUMN `audit_group` varchar(20) NOT NULL DEFAULT '' COMMENT '审批分组' AFTER `audit_ledger_id`,
 ADD COLUMN `audit_group_order` tinyint(4) NOT NULL DEFAULT 0 COMMENT '组内审批顺序' AFTER `audit_group`,
 ADD COLUMN `audit_group_order` tinyint(4) NOT NULL DEFAULT 0 COMMENT '组内审批顺序' AFTER `audit_group`,
@@ -24,4 +27,4 @@ ADD COLUMN `audit_group_need` tinyint(4) UNSIGNED NOT NULL DEFAULT 1 COMMENT '
 
 
 ------------------------------------
 ------------------------------------
 -- 表数据
 -- 表数据
-------------------------------------
+------------------------------------