소스 검색

批量加款,加款银行调整

lowkeyman 5 달 전
부모
커밋
04c2a5bab6
2개의 변경된 파일185개의 추가작업 그리고 55개의 파일을 삭제
  1. 19 2
      admin/templates/default/js/stats-component.js
  2. 166 53
      admin/templates/default/refill_amount_stats.index.php

+ 19 - 2
admin/templates/default/js/stats-component.js

@@ -134,6 +134,7 @@ function sortByName(list, key) {
 
 /*
  * 合并二维数据,表格数据合并/通道机构配置项合并
+ * 注意data1和data2的位置,data1为本平台的缓存,data2为导入的数据
  */
 function mergeData(data1, data2, key, systemTag) {
     let dataMormalMerge = [];
@@ -240,6 +241,20 @@ function formatDateTime(dateString) {
     return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
 }
 
+/*
+ * 过滤json数组,仅保留需要的字段
+ */
+function filterJsonFields(jsonArray, fieldsToKeep) {
+    return jsonArray.map(item => {
+        return fieldsToKeep.reduce((filteredItem, field) => {
+            if (field in item) {
+                filteredItem[field] = item[field];
+            }
+            return filteredItem;
+        }, {});
+    });
+}
+
 function isObjectEmpty(obj) {
     return Object.keys(obj).length === 0;
 }
@@ -1180,7 +1195,8 @@ class GlobalDataBase {
                     payment_design: item.payment_design,
                     store_id: item.store_id,
                     store_name: item.store_name,
-                    tag: item.tag
+                    tag: item.tag,
+                    pay_operation: item.pay_operation
                 };
             });
         },
@@ -1192,7 +1208,8 @@ class GlobalDataBase {
                     payment_design: item.payment_design,
                     store_id: item.store_id,
                     store_name: item.store_name,
-                    tag: item.tag
+                    tag: item.tag,
+                    pay_operation: item.pay_operation
                 };
             });
         }

+ 166 - 53
admin/templates/default/refill_amount_stats.index.php

@@ -59,7 +59,7 @@
     .stats-panel {
         margin-top: 40px;
         margin-left: 30px;
-        width: 1532px;
+        width: 1652px;
         overflow-x: auto;
     }
 
@@ -334,6 +334,16 @@
         background-color: #EF949F !important;
         /*color: #0e0e0e !important;*/
     }
+
+    #rechargeManual {
+        width: 700px;
+    }
+
+    #rechargeManualApprove {
+        display:none;
+        padding: 20px;
+        width: 1160px;
+    }
 </style>
 
 <div class="page" id="app">
@@ -414,27 +424,27 @@
         <div class="layui-form-item" id="rechargeConfirmItems">
             <table class="layui-hide" id="upstream_tb_transfer"></table>
         </div>
-        <div class="layui-form paymodel-form">
-            <div class="layui-form-item">
-                <label class="layui-form-label paymodel-label">
-                    <label class="red paymodel-red">*</label> 操作人姓名:
-                </label>
-                <div class="layui-input-inline paymodel-input-inline">
-                    <input type="text" id="inputPayOperation" class="layui-input paymodel-input" />
-                </div>
-            </div>
-            <div class="layui-form-item">
-                <label class="layui-form-label paymodel-label">备注:</label>
-                <div class="layui-input-inline paymodel-input-inline">
-                    <textarea id="inputPaybz" class="layui-textarea paymodel-textarea"></textarea>
-                </div>
-            </div>
-        </div>
+<!--        <div class="layui-form paymodel-form">-->
+<!--            <div class="layui-form-item">-->
+<!--                <label class="layui-form-label paymodel-label">-->
+<!--                    <label class="red paymodel-red">*</label> 操作人姓名:-->
+<!--                </label>-->
+<!--                <div class="layui-input-inline paymodel-input-inline">-->
+<!--                    <input type="text" id="inputPayOperation" class="layui-input paymodel-input" />-->
+<!--                </div>-->
+<!--            </div>-->
+<!--            <div class="layui-form-item">-->
+<!--                <label class="layui-form-label paymodel-label">备注:</label>-->
+<!--                <div class="layui-input-inline paymodel-input-inline">-->
+<!--                    <textarea id="inputPaybz" class="layui-textarea paymodel-textarea"></textarea>-->
+<!--                </div>-->
+<!--            </div>-->
+<!--        </div>-->
         <div id="rechargeTips"></div>
     </div>
 
     <!-- 审核 -->
