Procházet zdrojové kódy

ai合同附加属性

ellisran před 6 dny
rodič
revize
c4dd3afcbe

+ 39 - 83
app/public/css/main.css

@@ -2350,89 +2350,6 @@ animation:shake 1s .2s ease both;}
     background: #ccc;
     border-radius: 3px;
 }
-/* ai按钮css */
-.ai-fill-btn {
-    position: relative;
-    border: 1px solid rgba(255,255,255,0.15);
-    color: #fff;
-    cursor: pointer;
-    overflow: hidden;
-
-    /* AI动态渐变背景 */
-    background: linear-gradient(
-            270deg,
-            #a855f7,
-            #ec4899,
-            #f59e0b,
-            #a855f7
-    );
-    background-size: 400% 400%;
-
-    animation: aiGradient 6s ease infinite;
-
-    /* 发光 */
-    box-shadow:
-            0 0 6px rgba(0, 245, 255, 0.5),
-            0 0 12px rgba(139, 92, 246, 0.35);
-
-    transition: all 0.3s ease;
-}
-
-/*.ai-fill-btn:hover {*/
-/*    color: #fff;*/
-/*    transform: translateY(-1px);*/
-/*    box-shadow: 0 4px 12px rgba(255, 107, 157, 0.55);*/
-/*}*/
-
-/* 流光 */
-.ai-fill-btn::before {
-    content: '';
-    position: absolute;
-    top: 0;
-    left: -120%;
-    width: 80%;
-    height: 100%;
-    background: linear-gradient(
-            120deg,
-            transparent,
-            rgba(255,255,255,0.35),
-            transparent
-    );
-    transform: skewX(-25deg);
-    animation: shine 3s infinite;
-}
-
-.ai-fill-btn:hover {
-    transform: translateY(-2px);
-    box-shadow:
-            0 0 8px rgba(0, 245, 255, 0.8),
-            0 0 14px rgba(139, 92, 246, 0.6);
-}
-
-@keyframes aiGradient {
-    0% {
-        background-position: 0% 50%;
-    }
-    50% {
-        background-position: 100% 50%;
-    }
-    100% {
-        background-position: 0% 50%;
-    }
-}
-
-@keyframes shine {
-    0% {
-        left: -120%;
-    }
-    100% {
-        left: 150%;
-    }
-}
-/*.ai-fill-btn i {*/
-/*    margin-right: 4px;*/
-/*}*/
-
 .ai-upload-area {
     border: 2px dashed #d9d9d9;
     border-radius: 8px;
@@ -2478,6 +2395,7 @@ animation:shake 1s .2s ease both;}
     border-top: 1px solid #ffe6b8;
     margin: 8px 0;
 }
+/* ai按钮css */
 .ai-btn {
     position: relative;
     border: 1px solid rgba(255,255,255,0.15);
@@ -2516,11 +2434,32 @@ animation:shake 1s .2s ease both;}
     animation: shine 3s infinite;
 }
 .ai-btn:hover {
+    color: #fff;
     transform: translateY(-2px);
     box-shadow:
             0 0 8px rgba(0, 245, 255, 0.8),
             0 0 14px rgba(139, 92, 246, 0.6);
 }
+@keyframes aiGradient {
+    0% {
+        background-position: 0% 50%;
+    }
+    50% {
+        background-position: 100% 50%;
+    }
+    100% {
+        background-position: 0% 50%;
+    }
+}
+
+@keyframes shine {
+    0% {
+        left: -120%;
+    }
+    100% {
+        left: 150%;
+    }
+}
 
 .ai-section-label {
     font-size: 13px;
@@ -2548,3 +2487,20 @@ animation:shake 1s .2s ease both;}
     margin-bottom: 0;
     cursor: pointer;
 }
+.attribute-scroll-area {
+    max-height: 180px;
+    overflow-y: auto;
+    overflow-x: hidden;
+    padding: 10px 10px 0;
+    border: 1px solid #dee2e6;
+    border-radius: 4px;
+    /*background: #fafafa;*/
+}
+
+.attribute-fields-group .btn {
+    text-align: left;
+}
+
+.attribute-fields-group .form-group {
+    margin-bottom: .75rem;
+}

