瀏覽代碼

Merge branch 'raccount' of 39.97.239.116:gyfl/xyzshop into raccount

stanley-king 1 月之前
父節點
當前提交
a5636a9c28
共有 44 個文件被更改,包括 1848 次插入198 次删除
  1. 5 1
      admin/templates/default/js/stats-quota.js
  2. 17 7
      admin/templates/default/js/stats-service.js
  3. 9 0
      admin/templates/default/merchant.ratios.php
  4. 201 137
      admin/templates/default/refill_quota_stats.index.php
  5. 35 1
      admin/templates/default/refill_service.stats.index.php
  6. 59 8
      data/config/xyz/phone.ini.php
  7. 1 1
      data/config/xyz/refill.ini.php
  8. 125 0
      data/config/yl/phone.ini.php
  9. 1 1
      data/config/yl/refill.ini.php
  10. 2 0
      helper/refill/api/xyz/chanlian/config.php
  11. 2 0
      helper/refill/api/xyz/chanlian_sec/config.php
  12. 二進制
      helper/refill/api/xyz/guochuang/20250224_yd_guangdong_1.jpg
  13. 二進制
      helper/refill/api/xyz/guochuang/20250226_dx_henan.png
  14. 二進制
      helper/refill/api/xyz/guochuang/20250228_dx_anhui.png
  15. 二進制
      helper/refill/api/xyz/guochuang/20250228_yd_dx.jpg
  16. 18 10
      helper/refill/api/xyz/guochuang/config.php
  17. 二進制
      helper/refill/api/xyz/meixu_fs/20250225全量配置.xlsx
  18. 二進制
      helper/refill/api/xyz/meixu_fs/20250228_dx_anhui.jpg
  19. 174 21
      helper/refill/api/xyz/meixu_fs/config.php
  20. 2 1
      helper/refill/api/xyz/meixu_sec/config.php
  21. 2 0
      helper/refill/api/xyz/qingyu/config.php
  22. 2 0
      helper/refill/api/xyz/qingyu_sec/config.php
  23. 15 0
      helper/refill/api/xyz/yeyekc18/API.MD
  24. 76 0
      helper/refill/api/xyz/yeyekc18/RefillCallBack.php
  25. 161 0
      helper/refill/api/xyz/yeyekc18/RefillPhone.php
  26. 12 0
      helper/refill/api/xyz/yeyekc18/config.php
  27. 27 0
      helper/refill/api/yl/cuanqi_sec/API.MD
  28. 52 0
      helper/refill/api/yl/cuanqi_sec/RefillCallBack.php
  29. 146 0
      helper/refill/api/yl/cuanqi_sec/RefillPhone.php
  30. 39 0
      helper/refill/api/yl/cuanqi_sec/config.php
  31. 18 10
      helper/refill/api/yl/guochuang/config.php
  32. 42 0
      helper/refill/api/yl/lihui_fs/API.MD
  33. 52 0
      helper/refill/api/yl/lihui_fs/RefillCallBack.php
  34. 165 0
      helper/refill/api/yl/lihui_fs/RefillPhone.php
  35. 70 0
      helper/refill/api/yl/lihui_fs/config.php
  36. 34 0
      helper/refill/api/yl/xinguande/API.MD
  37. 52 0
      helper/refill/api/yl/xinguande/RefillCallBack.php
  38. 146 0
      helper/refill/api/yl/xinguande/RefillPhone.php
  39. 46 0
      helper/refill/api/yl/xinguande/config.php
  40. 4 0
      mobile/callback/refill_cuanqi_sec.php
  41. 4 0
      mobile/callback/refill_lihui_fs.php
  42. 4 0
      mobile/callback/refill_xinguande.php
  43. 4 0
      mobile/callback/refill_yeyekc18.php
  44. 24 0
      test/TestRefill.php

+ 5 - 1
admin/templates/default/js/stats-quota.js

@@ -13,7 +13,7 @@ class DataHandler {
             // channel结构: 对应主体(subject), 通道id(store_id), 已开票总金额(total_invoiced), 上次开票日期(last_invoice_date)
             [CONSTANTS.KEY_QUOTA_CHANNEL]: ['sort', 'subject', 'store_id', 'total_invoiced', 'last_invoice_date', 'remark', 'month_opened'],
             //summary结构: 主体(subject)
-            [CONSTANTS.KEY_QUOTA_SUMMARY]: ['sort', 'subject'],
+            [CONSTANTS.KEY_QUOTA_SUMMARY]: ['sort', 'subject', 'invoice_remaining_amount'],
             //condition结构: 月份(month)
             [CONSTANTS.KEY_QUOTA_CONDITION]: ['month']
         };
@@ -1218,4 +1218,8 @@ class SummaryComponent extends Component {
         summaryList.sort((a, b) => a.sort - b.sort);
         await dataHelper.updateAllData(CONSTANTS.KEY_QUOTA_SUMMARY, summaryList);
     }
+}
+
+function filterSubjectPrefix(str) {
+    return str.replace(/^\d+-/, '');
 }

+ 17 - 7
admin/templates/default/js/stats-service.js

@@ -27,21 +27,31 @@ class DataHandler {
         return list;
     }
 
-    async addServiceRate(structure, newData) {
+    async addServiceRate(structure, newData, backend = true) {
         const list = this[structure];
         const translatedData = this.translateToIndex(structure, newData);
-        const index = list.findIndex(item => item[0] === translatedData[0] && item[1] === translatedData[1]);
+        const mchid = translatedData[0];
+        const day = translatedData[1];
+
+        let mchidData = list.filter(item => item[0] === mchid);
+        const index = mchidData.findIndex(item => item[1] === day);
+
         if (index !== -1) {
-            list[index] = translatedData;
+            mchidData[index] = translatedData;
         } else {
-            list.push(translatedData);
+            mchidData.push(translatedData);
         }
 
-        if (list.length > 60) {
-            list.shift();
+        if (mchidData.length > 90) {
+            mchidData.shift();
         }
 
-        await this.saveDataToBackend(structure);
+        this[structure] = list.filter(item => item[0] !== mchid);
+        this[structure] = [...this[structure], ...mchidData];
+
+        if (backend === true) {
+            await this.saveDataToBackend(structure);
+        }
     }
 
     async removeData(structure, mchid, day) {

+ 9 - 0
admin/templates/default/merchant.ratios.php

@@ -109,6 +109,7 @@
                         <th class="align-center w10pre">1小时</th>
                         <th class="align-center w10pre">2小时</th>
                         <th class="align-center w10pre">3小时</th>
+                        <th class="align-center w10pre">4小时</th>
                         <th class="align-center w10pre">当天</th>
                 </thead>
                 <tbody class="tbodyd">
@@ -159,6 +160,14 @@
                                     <?php } ?>
                                 </td>
                                 <td class="align-center">
+                                    <?php if ($v['ratio']['ALL'][14400][1] > 0) { ?>
+                                        <?php echo ($v['ratio']['ALL'][14400][2] * 100) ?? 0; ?>%(<span style="color: #2d7255;display: inline-block; padding-bottom: 4px;"><?php echo ($v['ratio']['ALL'][14400][0]) ?? 0; ?></span>,<span style="color: red;"><?php echo ($v['ratio']['ALL'][14400][1] - $v['ratio']['ALL'][14400][0]) ?? 0; ?></span>,<?php echo $v['ratio']['ALL'][14400][1]; ?>) <br>
+                                        <?php echo ($v['ratio']['YD'][14400][2] * 100) ?? 0; ?>%(<?php echo ($v['ratio']['YD'][14400][0]) ?? 0; ?>)¥<?php echo ($v['ratio']['LT'][14400][2] * 100) ?? 0; ?>%(<?php echo ($v['ratio']['LT'][14400][0]) ?? 0; ?>)¥<?php echo ($v['ratio']['DX'][14400][2] * 100) ?? 0; ?>%(<?php echo ($v['ratio']['DX'][14400][0]) ?? 0; ?>)
+                                    <?php } else { ?>
+                                        ——
+                                    <?php } ?>
+                                </td>
+                                <td class="align-center">
                                     <?php if ($v['ratio']['ALL'][86400][1] > 0) { ?>
                                         <?php echo ($v['ratio']['ALL'][86400][2] * 100) ?? 0; ?>%(<span style="color: #2d7255;display: inline-block; padding-bottom: 4px;"><?php echo ($v['ratio']['ALL'][86400][0]) ?? 0; ?></span>,<span style="color: red;"><?php echo ($v['ratio']['ALL'][86400][1] - $v['ratio']['ALL'][86400][0]) ?? 0; ?></span>,<?php echo $v['ratio']['ALL'][86400][1]; ?>) <br>
                                         <?php echo ($v['ratio']['YD'][86400][2] * 100) ?? 0; ?>%(<?php echo ($v['ratio']['YD'][86400][0]) ?? 0; ?>)¥<?php echo ($v['ratio']['LT'][86400][2] * 100) ?? 0; ?>%(<?php echo ($v['ratio']['LT'][86400][0]) ?? 0; ?>)¥<?php echo ($v['ratio']['DX'][86400][2] * 100) ?? 0; ?>%(<?php echo ($v['ratio']['DX'][86400][0]) ?? 0; ?>)

+ 201 - 137
admin/templates/default/refill_quota_stats.index.php

@@ -310,27 +310,6 @@
         color: red;
     }
 
-    #tb-summary + .layui-table-view .layui-table-header .layui-table-cell {
-        white-space: normal !important;
-        line-height: 1.5em !important;
-        height: auto !important;
-        overflow: visible !important;
-    }
-
-    #tb-summary + .layui-table-view .layui-table-header th {
-        height: 50px !important;
-        vertical-align: middle !important;
-    }
-
-    #tb-summary + .layui-table-view .layui-table-header th[data-field="channel_invoice_quota"],
-    #tb-summary + .layui-table-view .layui-table-header th[data-field="mch_invoice_quota"] {
-        color: blue !important;
-    }
-
-    #tb-summary + .layui-table-view .layui-table-header th[data-field="channel_mch_delta"] {
-        background-color: #FFB800;
-    }
-
     .chinese-money {
         font-size: 12px;
         color: red;
@@ -353,6 +332,15 @@
         font-size: 10px;
         font-weight: bold;
     }
+
+    .summary-tables-subject {
+        width: 135px;
+        line-height: 30px;
+        font-size: 18px;
+        background-color: #1E9FFF;
+        padding-left: 15px;
+        font-weight: 800;
+    }
 </style>
 
 <div class="page" id="app">
@@ -427,7 +415,9 @@
     <!-- 综合统计 -->
     <div class="stats-panel layui-font-14">
         <summary-set type="KEY_QUOTA_SUMMARY" emit="updateSummary"></summary-set>
-        <table class="layui-hide" id="tb-summary"></table>
+        <div id="summary-tables">
+
+        </div>
     </div>
 
     <!-- 申请确认 -->
@@ -611,7 +601,7 @@
                 item.remark = remark || "";
 
                 await dataHelper.addOrUpdateData(CONSTANTS.KEY_QUOTA_COMPANY, item, 1);
-                summaryTable.renderTable();
+                renderSummaryTables();
             }
 
             applyOne(index) {
@@ -742,12 +732,12 @@
                                             await that.updateCompanyUsedQuota(subject);
                                             setTimeout(function () {
                                                 companyTable.renderTable();
-                                                summaryTable.renderTable();
+                                                renderSummaryTables()
                                             }, 0);
                                         }
                                         if (col === 'total_invoiced') {
                                             setTimeout(function () {
-                                                summaryTable.renderTable();
+                                                renderSummaryTables();
                                             }, 0);
                                         }
 
@@ -1271,7 +1261,7 @@
                 await dataHelper.addOrUpdateData(CONSTANTS.KEY_QUOTA_CHANNEL, item, 2);
 
                 setTimeout(function () {
-                    summaryTable.renderTable();
+                    renderSummaryTables();
                 }, 0);
             }
 
