更新后端查询收银平台订单明细功能

This commit is contained in:
技术老胡 2024-12-06 17:20:28 +08:00
parent 37cfebd7eb
commit 40a287ad41
4 changed files with 194 additions and 6 deletions

View File

@ -159,6 +159,42 @@ class PayManageController extends BaseController
return json(backMsg(1, '上传失败')); return json(backMsg(1, '上传失败'));
} }
} }
// 获取账号交易流水
public function getAccountTrade()
{
$req_info = $this->request->get();
$req_pid = $req_info['pid'];
$req_aid = $req_info['aid'];
// 加载配置文件
$config = \think\facade\Config::load("payconfig/{$req_pid}_{$req_aid}", 'payconfig');
// 收款平台账号配置
$pay_config = isset($config['pay']) ? $config['pay'] : [];
// 配置检查
if ($pay_config) {
// 账号配置信息
$aid = $pay_config['aid'];
if ($req_aid != $aid) return '监听收款配置不一致';
} else {
return '监听收款配置文件名错误';
}
// 登陆账号
$config = ['username' => $pay_config['account'], 'password' => $pay_config['password']];
// 收款查询
$query = $pay_config['query'];
// 实例监听客户端
$payclient_name = $pay_config['payclass'];
$payclient_path = "\\payclient\\{$payclient_name}";
$Payclient = new $payclient_path($config);
// 获取支付明细
$records = $Payclient->getOrderInfo($query);
if ($records) {
// 收款流水
return json(backMsg(0, '查询成功', $records));
} else {
return json(backMsg(1, '查询空订单'));
}
}
// 生成账号配置 // 生成账号配置
private function createAccountConfig($acc) private function createAccountConfig($acc)
{ {

112
public/static/js/helper.js Normal file
View File

@ -0,0 +1,112 @@
// 插件配置
const plugins = [
{
name: '收钱吧',
host: 'web-platforms-msp.shouqianba.com',
method: 'POST',
orderQuery: '/api/transaction/findTransactions',
channelKey: 'terminal_device_fingerprint',
moneyKey: 'original_amount',
listPath: 'data.records'
}
];
// 登陆配置
const logins = [
{
name: '新商城',
host: 'localhost',
method: 'GET',
orderQuery: '/api/Order/getOrders',
accPath: 'order_id',
pswPath: 'money',
}
];
// 提取订单信息
function extractOrderInfo(response, plugins) {
plugins.forEach((plugin) => {
const urlObj = new URL(response.url);
if (plugin.host === urlObj.hostname
&& plugin.orderQuery === urlObj.pathname
&& plugin.method === response.method) {
const jsonDatas = JSON.parse(response.response);
const orderDatas = eval(`jsonDatas.${plugin.listPath}`);
let lists = [];
orderDatas.forEach((orderData) => {
const data = {
'终端编号': orderData[plugin.channelKey],
'订单金额': orderData[plugin.moneyKey]
};
lists.push(data);
})
console.log(plugin.name);
console.table(lists);
}
})
}
// 提取登陆信息
function extractLoginInfo(request, logins) {
logins.forEach((login) => {
const urlObj = new URL(request.url);
if (login.host === urlObj.hostname
&& login.orderQuery === urlObj.pathname
&& login.method === request.method) {
const jsonData = JSON.parse(request.request);
const acc = eval(`jsonData.${login.accPath}`);
const psw = eval(`jsonData.${login.pswPath}`);
const data = {
'账号': acc,
'密码': psw
};
console.log(login.name);
console.table(data);
}
})
}
// XHR 重写
var oldOpen = XMLHttpRequest.prototype.open;
var oldSend = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.open = function (method, url) {
this._url = url;
this._method = method;
const res = {
url: this.responseURL,
method: this._method,
response: this._body
}
extractLoginInfo(res, logins);
return oldOpen.apply(this, arguments);
};
XMLHttpRequest.prototype.send = function (body) {
this._body = body;
this.addEventListener('load', function () {
const res = {
url: this.responseURL,
method: this._method,
response: this.responseText
}
console.log(res);
extractOrderInfo(res, plugins);
});
return oldSend.apply(this, arguments);
};
// fetch 重写
window.au_fetch = window.fetch;
window.fetch = function (url, options) {
// console.log('Fetch URL:', url);
// console.log('Fetch Options:', options);
return window.au_fetch.apply(window, [url, options]).then((response) => {
const res = {
url: url,
method: options.method,
response: response.text()
}
extractOrderInfo(res, plugins);
return response;
});
};

View File

@ -40,6 +40,11 @@
</div> </div>
</div> </div>
</div> </div>
<div class="main-container">
<div class="layui-text">
<p>终端编号如何填写,<strong><a href="https://f0bmwzqjtq2.feishu.cn/docx/HBVrdrsACo36bzxUCSPcjOBNnyb?from=from_copylink" target="_blank"><strong>请查看文档</strong></a></p>
</div>
</div>
</div> </div>
<div class="bottom"> <div class="bottom">
<div class="button-container"> <div class="button-container">

View File

@ -5,6 +5,11 @@
<meta charset="utf-8"> <meta charset="utf-8">
<title>收款管理</title> <title>收款管理</title>
<link rel="stylesheet" href="/component/pear/css/pear.css" /> <link rel="stylesheet" href="/component/pear/css/pear.css" />
<style>
.account-trade {
padding: 15px;
}
</style>
</head> </head>
<body class="pear-container"> <body class="pear-container">
@ -119,6 +124,7 @@
{ title: '启用状态', field: 'state', align: 'center', templet: '#account-state' }, { title: '启用状态', field: 'state', align: 'center', templet: '#account-state' },
{ title: '监听模式', field: 'pattern', align: 'center' }, { title: '监听模式', field: 'pattern', align: 'center' },
{ title: '监听地址 / 自定义模版', field: 'checkUrl', align: 'center', minWidth: 300, event: 'copy', templet: '#account-checkUrl' }, { title: '监听地址 / 自定义模版', field: 'checkUrl', align: 'center', minWidth: 300, event: 'copy', templet: '#account-checkUrl' },
{ title: '收款平台流水', field: 'trade', align: 'center', templet: '<div><a href="javascript:;" lay-event="queryTrade" data-url="/api/PayManage/getAccountTrade?pid={{= d.pid }}&aid={{= d.id }}"><span class="layui-badge layui-bg-green">查询</span></a></div>' },
{ title: '收款码数量', field: 'channel', align: 'center', templet: '<div><a href="javascript:;" lay-event="channelList"><span class="layui-badge layui-bg-green">{{= d.channel }}</span></a></div>' }, { title: '收款码数量', field: 'channel', align: 'center', templet: '<div><a href="javascript:;" lay-event="channelList"><span class="layui-badge layui-bg-green">{{= d.channel }}</span></a></div>' },
{ title: '操作', align: 'center', fixed: 'right', templet: '<div><a href="javascript:;" class="layui-font-green" lay-event="edit"><strong>编辑</strong></a></div>' } { title: '操作', align: 'center', fixed: 'right', templet: '<div><a href="javascript:;" class="layui-font-green" lay-event="edit"><strong>编辑</strong></a></div>' }
]] ]]
@ -147,18 +153,21 @@
account.editAccount(id); account.editAccount(id);
} else if (obj.event === 'channelList') { } else if (obj.event === 'channelList') {
account.channelList(id); account.channelList(id);
} else if (obj.event === 'queryTrade') {
const url = this.getAttribute('data-url');
account.getAccountTrade(url);
} }
}); });
table.on('toolDouble(account-table)', function (obj) { table.on('toolDouble(account-table)', function (obj) {
if (obj.event === 'copy') { if (obj.event === 'copy') {
const text = obj.tr[0].querySelector('td[data-field="checkUrl"]>div').innerText; const text = obj.tr[0].querySelector('td[data-field="checkUrl"]>div').innerText;
if (navigator.clipboard) { if (navigator.clipboard) {
navigator.clipboard.writeText(text).then(() => { navigator.clipboard.writeText(text).then(() => {
layer.msg('复制成功'); layer.msg('复制成功');
}); });
} else { } else {
layer.msg('复制失败,请手动复制'); layer.msg('复制失败,请手动复制');
} }
} }
}); });
// 表格头部按钮事件 // 表格头部按钮事件
@ -274,6 +283,32 @@
content: `/Order/testPay`, content: `/Order/testPay`,
}); });
} }
// 查询平台收银流水
account.getAccountTrade = async function (url) {
const res = await fetch(url);
if (res.status !== 200) {
layer.msg('请求失败,请重试!', { tips: 2, time: 1200 });
return false;
}
const rec_info = await res.json();
if (rec_info.code === 0) {
const data = rec_info.data;
let html = '';
data.forEach(order => {
html += `<tr><td>${order.order_no}</td><td>${order.channel}</td><td>${order.price}</td><td>${order.payway}</td></tr>`;
});
layer.open({
type: 1,
title: '收银流水(近3分钟)',
area: ['720px', '480px'],
content: `<div class="account-trade"><table class="layui-table"><thead><tr><th>订单流水</th><th>终端编号</th><th>收款金额</th><th>支付方式</th></tr></thead><tbody>${html}</tbody></table></div>`
});
} else {
layer.msg(rec_info.msg, { icon: 2, time: 1200 });
}
}
// 请求封装 // 请求封装
async function httpJSON(url, info) { async function httpJSON(url, info) {
const res = await fetch(url, { method: 'post', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(info) }); const res = await fetch(url, { method: 'post', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(info) });