-    <div id="rechargeManualApprove" style="display:none; padding: 20px;">
+    <div id="rechargeManualApprove">
         <table class="layui-hide" id="upstream_tb_approve"></table>
     </div>
 
@@ -656,10 +666,11 @@
                         return chan.name === item.name && chan.tag === item.tag;
                     });
 
-                    let tableItem = {}, alarm_amount = '0', payment_design = '0';
+                    let tableItem = {}, alarm_amount = '0', payment_design = '0', pay_operation = '';
                     if (setting) {
                         alarm_amount = setting.alarm_amount ?? '0';
                         payment_design = setting.payment_design ?? '0';
+                        pay_operation = setting.pay_operation ?? '';
                     }
 
                     tableItem['transfer'] = globalData.getPayinfoAmount(item.store_id, item.tag);
@@ -673,6 +684,7 @@
                     tableItem['alarm_amount'] = formatDecimals(alarm_amount);
                     tableItem['payment_design'] = formatDecimals(payment_design);
                     tableItem['upstream_group'] = '';
+                    tableItem['pay_operation'] = pay_operation;
 
                     tableData.push(tableItem);
                 }
@@ -684,7 +696,7 @@
 
                 let sortCust = [];
                 if (!isObjectEmpty(copyData)) {
-                    sortCust = mergeData(this.getCopySortChan(), chanCust, 'store_name', systemTag);
+                    sortCust = mergeData(chanCust, this.getCopySortChan(), 'store_name', systemTag);
                 } else {
                    sortCust = chanCust;
                 }
@@ -696,7 +708,7 @@
 
                 //更新统计字段的值:表格合并后是展示第一条数据的值,取值逻辑:当前组第一条不为0的数据
                 const groupUpdates = {}, groupAvailablePredeposit = {};
