فهرست منبع

附加属性显示及编辑

ellisran 1 روز پیش
والد
کامیت
eb2f9cb329
4فایلهای تغییر یافته به همراه119 افزوده شده و 26 حذف شده
  1. 1 1
      app/const/contract.js
  2. 3 0
      app/controller/contract_controller.js
  3. 36 0
      app/public/js/contract_detail.js
  4. 79 25
      app/view/contract/detail.ejs

+ 1 - 1
app/const/contract.js

@@ -82,7 +82,7 @@ const defaultColSet = {
 };
 
 const attributeSet = [
-    { name: '数值', field: 'num_val', fixed: [], type: 'int', type_name: '数字' },
+    { name: '数值', field: 'num_val', fixed: [], type: 'number', type_name: '数字' },
     { name: '丙方', field: 'party_c', fixed: [], type: 'text', type_name: '文本' },
     { name: '丁方', field: 'party_d', fixed: [], type: 'text', type_name: '文本' },
     { name: '文本', field: 'text', fixed: [], type: 'text', type_name: '文本' },

+ 3 - 0
app/controller/contract_controller.js

@@ -332,6 +332,9 @@ module.exports = app => {
                     const groupList = accountList.filter(item1 => item1.company === item.name);
                     return { groupName: item.name, groupList };
                 }).filter(x => { return x.groupList.length > 0; });