@@ -1281,127 +1271,184 @@
         }
 
         class SummaryTable extends LayuiTableBase {
-            constructor() {
-                super('tb-summary');
+            constructor(tableId, subject) {
+                super(tableId);
+                this.subject = subject;
+                this.lines = 0;
             }
 
             renderTable() {
                 const that = this;
 
-                const companyList = dataHelper.getCompanyList();
-                const tableData = dataHelper.getSummaryList();
-                tableData.forEach(item => {
-                    Object.assign(item, {
-                        subject_quota: 0,
-                        channel_amounts: 0,
-                        channel_total_invoiced: 0,
-                        channel_invoice_quota: 0,
-                        subject_channel_delta: 0,
-                        mch_invoice_quota: 0,
-                        subject_mch_delta: 0,
-                        channel_mch_delta: 0
-                    });
-
-                    const activeItem = companyList.find(cItem => cItem.name === item.subject);
-                    if (activeItem !== undefined) {
-                        item.subject_quota = formatDecimals(activeItem.total_quota);
-                    }
+                const channelData = this.channelTableData().filter(item => {
+                    return item.subject === that.subject;
                 });
+                this.lines = channelData.length;
+
+                const merchantData = this.merchantTableData();
+                const mch_invoice_quota = merchantData[this.subject] ?? 0;
+
+                const summaryData = dataHelper.getSummaryList().find(item => item.subject === that.subject);
+                const invoice_remaining_amount = summaryData === undefined || summaryData.invoice_remaining_amount === '' ? '0' : summaryData.invoice_remaining_amount;
+
+                const estimated_invoice_amount_total = channelData.reduce((total, item) => {
+                    return total + parseFloat(item.estimated_invoice_amount);
+                }, 0);
+                let invoice_needed_amount = mch_invoice_quota - estimated_invoice_amount_total - parseFloat(invoice_remaining_amount);
+                for (const chan of channelData) {
+                    chan.estimated_invoice_amount_total = formatDecimals(estimated_invoice_amount_total); //所有行都设置同一个合计值,以此满足合并需求
+                    chan.invoice_remaining_amount = invoice_remaining_amount;
+                    chan.invoice_needed_amount = formatDecimals(invoice_needed_amount);
+                }
 
                 layui.table.render({
                     elem: '#' + this.tableId,
-                    data: tableData,
-                    limit: tableData.length,
+                    data: channelData,
+                    limit: channelData.length,
                     cols: [[
-                        {field: 'subject', title: '对应主体', width: 150},
-                        {field: 'subject_quota', title: '本月总额度', width: 200},
-                        {field: 'channel_amounts', title: '上游本月需开票', width: 150},
-                        {field: 'channel_total_invoiced', title: '上游已开票', width: 150},
-                        {field: 'channel_invoice_quota', title: '上游可开票', width: 150},
-                        {field: 'subject_channel_delta', title: '差额(主体-上游)', width: 150},
-                        {field: 'mch_invoice_quota', title: '下游可开票', width: 150},
-                        {field: 'subject_mch_delta', title: '差额(主体-下游)', width: 150},
-                        {field: 'channel_mch_delta', title: '差额(上-下)<br>ps:还需进货', width: 150}
+                        {field: 'store_name', title: '上游', width: 150},
+                        {field: 'total_amounts', title: '总计', width: 200},
+                        {field: 'total_invoiced', title: '已开', width: 150},
+                        {field: 'estimated_invoice_amount', title: '待开', width: 150},
+                        {field: 'estimated_invoice_amount_total', title: '合计', width: 150},
+                        {field: 'invoice_remaining_amount', title: '现有多少票', width: 150},
+                        {field: 'invoice_needed_amount', title: '需进票', width: 150},
                     ]],
                     done: function (res, curr, count) {
-                        const channelQuota = {};
-                        const channelTb = $('#' + channelTable.tableId);
-                        const channelTrs = channelTb.next('.layui-table-view').find('.layui-table-body tbody tr');
-                        channelTrs.each(function (i, tr) {
-                            const subject = $(tr).find('td[data-field="subject"]').find('div').text();
-                            const estimated_amount = $(tr).find('td[data-field="estimated_invoice_amount"]').find('div').text();
-                            const channel_amounts = $(tr).find('td[data-field="total_amounts"]').find('div').text();
-                            const total_invoiced = $(tr).find('td[data-field="total_invoiced"]').find('div').text();
-
-                            if (!channelQuota[subject]) {
-                                channelQuota[subject] = {
-                                    channel_amounts: 0,
-                                    channel_total_invoiced: 0,
-                                    channel_invoice_quota: 0
-                                };
-                            }
+                        that.mergeCells();
+                        that.setRole();
+                        that.setEditCell();
+                        that.updateTable();
+                    }
+                });
+            }
 
-                            const n_estimated_amount = parseFloat(estimated_amount);
-                            channelQuota[subject].channel_invoice_quota += n_estimated_amount;
+            updateTable() {
+                this.setValueClass(['total_amounts', 'total_invoiced', 'estimated_invoice_amount', 'estimated_invoice_amount_total', 'invoice_remaining_amount', 'invoice_needed_amount']);
+            }
 
-                            channelQuota[subject].channel_amounts += parseFloat(channel_amounts);
-                            channelQuota[subject].channel_total_invoiced += parseFloat(total_invoiced);
-                        });
+            mergeCells() {
+                const tbRoot = $('#' + this.tableId);
+                const trs = tbRoot.next('.layui-table-view').find('.layui-table-body tbody tr');
 
-                        const merchantQuota = {};
-                        const merchantTb = $('#' + merchantTable.tableId);
-                        const merchantTrs = merchantTb.next('.layui-table-view').find('.layui-table-body tbody tr');
-                        merchantTrs.each(function (i, tr) {
-                            const subject = $(tr).find('td[data-field="subject"]').find('div').text();
-                            const estimated_amount = $(tr).find('td[data-field="estimated_invoice_amount"]').find('div').text();
-                            if (!merchantQuota[subject]) {
-                                merchantQuota[subject] = 0;
-                            }
+                const mergeColumns = ['estimated_invoice_amount_total', 'invoice_remaining_amount', 'invoice_needed_amount'];
+                for (let col of mergeColumns) {
+                    trs.eq(0).find('td[data-field="' + col + '"]').attr('rowspan', this.lines);
+                    for (let j = 1; j < this.lines; j++) {
+                        trs.eq(j).find('td[data-field="' + col + '"]').addClass('layui-hide');
+                    }
+                }
+            }
 
-                            const n_estimated_amount = parseFloat(estimated_amount);
-                            if (n_estimated_amount > 0) {
-                                merchantQuota[subject] += n_estimated_amount;
-                            }
-                        });
+            setEditCell() {
+                const that = this;
+                const tbRoot = $('#' + this.tableId);
+                const trs = tbRoot.next('.layui-table-view').find('.layui-table-body tbody tr');
+                trs.each(function (i, tr) {
+                    const editNumberColumns = ['invoice_remaining_amount'];
+
+                    for (let col of editNumberColumns) {
+                        const td = $(tr).find('td[data-field="' + col + '"]').not('.layui-hide');
+                        const valDiv = td.find('div');
+                        valDiv.attr('contenteditable', true).css('background-color', 'lightblue');
+                        valDiv.off('input', handleInputd2)
+                            .off('keypress')
+                            .off('blur')
+                            .on('input', handleInputd2)
+                            .on('keypress', function (e) {
+                                if (e.keyCode === 13) {
+                                    e.preventDefault();
+                                    $(this).blur();
+                                }
+                            })
+                            .on('blur', async function () {
+                                let val = valDiv.text().trim();
+                                if (!isNumeric(val)) {
+                                    valDiv.html('0');
+                                }
+                                val = normalizeAmount(val);//过滤,比如前导 0
+                                valDiv.html(formatDecimals(val));
 
-                        const summaryTb = $('#' + that.tableId);
-                        const summaryTrs = summaryTb.next('.layui-table-view').find('.layui-table-body tbody tr');
-                        summaryTrs.each(function (i, tr) {
-                            const subjectTd = $(tr).find('td[data-field="subject"]').find('div');
-                            const subjectQuotaTd = $(tr).find('td[data-field="subject_quota"]').find('div');
-                            const channelAmountsTd = $(tr).find('td[data-field="channel_amounts"]').find('div');
-                            const channelTotalInvoicedTd = $(tr).find('td[data-field="channel_total_invoiced"]').find('div');
-                            const channelInvoiceQuotaTd = $(tr).find('td[data-field="channel_invoice_quota"]').find('div');
-                            const subjectChannelDeltaTd = $(tr).find('td[data-field="subject_channel_delta"]').find('div');
-                            const mchInvoiceQuotaTd = $(tr).find('td[data-field="mch_invoice_quota"]').find('div');
-                            const subjectMchDeltaTd = $(tr).find('td[data-field="subject_mch_delta"]').find('div');
-                            const channelMchDeltaTd = $(tr).find('td[data-field="channel_mch_delta"]').find('div');
-
-                            let channel_invoice_quota = 0, channel_amounts = 0, channel_total_invoiced = 0, mch_invoice_quota = 0;
-                            const subject_quota = parseFloat(subjectQuotaTd.text());
-                            const subject = subjectTd.text();
-                            if (channelQuota[subject] !== undefined) {
-                                channel_invoice_quota = channelQuota[subject].channel_invoice_quota;
-                                channel_amounts = channelQuota[subject].channel_amounts;
-                                channel_total_invoiced = channelQuota[subject].channel_total_invoiced;
-                            }
-                            if (merchantQuota[subject] !== undefined) {
-                                mch_invoice_quota = merchantQuota[subject];
-                            }
+                                const index = $(this).parent().parent().data('index');
+                                await that.saveEdit(index);
 
-                            channelAmountsTd.html(formatDecimals(channel_amounts));
-                            channelTotalInvoicedTd.html(formatDecimals(channel_total_invoiced));
-                            channelInvoiceQuotaTd.html(formatDecimals(channel_invoice_quota));
-                            subjectChannelDeltaTd.html(formatDecimals(subject_quota - channel_invoice_quota));
-                            mchInvoiceQuotaTd.html(formatDecimals(mch_invoice_quota));
-                            subjectMchDeltaTd.html(formatDecimals(subject_quota - mch_invoice_quota));
-                            channelMchDeltaTd.html(formatDecimals(channel_invoice_quota - mch_invoice_quota));
-                        });
+                                that.updateTable();
+                            });
+                    }
+                });
+            }
 
-                        that.setValueClass(['subject_quota', 'channel_invoice_quota', 'subject_channel_delta', 'mch_invoice_quota', 'subject_mch_delta', 'channel_mch_delta']);
-                        that.setRole();
+            async saveEdit(index) {
+                const summaryData = dataHelper.getSummaryList();
+                if (index >= summaryData.length) {
+                    console.error('主体数据错误:编辑索引大于主体总数');
+                    return;
+                }
+
+                const tr = $('#' + this.tableId).next('.layui-table-view').find('.layui-table-body tbody tr[data-index="' + index + '"]');
+                const invoice_remaining_amount = tr.find('td[data-field="invoice_remaining_amount"]').find('div').not('.layui-hide').text().trim();
+
+                let item = dataHelper.getSummaryList().find(item => item.subject === this.subject);
+                if (item === undefined) {
+                    item = {
+                        sort: 0,
+                        subject: this.subject,
+                        invoice_remaining_amount: invoice_remaining_amount
+                    };
+                } else {
+                    item.invoice_remaining_amount = invoice_remaining_amount;
+                }
+
+                await dataHelper.addOrUpdateData(CONSTANTS.KEY_QUOTA_SUMMARY, item, 1);
+
+                const that = this;
+                setTimeout(function () {
+                    that.renderTable();
+                }, 0);
+            }
+
+            channelTableData() {
+                const data = [];
+
+                const channelTb = $('#' + channelTable.tableId);
+                const channelTrs = channelTb.next('.layui-table-view').find('.layui-table-body tbody tr');
+                channelTrs.each(function (i, tr) {
+                    const subject = $(tr).find('td[data-field="subject"]').find('div').text();
+                    const store_name = $(tr).find('td[data-field="store_name"]').find('div').text();
+                    const total_amounts = $(tr).find('td[data-field="total_amounts"]').find('div').text();
+                    const total_invoiced = $(tr).find('td[data-field="total_invoiced"]').find('div').text();
+                    const estimated_invoice_amount = $(tr).find('td[data-field="estimated_invoice_amount"]').find('div').text();
+                    data.push({
+                        subject,
+                        store_name,
+                        total_amounts,
+                        total_invoiced,
+                        estimated_invoice_amount
+                    });
+                });
+
+                return data;
+            }
+
+            merchantTableData() {
+                const data = {};
+
+                const merchantTb = $('#' + merchantTable.tableId);
+                const merchantTrs = merchantTb.next('.layui-table-view').find('.layui-table-body tbody tr');
+                merchantTrs.each(function (i, tr) {
+                    const subject = $(tr).find('td[data-field="subject"]').find('div').text();
+                    let estimated_invoice_amount = $(tr).find('td[data-field="estimated_invoice_amount"]').find('div').text();
+                    estimated_invoice_amount = parseFloat(estimated_invoice_amount);
+
+                    if (data[subject] === undefined) {
+                        data[subject] = 0;
+                    }
+                    if (estimated_invoice_amount > 0) {
+                        data[subject] += parseFloat(estimated_invoice_amount);
                     }
                 });
+
+                return data;
             }
 
             setRole() {
@@ -1813,11 +1860,11 @@
 
                             await dataHelper.updateAllData(CONSTANTS.KEY_QUOTA_COMPANY, companyData);
                             companyTable.renderTable();
-                            summaryTable.renderTable();
+                            renderSummaryTables();
                         } else if (that.type === 'chan') {
                             await dataHelper.updateAllData(CONSTANTS.KEY_QUOTA_CHANNEL, typeData);
                             await channelTable.renderTable();
-                            summaryTable.renderTable();
+                            renderSummaryTables();
                         }
 
 
@@ -2108,7 +2155,7 @@
 
                         await dataHelper.updateAllData(CONSTANTS.KEY_QUOTA_COMPANY, companyData);
                         companyTable.renderTable();
-                        summaryTable.renderTable();
+                        renderSummaryTables();
 
                         layer.closeAll();
                     },
@@ -2219,6 +2266,22 @@
             return condition.month;
         }
 
+        function renderSummaryTables() {
+            let $tables = $('#summary-tables');
+            $tables.html('');
+
+            const summarys = dataHelper.getSummaryList();
+            summarys.forEach(function(item, index) {
+                const subject = filterSubjectPrefix(item.subject);
+                $tables.append(`<div class="summary-tables-subject">${subject}</div>`);
+
+                const tableId = `tb-summary${item.subject}`;
+                $tables.append(`<table class="layui-hide" id="${tableId}"></table>`);
+                const summaryTable = new SummaryTable(tableId, item.subject);
+                summaryTable.renderTable();
+            });
+        }
+
         async function initPage() {
             const loadIndex = layer.load(2, {shade: [0.2, '#000']});
 
@@ -2235,27 +2298,29 @@
             companyTable.renderTable();
             await merchantTable.renderTable();
             await channelTable.renderTable();
-            summaryTable.renderTable();
+            renderSummaryTables();
 
             //UI回调事件
             app.on('updateCompany', () => {
                 companyTable.renderTable();
-                summaryTable.renderTable();
+                renderSummaryTables();
             });
             app.on('updateMerchant', async () => {
                 await merchantTable.renderTable();
-                summaryTable.renderTable();
+                renderSummaryTables();
             });
             app.on('updateChannel', async () => {
                 await channelTable.renderTable();
-                summaryTable.renderTable();
+                renderSummaryTables();
             });
             app.on('updateSummary', async () => {
-                summaryTable.renderTable();
+                renderSummaryTables();
             });
 
             loadMsgBadge();
 
+            renderSummaryTables();
+
             layer.close(loadIndex);
         }
 
@@ -2265,7 +2330,6 @@
         const companyTable = new CompanyTable();
         const merchantTable = new MerchantTable();
         const channelTable = new ChannelTable();
-        const summaryTable = new SummaryTable();
 
         $('.ac-approve').on('click', function () {
             if (systemUserName !== 'admin') {
@@ -2350,7 +2414,7 @@
 
                 await merchantTable.renderTable();
                 companyTable.renderTable();
-                summaryTable.renderTable();
+                renderSummaryTables();
             };
 
             const updateChannel = async (field) => {
@@ -2365,7 +2429,7 @@
                 await dataHelper.updateAllData(CONSTANTS.KEY_QUOTA_CHANNEL, channelList);
 
                 await channelTable.renderTable();
-                summaryTable.renderTable();
+                renderSummaryTables();
             };
 
             if (col === 'actual_invoice_amount') {

+ 35 - 1
admin/templates/default/refill_service.stats.index.php

@@ -74,6 +74,11 @@
                         <span>导出</span>
                     </a>
                 </td>
+                <td>
+                    <a href="javascript:void(0);" id="setpage" class="btn">
+                        <span>批量设置</span>
+                    </a>
+                </td>
             </tr>
             </tbody>
         </table>
@@ -220,7 +225,7 @@
             const mchid = $row.find('td:nth-child(3)').text();
             const serviceFeeRate = parseFloat($row.find('td.servicefee-rate input').val().trim()) / 100;
             const day = $row.find('td:nth-child(1)').text();
-            const service_rate = String(serviceFeeRate).replace(/^(.*\..{4}).*$/, "$1");
+            const service_rate = serviceFeeRate.toFixed(4);
             await dataHelper.addServiceRate(CONSTANTS.KEY_MCH_SERVICE_RATE, {
                 mchid,
                 day,
@@ -230,6 +235,35 @@
             window.location.reload();
         });
 
+        $('#setpage').on('click', async function() {
+            const processed = {};
+            const $buttons = $('.restats');
+
+            for (let i = 0; i < $buttons.length; i++) {
+                const $button = $($buttons[i]);
+                const $row = $button.closest('tr');
+                const mchid = $row.find('td:nth-child(3)').text();
+                const day = $row.find('td:nth-child(1)').text();
+
+                if (!processed[`${mchid}-${day}`]) {
+                    processed[`${mchid}-${day}`] = true;
+
+                    const serviceFeeRate = parseFloat($row.find('td.servicefee-rate input').val().trim()) / 100;
+                    const service_rate = serviceFeeRate.toFixed(4);
+
+                    await dataHelper.addServiceRate(CONSTANTS.KEY_MCH_SERVICE_RATE, {
+                        mchid,
+                        day,
+                        service_rate
+                    }, false);
+                }
+            }
+
+            await dataHelper.saveDataToBackend(CONSTANTS.KEY_MCH_SERVICE_RATE);
+
+            window.location.reload();
+        });
+
         $('#ncexport').click(function () {
             select_set();
 

+ 59 - 8
data/config/xyz/phone.ini.php

@@ -339,6 +339,9 @@ $xinyang_phone = [
 $guochuang_phone = [
 	'name' => 'guochuang', 'store_id' => 106, 'qualitys' => '2', 'official_sn' => true, 'refill_type' => 'api',	
 	'amount' => [
+        5 => [
+            ['goods_id' => 9438, 'price' => 5, 'quality' => 2, 'card_type' => 'chinamobile,chinaunicom,chinatelecom']
+        ],
 		10 => [
 			['goods_id' => 6941, 'price' => 9.99, 'quality' => 2, 'card_type' => 'chinamobile,chinaunicom,chinatelecom']
 			],
@@ -2452,10 +2455,12 @@ $meixu_sec_phone = [
 			],
 		50 => [
 			['goods_id' => 8722, 'price' => 50.4, 'quality' => 2, 'card_type' => 'chinamobile'],
+            ['goods_id' => 8722, 'price' => 50.025, 'quality' => 2, 'card_type' => 'chinaunicom'],
 			['goods_id' => 8722, 'price' => 50.55, 'quality' => 2, 'card_type' => 'chinatelecom']
 			],
 		100 => [
 			['goods_id' => 8723, 'price' => 100.55, 'quality' => 2, 'card_type' => 'chinamobile'],
+            ['goods_id' => 8723, 'price' => 100.05, 'quality' => 2, 'card_type' => 'chinaunicom'],
 			['goods_id' => 8723, 'price' => 100.5, 'quality' => 2, 'card_type' => 'chinatelecom']
 			],
 		200 => [
@@ -3775,9 +3780,9 @@ $qingyu_phone = [
 //            ['goods_id' => 9346, 'price' => 30, 'quality' => 2, 'card_type' => 'chinatelecom']
 //        ],
         50 => [
-//            ['goods_id' => 9347, 'price' => 50, 'quality' => 2, 'card_type' => 'chinamobile'],
+            ['goods_id' => 9347, 'price' => 52.75, 'quality' => 2, 'card_type' => 'chinamobile'],
             ['goods_id' => 9347, 'price' => 51.8, 'quality' => 2, 'card_type' => 'chinaunicom'],
-//            ['goods_id' => 9347, 'price' => 50, 'quality' => 2, 'card_type' => 'chinatelecom']
+            ['goods_id' => 9347, 'price' => 52.75, 'quality' => 2, 'card_type' => 'chinatelecom']
         ],
         100 => [
             ['goods_id' => 9348, 'price' => 103.6, 'quality' => 2, 'card_type' => 'chinamobile'],
@@ -3896,9 +3901,9 @@ $qingyu_sec_phone = [
 //            ['goods_id' => 9379, 'price' => 30, 'quality' => 2, 'card_type' => 'chinatelecom']
 //        ],
         50 => [
-//            ['goods_id' => 9380, 'price' => 50, 'quality' => 2, 'card_type' => 'chinamobile'],
+            ['goods_id' => 9380, 'price' => 52.75, 'quality' => 2, 'card_type' => 'chinamobile'],
             ['goods_id' => 9380, 'price' => 51.8, 'quality' => 2, 'card_type' => 'chinaunicom'],
-//            ['goods_id' => 9380, 'price' => 50, 'quality' => 2, 'card_type' => 'chinatelecom']
+            ['goods_id' => 9380, 'price' => 52.75, 'quality' => 2, 'card_type' => 'chinatelecom']
         ],
         100 => [
             ['goods_id' => 9381, 'price' => 103.6, 'quality' => 2, 'card_type' => 'chinamobile'],
@@ -4076,9 +4081,9 @@ $chanlian_phone = [
 //            ['goods_id' => 9412, 'price' => 30, 'quality' => 2, 'card_type' => 'chinatelecom']
 //        ],
         50 => [
-//            ['goods_id' => 9413, 'price' => 50, 'quality' => 2, 'card_type' => 'chinamobile'],
+            ['goods_id' => 9413, 'price' => 52.75, 'quality' => 2, 'card_type' => 'chinamobile'],
             ['goods_id' => 9413, 'price' => 51.8, 'quality' => 2, 'card_type' => 'chinaunicom'],
-//            ['goods_id' => 9413, 'price' => 50, 'quality' => 2, 'card_type' => 'chinatelecom']
+            ['goods_id' => 9413, 'price' => 52.75, 'quality' => 2, 'card_type' => 'chinatelecom']
         ],
         100 => [
             ['goods_id' => 9414, 'price' => 103.6, 'quality' => 2, 'card_type' => 'chinamobile'],
@@ -4121,9 +4126,9 @@ $chanlian_sec_phone = [
 //            ['goods_id' => 9420, 'price' => 30, 'quality' => 2, 'card_type' => 'chinatelecom']
 //        ],
         50 => [
-//            ['goods_id' => 9421, 'price' => 50, 'quality' => 2, 'card_type' => 'chinamobile'],
+            ['goods_id' => 9421, 'price' => 52.75, 'quality' => 2, 'card_type' => 'chinamobile'],
             ['goods_id' => 9421, 'price' => 51.8, 'quality' => 2, 'card_type' => 'chinaunicom'],
-//            ['goods_id' => 9421, 'price' => 50, 'quality' => 2, 'card_type' => 'chinatelecom']
+            ['goods_id' => 9421, 'price' => 52.75, 'quality' => 2, 'card_type' => 'chinatelecom']
         ],
         100 => [
             ['goods_id' => 9422, 'price' => 103.6, 'quality' => 2, 'card_type' => 'chinamobile'],
@@ -4147,6 +4152,51 @@ $chanlian_sec_phone = [
         ]
     ]
 ];
+$yeyekc18_phone = [
+    'name' => 'yeyekc18', 'store_id' => 434, 'qualitys' => '2', 'official_sn' => true, 'refill_type' => 'api',
+    'amount' => [
+        10 => [
+            ['goods_id' => 9426, 'price' => 10, 'quality' => 2, 'card_type' => 'chinamobile'],
+            ['goods_id' => 9426, 'price' => 10, 'quality' => 2, 'card_type' => 'chinaunicom'],
+            ['goods_id' => 9426, 'price' => 10, 'quality' => 2, 'card_type' => 'chinatelecom']
+        ],
+        20 => [
+            ['goods_id' => 9427, 'price' => 20, 'quality' => 2, 'card_type' => 'chinamobile'],
+            ['goods_id' => 9427, 'price' => 20, 'quality' => 2, 'card_type' => 'chinaunicom'],
+            ['goods_id' => 9427, 'price' => 20, 'quality' => 2, 'card_type' => 'chinatelecom']
+        ],
+        30 => [
+            ['goods_id' => 9428, 'price' => 30, 'quality' => 2, 'card_type' => 'chinamobile'],
+            ['goods_id' => 9428, 'price' => 30, 'quality' => 2, 'card_type' => 'chinaunicom'],
+            ['goods_id' => 9428, 'price' => 30, 'quality' => 2, 'card_type' => 'chinatelecom']
+        ],
+        50 => [
+            ['goods_id' => 9429, 'price' => 50, 'quality' => 2, 'card_type' => 'chinamobile'],
+            ['goods_id' => 9429, 'price' => 50, 'quality' => 2, 'card_type' => 'chinaunicom'],
+            ['goods_id' => 9429, 'price' => 50, 'quality' => 2, 'card_type' => 'chinatelecom']
+        ],
+        100 => [
+            ['goods_id' => 9430, 'price' => 100, 'quality' => 2, 'card_type' => 'chinamobile'],
+            ['goods_id' => 9430, 'price' => 100, 'quality' => 2, 'card_type' => 'chinaunicom'],
+            ['goods_id' => 9430, 'price' => 100, 'quality' => 2, 'card_type' => 'chinatelecom']
+        ],
+        200 => [
+            ['goods_id' => 9431, 'price' => 200, 'quality' => 2, 'card_type' => 'chinamobile'],
+            ['goods_id' => 9431, 'price' => 200, 'quality' => 2, 'card_type' => 'chinaunicom'],
+            ['goods_id' => 9431, 'price' => 200, 'quality' => 2, 'card_type' => 'chinatelecom']
+        ],
+        300 => [
+            ['goods_id' => 9432, 'price' => 300, 'quality' => 2, 'card_type' => 'chinamobile'],
+            ['goods_id' => 9432, 'price' => 300, 'quality' => 2, 'card_type' => 'chinaunicom'],
+            ['goods_id' => 9432, 'price' => 300, 'quality' => 2, 'card_type' => 'chinatelecom']
+        ],
+        500 => [
+            ['goods_id' => 9433, 'price' => 500, 'quality' => 2, 'card_type' => 'chinamobile'],
+            ['goods_id' => 9433, 'price' => 500, 'quality' => 2, 'card_type' => 'chinaunicom'],
+            ['goods_id' => 9433, 'price' => 500, 'quality' => 2, 'card_type' => 'chinatelecom']
+        ]
+    ]
+];
 
 $phone_providers = [
 	[ 'name' => 'xunyin', 'cfg' => $xunyin_phone ],
@@ -4268,4 +4318,5 @@ $phone_providers = [
     [ 'name' => 'kachong70', 'cfg' => $kachong70_phone ],
     [ 'name' => 'chanlian', 'cfg' => $chanlian_phone ],
     [ 'name' => 'chanlian_sec', 'cfg' => $chanlian_sec_phone ],
+    [ 'name' => 'yeyekc18', 'cfg' => $yeyekc18_phone ],
 	];

+ 1 - 1
data/config/xyz/refill.ini.php

@@ -44,7 +44,7 @@ $config['third_jumps'] = $third_jumps;
 
 #风险流水号管理
 $config['risk_official_sn'] = [
-    'exclude_stores' => [192, 273, 389, 390, 391, 121, 315, 424, 429]
+    'exclude_stores' => [192, 273, 389, 390, 391, 121, 315, 424, 429, 432, 433, 160, 101, 121]
 ];
 
 #不需要检测空号的机构

+ 125 - 0
data/config/yl/phone.ini.php

@@ -188,6 +188,9 @@ $miaoxt_phone = [
 $guochuang_phone = [
 	'name' => 'guochuang', 'store_id' => 106, 'qualitys' => '2', 'official_sn' => true, 'refill_type' => 'api',	
 	'amount' => [
+        5 => [
+            ['goods_id' => 8909, 'price' => 5, 'quality' => 2, 'card_type' => 'chinamobile,chinaunicom,chinatelecom']
+        ],
 		10 => [
 			['goods_id' => 6941, 'price' => 9.99, 'quality' => 2, 'card_type' => 'chinamobile,chinaunicom,chinatelecom']
 			],
@@ -2577,6 +2580,125 @@ $chaohe_sec_phone = [
 //        ]
     ]
 ];
+$xinguande_phone = [
+    'name' => 'xinguande', 'store_id' => 358, 'qualitys' => '1', 'official_sn' => true, 'refill_type' => 'api',
+    'amount' => [
+//        10 => [
+//            ['goods_id' => 8873, 'price' => 10, 'quality' => 1, 'card_type' => 'chinamobile'],
+//            ['goods_id' => 8873, 'price' => 10, 'quality' => 1, 'card_type' => 'chinaunicom'],
+//            ['goods_id' => 8873, 'price' => 10, 'quality' => 1, 'card_type' => 'chinatelecom']
+//        ],
+//        20 => [
+//            ['goods_id' => 8874, 'price' => 20, 'quality' => 1, 'card_type' => 'chinamobile'],
+//            ['goods_id' => 8874, 'price' => 20, 'quality' => 1, 'card_type' => 'chinaunicom'],
+//            ['goods_id' => 8874, 'price' => 20, 'quality' => 1, 'card_type' => 'chinatelecom']
+//        ],
+        30 => [
+//            ['goods_id' => 8875, 'price' => 30, 'quality' => 1, 'card_type' => 'chinamobile'],
+            ['goods_id' => 8875, 'price' => 28.05, 'quality' => 1, 'card_type' => 'chinaunicom'],
+//            ['goods_id' => 8875, 'price' => 30, 'quality' => 1, 'card_type' => 'chinatelecom']
+        ],
+        50 => [
+            ['goods_id' => 8876, 'price' => 48.3, 'quality' => 1, 'card_type' => 'chinamobile'],
+            ['goods_id' => 8876, 'price' => 46.75, 'quality' => 1, 'card_type' => 'chinaunicom'],
+            ['goods_id' => 8876, 'price' => 48.4, 'quality' => 1, 'card_type' => 'chinatelecom']
+        ],
+        100 => [
+            ['goods_id' => 8877, 'price' => 96.6, 'quality' => 1, 'card_type' => 'chinamobile'],
+            ['goods_id' => 8877, 'price' => 93.5, 'quality' => 1, 'card_type' => 'chinaunicom'],
+            ['goods_id' => 8877, 'price' => 96.8, 'quality' => 1, 'card_type' => 'chinatelecom']
+        ],
+        200 => [
+            ['goods_id' => 8878, 'price' => 193.2, 'quality' => 1, 'card_type' => 'chinamobile'],
+            ['goods_id' => 8878, 'price' => 187, 'quality' => 1, 'card_type' => 'chinaunicom'],
+            ['goods_id' => 8878, 'price' => 193.6, 'quality' => 1, 'card_type' => 'chinatelecom']
+        ],
+//        300 => [
+//            ['goods_id' => 8879, 'price' => 300, 'quality' => 1, 'card_type' => 'chinamobile'],
+//            ['goods_id' => 8879, 'price' => 300, 'quality' => 1, 'card_type' => 'chinaunicom'],
+//            ['goods_id' => 8879, 'price' => 300, 'quality' => 1, 'card_type' => 'chinatelecom']
+//        ],
+//        500 => [
+//            ['goods_id' => 8880, 'price' => 500, 'quality' => 1, 'card_type' => 'chinamobile'],
+//            ['goods_id' => 8880, 'price' => 500, 'quality' => 1, 'card_type' => 'chinaunicom'],
+//            ['goods_id' => 8880, 'price' => 500, 'quality' => 1, 'card_type' => 'chinatelecom']
+//        ]
+    ]
+];
+$lihui_fs_phone = [
+    'name' => 'lihui_fs', 'store_id' => 359, 'qualitys' => '1', 'official_sn' => true, 'refill_type' => 'api',
+    'amount' => [
+//        10 => [
+//            ['goods_id' => 8881, 'price' => 10, 'quality' => 1, 'card_type' => 'chinamobile'],
+//            ['goods_id' => 8881, 'price' => 10, 'quality' => 1, 'card_type' => 'chinaunicom'],
+//            ['goods_id' => 8881, 'price' => 10, 'quality' => 1, 'card_type' => 'chinatelecom']
+//        ],
+//        20 => [
+//            ['goods_id' => 8882, 'price' => 20, 'quality' => 1, 'card_type' => 'chinamobile'],
+//            ['goods_id' => 8882, 'price' => 20, 'quality' => 1, 'card_type' => 'chinaunicom'],
+//            ['goods_id' => 8882, 'price' => 20, 'quality' => 1, 'card_type' => 'chinatelecom']
+//        ],
+//        30 => [
+//            ['goods_id' => 8883, 'price' => 30, 'quality' => 1, 'card_type' => 'chinamobile'],
+//            ['goods_id' => 8883, 'price' => 30, 'quality' => 1, 'card_type' => 'chinaunicom'],
+//            ['goods_id' => 8883, 'price' => 30, 'quality' => 1, 'card_type' => 'chinatelecom']
+//        ],
+        50 => [
+            ['goods_id' => 8884, 'price' => 47.5, 'quality' => 1, 'card_type' => 'chinamobile'],
+            ['goods_id' => 8884, 'price' => 47.5, 'quality' => 1, 'card_type' => 'chinaunicom'],
+            ['goods_id' => 8884, 'price' => 47.5, 'quality' => 1, 'card_type' => 'chinatelecom']
+        ],
+        100 => [
+            ['goods_id' => 8885, 'price' => 95, 'quality' => 1, 'card_type' => 'chinamobile'],
+            ['goods_id' => 8885, 'price' => 95, 'quality' => 1, 'card_type' => 'chinaunicom'],
+            ['goods_id' => 8885, 'price' => 95, 'quality' => 1, 'card_type' => 'chinatelecom']
+        ],
+        200 => [
+            ['goods_id' => 8886, 'price' => 190, 'quality' => 1, 'card_type' => 'chinamobile'],
+            ['goods_id' => 8886, 'price' => 190, 'quality' => 1, 'card_type' => 'chinaunicom'],
+            ['goods_id' => 8886, 'price' => 190, 'quality' => 1, 'card_type' => 'chinatelecom']
+        ],
+//        300 => [
+//            ['goods_id' => 8887, 'price' => 300, 'quality' => 1, 'card_type' => 'chinamobile'],
+//            ['goods_id' => 8887, 'price' => 300, 'quality' => 1, 'card_type' => 'chinaunicom'],
+//            ['goods_id' => 8887, 'price' => 300, 'quality' => 1, 'card_type' => 'chinatelecom']
+//        ],
+//        500 => [
+//            ['goods_id' => 8888, 'price' => 500, 'quality' => 1, 'card_type' => 'chinamobile'],
+//            ['goods_id' => 8888, 'price' => 500, 'quality' => 1, 'card_type' => 'chinaunicom'],
+//            ['goods_id' => 8888, 'price' => 500, 'quality' => 1, 'card_type' => 'chinatelecom']
+//        ]
+    ]
+];
+$cuanqi_sec_phone = [
+    'name' => 'cuanqi_sec', 'store_id' => 361, 'qualitys' => '1', 'official_sn' => true, 'refill_type' => 'api',
+    'amount' => [
+//        10 => [
+//            ['goods_id' => 8897, 'price' => 10, 'quality' => 1, 'card_type' => 'chinamobile'],
+//        ],
+//        20 => [
+//            ['goods_id' => 8898, 'price' => 20, 'quality' => 1, 'card_type' => 'chinamobile'],
+//        ],
+//        30 => [
+//            ['goods_id' => 8899, 'price' => 30, 'quality' => 1, 'card_type' => 'chinamobile'],
+//        ],
+        50 => [
+            ['goods_id' => 8900, 'price' => 48.3, 'quality' => 1, 'card_type' => 'chinamobile'],
+        ],
+        100 => [
+            ['goods_id' => 8901, 'price' => 96.6, 'quality' => 1, 'card_type' => 'chinamobile'],
+        ],
+        200 => [
+            ['goods_id' => 8902, 'price' => 193.2, 'quality' => 1, 'card_type' => 'chinamobile'],
+        ],
+//        300 => [
+//            ['goods_id' => 8903, 'price' => 300, 'quality' => 1, 'card_type' => 'chinamobile'],
+//        ],
+//        500 => [
+//            ['goods_id' => 8904, 'price' => 500, 'quality' => 1, 'card_type' => 'chinamobile'],
+//        ]
+    ]
+];
 
 $phone_providers = [
 	[ 'name' => 'zhongst', 'cfg' => $zhongst_phone ],
@@ -2661,4 +2783,7 @@ $phone_providers = [
     [ 'name' => 'jizheng', 'cfg' => $jizheng_phone ],
     [ 'name' => 'kachong_trd', 'cfg' => $kachong_trd_phone ],
     [ 'name' => 'chaohe_sec', 'cfg' => $chaohe_sec_phone ],
+    [ 'name' => 'xinguande', 'cfg' => $xinguande_phone ],
+    [ 'name' => 'lihui_fs', 'cfg' => $lihui_fs_phone ],
+    [ 'name' => 'cuanqi_sec', 'cfg' => $cuanqi_sec_phone ],
 	];

+ 1 - 1
data/config/yl/refill.ini.php

@@ -63,5 +63,5 @@ $config['sms_mchids'] = [10325, 10361];
 
 #风险流水号管理
 $config['risk_official_sn'] = [
-    'exclude_stores' => [121]
+    'exclude_stores' => [121, 344]
 ];

+ 2 - 0
helper/refill/api/xyz/chanlian/config.php

@@ -19,6 +19,7 @@ class config
     ];
     const Product = [
         mtopcard\ChinaMobileCard => [
+            50 => 20004,
             100 => 20005,
             200 => 20006,
             300 => 20007,
@@ -31,6 +32,7 @@ class config
             300 => 20015,
         ],
         mtopcard\ChinaTelecomCard => [
+            50 => 20020,
             100 => 20021,
             200 => 20022,
             300 => 20023,

+ 2 - 0
helper/refill/api/xyz/chanlian_sec/config.php

@@ -19,6 +19,7 @@ class config
     ];
     const Product = [
         mtopcard\ChinaMobileCard => [
+            50 => 20004,
             100 => 20005,
             200 => 20006,
             300 => 20007,
@@ -31,6 +32,7 @@ class config
             300 => 20015,
         ],
         mtopcard\ChinaTelecomCard => [
+            50 => 20020,
             100 => 20021,
             200 => 20022,
             300 => 20023,

二進制
helper/refill/api/xyz/guochuang/20250224_yd_guangdong_1.jpg


二進制
helper/refill/api/xyz/guochuang/20250226_dx_henan.png


二進制
helper/refill/api/xyz/guochuang/20250228_dx_anhui.png


二進制
helper/refill/api/xyz/guochuang/20250228_yd_dx.jpg


+ 18 - 10
helper/refill/api/xyz/guochuang/config.php

@@ -67,22 +67,22 @@ class config
         "4-10-6" => 9.67, "4-20-6" => 19.34, "4-30-6" => 29.01, "4-50-6" => 48.35, "4-100-6" => 96.7, "4-200-6" => 193.4, "4-300-6" => 290.1, "4-500-6" => 483.5,//辽宁 6
         "4-10-9" => 9.94, "4-20-9" => 19.88, "4-30-9" => 29.82, "4-50-9" => 49.7, "4-100-9" => 99.4,//上海 9
         "4-10-8" => 9.98, "4-20-8" => 19.96, "4-30-8" => 29.94, "4-50-8" => 49.9, "4-100-8" => 99.8, "4-200-8" => 199.6, "4-300-8" => 299.4, "4-500-8" => 499,//黑龙江 8
-        "4-10-29" => 10.01, "4-20-29" => 20.02, "4-30-29" => 30.03, "4-50-29" => 50.05, "4-100-29" => 99.6, "4-200-29" => 199.2, "4-300-29" => 298.8, "4-500-29" => 498,//青海 29
+        "4-5-29" => 5.775, "4-10-29" => 10.01, "4-20-29" => 20.02, "4-30-29" => 30.03, "4-50-29" => 50.05, "4-100-29" => 99.6, "4-200-29" => 199.2, "4-300-29" => 298.8, "4-500-29" => 498,//青海 29
         "4-10-28" => 10.45, "4-20-28" => 20.74, "4-30-28" => 31.11, "4-50-28" => 50.65, "4-100-28" => 99.85, "4-200-28" => 199.7, "4-300-28" => 299.55, "4-500-28" => 499.25,//甘肃 28
         "4-10-13" => 9.965, "4-20-13" => 19.93, "4-30-13" => 29.895, "4-50-13" => 49.825, "4-100-13" => 99.65, "4-200-13" => 199.3, "4-300-13" => 298.95, "4-500-13" => 498.25,//福建 13
-        "4-10-5" => 10.035, "4-20-5" => 20.07, "4-30-5" => 30.09, "4-50-5" => 50.15, "4-100-5" => 100.3, "4-200-5" => 200.4, "4-300-5" => 300.6, "4-500-5" => 501,//内蒙古 5
+        "4-10-5" => 10.26, "4-20-5" => 20.52, "4-30-5" => 30.78, "4-50-5" => 50.8, "4-100-5" => 100.3, "4-200-5" => 200.4, "4-300-5" => 300.6, "4-500-5" => 501,//内蒙古 5
         "4-30-18" => 29.835, "4-50-18" => 49.725, "4-100-18" => 99.45, "4-200-18" => 198.3,//湖南 18
-        "4-10-19" => 10.1, "4-20-19" => 20.2, "4-30-19" => 30.03, "4-50-19" => 50.475, "4-100-19" => 100.95, "4-200-19" => 201.9, "4-300-19" => 302.85, "4-500-19" => 504.75,//广东 19
+        "4-10-19" => 10.37, "4-20-19" => 20.74, "4-30-19" => 30.96, "4-50-19" => 50.475, "4-100-19" => 100.95, "4-200-19" => 201.9, "4-300-19" => 302.85, "4-500-19" => 504.75,//广东 19
         "4-10-7" => 9.93, "4-20-7" => 19.86, "4-30-7" => 29.52, "4-50-7" => 49.2, "4-100-7" => 98.4, "4-200-7" => 196.8, "4-300-7" => 295.2, "4-500-7" => 492,//吉林 7
-        "4-10-1" => 10.31, "4-20-1" => 20.32, "4-30-1" => 30.33, "4-50-1" => 50.35, "4-100-1" => 100.4, "4-200-1" => 200.3, "4-300-1" => 300.45, "4-500-1" => 500.75,//北京 1
+        "4-10-1" => 10.31, "4-20-1" => 20.32, "4-30-1" => 30.33, "4-50-1" => 50.6, "4-100-1" => 100.4, "4-200-1" => 200.3, "4-300-1" => 300.45, "4-500-1" => 500.75,//北京 1
         "4-10-22" => 10.015, "4-20-22" => 20.03, "4-30-22" => 30.045, "4-50-22" => 50.075, "4-100-22" => 100.15, "4-200-22" => 200.3, "4-300-22" => 300.45, "4-500-22" => 500.75,//重庆 22
-        "4-1-15" => 1.04, "4-2-15" => 2.08, "4-3-15" => 3.12, "4-4-15" => 4.16, "4-5-15" => 5.2, "4-6-15" => 6.24, "4-7-15" => 7.28, "4-8-15" => 8.32, "4-9-15" => 9.36, "4-10-15" => 10.62, "4-20-15" => 20.64, "4-30-15" => 30.66, "4-50-15" => 50.7, "4-100-15" => 99.3, "4-200-15" => 198.6, "4-300-15" => 297.9,//山东 15
+        "4-1-15" => 1.04, "4-2-15" => 2.08, "4-3-15" => 3.12, "4-4-15" => 4.16, "4-5-15" => 5.61, "4-6-15" => 6.24, "4-7-15" => 7.28, "4-8-15" => 8.32, "4-9-15" => 9.36, "4-10-15" => 10.62, "4-20-15" => 20.64, "4-30-15" => 30.66, "4-50-15" => 50.7, "4-100-15" => 99.3, "4-200-15" => 198.6, "4-300-15" => 297.9,//山东 15
         "4-10-10" => 9.945, "4-20-10" => 19.89, "4-30-10" => 30.18, "4-50-10" => 50.4, "4-100-10" => 100.48, "4-200-10" => 200.56, "4-300-10" => 300.84, "4-500-10" => 501.4,//江苏 10
         "4-10-11" => 9.945, "4-20-11" => 19.89, "4-30-11" => 29.835, "4-50-11" => 49.725, "4-100-11" => 99.45, "4-200-11" => 198.9, "4-300-11" => 298.35, "4-500-11" => 497.25,//浙江 11
         "4-10-17" => 9.945, "4-20-17" => 19.89, "4-30-17" => 29.835, "4-50-17" => 49.725, "4-100-17" => 99.45, "4-200-17" => 198.9, "4-300-17" => 298.35, "4-500-17" => 497.25,//湖北 17
         "4-10-16" => 10.27, "4-20-16" => 20.54, "4-30-16" => 30.81, "4-50-16" => 50.175, "4-100-16" => 100.2, "4-200-16" => 200.4, "4-300-16" => 300.6, "4-500-16" => 501,//河南 16
         "4-10-4" => 10.23, "4-20-4" => 20.46, "4-30-4" => 30.105, "4-50-4" => 50.175, "4-100-4" => 100.35, "4-200-4" => 200.7, "4-300-4" => 301.05, "4-500-4" => 501.75,//山西 4
-        "4-10-24" => 10.12, "4-20-24" => 20.14, "4-30-24" => 30.165, "4-50-24" => 50.1, "4-100-24" => 100.2, "4-200-24" => 200.4, "4-300-24" => 300.6, "4-500-24" => 501,//贵州 24
+        "4-5-24" => 5.775, "4-10-24" => 10.045, "4-20-24" => 20.09, "4-30-24" => 29.91, "4-50-24" => 49.9, "4-100-24" => 99.8, "4-200-24" => 200.4, "4-300-24" => 300.6, "4-500-24" => 501,//贵州 24
         "4-10-30" => 10.12, "4-20-30" => 20.24, "4-30-30" => 30.129, "4-50-30" => 50.15, "4-100-30" => 100.2, "4-200-30" => 200.4, "4-300-30" => 300.3, "4-500-30" => 500.5,//宁夏 30
         "4-10-25" => 10.14, "4-20-25" => 20.2, "4-30-25" => 30.18, "4-50-25" => 50.1, "4-100-25" => 100.2, "4-200-25" => 200.4, "4-300-25" => 300.6, "4-500-25" => 501,//云南 25
         "4-10-27" => 10.22, "4-20-27" => 20.44, "4-30-27" => 30.66, "4-50-27" => 50.1, "4-100-27" => 100.1, "4-200-27" => 200.2, "4-300-27" => 300.3, "4-500-27" => 500.5,//陕西 27
@@ -100,17 +100,25 @@ class config
         //电信
         "6-10-27" => 10.12, "6-20-27" => 20.24, "6-30-27" => 30.36, "6-50-27" => 50.1, "6-100-27" => 100.2, "6-200-27" => 199.94, "6-300-27" => 299.91, "6-500-27" => 501,//陕西 27
         "6-10-4" => 10.37, "6-20-4" => 20.39, "6-30-4" => 30.42, "6-50-4" => 50.45, "6-100-4" => 100.6, "6-200-4" => 201.2, "6-300-4" => 301.8, "6-500-4" => 503,//山西 4
-        "6-10-18" => 10.04, "6-20-18" => 20.08, "6-30-18" => 30.12, "6-50-18" => 50.15, "6-100-18" => 100.3, "6-200-18" => 200.6, "6-300-18" => 300.9, "6-500-18" => 501.5,//湖南 18
+        "6-10-18" => 10.09, "6-20-18" => 20.1, "6-30-18" => 30.12, "6-50-18" => 50.1, "6-100-18" => 100.2, "6-200-18" => 200.3, "6-300-18" => 300.45, "6-500-18" => 500.75,//湖南 18
         "6-10-15" => 10.37, "6-20-15" => 20.38, "6-30-15" => 30.42, "6-50-15" => 50.8, "6-100-15" => 101, "6-200-15" => 200.4, "6-300-15" => 300.6, "6-500-15" => 501,//山东 15
-        "6-10-12" => 10.2, "6-20-12" => 20.24, "6-30-12" => 30.21, "6-50-12" => 50.275, "6-100-12" => 100.35, "6-200-12" => 200.4, "6-300-12" => 300.9, "6-500-12" => 501.5,//安徽 12
+        "6-10-12" => 10.2, "6-20-12" => 20.24, "6-30-12" => 30.21, "6-50-12" => 50.4, "6-100-12" => 100.7, "6-200-12" => 200.6, "6-300-12" => 300.9, "6-500-12" => 501.5,//安徽 12
         "6-10-2" => 10.12, "6-20-2" => 20.16, "6-30-2" => 30.21, "6-50-2" => 50.175, "6-100-2" => 100.35, "6-200-2" => 200.7, "6-300-2" => 301.05, "6-500-2" => 501.75,//天津 2
         "6-10-20" => 10.15, "6-20-20" => 20.18, "6-30-20" => 30.21, "6-50-20" => 50.3, "6-100-20" => 100.45, "6-200-20" => 200.6, "6-300-20" => 300.9, "6-500-20" => 501.5,//广西 20
         "6-10-29" => 10.13, "6-20-29" => 20.14, "6-30-29" => 30.18, "6-50-29" => 50.25, "6-100-29" => 100.35, "6-200-29" => 200.6, "6-300-29" => 300.9, "6-500-29" => 501.5,//青海 29
         "6-100-1" => 100.2, "6-200-1" => 200.2, "6-300-1" => 300.3, "6-500-1" => 500.5,//北京 1
-        "6-10-16" => 10.13, "6-20-16" => 20.24, "6-30-16" => 30.36, "6-50-16" => 50.3, "6-100-16" => 100.5, "6-200-16" => 200.8, "6-300-16" => 301.2, "6-500-16" => 502,//河南 16
-        "6-10-13" => 10.07, "6-20-13" => 20.14, "6-30-13" => 30.21, "6-50-13" => 50.5, "6-100-13" => 100.9, "6-200-13" => 200.8, "6-300-13" => 300.9, "6-500-13" => 501.5,//福建 13
+        "6-10-16" => 10.13, "6-20-16" => 20.24, "6-30-16" => 30.36, "6-50-16" => 50.3, "6-100-16" => 100.4, "6-200-16" => 200.8, "6-300-16" => 301.2, "6-500-16" => 502,//河南 16
+        "6-10-13" => 10.17, "6-20-13" => 20.16, "6-30-13" => 30.18, "6-50-13" => 50.3, "6-100-13" => 100.55, "6-200-13" => 200.8, "6-300-13" => 301.2, "6-500-13" => 502,//福建 13
         "6-10-6" => 10.21, "6-20-6" => 20.24, "6-30-6" => 30.27, "6-50-6" => 50.175, "6-100-6" => 100.35, "6-200-6" => 200.7, "6-300-6" => 301.05, "6-500-6" => 501.75,//辽宁 6
         "6-10-17" => 10.23, "6-20-17" => 20.46, "6-30-17" => 30.69, "6-50-17" => 51.1,//湖北 17
         "6-10-3" => 10.15, "6-20-3" => 20.3, "6-30-3" => 30.45, "6-50-3" => 50.45, "6-100-3" => 100.9, "6-200-3" => 201.6, "6-300-3" => 302.4, "6-500-3" => 504,//河北 3
+        "6-10-14" => 10.15, "6-20-14" => 20.1, "6-30-14" => 30.15, "6-50-14" => 50.3, "6-100-14" => 100.6, "6-200-14" => 200.7, "6-300-14" => 301.05, "6-500-14" => 501.75,//江西 14
+        "6-10-31" => 10.1, "6-20-31" => 20.12, "6-30-31" => 30.15, "6-50-31" => 50.2, "6-100-31" => 100.3, "6-200-31" => 200.6, "6-300-31" => 300.75, "6-500-31" => 501.25,//新疆 31
+        "6-10-10" => 10.15, "6-20-10" => 20.16, "6-30-10" => 30.225,//江苏 10
+        "6-10-24" => 10.14, "6-20-24" => 20.16, "6-30-24" => 30.18, "6-50-24" => 50.3, "6-100-24" => 100.45, "6-200-24" => 200.6, "6-300-24" => 300.9, "6-500-24" => 501.5,//贵州 24
+        "6-10-22" => 10.16, "6-20-22" => 20.18, "6-30-22" => 30.24, "6-50-22" => 50.4, "6-100-22" => 100.45, "6-200-22" => 200.6, "6-300-22" => 300.9, "6-500-22" => 501.5,//重庆 22
+        "6-10-28" => 10.12, "6-20-28" => 20.24, "6-30-28" => 30.36, "6-50-28" => 50.45, "6-100-28" => 100.9, "6-200-28" => 201.6, "6-300-28" => 302.4, "6-500-28" => 504,//甘肃 28
+        "6-10-23" => 10.15, "6-20-23" => 20.3, "6-30-23" => 30.45, "6-50-23" => 50.45, "6-100-23" => 100.9, "6-200-23" => 201.6, "6-300-23" => 302.4, "6-500-23" => 504,//四川 23
+        "6-10-9" => 10.15, "6-20-9" => 20.18, "6-30-9" => 30.21, "6-50-9" => 50.25, "6-100-9" => 100.4, "6-200-9" => 200.5, "6-300-9" => 300.75, "6-500-9" => 501.25,//上海 9
     ];
 }

二進制
helper/refill/api/xyz/meixu_fs/20250225全量配置.xlsx


二進制
helper/refill/api/xyz/meixu_fs/20250228_dx_anhui.jpg


+ 174 - 21
helper/refill/api/xyz/meixu_fs/config.php

@@ -38,7 +38,9 @@ class config
             ],
             //广东
             19 => [
-                30 => 100059,
+                10 => 30000004830,
+                20 => 30000004831,
+                30 => 30000004870,
                 50 => 100060,
                 100 => 100061,
                 200 => 100062,
@@ -85,11 +87,14 @@ class config
             ],
             //贵州
             24 => [
-                10 => 30000001589,
-                20 => 30000001590,
-                30 => 30000001591,
-                50 => 30000001592,
-                100 => 30000001593,
+                10 => 30000002038,
+                20 => 30000002039,
+                30 => 30000002040,
+                50 => 30000002041,
+                100 => 30000002042,
+                200 => 30000002043,
+                300 => 30000002044,
+                500 => 30000002045,
             ],
             //内蒙古
             5 => [
@@ -97,6 +102,10 @@ class config
                 20 => 100218,
                 30 => 100219,
                 50 => 100220,
+                100 => 100221,
+                200 => 100222,
+                300 => 100223,
+                500 => 100224,
             ],
             //山东
             15 => [
@@ -105,20 +114,42 @@ class config
                 30 => 100131,
                 50 => 100132,
             ],
+            //陕西
+            27 => [
+                10 => 30000002312,
+                20 => 30000002313,
+                30 => 30000002314,
+                50 => 30000002315,
+                100 => 30000002316,
+                200 => 30000002317,
+                300 => 30000002318,
+                500 => 30000002319,
+            ],
         ],
         mtopcard\ChinaUnicomCard => [
+            //江西
+            14 => [
+                10 => 30000002126,
+                20 => 30000002127,
+                30 => 30000002128,
+                50 => 30000002129,
+                100 => 30000002130,
+                200 => 30000002131,
+                300 => 30000002132,
+                500 => 30000002133,
+            ],
         ],
         mtopcard\ChinaTelecomCard => [
             //四川
             23 => [
-                10 => 30000003570,
-                20 => 30000003571,
-                30 => 30000003572,
-                50 => 30000003573,
-                100 => 30000003574,
-                200 => 30000003575,
-                300 => 30000003576,
-                500 => 30000003577,
+                10 => 30000003290,
+                20 => 30000003291,
+                30 => 30000003292,
+                50 => 30000003293,
+                100 => 30000003294,
+                200 => 30000003295,
+                300 => 30000003296,
+                500 => 30000003297,
             ],
             //陕西
             27 => [
@@ -131,23 +162,145 @@ class config
                 300 => 100319,
                 500 => 100320,
             ],
+            //江西
+            14 => [
+                10 => 30000002118,
+                20 => 30000002119,
+                30 => 30000002120,
+                50 => 30000002121,
+                100 => 30000002122,
+                200 => 30000002123,
+                300 => 30000002124,
+                500 => 30000002125,
+            ],
+            //河南
+            16 => [
+                10 => 30000002250,
+                20 => 30000002251,
+                30 => 30000002252,
+                50 => 30000002253,
+                100 => 30000002254,
+                200 => 30000002255,
+                300 => 30000002256,
+                500 => 30000002257,
+            ],
+            //湖南
+            18 => [
+                10 => 30000002830,
+                20 => 30000002831,
+                30 => 30000002832,
+                50 => 30000002833,
+                100 => 30000002834,
+                200 => 30000002835,
+                300 => 30000002836,
+                500 => 30000002837,
+            ],
+            //新疆
+            31 => [
+                10 => 30000002990,
+                20 => 30000002991,
+                30 => 30000002992,
+                50 => 30000002993,
+                100 => 30000002994,
+                200 => 30000002995,
+                300 => 30000002996,
+                500 => 30000002997,
+            ],
+            //福建
+            13 => [
+                10 => 30000003434,
+                20 => 30000003435,
+                30 => 30000003436,
+                50 => 30000003437,
+                100 => 30000003438,
+                200 => 30000003439,
+                300 => 30000003440,
+                500 => 30000003441,
+            ],
+            //天津
+            2 => [
+                10 => 30000003870,
+                20 => 30000003871,
+                30 => 30000003872,
+                50 => 30000003873,
+                100 => 30000003874,
+                200 => 30000003875,
+                300 => 30000003876,
+                500 => 30000003877,
+            ],
+            //辽宁
+            6 => [
+                10 => 30000004570,
+                20 => 30000004571,
+                30 => 30000004572,
+                50 => 30000004573,
+                100 => 30000004574,
+                200 => 30000004575,
+                300 => 30000004576,
+                500 => 30000004577,
+            ],
+            //安徽
+            12 => [
+                10 => 30000004610,
+                20 => 30000004611,
+                30 => 30000004612,
+                50 => 30000004613,
+                100 => 30000004614,
+                200 => 30000004615,
+                300 => 30000004616,
+                500 => 30000004617,
+            ],
+            //江苏
+            10 => [
+                10 => 30000004990,
+                20 => 30000004991,
+                30 => 30000004992,
+                50 => 30000004993,
+                100 => 30000004994,
+                200 => 30000004995,
+                300 => 30000004996,
+                500 => 30000004997,
+            ],
+            //北京
+            1 => [
+                10 => 30000005881,
+                20 => 30000005882,
+                30 => 30000005883,
+                50 => 30000005884,
+                100 => 30000006110,
+                200 => 30000006154,
+            ],
         ],
     ];
 
     const Price = [
         //移动
         "4-10-6" => 9.665, "4-20-6" => 19.33, "4-30-6" => 28.995, "4-50-6" => 48.325, "4-100-6" => 96.65, "4-200-6" => 193.3, "4-300-6" => 289.95, "4-500-6" => 483.25,//辽宁 6
-        "4-30-19" => 29.994, "4-50-19" => 50.54, "4-100-19" => 101.08, "4-200-19" => 202.16, "4-300-19" => 303.24, "4-500-19" => 505.4,//广东 19
+        "4-10-19" => 10.36, "4-20-19" => 20.72, "4-30-19" => 30.93, "4-50-19" => 50.55, "4-100-19" => 101.1, "4-200-19" => 202.2, "4-300-19" => 303.3, "4-500-19" => 505.5,//广东 19
         "4-10-13" => 10.145, "4-20-13" => 20.29, "4-30-13" => 30.435, "4-50-13" => 50.05, "4-100-13" => 100.1, "4-200-13" => 200.2, "4-300-13" => 300.3, "4-500-13" => 500.5,//福建 13
-        "4-10-29" => 9.84, "4-20-29" => 19.68, "4-30-29" => 29.52, "4-50-29" => 49.2, "4-100-29" => 98.4, "4-200-29" => 196.8, "4-300-29" => 295.2, "4-500-29" => 492,//青海 29
+        "4-10-29" => 10, "4-20-29" => 20, "4-30-29" => 30, "4-50-29" => 50, "4-100-29" => 99.5, "4-200-29" => 199, "4-300-29" => 298.5, "4-500-29" => 497.5,//青海 29
         "4-30-10" => 30.9, "4-50-10" => 50.6, "4-100-10" => 100.25, "4-200-10" => 200.5,//江苏 10
         "4-10-8" => 9.988, "4-20-8" => 19.976, "4-30-8" => 29.964, "4-50-8" => 49.94, "4-100-8" => 99.88, "4-200-8" => 199.76,//黑龙江 8
-        "4-10-24" => 10.08, "4-20-24" => 20.16, "4-30-24" => 30.24, "4-50-24" => 50, "4-100-24" => 100,//贵州 24
-        "4-10-5" => 10.21, "4-20-5" => 20.42, "4-30-5" => 30.63, "4-50-5" => 50.55,//内蒙古 5
-        "4-10-15" => 10.51, "4-20-15" => 20.62, "4-30-15" => 30.63, "4-50-15" => 50.65,//山东 15
+        "4-10-24" => 10.048, "4-20-24" => 20.096, "4-30-24" => 30.144, "4-50-24" => 49.79, "4-100-24" => 99.58, "4-200-24" => 200.2, "4-300-24" => 300.3, "4-500-24" => 500.5,//贵州 24
+        "4-10-5" => 10.26, "4-20-5" => 20.52, "4-30-5" => 30.78, "4-50-5" => 50.8, "4-100-5" => 100.3, "4-200-5" => 200.6, "4-300-5" => 300.9, "4-500-5" => 501.5,//内蒙古 5
+        "4-10-15" => 10.32, "4-20-15" => 20.64, "4-30-15" => 30.66, "4-50-15" => 50.55,//山东 15
+        "4-10-27" => 10.2, "4-20-27" => 20.4, "4-30-27" => 30.6, "4-50-27" => 49.99, "4-100-27" => 99.98, "4-200-27" => 199.96, "4-300-27" => 299.94, "4-500-27" => 499.9,//陕西 27
+
+        //联通
+        "5-10-14" => 10.14, "5-20-14" => 20.28, "5-30-14" => 30.42, "5-50-14" => 50.1, "5-100-14" => 100.2, "5-200-14" => 200.4, "5-300-14" => 300.6, "5-500-14" => 501,//江西 14
 
         //电信
-        "4-10-23" => 10.21, "4-20-23" => 20.22, "4-30-23" => 30.24, "4-50-23" => 50.15, "4-100-23" => 100.3, "4-200-23" => 200.6, "4-300-23" => 300.9, "4-500-23" => 501.5,//四川 6
-        "6-10-27" => 9.985, "6-20-27" => 19.97, "6-30-27" => 29.955, "6-50-27" => 49.925, "6-100-27" => 99.85, "6-200-27" => 199.7, "6-300-27" => 299.55, "6-500-27" => 499.25,//陕西 27
+        "6-10-23" => 10.22, "6-20-23" => 20.24, "6-30-23" => 30.24, "6-50-23" => 50.3, "6-100-23" => 100.3, "6-200-23" => 200.96, "6-300-23" => 301.44, "6-500-23" => 502.4,//四川 23
+        "6-10-27" => 10.11, "6-20-27" => 20.22, "6-30-27" => 30.33, "6-50-27" => 50.05, "6-100-27" => 100.1, "6-200-27" => 199.96, "6-300-27" => 299.55, "6-500-27" => 499.25,//陕西 27
+        "6-10-14" => 10.21, "6-20-14" => 20.08, "6-30-14" => 30.12, "6-50-14" => 50.225, "6-100-14" => 100.3, "6-200-14" => 200.4, "6-300-14" => 301.05, "6-500-14" => 501.75,//江西 14
+        "6-10-16" => 10.13, "6-20-16" => 20.2, "6-30-16" => 30.3, "6-50-16" => 50.25, "6-100-16" => 100.25, "6-200-16" => 200.4, "6-300-16" => 300.6, "6-500-16" => 501,//河南 16
+        "6-10-18" => 10.21, "6-20-18" => 20.22, "6-30-18" => 30.225, "6-50-18" => 50.2, "6-100-18" => 100.35, "6-200-18" => 200.7, "6-300-18" => 301.05, "6-500-18" => 501.75,//湖南 18
+        "6-10-31" => 10.11, "6-20-31" => 20.12, "6-30-31" => 30.18, "6-50-31" => 50.15, "6-100-31" => 100.2, "6-200-31" => 200.3, "6-300-31" => 300.3, "6-500-31" => 500.5,//新疆 31
+        "6-10-13" => 10.16, "6-20-13" => 20.14, "6-30-13" => 30.15, "6-50-13" => 50.25, "6-100-13" => 100.5, "6-200-13" => 200.8, "6-300-13" => 301.2, "6-500-13" => 502,//福建 13
+        "6-10-2" => 10.22, "6-20-2" => 20.1, "6-30-2" => 30.24, "6-50-2" => 50.2, "6-100-2" => 100.4, "6-200-2" => 200.8, "6-300-2" => 301.2, "6-500-2" => 502,//天津 2
+        "6-10-6" => 10.22, "6-20-6" => 20.1, "6-30-6" => 30.24, "6-50-6" => 50.2, "6-100-6" => 100.4, "6-200-6" => 200.8, "6-300-6" => 301.2, "6-500-6" => 502,//辽宁 6
+        "6-10-12" => 10.215, "6-20-12" => 20.23, "6-30-12" => 30.285, "6-50-12" => 50.3, "6-100-12" => 100.45, "6-200-12" => 200.56, "6-300-12" => 300.84, "6-500-12" => 501.4,//安徽 12
+        "6-10-10" => 10.17, "6-20-10" => 20.2, "6-30-10" => 30.24, "6-50-10" => 50.4, "6-100-10" => 100.7, "6-200-10" => 201, "6-300-10" => 301.5, "6-500-10" => 502.5,//江苏 10
+        "6-10-1" => 10.28, "6-20-1" => 20.3, "6-30-1" => 30.3, "6-50-1" => 50.35, "6-100-1" => 100.35, "6-200-1" => 200.5,//北京 1
     ];
 }

+ 2 - 1
helper/refill/api/xyz/meixu_sec/config.php

@@ -34,7 +34,8 @@ class config
             500 => 30000003377,
         ],
         mtopcard\ChinaUnicomCard => [
-
+            50 => 100361,
+            100 => 100362,
         ],
         mtopcard\ChinaTelecomCard => [
             50 => 30000003445,

+ 2 - 0
helper/refill/api/xyz/qingyu/config.php

@@ -19,6 +19,7 @@ class config
     ];
     const Product = [
         mtopcard\ChinaMobileCard => [
+            50 => 20004,
             100 => 20005,
             200 => 20006,
             300 => 20007,
@@ -31,6 +32,7 @@ class config
             300 => 20015,
         ],
         mtopcard\ChinaTelecomCard => [
+            50 => 20020,
             100 => 20021,
             200 => 20022,
             300 => 20023,

+ 2 - 0
helper/refill/api/xyz/qingyu_sec/config.php

@@ -19,6 +19,7 @@ class config
     ];
     const Product = [
         mtopcard\ChinaMobileCard => [
+            50 => 20004,
             100 => 20005,
             200 => 20006,
             300 => 20007,
@@ -31,6 +32,7 @@ class config
             300 => 20015,
         ],
         mtopcard\ChinaTelecomCard => [
+            50 => 20020,
             100 => 20021,
             200 => 20022,
             300 => 20023,

+ 15 - 0
helper/refill/api/xyz/yeyekc18/API.MD

@@ -0,0 +1,15 @@
+
+## YY椰椰-快充18
+
+### 机构账号
+- 后台登录地址:https://ylweb.xyzshops.cn/merchant/#/login
+- ID:10410
+- 登录名:yeyekc18
+- 初始密码:dxhoi_io9
+
+### 接口信息
+- 密钥:648b9d220b62b0ee894d3bfe59cd3a22
+
+## 店铺账号
+- 账号:yeyekc18
+- 密码:yeyekc1867890

+ 76 - 0
helper/refill/api/xyz/yeyekc18/RefillCallBack.php

@@ -0,0 +1,76 @@
+<?php
+namespace refill\yeyekc18;
+
+require_once(BASE_HELPER_RAPI_PATH . '/yeyekc18/config.php');
+use refill;
+class RefillCallBack implements refill\IRefillCallBack
+{
+    public function verify($params): bool
+    {
+        $input = $params;
+        unset($input['sign']);
+        $sign = $this->sign($input);
+        if ($params['sign'] == $sign) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    protected function check_empty($value)
+    {
+        if (!isset($value))
+            return true;
+        if ($value === null)
+            return true;
+        if (trim($value) === "")
+            return true;
+
+        return false;
+    }
+
+    private function sign($params)
+    {
+        ksort($params);
+
+        $body = "";
+        $i = 0;
+        foreach ($params as $k => $v) {
+            if (false === $this->check_empty($v) && "@" != substr($v, 0, 1)) {
+                if ($i == 0) {
+                    $body .= "{$k}" . "=" . urlencode($v);
+                } else {
+                    $body .= "&" . "{$k}" . "=" . urlencode($v);
+                }
+                $i++;
+            }
+        }
+
+        $body .= "&key=".config::KEY;
+        return md5($body);
+    }
+
+    public function notify($params)
+    {
+        $status = $params['state'];
+        $order_sn = $params['order_sn'];
+        $order_info = Model('vr_order')->getOrderInfoForNotify(['order_sn' => $order_sn]);
+        if (empty($order_info)) {
+            return [false, false, false,false];
+        }
+        $order_id = $order_info['order_id'];
+        if ($status === 'SUCCESS') {
+            $data['ch_trade_no'] = $params['trade_no'];
+            $data['official_sn'] = strtolower($params['official_sn']) == 'null' ? '' : $params['official_sn'];
+            Model('refill_order')->edit($order_id, $data);
+            return [$order_id, true, false,true];
+        }
+        elseif ($status === 'CANCEL') {
+            Model('refill_order')->edit($order_id, ['ch_trade_no' => $params['trade_no']]);
+            return [$order_id, false, true,true];
+        }
+        else {
+            return [$order_id, false, false,false];
+        }
+    }
+}

+ 161 - 0
helper/refill/api/xyz/yeyekc18/RefillPhone.php

@@ -0,0 +1,161 @@
+<?php
+
+namespace refill\yeyekc18;
+
+require_once(BASE_HELPER_RAPI_PATH . '/yeyekc18/config.php');
+
+use refill;
+use Log;
+
+class RefillPhone extends refill\IRefillPhone
+{
+    public function __construct($cfgs)
+    {
+        parent::__construct($cfgs);
+    }
+
+    private function req_params(int $phone, int $amount, string $order_sn)
+    {
+        $params['act'] = 'refill';
+        $params['op'] = 'add';
+        $params['mchid'] = config::MCH_ID;
+        $params['cardno'] = $phone;
+        $params['amount'] = $amount;
+        $params['order_sn'] = $order_sn;
+        $params['notifyurl'] = config::NOTIFY_URL;
+        return $params;
+    }
+
+    public function add($card_no, $card_type, $amount, $params,&$net_errno = 0)
+    {
+        $params = $this->req_params($card_no, $amount, $params['order_sn']);
+        $sign = $this->sign($params);
+        $params['sign'] = $sign;
+
+        $resp = http_request(config::ORDER_URL, $params , 'POST' , false , [] , $net_errno);
+
+        if (empty($resp)) {
+            return [false, '系统错误', true];
+        }
+        else
+        {
+            Log::record($resp, Log::DEBUG);
+            $resp = json_decode($resp ,true);
+            if (empty($resp)) {
+                return [false, '系统错误', true];
+            } elseif ($resp['code'] === 200) {
+                return [true, '', false];
+            } else {
+                return [false, $resp['message'], false];
+            }
+        }
+    }
+
+    public function query($refill_info)
+    {
+        $params['act'] = 'refill';
+        $params['op'] = 'query';
+        $params['mchid'] = config::MCH_ID;
+        $params['order_sn'] = $refill_info['order_sn'];
+        $params['sign'] = $this->sign($params);
+
+        $resp = http_request(config::ORDER_URL, $params , 'POST');
+        if (empty($resp)) {
+            return [false, '系统错误'];
+        }
+        else
+        {
+            Log::record($resp, Log::DEBUG);
+            $resp = json_decode($resp, true);
+            if (empty($resp)) {
+                return [false, '系统错误'];
+            }
+            elseif ($resp['code'] === 200)
+            {
+                $data = $resp['datas'];
+                if ($data['order_state'] == '40') {
+                    $save['ch_trade_no'] = $data['trade_no'];
+                    $save['official_sn'] = strtolower($resp['official_sn']) == 'null' ? '' : $resp['official_sn'];
+                    Model('refill_order')->edit($refill_info['order_id'], $save);
+                    $order_state = ORDER_STATE_SUCCESS;
+                } elseif ($data['order_state'] === '0') {
+                    Model('refill_order')->edit($refill_info['order_id'], ['ch_trade_no' => $data['trade_no']]);
+                    $order_state = ORDER_STATE_CANCEL;
+                } elseif (in_array($data['order_state'], ['10', '20', '30', '50'], true)) {
+                    $order_state = ORDER_STATE_SEND;
+                } else {
+                    return [false, $resp['message']];
+                }
+                return [true, $order_state];
+            }
+            elseif ($resp['code'] === 202 && (time() - $refill_info['commit_time'] >= 600))
+            {
+                return [true, ORDER_STATE_NOEXIST];
+            }
+            else
+            {
+                return [false, $resp['message']];
+            }
+        }
+    }
+
+    public function balance()
+    {
+        $params['act'] = 'refill';
+        $params['op'] = 'balance';
+        $params['mchid'] = config::MCH_ID;
+        $params['sign'] = $this->sign($params);
+
+        $resp = http_request(config::ORDER_URL, $params , 'POST');
+
+        if (empty($resp)) {
+            return [false, '系统错误'];
+        }
+        else
+        {
+            Log::record($resp, Log::DEBUG);
+            $resp = json_decode($resp, true);
+            if (empty($resp)) {
+                return [false, '系统错误'];
+            } elseif ($resp['code'] === 200) {
+                return [true, $resp['datas']['balance']];
+            } else {
+                return [false, $resp['message']];
+            }
+        }
+    }
+
+    protected function check_empty($value)
+    {
+        if (!isset($value))
+            return true;
+        if ($value === null)
+            return true;
+        if (trim($value) === "")
+            return true;
+
+        return false;
+    }
+
+    private function sign($params)
+    {
+        ksort($params);
+
+        $body = "";
+        $i = 0;
+        foreach ($params as $k => $v) {
+            if (false === $this->check_empty($v) && "@" != substr($v, 0, 1)) {
+                if ($i == 0) {
+                    $body .= "{$k}" . "=" . urlencode($v);
+                } else {
+                    $body .= "&" . "{$k}" . "=" . urlencode($v);
+                }
+                $i++;
+            }
+        }
+
+        $body .= "&key=".config::KEY;
+
+        return md5($body);
+    }
+}

+ 12 - 0
helper/refill/api/xyz/yeyekc18/config.php

@@ -0,0 +1,12 @@
+<?php
+
+namespace refill\yeyekc18;
+
+class config
+{
+    const ORDER_URL = 'https://ylapi.xyzshops.cn/mobile/index.php';
+
+    const MCH_ID = 10410;
+    const KEY = '648b9d220b62b0ee894d3bfe59cd3a22';
+    const NOTIFY_URL = BASE_SITE_URL . "/mobile/callback/refill_yeyekc18.php";
+}

+ 27 - 0
helper/refill/api/yl/cuanqi_sec/API.MD

@@ -0,0 +1,27 @@
+## 促安起全国2号
+
+### 正式环境:
+- 话费下单地址:http://8.130.117.16:16188/plat/api/hf/submitorder
+- 查询地址:http://8.130.117.16:16188/plat/api/queryorder
+- 查询余额地址:http://8.130.117.16:16188/plat/api/querybalance
+
+- 客户端地址:http://8.130.117.16:16188/plat/login
+- 账号:xj123456
+- 密码:xj123456
+- 客户ID:100009
+- 密钥:bfde8e81f37042d1b2817a7b1f48855d
+
+### 对接文档地址:
+> https://docs.qq.com/doc/DWEhQWEhDVEJIdUVC
+
+### 店铺账号
+- cuanqi_sec
+- cuanqi_sec67890
+
+### 产品编码
+```angular2html
+移动
+编码:1000050 面值50 折扣96.6
+编码:1000100 面值100 折扣96.6
+编码:1000200 面值200 折扣96.6
+```

+ 52 - 0
helper/refill/api/yl/cuanqi_sec/RefillCallBack.php

@@ -0,0 +1,52 @@
+<?php
+namespace refill\cuanqi_sec;
+
+require_once(BASE_HELPER_RAPI_PATH . '/cuanqi_sec/config.php');
+
+use refill;
+class RefillCallBack implements refill\IRefillCallBack
+{
+    public function verify($params): bool
+    {
+        $sign = $this->sign($params);
+        if ($params['szVerifyString'] == $sign) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    private function sign($params)
+    {
+        $userid = config::USER_ID;
+        $key = config::KEY;
+        $content = "szAgentId={$userid}&szOrderId={$params['szOrderId']}&szPhoneNum={$params['szPhoneNum']}&nDemo={$params['nDemo']}&fSalePrice={$params['fSalePrice']}";
+        $content .= "&nFlag={$params['nFlag']}&szKey={$key}";
+        return md5($content);
+    }
+
+    public function notify($params)
+    {
+        $status = intval($params['nFlag']);
+        $order_sn = $params['szOrderId'];
+        $order_info = Model('vr_order')->getOrderInfoForNotify(['order_sn' => $order_sn]);
+        if (empty($order_info)) {
+            return [false, false, false, false, ''];
+        }
+        $order_id = $order_info['order_id'];
+
+        if ($status === 2) {
+            $official_sn = strtolower($params['szRtnMsg']) == 'null' ? '' : $params['szRtnMsg'];
+
+            $data['official_sn'] = $official_sn;
+            Model('refill_order')->edit($order_id, $data);
+            return [$order_id, true, false, true, $official_sn];
+        }
+        elseif ($status === 3) {
+            return [$order_id, false, true, true, ''];
+        }
+        else {
+            return [$order_id, false, false, false, ''];
+        }
+    }
+}

+ 146 - 0
helper/refill/api/yl/cuanqi_sec/RefillPhone.php

@@ -0,0 +1,146 @@
+<?php
+
+namespace refill\cuanqi_sec;
+
+require_once(BASE_HELPER_RAPI_PATH . '/cuanqi_sec/config.php');
+
+use refill;
+use Log;
+
+class RefillPhone extends refill\IRefillPhone
+{
+    public function __construct($cfgs)
+    {
+        parent::__construct($cfgs);
+    }
+
+    private function req_params(int $phone, int $amount, int $card_type, string $order_sn)
+    {
+        $params['szAgentId'] = config::USER_ID;
+        $params['szOrderId'] = $order_sn;
+        $params['szPhoneNum'] = $phone;
+        $params['nMoney'] = $amount;
+        $params['nSortType'] = config::operator[$card_type];
+        $params['szProductId'] = config::Product[$card_type][$amount];
+        $params['nProductClass'] = 1;
+        $params['nProductType'] = 1;
+        $params['szTimeStamp'] = date("Y-m-d H:i:s");
+        $params['szNotifyUrl'] = config::NOTIFY_URL;
+        return $params;
+    }
+
+    public function add($card_no, $card_type, $amount, $params,&$net_errno = 0)
+    {
+        $order_sn = $params['order_sn'];
+        $params = $this->req_params($card_no, $amount, $card_type, $order_sn);
+
+        $sign = $this->sign($params);
+        $params['szVerifyString'] = $sign;
+
+        $resp = http_request(config::ORDER_URL, $params, 'POST', false, config::ExtHeaders, $net_errno);
+
+        if (empty($resp)) {
+            return [false, '网络错误', true];
+        }
+        else
+        {
+            Log::record($resp, Log::DEBUG);
+            $resp = json_decode($resp, true);
+
+            $nRtn = $resp['nRtn'];
+            if (empty($resp)) {
+                return [false, '网络错误', true];
+            } elseif ($nRtn === 0) {
+                return [true, '', false];
+            } elseif (in_array($nRtn, config::ERR_NOS, true)) {
+                return [false, $resp['szRtnCode'], false];
+            } elseif (in_array($nRtn, [2050, 999], true)) {
+                $net_errno = "HTTP-{$nRtn}";
+                return [false, $resp['szRtnCode'], true];
+            } else {
+                $err = 998;
+                $net_errno = "HTTP-{$err}";
+                return [false, $resp['szRtnCode'], true];
+            }
+        }
+    }
+
+    public function query($refill_info)
+    {
+        $params['szAgentId'] = config::USER_ID;
+        $params['szOrderId'] = $refill_info['order_sn'];
+        $key = config::KEY;
+        $content = "szAgentId={$params['szAgentId']}&szOrderId={$params['szOrderId']}&szKey={$key}";
+        $params['szVerifyString'] = md5($content);
+
+        $resp = http_request(config::QUERY_URL, $params, 'POST', false, config::ExtHeaders);
+
+        if (empty($resp)) {
+            return [false, '网络错误', ''];
+        }
+        else
+        {
+            Log::record($resp, Log::DEBUG);
+            $resp = json_decode($resp, true);
+            if (empty($resp)) {
+                return [false, '网络错误', ''];
+            }
+
+            $official_sn = '';
+
+            $status = $resp['nRtn'];
+            if ($status === 5012) {
+                $official_sn = $resp['szRtnMsg'];
+
+                $updata['official_sn'] = $official_sn;
+                Model('refill_order')->edit($refill_info['order_id'], $updata);
+                $order_state = ORDER_STATE_SUCCESS;
+            } elseif ($status === 5013) {
+                $order_state = ORDER_STATE_CANCEL;
+            } elseif (in_array($status, [5011,5019],true)) {
+                $order_state = ORDER_STATE_SEND;
+            } elseif ($status === 5005 && (time() - $refill_info['commit_time'] > 300)) {
+                $order_state = ORDER_STATE_NOEXIST;
+            } else {
+                return [false, $resp['szRtnMsg'], ''];
+            }
+
+            return [true, $order_state, $official_sn];
+        }
+    }
+
+    public function balance()
+    {
+        $params['szAgentId'] = config::USER_ID;
+        $key = config::KEY;
+        $content = "szAgentId={$params['szAgentId']}&szKey={$key}";
+        $params['szVerifyString'] = md5($content);
+
+        $resp = http_request(config::BALANCE_URL, $params, 'POST', false, config::ExtHeaders);
+
+        if (empty($resp)) {
+            return [false, '网络错误'];
+        }
+        else
+        {
+            Log::record($resp, Log::DEBUG);
+            $resp = json_decode($resp, true);
+            if (empty($resp)) {
+                return [false, '网络错误'];
+            } elseif ($resp['nRtn'] === 0) {
+                return [true, $resp['fBalance']];
+            } else {
+                return [false, $resp['szRtnCode']];
+            }
+        }
+    }
+
+    private function sign($params)
+    {
+        $userid = config::USER_ID;
+        $key = config::KEY;
+        $content = "szAgentId={$userid}&szOrderId={$params['szOrderId']}&szPhoneNum={$params['szPhoneNum']}&nMoney={$params['nMoney']}&nSortType={$params['nSortType']}";
+        $content .= "&nProductClass={$params['nProductClass']}&nProductType={$params['nProductType']}&szTimeStamp={$params['szTimeStamp']}&szKey={$key}";
+        return md5($content);
+    }
+}

+ 39 - 0
helper/refill/api/yl/cuanqi_sec/config.php

@@ -0,0 +1,39 @@
+<?php
+
+
+namespace refill\cuanqi_sec;
+
+use mtopcard;
+class config
+{
+    const ORDER_URL = 'http://8.130.117.16:16188/plat/api/hf/submitorder';
+    const QUERY_URL= 'http://8.130.117.16:16188/plat/api/queryorder';
+    const BALANCE_URL = 'http://8.130.117.16:16188/plat/api/querybalance';
+
+    const USER_ID= '100009';
+    const KEY = 'bfde8e81f37042d1b2817a7b1f48855d';
+    const NOTIFY_URL = BASE_SITE_URL . "/mobile/callback/refill_cuanqi_sec.php";
+
+    const operator = [
+        mtopcard\ChinaMobileCard  => 1,
+        mtopcard\ChinaUnicomCard  => 2,
+        mtopcard\ChinaTelecomCard => 3
+    ];
+    const ExtHeaders = ['Content-Type:application/x-www-form-urlencoded;charset=utf-8'];
+
+    const ERR_NOS = [
+        1000,1001,1003,1004,2001,2002,2003,2020,2021,1006,2030,3003
+    ];
+
+    const Product = [
+        mtopcard\ChinaMobileCard => [
+            50 => 1000050,
+            100 => 1000100,
+            200 => 1000200,
+        ],
+        mtopcard\ChinaUnicomCard => [
+        ],
+        mtopcard\ChinaTelecomCard => [
+        ],
+    ];
+}

+ 18 - 10
helper/refill/api/yl/guochuang/config.php

@@ -67,22 +67,22 @@ class config
         "4-10-6" => 9.67, "4-20-6" => 19.34, "4-30-6" => 29.01, "4-50-6" => 48.35, "4-100-6" => 96.7, "4-200-6" => 193.4, "4-300-6" => 290.1, "4-500-6" => 483.5,//辽宁 6
         "4-10-9" => 9.94, "4-20-9" => 19.88, "4-30-9" => 29.82, "4-50-9" => 49.7, "4-100-9" => 99.4,//上海 9
         "4-10-8" => 9.98, "4-20-8" => 19.96, "4-30-8" => 29.94, "4-50-8" => 49.9, "4-100-8" => 99.8, "4-200-8" => 199.6, "4-300-8" => 299.4, "4-500-8" => 499,//黑龙江 8
-        "4-10-29" => 10.01, "4-20-29" => 20.02, "4-30-29" => 30.03, "4-50-29" => 50.05, "4-100-29" => 99.6, "4-200-29" => 199.2, "4-300-29" => 298.8, "4-500-29" => 498,//青海 29
+        "4-5-29" => 5.775, "4-10-29" => 10.01, "4-20-29" => 20.02, "4-30-29" => 30.03, "4-50-29" => 50.05, "4-100-29" => 99.6, "4-200-29" => 199.2, "4-300-29" => 298.8, "4-500-29" => 498,//青海 29
         "4-10-28" => 10.45, "4-20-28" => 20.74, "4-30-28" => 31.11, "4-50-28" => 50.65, "4-100-28" => 99.85, "4-200-28" => 199.7, "4-300-28" => 299.55, "4-500-28" => 499.25,//甘肃 28
         "4-10-13" => 9.965, "4-20-13" => 19.93, "4-30-13" => 29.895, "4-50-13" => 49.825, "4-100-13" => 99.65, "4-200-13" => 199.3, "4-300-13" => 298.95, "4-500-13" => 498.25,//福建 13
-        "4-10-5" => 10.035, "4-20-5" => 20.07, "4-30-5" => 30.09, "4-50-5" => 50.15, "4-100-5" => 100.3, "4-200-5" => 200.4, "4-300-5" => 300.6, "4-500-5" => 501,//内蒙古 5
+        "4-10-5" => 10.26, "4-20-5" => 20.52, "4-30-5" => 30.78, "4-50-5" => 50.8, "4-100-5" => 100.3, "4-200-5" => 200.4, "4-300-5" => 300.6, "4-500-5" => 501,//内蒙古 5
         "4-30-18" => 29.835, "4-50-18" => 49.725, "4-100-18" => 99.45, "4-200-18" => 198.3,//湖南 18
-        "4-10-19" => 10.1, "4-20-19" => 20.2, "4-30-19" => 30.03, "4-50-19" => 50.475, "4-100-19" => 100.95, "4-200-19" => 201.9, "4-300-19" => 302.85, "4-500-19" => 504.75,//广东 19
+        "4-10-19" => 10.37, "4-20-19" => 20.74, "4-30-19" => 30.96, "4-50-19" => 50.475, "4-100-19" => 100.95, "4-200-19" => 201.9, "4-300-19" => 302.85, "4-500-19" => 504.75,//广东 19
         "4-10-7" => 9.93, "4-20-7" => 19.86, "4-30-7" => 29.52, "4-50-7" => 49.2, "4-100-7" => 98.4, "4-200-7" => 196.8, "4-300-7" => 295.2, "4-500-7" => 492,//吉林 7
-        "4-10-1" => 10.31, "4-20-1" => 20.32, "4-30-1" => 30.33, "4-50-1" => 50.35, "4-100-1" => 100.4, "4-200-1" => 200.3, "4-300-1" => 300.45, "4-500-1" => 500.75,//北京 1
+        "4-10-1" => 10.31, "4-20-1" => 20.32, "4-30-1" => 30.33, "4-50-1" => 50.6, "4-100-1" => 100.4, "4-200-1" => 200.3, "4-300-1" => 300.45, "4-500-1" => 500.75,//北京 1
         "4-10-22" => 10.015, "4-20-22" => 20.03, "4-30-22" => 30.045, "4-50-22" => 50.075, "4-100-22" => 100.15, "4-200-22" => 200.3, "4-300-22" => 300.45, "4-500-22" => 500.75,//重庆 22
-        "4-1-15" => 1.04, "4-2-15" => 2.08, "4-3-15" => 3.12, "4-4-15" => 4.16, "4-5-15" => 5.2, "4-6-15" => 6.24, "4-7-15" => 7.28, "4-8-15" => 8.32, "4-9-15" => 9.36, "4-10-15" => 10.62, "4-20-15" => 20.64, "4-30-15" => 30.66, "4-50-15" => 50.7, "4-100-15" => 99.3, "4-200-15" => 198.6, "4-300-15" => 297.9,//山东 15
+        "4-1-15" => 1.04, "4-2-15" => 2.08, "4-3-15" => 3.12, "4-4-15" => 4.16, "4-5-15" => 5.61, "4-6-15" => 6.24, "4-7-15" => 7.28, "4-8-15" => 8.32, "4-9-15" => 9.36, "4-10-15" => 10.62, "4-20-15" => 20.64, "4-30-15" => 30.66, "4-50-15" => 50.7, "4-100-15" => 99.3, "4-200-15" => 198.6, "4-300-15" => 297.9,//山东 15
         "4-10-10" => 9.945, "4-20-10" => 19.89, "4-30-10" => 30.18, "4-50-10" => 50.4, "4-100-10" => 100.48, "4-200-10" => 200.56, "4-300-10" => 300.84, "4-500-10" => 501.4,//江苏 10
         "4-10-11" => 9.945, "4-20-11" => 19.89, "4-30-11" => 29.835, "4-50-11" => 49.725, "4-100-11" => 99.45, "4-200-11" => 198.9, "4-300-11" => 298.35, "4-500-11" => 497.25,//浙江 11
         "4-10-17" => 9.945, "4-20-17" => 19.89, "4-30-17" => 29.835, "4-50-17" => 49.725, "4-100-17" => 99.45, "4-200-17" => 198.9, "4-300-17" => 298.35, "4-500-17" => 497.25,//湖北 17
         "4-10-16" => 10.27, "4-20-16" => 20.54, "4-30-16" => 30.81, "4-50-16" => 50.175, "4-100-16" => 100.2, "4-200-16" => 200.4, "4-300-16" => 300.6, "4-500-16" => 501,//河南 16
         "4-10-4" => 10.23, "4-20-4" => 20.46, "4-30-4" => 30.105, "4-50-4" => 50.175, "4-100-4" => 100.35, "4-200-4" => 200.7, "4-300-4" => 301.05, "4-500-4" => 501.75,//山西 4
-        "4-10-24" => 10.12, "4-20-24" => 20.14, "4-30-24" => 30.165, "4-50-24" => 50.1, "4-100-24" => 100.2, "4-200-24" => 200.4, "4-300-24" => 300.6, "4-500-24" => 501,//贵州 24
+        "4-5-24" => 5.775, "4-10-24" => 10.045, "4-20-24" => 20.09, "4-30-24" => 29.91, "4-50-24" => 49.9, "4-100-24" => 99.8, "4-200-24" => 200.4, "4-300-24" => 300.6, "4-500-24" => 501,//贵州 24
         "4-10-30" => 10.12, "4-20-30" => 20.24, "4-30-30" => 30.129, "4-50-30" => 50.15, "4-100-30" => 100.2, "4-200-30" => 200.4, "4-300-30" => 300.3, "4-500-30" => 500.5,//宁夏 30
         "4-10-25" => 10.14, "4-20-25" => 20.2, "4-30-25" => 30.18, "4-50-25" => 50.1, "4-100-25" => 100.2, "4-200-25" => 200.4, "4-300-25" => 300.6, "4-500-25" => 501,//云南 25
         "4-10-27" => 10.22, "4-20-27" => 20.44, "4-30-27" => 30.66, "4-50-27" => 50.1, "4-100-27" => 100.1, "4-200-27" => 200.2, "4-300-27" => 300.3, "4-500-27" => 500.5,//陕西 27
@@ -100,17 +100,25 @@ class config
         //电信
         "6-10-27" => 10.12, "6-20-27" => 20.24, "6-30-27" => 30.36, "6-50-27" => 50.1, "6-100-27" => 100.2, "6-200-27" => 199.94, "6-300-27" => 299.91, "6-500-27" => 501,//陕西 27
         "6-10-4" => 10.37, "6-20-4" => 20.39, "6-30-4" => 30.42, "6-50-4" => 50.45, "6-100-4" => 100.6, "6-200-4" => 201.2, "6-300-4" => 301.8, "6-500-4" => 503,//山西 4
-        "6-10-18" => 10.04, "6-20-18" => 20.08, "6-30-18" => 30.12, "6-50-18" => 50.15, "6-100-18" => 100.3, "6-200-18" => 200.6, "6-300-18" => 300.9, "6-500-18" => 501.5,//湖南 18
+        "6-10-18" => 10.09, "6-20-18" => 20.1, "6-30-18" => 30.12, "6-50-18" => 50.1, "6-100-18" => 100.2, "6-200-18" => 200.3, "6-300-18" => 300.45, "6-500-18" => 500.75,//湖南 18
         "6-10-15" => 10.37, "6-20-15" => 20.38, "6-30-15" => 30.42, "6-50-15" => 50.8, "6-100-15" => 101, "6-200-15" => 200.4, "6-300-15" => 300.6, "6-500-15" => 501,//山东 15
-        "6-10-12" => 10.2, "6-20-12" => 20.24, "6-30-12" => 30.21, "6-50-12" => 50.275, "6-100-12" => 100.35, "6-200-12" => 200.4, "6-300-12" => 300.9, "6-500-12" => 501.5,//安徽 12
+        "6-10-12" => 10.2, "6-20-12" => 20.24, "6-30-12" => 30.21, "6-50-12" => 50.4, "6-100-12" => 100.7, "6-200-12" => 200.6, "6-300-12" => 300.9, "6-500-12" => 501.5,//安徽 12
         "6-10-2" => 10.12, "6-20-2" => 20.16, "6-30-2" => 30.21, "6-50-2" => 50.175, "6-100-2" => 100.35, "6-200-2" => 200.7, "6-300-2" => 301.05, "6-500-2" => 501.75,//天津 2
         "6-10-20" => 10.15, "6-20-20" => 20.18, "6-30-20" => 30.21, "6-50-20" => 50.3, "6-100-20" => 100.45, "6-200-20" => 200.6, "6-300-20" => 300.9, "6-500-20" => 501.5,//广西 20
         "6-10-29" => 10.13, "6-20-29" => 20.14, "6-30-29" => 30.18, "6-50-29" => 50.25, "6-100-29" => 100.35, "6-200-29" => 200.6, "6-300-29" => 300.9, "6-500-29" => 501.5,//青海 29
         "6-100-1" => 100.2, "6-200-1" => 200.2, "6-300-1" => 300.3, "6-500-1" => 500.5,//北京 1
-        "6-10-16" => 10.13, "6-20-16" => 20.24, "6-30-16" => 30.36, "6-50-16" => 50.3, "6-100-16" => 100.5, "6-200-16" => 200.8, "6-300-16" => 301.2, "6-500-16" => 502,//河南 16
-        "6-10-13" => 10.07, "6-20-13" => 20.14, "6-30-13" => 30.21, "6-50-13" => 50.5, "6-100-13" => 100.9, "6-200-13" => 200.8, "6-300-13" => 300.9, "6-500-13" => 501.5,//福建 13
+        "6-10-16" => 10.13, "6-20-16" => 20.24, "6-30-16" => 30.36, "6-50-16" => 50.3, "6-100-16" => 100.4, "6-200-16" => 200.8, "6-300-16" => 301.2, "6-500-16" => 502,//河南 16
+        "6-10-13" => 10.17, "6-20-13" => 20.16, "6-30-13" => 30.18, "6-50-13" => 50.3, "6-100-13" => 100.55, "6-200-13" => 200.8, "6-300-13" => 301.2, "6-500-13" => 502,//福建 13
         "6-10-6" => 10.21, "6-20-6" => 20.24, "6-30-6" => 30.27, "6-50-6" => 50.175, "6-100-6" => 100.35, "6-200-6" => 200.7, "6-300-6" => 301.05, "6-500-6" => 501.75,//辽宁 6
         "6-10-17" => 10.23, "6-20-17" => 20.46, "6-30-17" => 30.69, "6-50-17" => 51.1,//湖北 17
         "6-10-3" => 10.15, "6-20-3" => 20.3, "6-30-3" => 30.45, "6-50-3" => 50.45, "6-100-3" => 100.9, "6-200-3" => 201.6, "6-300-3" => 302.4, "6-500-3" => 504,//河北 3
+        "6-10-14" => 10.15, "6-20-14" => 20.1, "6-30-14" => 30.15, "6-50-14" => 50.3, "6-100-14" => 100.6, "6-200-14" => 200.7, "6-300-14" => 301.05, "6-500-14" => 501.75,//江西 14
+        "6-10-31" => 10.1, "6-20-31" => 20.12, "6-30-31" => 30.15, "6-50-31" => 50.2, "6-100-31" => 100.3, "6-200-31" => 200.6, "6-300-31" => 300.75, "6-500-31" => 501.25,//新疆 31
+        "6-10-10" => 10.15, "6-20-10" => 20.16, "6-30-10" => 30.225,//江苏 10
+        "6-10-24" => 10.14, "6-20-24" => 20.16, "6-30-24" => 30.18, "6-50-24" => 50.3, "6-100-24" => 100.45, "6-200-24" => 200.6, "6-300-24" => 300.9, "6-500-24" => 501.5,//贵州 24
+        "6-10-22" => 10.16, "6-20-22" => 20.18, "6-30-22" => 30.24, "6-50-22" => 50.4, "6-100-22" => 100.45, "6-200-22" => 200.6, "6-300-22" => 300.9, "6-500-22" => 501.5,//重庆 22
+        "6-10-28" => 10.12, "6-20-28" => 20.24, "6-30-28" => 30.36, "6-50-28" => 50.45, "6-100-28" => 100.9, "6-200-28" => 201.6, "6-300-28" => 302.4, "6-500-28" => 504,//甘肃 28
+        "6-10-23" => 10.15, "6-20-23" => 20.3, "6-30-23" => 30.45, "6-50-23" => 50.45, "6-100-23" => 100.9, "6-200-23" => 201.6, "6-300-23" => 302.4, "6-500-23" => 504,//四川 23
+        "6-10-9" => 10.15, "6-20-9" => 20.18, "6-30-9" => 30.21, "6-50-9" => 50.25, "6-100-9" => 100.4, "6-200-9" => 200.5, "6-300-9" => 300.75, "6-500-9" => 501.25,//上海 9
     ];
 }

+ 42 - 0
helper/refill/api/yl/lihui_fs/API.MD

@@ -0,0 +1,42 @@
+## 栎辉分省
+
+### 正式环境:
+- 话费下单地址:http://121.199.22.114:16188/plat/api/hf/submitorder
+- 查询地址:http://121.199.22.114:16188/plat/api/queryorder
+- 查询余额地址:http://121.199.22.114:16188/plat/api/querybalance
+
+- 客户端地址: http://121.199.22.114:16188/plat/login
+- 账号:炫捷-FS
+- 密码:xj123456
+- ID   :   100014
+- 秘钥:02dbb578cbbf4e969b66599148106cd2
+
+### 对接文档地址
+> https://docs.qq.com/doc/DWkV1VkxQVk13eEtQ
+
+### 店铺账号
+- lihui_fs
+- lihui_fs67890
+
+### 编码&折扣
+```angular2html
+陕西移动
+编码:1610050 面值50 折扣95
+编码:1610100 面值100 折扣95
+编码:1610200 面值200 折扣95
+
+广东电信
+编码:3440050 面值50 折扣95
+编码:3440100 面值100 折扣95
+编码:3440200 面值200 折扣95
+
+湖南电信
+编码:3430050 面值50 折扣95
+编码:3430100 面值100 折扣95
+编码:3430200 面值200 折扣95
+
+天津电信
+编码:3120050 面值50 折扣95
+编码:3120100 面值100 折扣95
+编码:3120200 面值200 折扣95
+```

+ 52 - 0
helper/refill/api/yl/lihui_fs/RefillCallBack.php

@@ -0,0 +1,52 @@
+<?php
+namespace refill\lihui_fs;
+
+require_once(BASE_HELPER_RAPI_PATH . '/lihui_fs/config.php');
+
+use refill;
+class RefillCallBack implements refill\IRefillCallBack
+{
+    public function verify($params): bool
+    {
+        $sign = $this->sign($params);
+        if ($params['szVerifyString'] == $sign) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    private function sign($params)
+    {
+        $userid = config::USER_ID;
+        $key = config::KEY;
+        $content = "szAgentId={$userid}&szOrderId={$params['szOrderId']}&szPhoneNum={$params['szPhoneNum']}&nDemo={$params['nDemo']}&fSalePrice={$params['fSalePrice']}";
+        $content .= "&nFlag={$params['nFlag']}&szKey={$key}";
+        return md5($content);
+    }
+
+    public function notify($params)
+    {
+        $status = intval($params['nFlag']);
+        $order_sn = $params['szOrderId'];
+        $order_info = Model('vr_order')->getOrderInfoForNotify(['order_sn' => $order_sn]);
+        if (empty($order_info)) {
+            return [false, false, false, false, ''];
+        }
+        $order_id = $order_info['order_id'];
+
+        if ($status === 2) {
+            $official_sn = strtolower($params['szRtnMsg']) == 'null' ? '' : $params['szRtnMsg'];
+
+            $data['official_sn'] = $official_sn;
+            Model('refill_order')->edit($order_id, $data);
+            return [$order_id, true, false, true, $official_sn];
+        }
+        elseif ($status === 3) {
+            return [$order_id, false, true, true, ''];
+        }
+        else {
+            return [$order_id, false, false, false, ''];
+        }
+    }
+}

+ 165 - 0
helper/refill/api/yl/lihui_fs/RefillPhone.php

@@ -0,0 +1,165 @@
+<?php
+
+namespace refill\lihui_fs;
+
+require_once(BASE_HELPER_RAPI_PATH . '/lihui_fs/config.php');
+
+use refill;
+use Log;
+
+class RefillPhone extends refill\IRefillPhone
+{
+    public function __construct($cfgs)
+    {
+        parent::__construct($cfgs);
+    }
+
+    public function goods($quality,int $amount,int $card_type,$regin_no,$other)
+    {
+        [$goods_id, $price] = parent::goods($quality,$amount,$card_type,$regin_no,$other);
+        if($goods_id <= 0) return [0,0];
+        $key = "{$card_type}-{$amount}-{$regin_no}";
+        $price = config::Price[$key];
+        if(empty($price)) {
+            Log::record("channel cannot find price where name={$this->mName}, goods_id = {$goods_id} card_type={$card_type} amount={$amount} regin_no={$regin_no}",Log::ERR);
+            return [0,0];
+        } else {
+            return [$goods_id,ncPriceFormat($price)];
+        }
+    }
+
+    private function req_params(int $phone, int $amount, int $card_type, string $order_sn, $regin_no)
+    {
+        $params['szAgentId'] = config::USER_ID;
+        $params['szOrderId'] = $order_sn;
+        $params['szPhoneNum'] = $phone;
+        $params['nMoney'] = $amount;
+        $params['nSortType'] = config::operator[$card_type];
+        $params['szProductId'] = config::Product[$card_type][$regin_no][$amount];
+        $params['nProductClass'] = 1;
+        $params['nProductType'] = 1;
+        $params['szTimeStamp'] = date("Y-m-d H:i:s");
+        $params['szNotifyUrl'] = config::NOTIFY_URL;
+        return $params;
+    }
+
+    public function add($card_no, $card_type, $amount, $params,&$net_errno = 0)
+    {
+        $order_sn = $params['order_sn'];
+        $regin_no = $params['regin_no'] ?? -1;
+
+        if($regin_no <= 0) {
+            return [false, '省份获取错误', false];
+        }
+        $params = $this->req_params($card_no, $amount, $card_type, $order_sn, $regin_no);
+
+        $sign = $this->sign($params);
+        $params['szVerifyString'] = $sign;
+
+        $resp = http_request(config::ORDER_URL, $params, 'POST', false, config::ExtHeaders, $net_errno);
+
+        if (empty($resp)) {
+            return [false, '网络错误', true];
+        }
+        else
+        {
+            Log::record($resp, Log::DEBUG);
+            $resp = json_decode($resp, true);
+
+            $nRtn = $resp['nRtn'];
+            if (empty($resp)) {
+                return [false, '网络错误', true];
+            } elseif ($nRtn === 0) {
+                return [true, '', false];
+            } elseif (in_array($nRtn, config::ERR_NOS, true)) {
+                return [false, $resp['szRtnCode'], false];
+            } elseif (in_array($nRtn, [2050, 999], true)) {
+                $net_errno = "HTTP-{$nRtn}";
+                return [false, $resp['szRtnCode'], true];
+            } else {
+                $err = 998;
+                $net_errno = "HTTP-{$err}";
+                return [false, $resp['szRtnCode'], true];
+            }
+        }
+    }
+
+    public function query($refill_info)
+    {
+        $params['szAgentId'] = config::USER_ID;
+        $params['szOrderId'] = $refill_info['order_sn'];
+        $key = config::KEY;
+        $content = "szAgentId={$params['szAgentId']}&szOrderId={$params['szOrderId']}&szKey={$key}";
+        $params['szVerifyString'] = md5($content);
+
+        $resp = http_request(config::QUERY_URL, $params, 'POST', false, config::ExtHeaders);
+
+        if (empty($resp)) {
+            return [false, '网络错误', ''];
+        }
+        else
+        {
+            Log::record($resp, Log::DEBUG);
+            $resp = json_decode($resp, true);
+            if (empty($resp)) {
+                return [false, '网络错误', ''];
+            }
+
+            $official_sn = '';
+
+            $status = $resp['nRtn'];
+            if ($status === 5012) {
+                $official_sn = $resp['szRtnMsg'];
+
+                $updata['official_sn'] = $official_sn;
+                Model('refill_order')->edit($refill_info['order_id'], $updata);
+                $order_state = ORDER_STATE_SUCCESS;
+            } elseif ($status === 5013) {
+                $order_state = ORDER_STATE_CANCEL;
+            } elseif (in_array($status, [5011,5019],true)) {
+                $order_state = ORDER_STATE_SEND;
+            } elseif ($status === 5005 && (time() - $refill_info['commit_time'] >= 300)) {
+                $order_state = ORDER_STATE_NOEXIST;
+            } else {
+                return [false, $resp['szRtnMsg'], ''];
+            }
+
+            return [true, $order_state, $official_sn];
+        }
+    }
+
+    public function balance()
+    {
+        $params['szAgentId'] = config::USER_ID;
+        $key = config::KEY;
+        $content = "szAgentId={$params['szAgentId']}&szKey={$key}";
+        $params['szVerifyString'] = md5($content);
+
+        $resp = http_request(config::BALANCE_URL, $params, 'POST', false, config::ExtHeaders);
+
+        if (empty($resp)) {
+            return [false, '网络错误'];
+        }
+        else
+        {
+            Log::record($resp, Log::DEBUG);
+            $resp = json_decode($resp, true);
+            if (empty($resp)) {
+                return [false, '网络错误'];
+            } elseif ($resp['nRtn'] === 0) {
+                return [true, $resp['fBalance']];
+            } else {
+                return [false, $resp['szRtnCode']];
+            }
+        }
+    }
+
+    private function sign($params)
+    {
+        $userid = config::USER_ID;
+        $key = config::KEY;
+        $content = "szAgentId={$userid}&szOrderId={$params['szOrderId']}&szPhoneNum={$params['szPhoneNum']}&nMoney={$params['nMoney']}&nSortType={$params['nSortType']}";
+        $content .= "&nProductClass={$params['nProductClass']}&nProductType={$params['nProductType']}&szTimeStamp={$params['szTimeStamp']}&szKey={$key}";
+        return md5($content);
+    }
+}

+ 70 - 0
helper/refill/api/yl/lihui_fs/config.php

@@ -0,0 +1,70 @@
+<?php
+
+
+namespace refill\lihui_fs;
+
+use mtopcard;
+class config
+{
+    const ORDER_URL = 'http://121.199.22.114:16188/plat/api/hf/submitorder';
+    const QUERY_URL= 'http://121.199.22.114:16188/plat/api/queryorder';
+    const BALANCE_URL = 'http://121.199.22.114:16188/plat/api/querybalance';
+
+    const USER_ID= '100014';
+    const KEY = '02dbb578cbbf4e969b66599148106cd2';
+    const NOTIFY_URL = BASE_SITE_URL . "/mobile/callback/refill_lihui_fs.php";
+
+    const operator = [
+        mtopcard\ChinaMobileCard  => 1,
+        mtopcard\ChinaUnicomCard  => 2,
+        mtopcard\ChinaTelecomCard => 3
+    ];
+    const ExtHeaders = ['Content-Type:application/x-www-form-urlencoded;charset=utf-8'];
+
+    const ERR_NOS = [
+        1000,1001,1003,1004,2001,2002,2003,2020,2021,1006,2030,3003
+    ];
+
+    const Product = [
+        mtopcard\ChinaMobileCard => [
+            //陕西
+            27 => [
+                50  => 1610050,
+                100 => 1610100,
+                200 => 1610200,
+            ],
+        ],
+        mtopcard\ChinaTelecomCard => [
+            //广东
+            19 => [
+                50  => 3440050,
+                100 => 3440100,
+                200 => 3440200,
+            ],
+            //湖南
+            18 => [
+                50  => 3430050,
+                100 => 3430100,
+                200 => 3430200,
+            ],
+            //天津
+            2 => [
+                50  => 3120050,
+                100 => 3120100,
+                200 => 3120200,
+            ],
+        ],
+    ];
+
+    //key格式 卡类型-面值-regin_no
+    const Price = [
+        //移动
+        "4-50-27" => 47.5, "4-100-27" => 95, "4-200-27" => 190, //陕西
+
+        //电信
+        "6-50-19" => 47.5, "6-100-19" => 95, "6-200-19" => 190, //广东
+        "6-50-18" => 47.5, "6-100-18" => 95, "6-200-18" => 190, //湖南
+        "6-50-2" => 47.5, "6-100-2" => 95, "6-200-2" => 190, //天津
+    ];
+
+}

+ 34 - 0
helper/refill/api/yl/xinguande/API.MD

@@ -0,0 +1,34 @@
+## 新冠德全国1号
+
+### 正式环境:
+- 话费下单地址:http://121.43.129.225:16188/plat/api/hf/submitorder
+- 查询地址:http://121.43.129.225:16188/plat/api/queryorder
+- 查询余额地址:http://121.43.129.225:16188/plat/api/querybalance
+
+- 客户端地址:http://121.43.129.225:16188/plat/login
+- 账号:xjqgsw
+- 密码:123456
+- 客户ID:100080
+- 密钥:bb99a12a11244924adeac12b74ca7899
+
+### 对接文档地址:
+> https://docs.qq.com/doc/DWEhQWEhDVEJIdUVC
+
+### 店铺账号
+- xinguande
+- xinguande67890
+
+### 产品编码
+客户 名称 编码 产品类型 凭证 原价  
+炫捷全国三网 全国联通200元 2000200 话费 普通 200  
+炫捷全国三网 全国联通100元 2000100 话费 普通 100  
+炫捷全国三网 全国联通50元 2000050 话费 普通 50  
+炫捷全国三网 全国联通30元 2000030 话费 普通 30  
+
+炫捷全国三网 全国移动200元 1000200 话费 普通 200  
+炫捷全国三网 全国移动100元 1000100 话费 普通 100  
+炫捷全国三网 全国移动50元 1000050 话费 普通 50  
+
+炫捷全国三网 全国电信200元 3000200 话费 普通 200  
+炫捷全国三网 全国电信100元 3000100 话费 普通 100  
+炫捷全国三网 全国电信50元 3000050 话费 普通 50  

+ 52 - 0
helper/refill/api/yl/xinguande/RefillCallBack.php

@@ -0,0 +1,52 @@
+<?php
+namespace refill\xinguande;
+
+require_once(BASE_HELPER_RAPI_PATH . '/xinguande/config.php');
+
+use refill;
+class RefillCallBack implements refill\IRefillCallBack
+{
+    public function verify($params): bool
+    {
+        $sign = $this->sign($params);
+        if ($params['szVerifyString'] == $sign) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    private function sign($params)
+    {
+        $userid = config::USER_ID;
+        $key = config::KEY;
+        $content = "szAgentId={$userid}&szOrderId={$params['szOrderId']}&szPhoneNum={$params['szPhoneNum']}&nDemo={$params['nDemo']}&fSalePrice={$params['fSalePrice']}";
+        $content .= "&nFlag={$params['nFlag']}&szKey={$key}";
+        return md5($content);
+    }
+
+    public function notify($params)
+    {
+        $status = intval($params['nFlag']);
+        $order_sn = $params['szOrderId'];
+        $order_info = Model('vr_order')->getOrderInfoForNotify(['order_sn' => $order_sn]);
+        if (empty($order_info)) {
+            return [false, false, false, false, ''];
+        }
+        $order_id = $order_info['order_id'];
+
+        if ($status === 2) {
+            $official_sn = strtolower($params['szRtnMsg']) == 'null' ? '' : $params['szRtnMsg'];
+
+            $data['official_sn'] = $official_sn;
+            Model('refill_order')->edit($order_id, $data);
+            return [$order_id, true, false, true, $official_sn];
+        }
+        elseif ($status === 3) {
+            return [$order_id, false, true, true, ''];
+        }
+        else {
+            return [$order_id, false, false, false, ''];
+        }
+    }
+}

+ 146 - 0
helper/refill/api/yl/xinguande/RefillPhone.php

@@ -0,0 +1,146 @@
+<?php
+
+namespace refill\xinguande;
+
+require_once(BASE_HELPER_RAPI_PATH . '/xinguande/config.php');
+
+use refill;
+use Log;
+
+class RefillPhone extends refill\IRefillPhone
+{
+    public function __construct($cfgs)
+    {
+        parent::__construct($cfgs);
+    }
+
+    private function req_params(int $phone, int $amount, int $card_type, string $order_sn)
+    {
+        $params['szAgentId'] = config::USER_ID;
+        $params['szOrderId'] = $order_sn;
+        $params['szPhoneNum'] = $phone;
+        $params['nMoney'] = $amount;
+        $params['nSortType'] = config::operator[$card_type];
+        $params['szProductId'] = config::Product[$card_type][$amount];
+        $params['nProductClass'] = 1;
+        $params['nProductType'] = 1;
+        $params['szTimeStamp'] = date("Y-m-d H:i:s");
+        $params['szNotifyUrl'] = config::NOTIFY_URL;
+        return $params;
+    }
+
+    public function add($card_no, $card_type, $amount, $params,&$net_errno = 0)
+    {
+        $order_sn = $params['order_sn'];
+        $params = $this->req_params($card_no, $amount, $card_type, $order_sn);
+
+        $sign = $this->sign($params);
+        $params['szVerifyString'] = $sign;
+
+        $resp = http_request(config::ORDER_URL, $params, 'POST', false, config::ExtHeaders, $net_errno);
+
+        if (empty($resp)) {
+            return [false, '网络错误', true];
+        }
+        else
+        {
+            Log::record($resp, Log::DEBUG);
+            $resp = json_decode($resp, true);
+
+            $nRtn = $resp['nRtn'];
+            if (empty($resp)) {
+                return [false, '网络错误', true];
+            } elseif ($nRtn === 0) {
+                return [true, '', false];
+            } elseif (in_array($nRtn, config::ERR_NOS, true)) {
+                return [false, $resp['szRtnCode'], false];
+            } elseif (in_array($nRtn, [2050, 999], true)) {
+                $net_errno = "HTTP-{$nRtn}";
+                return [false, $resp['szRtnCode'], true];
+            } else {
+                $err = 998;
+                $net_errno = "HTTP-{$err}";
+                return [false, $resp['szRtnCode'], true];
+            }
+        }
+    }
+
+    public function query($refill_info)
+    {
+        $params['szAgentId'] = config::USER_ID;
+        $params['szOrderId'] = $refill_info['order_sn'];
+        $key = config::KEY;
+        $content = "szAgentId={$params['szAgentId']}&szOrderId={$params['szOrderId']}&szKey={$key}";
+        $params['szVerifyString'] = md5($content);
+
+        $resp = http_request(config::QUERY_URL, $params, 'POST', false, config::ExtHeaders);
+
+        if (empty($resp)) {
+            return [false, '网络错误', ''];
+        }
+        else
+        {
+            Log::record($resp, Log::DEBUG);
+            $resp = json_decode($resp, true);
+            if (empty($resp)) {
+                return [false, '网络错误', ''];
+            }
+
+            $official_sn = '';
+
+            $status = $resp['nRtn'];
+            if ($status === 5012) {
+                $official_sn = $resp['szRtnMsg'];
+
+                $updata['official_sn'] = $official_sn;
+                Model('refill_order')->edit($refill_info['order_id'], $updata);
+                $order_state = ORDER_STATE_SUCCESS;
+            } elseif ($status === 5013) {
+                $order_state = ORDER_STATE_CANCEL;
+            } elseif (in_array($status, [5011,5019],true)) {
+                $order_state = ORDER_STATE_SEND;
+            } elseif ($status === 5005 && (time() - $refill_info['commit_time'] > 300)) {
+                $order_state = ORDER_STATE_NOEXIST;
+            } else {
+                return [false, $resp['szRtnMsg'], ''];
+            }
+
+            return [true, $order_state, $official_sn];
+        }
+    }
+
+    public function balance()
+    {
+        $params['szAgentId'] = config::USER_ID;
+        $key = config::KEY;
+        $content = "szAgentId={$params['szAgentId']}&szKey={$key}";
+        $params['szVerifyString'] = md5($content);
+
+        $resp = http_request(config::BALANCE_URL, $params, 'POST', false, config::ExtHeaders);
+
+        if (empty($resp)) {
+            return [false, '网络错误'];
+        }
+        else
+        {
+            Log::record($resp, Log::DEBUG);
+            $resp = json_decode($resp, true);
+            if (empty($resp)) {
+                return [false, '网络错误'];
+            } elseif ($resp['nRtn'] === 0) {
+                return [true, $resp['fBalance']];
+            } else {
+                return [false, $resp['szRtnCode']];
+            }
+        }
+    }
+
+    private function sign($params)
+    {
+        $userid = config::USER_ID;
+        $key = config::KEY;
+        $content = "szAgentId={$userid}&szOrderId={$params['szOrderId']}&szPhoneNum={$params['szPhoneNum']}&nMoney={$params['nMoney']}&nSortType={$params['nSortType']}";
+        $content .= "&nProductClass={$params['nProductClass']}&nProductType={$params['nProductType']}&szTimeStamp={$params['szTimeStamp']}&szKey={$key}";
+        return md5($content);
+    }
+}

+ 46 - 0
helper/refill/api/yl/xinguande/config.php

@@ -0,0 +1,46 @@
+<?php
+
+
+namespace refill\xinguande;
+
+use mtopcard;
+class config
+{
+    const ORDER_URL = 'http://121.43.129.225:16188/plat/api/hf/submitorder';
+    const QUERY_URL= 'http://121.43.129.225:16188/plat/api/queryorder';
+    const BALANCE_URL = 'http://121.43.129.225:16188/plat/api/querybalance';
+
+    const USER_ID= '100080';
+    const KEY = 'bb99a12a11244924adeac12b74ca7899';
+    const NOTIFY_URL = BASE_SITE_URL . "/mobile/callback/refill_xinguande.php";
+
+    const operator = [
+        mtopcard\ChinaMobileCard  => 1,
+        mtopcard\ChinaUnicomCard  => 2,
+        mtopcard\ChinaTelecomCard => 3
+    ];
+    const ExtHeaders = ['Content-Type:application/x-www-form-urlencoded;charset=utf-8'];
+
+    const ERR_NOS = [
+        1000,1001,1003,1004,2001,2002,2003,2020,2021,1006,2030,3003
+    ];
+
+    const Product = [
+        mtopcard\ChinaMobileCard => [
+            50 => 1000050,
+            100 => 1000100,
+            200 => 1000200,
+        ],
+        mtopcard\ChinaUnicomCard => [
+            30  => 2000030,
+            50  => 2000050,
+            100 => 2000100,
+            200 => 2000200,
+        ],
+        mtopcard\ChinaTelecomCard => [
+            50  => 3000050,
+            100 => 3000100,
+            200 => 3000200,
+        ],
+    ];
+}

+ 4 - 0
mobile/callback/refill_cuanqi_sec.php

@@ -0,0 +1,4 @@
+<?php
+
+refill\util::push_notify('cuanqi_sec',$_POST);
+echo ('ok');

+ 4 - 0
mobile/callback/refill_lihui_fs.php

@@ -0,0 +1,4 @@
+<?php
+
+refill\util::push_notify('lihui_fs',$_POST);
+echo ('ok');

+ 4 - 0
mobile/callback/refill_xinguande.php

@@ -0,0 +1,4 @@
+<?php
+
+refill\util::push_notify('xinguande',$_POST);
+echo ('ok');

+ 4 - 0
mobile/callback/refill_yeyekc18.php

@@ -0,0 +1,4 @@
+<?php
+
+refill\util::push_notify('yeyekc18',$_POST);
+echo ('SUCCESS');

+ 24 - 0
test/TestRefill.php

@@ -6479,6 +6479,30 @@ class TestRefill extends TestCase
         $provider = $this->getProvider('chanlian_sec');
         $resp = $provider->balance();
     }
+
+    public function testyeyekc18()
+    {
+        $provider = $this->getProvider('yeyekc18');
+        $resp = $provider->balance();
+    }
+
+    public function testxinguande()
+    {
+        $provider = $this->getProvider('xinguande');
+        $resp = $provider->balance();
+    }
+
+    public function testlihui_fs()
+    {
+        $provider = $this->getProvider('lihui_fs');
+        $resp = $provider->balance();
+    }
+
+    public function testcuanqi_sec()
+    {
+        $provider = $this->getProvider('cuanqi_sec');
+        $resp = $provider->balance();
+    }
 }