-                chanDataSort.forEach((item) => {
+                chanDataSort.forEach(item => {
                     if (!groupAvailablePredeposit[item.upstream_group]) {
                         groupAvailablePredeposit[item.upstream_group] = 0;
                     }
@@ -706,7 +718,8 @@
                     if (!groupUpdates[item.upstream_group]) {
                         groupUpdates[item.upstream_group] = {
                             alarm_amount: '0',
-                            payment_design: '0'
+                            payment_design: '0',
+                            pay_operation: ''
                         };
                     }
                     if (groupUpdates[item.upstream_group].alarm_amount === '0' && item.alarm_amount !== '0') {
@@ -715,20 +728,26 @@
                     if (groupUpdates[item.upstream_group].payment_design === '0' && item.payment_design !== '0') {
                         groupUpdates[item.upstream_group].payment_design = item.payment_design;
                     }
+                    if (groupUpdates[item.upstream_group].pay_operation === '' && item.pay_operation !== '') {
+                        groupUpdates[item.upstream_group].pay_operation = item.pay_operation;
+                    }
                 });
 
                 chanDataSort.forEach((item) => {
                     if (groupUpdates[item.upstream_group] !== undefined) {
                         item.alarm_amount = groupUpdates[item.upstream_group].alarm_amount;
                         item.payment_design = groupUpdates[item.upstream_group].payment_design;
+                        item.pay_operation = groupUpdates[item.upstream_group].pay_operation;
                     }
                 });
+
                 this.setChannelData(chanDataSort);
             }
 
             syncChannelData() {
                 const channelCust = this.getChannelSettings();
                 const cacheKey = this.getCacheKey();
+
                 statsApi.setStatsSettings(cacheKey, channelCust)
                     .then(function (data) {
                         if (data.state !== true) {
@@ -773,6 +792,7 @@
                         if (itemData.upstream_group === groupName) {
                             item.alarm_amount = itemData.alarm_amount;
                             item.payment_design = itemData.payment_design;
+                            item.pay_operation = itemData.pay_operation;
                         }
                     });
                 } else if (action ==='del') {
@@ -809,6 +829,7 @@
                         {field: 'plan_payment_amount', title: '预计打款金额', width: 150},
                         {field: 'payment_design', title: '打款设计', width: 110},
                         {field: 'upstream_group', title: '需打款上游', width: 100},
+                        {field: 'pay_operation', title: '操作人姓名', width: 120},
                         {field: 'delete', title: '删除', width: 100, templet: function(d){return '<button class="layui-btn layui-btn-sm delete-btn" data-index="'+d.LAY_TABLE_INDEX+'">删除</button>';}},
                         {field: 'transfer_action', title: '调款', width: 160, templet: function(d){
                             return '<button class="layui-btn layui-btn-sm transfer-btn" data-index="'+d.LAY_TABLE_INDEX+'">单个加款</button>' +
@@ -830,9 +851,9 @@
                         that.mergeCells();
 
                         trs.each(function(i, tr) {
-                            const editColumns = ['transfer', 'alarm_amount', 'payment_design'];
+                            const editNumberColumns = ['transfer', 'alarm_amount', 'payment_design'];
 
-                            for(let col of editColumns) {
+                            for(let col of editNumberColumns) {
                                 const td = $(tr).find('td[data-field="' + col + '"]').not('.layui-hide');
                                 if (td.length > 0) {//合并隐藏的不处理
                                     const valDiv = td.find('div');
@@ -901,6 +922,34 @@
                                         });
                                 }
                             }
+
+                            const editTextColumns = ['pay_operation'];
+
+                            for(let col of editTextColumns) {
+                                const td = $(tr).find('td[data-field="' + col + '"]').not('.layui-hide');
+                                if (td.length > 0) {//合并隐藏的不处理
+                                    const valDiv = td.find('div');
+                                    let val = valDiv.text().trim();
+                                    valDiv.html(val);
+                                    valDiv.attr('contenteditable', true).css('background-color', 'lightblue');
+
+                                    valDiv.off('input')
+                                        .off('keypress')
+                                        .off('blur')
+                                        .on('input')
+                                        .on('keypress', function(e) {
+                                            if (e.keyCode === 13) {
+                                                e.preventDefault();
+                                                $(this).blur();
+                                            }
+                                        })
+                                        .on('blur', function() {
+                                            const index = $(this).parent().parent().data('index');
+                                            that.saveEdit(index);
+                                            that.syncChannelData();
+                                        });
+                                }
+                            }
                         });
 
                         tableItem.next('.layui-table-view').find('.layui-table-body tbody').append(
@@ -981,6 +1030,7 @@
                 const alarm_amount = tr.find('td[data-field="alarm_amount"]').find('div').text().trim();
                 const payment_design = tr.find('td[data-field="payment_design"]').find('div').text().trim();
                 const transfer = tr.find('td[data-field="transfer"]').find('div').text().trim();
+                const pay_operation = tr.find('td[data-field="pay_operation"]').find('div').text().trim();
 
                 //由于这几列按组合并了,在更新的时候,要给组内的每一条数据同步相同的值
                 const groupName = channelData[index].upstream_group;
@@ -989,6 +1039,7 @@
                         item.alarm_amount = alarm_amount || "0";
                         item.payment_design = payment_design || "0";
                         item.transfer = transfer || "0";
+                        item.pay_operation = pay_operation || "";
 
                         if (groupAvailablePredeposit[item.upstream_group] !== undefined) {
                             const planPaymentAmount = parseFloat(groupAvailablePredeposit[item.upstream_group]) - parseFloat(item.alarm_amount);
@@ -997,6 +1048,7 @@
                         if (groupTransfer[item.upstream_group] !== undefined) {
                             item.payment_deviation = parseFloat(groupTransfer[item.upstream_group]) - parseFloat(item.alarm_amount);
                         }
+
                         that.updateChannelCache(item, 'edit');
                     }
                 });
@@ -1021,8 +1073,8 @@
                 for (let group in upstreamMap) {
                     const info = upstreamMap[group];
                     if (info.count > 1) {
-                        //合并的列:打款预警金额/预计打款金额/打款设计/打款上游/调款按钮
-                        const mergeColumns = ['alarm_amount', 'plan_payment_amount', 'payment_design', 'upstream_group', 'transfer_action', 'payment_deviation'];
+                        //合并的列:打款预警金额/预计打款金额/打款设计/打款上游/调款按钮/操作人姓名
+                        const mergeColumns = ['alarm_amount', 'plan_payment_amount', 'payment_design', 'upstream_group', 'transfer_action', 'payment_deviation', 'pay_operation'];
                         for (let col of mergeColumns) {
                             trs.eq(info.startIndex).find('td[data-field="' + col + '"]').attr('rowspan', info.count);
                             for (let j = 1; j < info.count; j++) {
@@ -1040,6 +1092,7 @@
                 const delItem = channelData[index];
                 layer.confirm('确定要删除 ' + delItem.store_name + ' 吗?', { icon: 3, title: '删除确认' }, function (confirmIndex) {
                     const itemData = channelData.splice(index, 1);
+
                     that.updateChannelCache(itemData[0], 'del');
                     that.syncChannelData();
 
@@ -1299,7 +1352,7 @@
 
                 let sortMch = [];
                 if (!isObjectEmpty(copyData)) {
-                    sortMch = mergeData(copyData.stats_merchant, mchCust, 'mch_name', systemTag);
+                    sortMch = mergeData(mchCust, copyData.stats_merchant, 'mch_name', systemTag);
                 } else {
                     sortMch = mchCust;
                 }
@@ -1637,6 +1690,7 @@
                 }
 
                 this.type = type;
+                this.dv = 1; //数据版本,作用:由于需求变化导致存储的缓存数据格式发生变化,由该字段标记,审核的时候如果数据版本与当前dv版本不一致,需要手动作废审核重新操作。
             }
             doApplyOne(tableId, channelData, index) {
                 const trs = $('#' + tableId).next('.layui-table-view').find('.layui-table-body tbody tr');
@@ -1694,7 +1748,9 @@
                             tag: channelItem.tag,
                             amount: paymentAmount,
                             upstream_group: channelItem.upstream_group,
-                            list_name: `${channelItem.store_name}:${paymentAmount}`
+                            list_name: `${channelItem.store_name}:${paymentAmount}`,
+                            pay_operation: channelItem.pay_operation,
+                            remark: ''
                         });
                     }
                 });
@@ -1758,6 +1814,8 @@
                         cols: [[
                             {field: 'list_name', title: '加款项', width: 200},
                             {field: 'total', title: '合计', width: 100},
+                            {field: 'pay_operation', title: '操作人姓名', width: 200},
+                            {field: 'remark', title: '备注', width: 200},
                         ]],
                         done: function (res, curr, count) {
                             const tbRoot = $('#upstream_tb_transfer');
@@ -1789,16 +1847,28 @@
 
                                 for (let group in upstreamMap) {
                                     const info = upstreamMap[group];
-                                    if (info.count > 1) {
-                                        trs.eq(info.startIndex).find('td[data-field="total"]').attr('rowspan', info.count);
-                                        for (let j = 1; j < info.count; j++) {
-                                            trs.eq(info.startIndex + j).find('td[data-field="total"]').addClass('layui-hide');
-                                        }
+                                    trs.eq(info.startIndex).find('td[data-field="total"]').
+                                    attr('rowspan', info.count);
+
+                                    trs.eq(info.startIndex).find('td[data-field="pay_operation"]').
+                                    attr('rowspan', info.count).
+                                    attr('contenteditable', true).
+                                    css('background-color', 'lightblue');
+
+                                    trs.eq(info.startIndex).find('td[data-field="remark"]').
+                                    attr('rowspan', info.count).
+                                    attr('contenteditable', true).
+                                    css('background-color', 'lightblue');
+
+                                    for (let j = 1; j < info.count; j++) {
+                                        trs.eq(info.startIndex + j).find('td[data-field="total"]').addClass('layui-hide');
+                                        trs.eq(info.startIndex + j).find('td[data-field="pay_operation"]').addClass('layui-hide');
+                                        trs.eq(info.startIndex + j).find('td[data-field="remark"]').addClass('layui-hide');
                                     }
                                 }
                             };
 
-                            hideHeader();
+                            // hideHeader();
                             setAttr();
                             mergeTotal();
                         }
@@ -1824,19 +1894,43 @@
                             });
                         },
                         btn2: function () {
-                            const operationVal = $('#inputPayOperation').val();
-                            const bzVal = $('#inputPaybz').val();
-                            if (operationVal === '') {
-                                showErr('请输入操作人');
-                                return false;
+                            let groupInput = {};
+                            const trs = $('#upstream_tb_transfer').next('.layui-table-view').find('.layui-table-body tbody tr');
+                            trs.each(function(i, tr) {
+                                const td_pay_operation = $(tr).find('td[data-field="pay_operation"]').not('.layui-hide');
+                                const td_remark = $(tr).find('td[data-field="remark"]').not('.layui-hide');
+
+                                if (td_pay_operation.length > 0 && td_remark.length > 0) {
+                                    const currGroup = $(tr).attr('upstream_group');
+                                    if (!groupInput[currGroup]) {
+                                        groupInput[currGroup] = {
+                                            pay_operation: td_pay_operation.text().trim(),
+                                            remark: td_remark.text().trim()
+                                        };
+                                    }
+                                }
+                            });
+
+                            for (let i = 0; i < payUnit.length; i++) {
+                                const group = payUnit[i].upstream_group;
+                                const unit_pay_operation = groupInput[group].pay_operation ?? '';
+                                if (unit_pay_operation === '') {
+                                    showErr(`${ group } 未设置操作人`);
+                                    return false;
+                                }
+
+                                const unit_remark = groupInput[group].remark ?? '';
+                                payUnit[i].pay_operation = unit_pay_operation;
+                                payUnit[i].remark = unit_remark;
                             }
 
                             layer.closeAll();
 
+                            //由于渲染表格过程中payUnit产生了多余的字段,进行过滤
+                            const taskData = filterJsonFields(payUnit, ["amount", "list_name", "pay_operation", "remark", "store_id", "store_name", "tag", "upstream_group"]);
                             const applyData = {
-                                items: payUnit,
-                                operation: operationVal,
-                                remark: bzVal
+                                items: taskData,
+                                dv: that.dv
                             };
                             that.workflow.addTask(applyData, systemUserName, 'admin')
                                 .then(succ => {
@@ -1865,7 +1959,8 @@
             }
 
             async doBatchDeposit() {
-                let sortedPayUnit = [], worklist = [], payUnit = [], paySum = 0;
+                const that = this;
+                let sortedPayUnit = [], worklist = [], payUnit = [], paySum = 0, isCorrectVersion = true;
 
                 const loadPayUnit = async () => {
                     await this.workflow.initializeGlobalTaskList();
@@ -1874,6 +1969,13 @@
                     paySum = 0;
 
                     worklist = this.workflow.getPendingTasksByApprover();
+                    for (const task of worklist) {
+                        if (Number(task.data.dv) !== that.dv) {
+                            isCorrectVersion = false;
+                            break;
+                        }
+                    }
+
                     payUnit = this.workflow.getPendingTaskDetails();
 
                     sortedPayUnit = sortByName(payUnit, 'store_name');
@@ -1893,6 +1995,12 @@
 
                 await loadPayUnit();
 
+                if (isCorrectVersion === false) {
+                    setTimeout(function() {
+                        showErr('数据与当前程序版本不匹配,请作废当前数据后重新加款');
+                    }, 500);
+                }
+
                 layui.table.render({
                     elem: '#upstream_tb_approve',
                     data: sortedPayUnit,
@@ -1902,6 +2010,8 @@
                         {field: 'amount', title: '加款金额', width: 150},
                         {field: 'time', title: '申请时间', width: 250},
                         {field: 'total', title: '合计', width: 150},
+                        {field: 'pay_operation', title: '操作人姓名', width: 150},
+                        {field: 'remark', title: '备注', width: 150},
                         {field: 'void_task', title: '', width: 100, templet: function(d){return '<button class="layui-btn layui-btn-sm layui-btn-primary task-void-btn" data-index="'+d.LAY_TABLE_INDEX+'">作废</button>';}}
                     ]],
                     done: function (res, curr, count) {
@@ -1979,11 +2089,10 @@
                     }
                 });
 
-                const that = this;
                 layer.open({
                     type: 1,
                     title: '加款审核',
-                    area: ['938px', '500px'],
+                    area: ['1240px', '500px'],
                     content: $('#rechargeManualApprove'),
                     btn: ['批准', '作废'],
                     success: function (layero) {
@@ -2001,10 +2110,15 @@
                             'margin-right': '10px'
                         });
                     },
-                    btn2: async function () {
+                    btn2: function () {
                         if (worklist.length === 0) {
                             showErr('没有待审核的加款申请');
-                            return;
+                            return false;
+                        }
+
+                        if (isCorrectVersion === false) {
+                            showErr('数据与当前程序版本不匹配,请作废当前数据后重新加款');
+                            return false;
                         }
 
                         layer.closeAll();
@@ -2041,7 +2155,7 @@
                             const processNum = payUnit.length;
                             let processedCount = 0;
 
-                            const payHandler = async (item, operation, remark) => {
+                            const payHandler = async (item) => {
                                 const providerInfo = providers.find(p => item.store_id === p.store_id);
                                 if (!providerInfo) {
                                     errs.push(item.store_name + ' 加款 ' + item.amount + ' 执行失败(数据错误)');
@@ -2054,10 +2168,10 @@
 
                                 const params = {
                                     form_submit: 'ok',
-                                    operation: operation,
+                                    operation: item.pay_operation,
                                     operatetype: 'add',
                                     pointsnum: item.amount,
-                                    bz: remark
+                                    bz: item.remark
                                 };
                                 const result = await statsApi.rechargeManual(providerInfo.provider_id, params);
 
@@ -2078,7 +2192,7 @@
                                             continue;
                                         }
 
-                                        const succ = await payHandler(payItem, task.data.operation, task.data.remark);
+                                        const succ = await payHandler(payItem);
                                         if (succ === false) {
                                             retryItems.push(payItem);
                                         }
@@ -2086,8 +2200,7 @@
                                     if (retryItems.length > 0) {
                                         const applyData = {
                                             items: retryItems,
-                                            operation: task.data.operation,
-                                            remark: task.data.remark
+                                            dv: that.dv
                                         };
                                         const succ = await that.workflow.addTask(applyData, systemUserName, 'admin');
                                         const resultTips = succ === true ? '已重新加入审批列表' : '重新加入审批列表失败';