+                const contractAttributeSet = commonJson && commonJson.contract_attribute ? commonJson.contract_attribute : contractConst.attributeSet;
+                const attributeSet = ctx.service.contractColSet.analysisColSetWithDefine(contractConst.attributeSet, contractAttributeSet, contractConst.defaultAttributeSet);
+                renderData.attributeSet = ctx.helper._.filter(attributeSet, { show: 1 });
                 await this.layout('contract/detail.ejs', renderData, 'contract/detail_modal.ejs');
             } catch (err) {
                 ctx.log(err);

+ 36 - 0
app/public/js/contract_detail.js

@@ -352,6 +352,11 @@ $(document).ready(function() {
                         $('#htdetail_' + c).text(node[c] || '');
                     }
                     $('#htdetail_df_price').text(ZhCalc.sub(node.yf_price, node.sf_price) || '');
+                    const attrInfo = node.attribute_json ? JSON.parse(node.attribute_json) : null;
+                    for (const attr of attributeSet) {
+                        $('#htdetail_' + attr.field).text(attrInfo && attrInfo[attr.field] ? attrInfo[attr.field] : '');
+                    }
+
                 }
             } else if ($('.bc-bar .nav li .active').attr('href') === '#htpay') {
                 $('#edit_contract_btn').hide();
@@ -554,6 +559,7 @@ $(document).ready(function() {
 
             if (node && node.c_code) {
                 $('#htdetail-table').show();
+                $('#htdetail-attr').show();
                 $('#htpay-table').show();
                 $('#htfile-table').show();
                 for (const c of contractDetail) {
@@ -566,6 +572,10 @@ $(document).ready(function() {
                     }
                     $('#htdetail_' + c).text(node[c] || '');
                 }
+                const attrInfo = node.attribute_json ? JSON.parse(node.attribute_json) : null;
+                for (const attr of attributeSet) {
+                    $('#htdetail_' + attr.field).text(attrInfo && attrInfo[attr.field] ? attrInfo[attr.field] : '');
+                }
                 $('#htdetail_df_price').text(ZhCalc.sub(node.yf_price, node.sf_price) || '');
                 if (needPost) {
                     postData(window.location.pathname + '/update', {postType: 'get-contract', postData: node.id}, function (result) {
@@ -578,6 +588,7 @@ $(document).ready(function() {
                 }
             } else {
                 $('#htdetail-table').hide();
+                $('#htdetail-attr').hide();
                 $('#htpay-table').hide();
                 $('#htfile-table').hide();
                 $('#edit_contract_btn').hide();
@@ -1654,6 +1665,14 @@ $(document).ready(function() {
                     $('#htdetail_' + c).html('<input type="text" class="form-control form-control-sm" value="' + node[c] + '">');
                 }
             }
+            const attrInfo = node.attribute_json ? JSON.parse(node.attribute_json) : null;
+            for (const attr of attributeSet) {
+                if (attr.type === 'long_text') {
+                    $('#htdetail_' + attr.field).html('<textarea class="form-control form-control-sm" rows="3">' + (attrInfo && attrInfo[attr.field] ? attrInfo[attr.field] : '') + '</textarea>');
+                    continue;
+                }
+                $('#htdetail_' + attr.field).html('<input type="' + attr.type + '" class="form-control form-control-sm" value="' + (attrInfo && attrInfo[attr.field] ? attrInfo[attr.field] : '') + '">');
+            }
         }
     });
 
@@ -1675,6 +1694,15 @@ $(document).ready(function() {
                     data[c] = $('#htdetail_' + c + ' input').val();
                 }
             }
+            const attrInfo = node.attribute_json ? JSON.parse(node.attribute_json) : {};
+            for (const attr of attributeSet) {
+                if (attr.type === 'long_text') {
+                    attrInfo[attr.field] = $('#htdetail_' + attr.field + ' textarea').val();
+                    continue;
+                }
+                attrInfo[attr.field] = $('#htdetail_' + attr.field + ' input').val();
+            }
+            data.attribute_json = JSON.stringify(attrInfo);
             if (data.c_code === '' || data.name === '') {
                 toastr.warning('合同编号和合同名称不能为空');
                 return;
@@ -1730,6 +1758,14 @@ $(document).ready(function() {
                     }
                 }
             }
+            const attrInfo = node.attribute_json ? JSON.parse(node.attribute_json) : {};
+            for (const attr of attributeSet) {
+                if (attr.type === 'long_text') {
+                    $('#htdetail_' + attr.field).text(attrInfo && attrInfo[attr.field] ? attrInfo[attr.field] : '');
+                    continue;
+                }
+                $('#htdetail_' + attr.field).text(attrInfo && attrInfo[attr.field] ? attrInfo[attr.field] : '');
+            }
         }
     });
 

+ 79 - 25
app/view/contract/detail.ejs

@@ -15,7 +15,7 @@
                         <a class="dropdown-item" name="showLevel" tag="4" href="javascript: void(0);">第四层</a>
                         <a class="dropdown-item" name="showLevel" tag="5" href="javascript: void(0);">第五层</a>
                         <a class="dropdown-item" name="showLevel" tag="last" href="javascript: void(0);">最底层</a>
-<!--                        <a class="dropdown-item" name="showLevel" tag="leafXmj" href="javascript: void(0);">只显示项目节</a>-->
+                        <!--                        <a class="dropdown-item" name="showLevel" tag="leafXmj" href="javascript: void(0);">只显示项目节</a>-->
                     </div>
                 </div>
             </div>
@@ -28,20 +28,20 @@
                     <a href="javascript: void(0);" name="base-opr" type="down-level" class="btn btn-sm btn-light text-primary" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="降级"><i class="fa fa-arrow-right" aria-hidden="true"></i></a>
                     <a href="javascript: void(0);" name="base-opr" type="down-move" class="btn btn-sm btn-light text-primary" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="下移"><i class="fa fa-arrow-down" aria-hidden="true"></i></a>
                     <a href="javascript: void(0);" name="base-opr" type="up-move" class="btn btn-sm btn-light text-primary" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="上移"><i class="fa fa-arrow-up" aria-hidden="true"></i></a>
-<!--                    <a href="javascript: void(0);" name="cpc" type="copy" class="btn btn-sm btn-light text-primary" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="复制"><i class="fa fa-files-o" aria-hidden="true"></i></a>-->
-<!--                    <a href="javascript: void(0);" name="cpc" type="cut" class="btn btn-sm btn-light text-primary" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="剪切"><i class="fa fa-scissors" aria-hidden="true"></i></a>-->
-<!--                    <a href="javascript: void(0);" name="cpc" type="paste" class="btn btn-sm btn-light text-primary" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="粘贴"><i class="fa fa-clipboard" aria-hidden="true"></i></a>-->
+                    <!--                    <a href="javascript: void(0);" name="cpc" type="copy" class="btn btn-sm btn-light text-primary" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="复制"><i class="fa fa-files-o" aria-hidden="true"></i></a>-->
+                    <!--                    <a href="javascript: void(0);" name="cpc" type="cut" class="btn btn-sm btn-light text-primary" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="剪切"><i class="fa fa-scissors" aria-hidden="true"></i></a>-->
+                    <!--                    <a href="javascript: void(0);" name="cpc" type="paste" class="btn btn-sm btn-light text-primary" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="粘贴"><i class="fa fa-clipboard" aria-hidden="true"></i></a>-->
                 </div>
             <% } %>
             <div class="ml-auto">
                 <% if (ctx.session.sessionUser.is_admin) { %>
-                  <a href="#col-set" data-toggle="modal" data-target="#col-set" class="btn btn-sm btn-primary mr-2">列设置</a>
-                <a href="javascript:void(0);" data-stid="<%- ctx.contract_tender ? ctx.contractOptions.tid : '' %>" class="btn btn-sm btn-primary get-audits mr-2">成员管理</a>
-                <a href="#empower" data-toggle="modal" data-target="#empower" class="btn btn-sm btn-primary mr-2">节点授权</a>
+                    <a href="#col-set" data-toggle="modal" data-target="#col-set" class="btn btn-sm btn-primary mr-2">列设置</a>
+                    <a href="javascript:void(0);" data-stid="<%- ctx.contract_tender ? ctx.contractOptions.tid : '' %>" class="btn btn-sm btn-primary get-audits mr-2">成员管理</a>
+                    <a href="#empower" data-toggle="modal" data-target="#empower" class="btn btn-sm btn-primary mr-2">节点授权</a>
                 <% } %>
-<!--                <a href="#cons-relat" data-toggle="modal" data-target="#cons-relat" class="btn btn-primary btn-sm pull-right">关联合同</a>-->
+                <!--                <a href="#cons-relat" data-toggle="modal" data-target="#cons-relat" class="btn btn-primary btn-sm pull-right">关联合同</a>-->
                 <% if (ctx.session.sessionUser.is_admin || audit_permission.permission_add) { %>
-                <a href="#cons-add" data-toggle="modal" data-target="#cons-add" class="btn btn-primary btn-sm pull-right mr-2" id="add-cons-btn" style="display: none">新增合同</a>
+                    <a href="#cons-add" data-toggle="modal" data-target="#cons-add" class="btn btn-primary btn-sm pull-right mr-2" id="add-cons-btn" style="display: none">新增合同</a>
                 <% } %>
             </div>
         </div>
@@ -86,14 +86,14 @@
                                 <!-- 合同文件的按钮 -->
                                 <a href="#cons-upfile" data-toggle="modal" data-target="#cons-upfile" style="display: none;" class="btn btn-primary btn-sm pull-right mr-2">上传文件</a>
                                 <!-- 合同支付的按钮 -->
-<!--                                <a href="#cons-addpay2" data-toggle="modal" data-target="#cons-addpay2" class="btn btn-primary btn-sm pull-right mr-2">添加回款2</a>-->
+                                <!--                                <a href="#cons-addpay2" data-toggle="modal" data-target="#cons-addpay2" class="btn btn-primary btn-sm pull-right mr-2">添加回款2</a>-->
                                 <a href="javascript:void(0);" id="add_contract_pay_btn" style="display: none;" class="btn btn-primary btn-sm pull-right mr-2">添加<% if (ctx.contract_type === contractConst.type.expenses) { %>支付<% } else if (ctx.contract_type === contractConst.type.income) { %>回款<% } %></a>
                                 <!-- 合同详情的按钮,点击编辑出现确定和取消按钮 -->
                                 <a href="javascript:void(0);" id="cancel_contract_btn" style="display: none" class="btn btn-secondary btn-sm pull-right mr-2">取消</a>
                                 <a href="javascript:void(0);" id="save_contract_btn" style="display: none" class="btn btn-primary btn-sm pull-right mr-2">确定</a>
                                 <a href="javascript:void(0);" id="edit_contract_btn" style="display: none" class="btn btn-primary btn-sm pull-right mr-2">编辑合同</a>
                                 <% if (shenpi_status) { %>
-                                <span class="pull-right mr-2" id="shenpi_btn">
+                                    <span class="pull-right mr-2" id="shenpi_btn">
                                     <a href="#sub-sp" data-toggle="modal" data-target="#sub-sp" class="btn btn-primary btn-sm">待上报</a>
                                 </span>
                                 <% } %>
@@ -103,7 +103,7 @@
                     <div class="tab-content">
                         <div class="tab-pane active" id="htdetail">
                             <div class="sp-wrap col-12" style="overflow: auto;">
-                                <table class="table table-sm table-bordered" id="htdetail-table" style="display: none;">
+                                <table class="table table-sm table-bordered mb-1" id="htdetail-table" style="display: none;">
                                     <tr>
                                         <th class="text-center align-middle" width="10%">合同编号</th>
                                         <td width="20%" class="change-input-td" id="htdetail_c_code"></td>
@@ -145,14 +145,14 @@
                                         <td class="change-input-td" id="htdetail_address"></td>
                                     </tr>
                                     <% if (ctx.contract_type === contractConst.type.expenses) { %>
-                                    <tr class="contract-expenses">
-                                        <th class="text-center align-middle">收款单位</th>
-                                        <td class="change-input-td" id="htdetail_entity"></td>
-                                        <th class="text-center align-middle">收款开户行</th>
-                                        <td class="change-input-td" id="htdetail_bank"></td>
-                                        <th class="text-center align-middle">收款账号</th>
-                                        <td class="change-input-td" id="htdetail_bank_account"></td>
-                                    </tr>
+                                        <tr class="contract-expenses">
+                                            <th class="text-center align-middle">收款单位</th>
+                                            <td class="change-input-td" id="htdetail_entity"></td>
+                                            <th class="text-center align-middle">收款开户行</th>
+                                            <td class="change-input-td" id="htdetail_bank"></td>
+                                            <th class="text-center align-middle">收款账号</th>
+                                            <td class="change-input-td" id="htdetail_bank_account"></td>
+                                        </tr>
                                     <% } %>
                                     <tr>
                                         <th class="text-center align-middle">结算书编号</th>
@@ -165,6 +165,59 @@
                                         <td class="change-input-td" colspan="5" id="htdetail_remark"></td>
                                     </tr>
                                 </table>
+                                <% if (attributeSet.length > 0) { %>
+                                    <div class="mb-1">附加属性</div>
+                                    <%
+                                        // 按顺序分组:遇到 long_text 就切断,形成 segments
+                                        // segments 结构:[{ type: 'inline', items: [...] }, { type: 'long', item: {...} }, ...]
+                                        const segments = [];
+                                        let buffer = [];
+
+                                        for (const attr of attributeSet) {
+                                            if (attr.type === 'long_text') {
+                                                if (buffer.length) {
+                                                    segments.push({ type: 'inline', items: [...buffer] });
+                                                    buffer = [];
+                                                }
+                                                segments.push({ type: 'long', item: attr });
+                                            } else {
+                                                buffer.push(attr);
+                                            }
+                                        }
+                                        if (buffer.length) segments.push({ type: 'inline', items: [...buffer] });
+
+                                        // 每行3列对应的 td 宽度
+                                        const tdWidths = ['20%', '30%', '20%'];
+                                    %>
+                                    <table class="table table-sm table-bordered" id="htdetail-attr" style="display: none;">
+                                        <% for (const seg of segments) { %>
+                                            <% if (seg.type === 'long') { %>
+                                                <tr>
+                                                    <th class="text-center align-middle" width="10%"><%- seg.item.alias %></th>
+                                                    <td class="change-input-td" colspan="5"
+                                                        data-type="<%- seg.item.field %>"
+                                                        id="htdetail_<%- seg.item.field %>"></td>
+                                                </tr>
+                                            <% } else { %>
+                                                <% for (let i = 0; i < seg.items.length; i += 3) { %>
+                                                    <% const row = seg.items.slice(i, i + 3) %>
+                                                    <tr>
+                                                        <% for (let k = 0; k < row.length; k++) { %>
+                                                            <th class="text-center align-middle" width="10%"><%- row[k].alias %></th>
+                                                            <td width="<%= tdWidths[k] %>" class="change-input-td"
+                                                                data-type="<%- row[k].field %>"
+                                                                id="htdetail_<%- row[k].field %>"></td>
+                                                        <% } %>
+                                                        <% if (row.length < 3) { %>
+                                                            <% const remainColspan = (3 - row.length) * 2 %>
+                                                            <td colspan="<%= remainColspan %>"></td>
+                                                        <% } %>
+                                                    </tr>
+                                                <% } %>
+                                            <% } %>
+                                        <% } %>
+                                    </table>
+                                <% } %>
                             </div>
                         </div>
                         <div class="tab-pane" id="htpay">
@@ -175,13 +228,13 @@
                                         <% if (ctx.contract_type === contractConst.type.income) { %>
                                             <th width="4%">序号</th><th width="5%">回款日期</th><th width="5%">用途</th><th width="7%">回款金额</th><th width="7%">扣款金额</th><th width="7%">应回金额</th><th width="7%">实回金额</th><th width="5%">回款方式</th><th width="5%">创建人</th><th width="9%">创建时间</th><th width="10%">备注</th><th width="4%">附件</th>
                                             <% if (pay_shenpi_status) { %>
-                                            <th width="15%">审批进度</th>
+                                                <th width="15%">审批进度</th>
                                             <% } %>
                                             <th width="10%">操作</th>
                                         <% } else if (ctx.contract_type === contractConst.type.expenses) { %>
                                             <th width="4%">序号</th><th width="5%">支付日期</th><th width="5%">用途</th><th width="7%">付款金额</th><th width="7%">扣款金额</th><th width="7%">应付金额</th><th width="7%">实付金额</th><th width="5%">支付方式</th><th width="5%">创建人</th><th width="9%">创建时间</th><th width="10%">备注</th><th width="4%">附件</th>
                                             <% if (pay_shenpi_status) { %>
-                                            <th width="15%">审批进度</th>
+                                                <th width="15%">审批进度</th>
                                             <% } %>
                                             <th width="10%">操作</th>
                                         <% } %>
@@ -196,9 +249,9 @@
                             <div class="sp-wrap" style="overflow: auto">
                                 <table class="table table-sm table-bordered" id="htfile-table" style="display: none;">
                                     <thead>
-                                        <tr class="text-center">
-                                            <th width="5%">序号</th><th>名称</th><th width="5%">上传人</th><th width="15%">上传时间</th><th width="15%">操作</th>
-                                        </tr>
+                                    <tr class="text-center">
+                                        <th width="5%">序号</th><th>名称</th><th width="5%">上传人</th><th width="15%">上传时间</th><th width="15%">操作</th>
+                                    </tr>
                                     </thead>
                                     <tbody>
                                     </tbody>
@@ -240,6 +293,7 @@
     const auditType = JSON.parse(unescape('<%- escape(JSON.stringify(auditType)) %>'));
     const accountGroup3 = JSON.parse(unescape('<%- escape(JSON.stringify(accountGroup)) %>'));
     const accountList3 = JSON.parse(unescape('<%- escape(JSON.stringify(accountList)) %>'));
+    const attributeSet = JSON.parse(unescape('<%- escape(JSON.stringify(attributeSet)) %>'));
 
     const thisUrl = JSON.parse(unescape('<%- escape(JSON.stringify(thisUrl)) %>'));
     const stdChapters = JSON.parse(unescape('<%- escape(JSON.stringify(stdChapters)) %>'));