+ 63 - 2
app/public/js/contract_detail.js

@@ -676,6 +676,7 @@ $(document).ready(function() {
                 for (const attr of attributeSet) {
                     $('#htdetail_' + attr.field).text(attrInfo && attrInfo[attr.field] ? attrInfo[attr.field] : '');
                 }
+                $('#hidden_pay_condition').val(attrInfo && attrInfo.pay_condition ? attrInfo.pay_condition : '');
                 $('#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) {
@@ -1882,14 +1883,19 @@ $(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;
+        const attrInfo = node.attribute_json ? JSON.parse(node.attribute_json) : {};
+        let havePayCondition = false;
         for (const attr of attributeSet) {
+            if (attr.field === 'pay_condition') havePayCondition = true;
             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] : '') + '">');
         }
+        if (!havePayCondition) {
+            $('#hidden_pay_condition').val(attrInfo && attrInfo.pay_condition ? attrInfo.pay_condition : '');
+        }
     }
 
     $('#save_contract_btn').on('click', function () {
@@ -1937,7 +1943,9 @@ $(document).ready(function() {
                 return;
             }
             const attrInfo = node.attribute_json ? JSON.parse(node.attribute_json) : {};
+            let havePayCondition = false;
             for (const attr of attributeSet) {
+                if (attr.field === 'pay_condition') havePayCondition = true;
                 if (attr.type === 'long_text') {
                     attrInfo[attr.field] = $('#htdetail_' + attr.field + ' textarea').val();
                     // 判断长度超过1000字提示
@@ -1963,11 +1971,15 @@ $(document).ready(function() {
                 }
                 attrInfo[attr.field] = $('#htdetail_' + attr.field + ' input').val();
             }
+            if (!havePayCondition) {
+                attrInfo.pay_condition = $('#hidden_pay_condition').val();
+            }
             data.attribute_json = JSON.stringify(attrInfo);
             // if (data.party_b === '') {
             //     toastr.warning('签订单位(乙方)不能为空');
             //     return;
             // }
+            console.log(data);
             // 更新至服务器
             postData(window.location.pathname + '/update', {postType: 'update-contract', postData: data}, function (result) {
                 toastr.success('已编辑成功');
@@ -2005,6 +2017,7 @@ $(document).ready(function() {
                 }
                 $('#htdetail_' + attr.field).text(attrInfo && attrInfo[attr.field] ? attrInfo[attr.field] : '');
             }
+            $('#hidden_pay_condition').val(attrInfo && attrInfo.pay_condition ? attrInfo.pay_condition : '');
         }
     });
 
@@ -2659,6 +2672,15 @@ $(document).ready(function() {
             }
             signDate.selectDate('');
             $('#cons-add textarea[name="remark"]').val('');
+            // 附加属性也清空
+            for (const attr of attributeSet) {
+                if (attr.type === 'long_text') {
+                    $('#cons-add textarea[name="' + attr.field + '"]').val('');
+                    continue;
+                }
+                $('#cons-add input[name="' + attr.field + '"]').val('');
+            }
+            $('#cons-add textarea[name="pay_condition"]').val('');
             // type选回第一个
             $('#cons-add select[name="type"]').val($('#cons-add select[name="type"] option:first').val());
             $('#contract-add-cid').val('');
@@ -2668,6 +2690,22 @@ $(document).ready(function() {
             $('#ai-file-panel').hide();
         });
 
+        $('#contractAttrCollapse')
+            .on('show.bs.collapse', function () {
+                $(this)
+                    .prev()
+                    .find('.attr-collapse-icon')
+                    .removeClass('fa-chevron-down')
+                    .addClass('fa-chevron-up');
+            })
+            .on('hide.bs.collapse', function () {
+                $(this)
+                    .prev()
+                    .find('.attr-collapse-icon')
+                    .removeClass('fa-chevron-up')
+                    .addClass('fa-chevron-down');
+            });
+
         $('#add-contract').click(function () {
             const node = SpreadJsObj.getSelectObject(contractSheet);
             if (!node) {
@@ -2679,6 +2717,20 @@ $(document).ready(function() {
             for (const key of edit_contract_input_key) {
                 data[key] = $('#cons-add input[name="'+ key +'"]').val();
             }
+            const attribute_json = {};
+            let havePayCondition = false;
+            for (const attr of attributeSet) {
+                if (attr.field === 'pay_condition') havePayCondition = true;
+                if (attr.type === 'long_text') {
+                    attribute_json[attr.field] = $('#cons-add textarea[name="' + attr.field + '"]').val();
+                    continue;
+                }
+                attribute_json[attr.field] = $('#cons-add input[name="' + attr.field + '"]').val();
+            }
+            if (!havePayCondition) {
+                attribute_json.pay_condition = $('#cons-add textarea[name="pay_condition"]').val();
+            }
+            data.attribute_json = JSON.stringify(attribute_json);
             const new_cid = $('#contract-add-cid').val();
             data.cid = new_cid;
             data.attach = $('#contract-add-attach').prop('checked');
@@ -4166,6 +4218,7 @@ $(document).ready(function() {
                 $('#cons-add input[name="' + key + '"]').val(data[key] || '');
             }
             signDate.selectDate(data && data.sign_date ? new Date(moment(data.sign_date).format('YYYY-MM-DD')) : '');
+            $('#cons-add textarea[name="pay_condition"]').val(data.pay_condition || '');
             $('#contract-add-cid').val(result.cid);
             if (result.file) {
                 $('#contract-add-fid').val(result.file.id || '');
@@ -4200,13 +4253,21 @@ $(document).ready(function() {
                     }
                 }
                 const attrInfo = node.attribute_json ? JSON.parse(node.attribute_json) : null;
+                let havePayCondition = false;
                 for (const attr of attributeSet) {
-                    if (attr.type === 'long_text') {
+                    if (attr.field === 'pay_condition') {
+                        havePayCondition = true;
+                        $('#htdetail_' + attr.field).html('<textarea class="form-control form-control-sm" rows="3">' + (data && data[attr.field] ? data[attr.field] : '') + '</textarea>');
+                        continue;
+                    } else 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] : '') + '">');
                 }
+                if (!havePayCondition) {
+                    $('#hidden_pay_condition').val(data && data.pay_condition ? data.pay_condition : '');
+                }
             }
             if (result.file) {
                 // 插入到files最前面

+ 1 - 0
app/service/contract.js

@@ -80,6 +80,7 @@ module.exports = app => {
                     }
                     insertData[key] = data[key] || '';
                 }
+                if (data.attribute_json) insertData.attribute_json = data.attribute_json;
                 // 删除attachments
                 if (!data.attach && data.fid) {
                     const fileInfo = await this.ctx.service.contractAtt.getDataById(data.fid);

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

@@ -95,7 +95,7 @@
                                 <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>
-                                <a href="javascript:void(0);" id="ai_edit_contract_btn" style="display: none" class="btn btn-sm ai-fill-btn pull-right mr-2"><i class="fa fa-magic"></i> AI识别编辑合同</a>
+                                <a href="javascript:void(0);" id="ai_edit_contract_btn" style="display: none" class="btn btn-sm ai-btn pull-right mr-2"><i class="fa fa-magic"></i> AI识别编辑合同</a>
                                 <a href="javascript:void(0);" id="add_contract_supplement_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">
@@ -174,6 +174,7 @@
                                         <td class="change-input-td" colspan="5" id="htdetail_remark"></td>
                                     </tr>
                                 </table>
+                                <% let tableHavePayCondition = false; %>
                                 <% if (attributeSet.length > 0) { %>
                                     <div class="mb-1">附加属性</div>
                                     <%
@@ -183,6 +184,7 @@
                                         let buffer = [];
 
                                         for (const attr of attributeSet) {
+                                            if (attr.field === 'pay_condition') tableHavePayCondition = true;
                                             if (attr.type === 'long_text') {
                                                 if (buffer.length) {
                                                     segments.push({ type: 'inline', items: [...buffer] });
@@ -227,6 +229,9 @@
                                         <% } %>
                                     </table>
                                 <% } %>
+                                <% if (!tableHavePayCondition) { %>
+                                    <textarea style="display: none" id="hidden_pay_condition"></textarea>
+                                <% } %>
                             </div>
                         </div>
                         <div class="tab-pane" id="htpay">
@@ -320,6 +325,7 @@
     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)) %>'));
+    console.log(attributeSet);
 
     const thisUrl = JSON.parse(unescape('<%- escape(JSON.stringify(thisUrl)) %>'));
     const stdChapters = JSON.parse(unescape('<%- escape(JSON.stringify(stdChapters)) %>'));

+ 91 - 2
app/view/contract/detail_modal.ejs

@@ -125,9 +125,98 @@
 
                 <div class="form-group">
                     <label>备注</label>
-                    <textarea class="form-control form-control-sm" name="remark" rows="3"></textarea>
+                    <textarea class="form-control form-control-sm" name="remark" rows="2"></textarea>
+                </div>
+                <% let havePayCondition = false; %>
+                <% if (attributeSet.length > 0) { %>
+                    <div class="attribute-fields-group">
+                        <hr class="my-2">
+
+                        <a class="btn btn-light btn-sm w-100 d-flex justify-content-between align-items-center"
+                           data-toggle="collapse"
+                           href="#contractAttrCollapse"
+                           role="button"
+                           aria-expanded="true"
+                           aria-controls="contractAttrCollapse">
+
+                            <span>
+                                <i class="fa fa-list-alt mr-1"></i>
+                                附加属性(<%= attributeSet.length %>项)
+                            </span>
+
+                            <i class="fa fa-chevron-up attr-collapse-icon"></i>
+                        </a>
+
+                        <div class="collapse show mt-2" id="contractAttrCollapse">
+
+                            <div class="attribute-scroll-area">
+
+                        <%
+                            let colCount = 0;
+                        %>
+
+                        <div class="row">
+
+                            <% for (const attr of attributeSet) { %>
+                            <% if (attr.field === 'pay_condition') { havePayCondition = true; } %>
+
+                                <% if (attr.type === 'long_text') { %>
+
+                                    <% if (colCount > 0) { %>
+                        </div>
+                        <div class="row">
+                            <% colCount = 0; %>
+                            <% } %>
+
+                            <div class="col-md-12">
+                                <div class="form-group">
+                                    <label><%- attr.alias || attr.name %></label>
+                                    <textarea
+                                            class="form-control form-control-sm"
+                                            name="<%- attr.field %>"
+                                            rows="2"></textarea>
+                                </div>
+                            </div>
+
+                        </div>
+                        <div class="row">
+
+                            <% } else { %>
+
+                                <div class="col-md-4">
+                                    <div class="form-group">
+                                        <label><%- attr.alias || attr.name %></label>
+                                        <input
+                                                class="form-control form-control-sm"
+                                                type="<%- attr.type %>"
+                                                name="<%- attr.field %>">
+                                    </div>
+                                </div>
+
+                                <% colCount++; %>
+
+                                <% if (colCount === 3) { %>
+                        </div>
+                        <div class="row">
+                            <% colCount = 0; %>
+                            <% } %>
+
+                            <% } %>
+
+                            <% } %>
+
+                        </div>
+
+                    </div>
+
                 </div>
 
+            </div>
+                <% } %>
+                <% if (!havePayCondition) { %>
+                    <textarea style="display: none" name="pay_condition"></textarea>
+                <% } %>
+
                 <!-- AI识别文件 -->
                 <div id="ai-file-panel" class="border rounded p-2 mt-2" style="display:none;">
                     <div class="d-flex justify-content-between align-items-center">
@@ -156,7 +245,7 @@
                 </div>
             </div>
             <div class="modal-footer">
-                <a href="javascript:void(0);" class="btn btn-sm ai-fill-btn" id="aiFillBtn"><i class="fa fa-magic"></i> AI识别填写</a>
+                <a href="javascript:void(0);" class="btn btn-sm ai-btn" id="aiFillBtn"><i class="fa fa-magic"></i> AI识别填写</a>
                 <input type="hidden" id="contract-add-cid">
                 <input type="hidden" id="contract-add-fid">
                 <button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">关闭</button>