feat: 完善协议管理、师傅资质认证、分账配置并完成测试环境全量部署与同步
这个提交包含在:
@@ -127,6 +127,8 @@ class Order extends Backend
|
||||
$params['discount_amount'],
|
||||
$params['total_amount'],
|
||||
$params['pay_amount'],
|
||||
$params['commission_rate'],
|
||||
$params['commission_snapshot'],
|
||||
$params['pay_status'],
|
||||
$params['pay_type'],
|
||||
$params['pay_time'],
|
||||
@@ -173,6 +175,23 @@ class Order extends Backend
|
||||
}
|
||||
}
|
||||
|
||||
// 后台取消工单前置防资损与原路退款(必须在开启数据库事务之前调用远程退款接口)
|
||||
if ($oldStatus !== 9 && $newStatus === 9) {
|
||||
if ((int)$row['settle_status'] === 1) {
|
||||
$this->error('该工单已完成向师傅结算分账,不允许直接取消退款');
|
||||
}
|
||||
if ((int)$row['pay_status'] === 1) {
|
||||
$cancelReasonPre = trim((string)($params['cancel_reason'] ?? $row['cancel_reason'] ?? '平台后台取消工单'));
|
||||
try {
|
||||
$refundedAmount = \app\common\library\PaymentService::refundOrder((int)$row['id'], $cancelReasonPre ?: '平台后台取消工单');
|
||||
} catch (\Throwable $re) {
|
||||
$this->error('微信原路退款失败:' . $re->getMessage());
|
||||
}
|
||||
$params['pay_status'] = 2;
|
||||
$params['refund_amount'] = $refundedAmount > 0 ? $refundedAmount : (float)$row['pay_amount'];
|
||||
}
|
||||
}
|
||||
|
||||
$result = false;
|
||||
Db::startTrans();
|
||||
try {
|
||||
@@ -523,8 +542,9 @@ class Order extends Backend
|
||||
$review['tags_arr'] = $tagsArr;
|
||||
}
|
||||
|
||||
// 6. 财务结算记录
|
||||
// 6. 财务结算记录与订单锁定快照预计结算核算
|
||||
$settle = Db::name('settle')->where('order_id', $row['id'])->find();
|
||||
$settlePreview = \app\common\library\CommissionService::calcByOrder($row->toArray());
|
||||
|
||||
// 7. 企业商家协同发包来源
|
||||
$merchantOrder = Db::name('merchant_order')
|
||||
@@ -552,6 +572,24 @@ class Order extends Backend
|
||||
->order('a.id desc')
|
||||
->select();
|
||||
|
||||
// 10. 微信支付与原路退款交易流水(含失败错误码及中文诊断原因)
|
||||
$sceneMap = [
|
||||
'order' => '主订单支付',
|
||||
'quote' => '选定师傅报价',
|
||||
'diff' => '增项补差价',
|
||||
'batch' => '批量下单',
|
||||
];
|
||||
$payOrders = Db::name('pay_order')
|
||||
->where('order_id', (int)$row['id'])
|
||||
->order('id desc')
|
||||
->select();
|
||||
foreach ($payOrders as &$poItem) {
|
||||
$poItem['scene_text'] = $sceneMap[$poItem['scene'] ?? ''] ?? ($poItem['scene'] ?? '-');
|
||||
$poItem['status_text'] = \app\common\library\PaymentService::payOrderStatusLabel($poItem['status'] ?? '');
|
||||
$poItem['refund_status_text'] = \app\common\library\PaymentService::refundStatusLabel($poItem['refund_status'] ?? 'none');
|
||||
}
|
||||
unset($poItem);
|
||||
|
||||
$this->view->assign([
|
||||
'row' => $row,
|
||||
'goodsList' => $goodsList,
|
||||
@@ -560,11 +598,126 @@ class Order extends Backend
|
||||
'quoteList' => $quoteList,
|
||||
'review' => $review,
|
||||
'settle' => $settle,
|
||||
'settlePreview' => $settlePreview,
|
||||
'merchantOrder' => $merchantOrder,
|
||||
'invoiceInfo' => $invoiceInfo,
|
||||
'appealList' => $appealList,
|
||||
'payOrders' => $payOrders,
|
||||
]);
|
||||
|
||||
return $this->view->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 后台主动同步单笔支付/退款流水在微信网关的真实状态
|
||||
*/
|
||||
public function syncpay($ids = null)
|
||||
{
|
||||
if (!$this->request->isPost()) {
|
||||
$this->error('非法请求方式');
|
||||
}
|
||||
$payOrderId = $this->request->post('pay_order_id/d', 0);
|
||||
if ($payOrderId <= 0) {
|
||||
$payOrderId = (int)$ids;
|
||||
}
|
||||
$po = Db::name('pay_order')->where('id', $payOrderId)->find();
|
||||
if (!$po) {
|
||||
$this->error('未找到指定的支付交易流水');
|
||||
}
|
||||
|
||||
$status = (string)($po['status'] ?? '');
|
||||
try {
|
||||
if (in_array($status, ['refunding', 'refund_failed'], true) || trim((string)($po['refund_no'] ?? '')) !== '') {
|
||||
$updated = \app\common\library\PaymentService::syncRefundPayOrder($payOrderId);
|
||||
$label = \app\common\library\PaymentService::refundStatusLabel($updated['refund_status'] ?? '');
|
||||
$this->success('退款状态已从微信同步:' . $label);
|
||||
}
|
||||
|
||||
if ($status === 'paid') {
|
||||
$this->success('该笔流水当前已完成微信入账,状态正常');
|
||||
}
|
||||
|
||||
$res = \app\common\library\PaymentService::confirmOrderPay((string)$po['out_trade_no']);
|
||||
if (!empty($res['paid'])) {
|
||||
$msg = '微信已确认支付成功,系统已完成入账核销';
|
||||
if (!empty($res['duplicate_refund_error'])) {
|
||||
$this->error($res['duplicate_refund_error']);
|
||||
}
|
||||
$this->success($msg);
|
||||
}
|
||||
$this->success('同步成功,当前微信状态:' . ($res['trade_state_text'] ?? '待确认'));
|
||||
} catch (\Throwable $e) {
|
||||
$this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 后台手动对退款失败(或未退)的微信支付流水重发原路退款
|
||||
*/
|
||||
public function retryrefund($ids = null)
|
||||
{
|
||||
if (!$this->request->isPost()) {
|
||||
$this->error('非法请求方式');
|
||||
}
|
||||
$payOrderId = $this->request->post('pay_order_id/d', 0);
|
||||
if ($payOrderId <= 0) {
|
||||
$payOrderId = (int)$ids;
|
||||
}
|
||||
$po = Db::name('pay_order')->where('id', $payOrderId)->find();
|
||||
if (!$po) {
|
||||
$this->error('未找到指定的支付交易流水');
|
||||
}
|
||||
|
||||
$order = Db::name('order')->where('id', (int)$po['order_id'])->find();
|
||||
if (!$order) {
|
||||
$this->error('关联业务订单不存在');
|
||||
}
|
||||
if ((int)$order['settle_status'] === 1) {
|
||||
$this->error('该工单已完成向师傅结算分账,不允许再执行退款');
|
||||
}
|
||||
|
||||
$status = (string)($po['status'] ?? '');
|
||||
if ($status === 'refunding') {
|
||||
$this->error('该流水处于微信退款处理中,请先点击【同步微信状态】核实是否已到账,切勿盲目重退');
|
||||
}
|
||||
if (!in_array($status, ['refund_failed', 'paid'], true)) {
|
||||
$this->error('当前流水状态为「' . \app\common\library\PaymentService::payOrderStatusLabel($status) . '」,不可发起原路退款');
|
||||
}
|
||||
|
||||
$reason = trim($this->request->post('reason/s', ''));
|
||||
try {
|
||||
$after = \app\common\library\PaymentService::refundSinglePayOrder(
|
||||
$payOrderId,
|
||||
$reason !== '' ? $reason : '管理员后台手动发起/重试原路退款'
|
||||
);
|
||||
} catch (\Throwable $e) {
|
||||
$this->error('发起原路退款失败:' . $e->getMessage());
|
||||
}
|
||||
|
||||
// 若主工单已处于取消状态且本笔退款受理/到账成功,同步汇总真实退款金额
|
||||
if ((int)$order['status'] === 9 && in_array($after['status'] ?? '', ['refunding', 'refunded'], true)) {
|
||||
$allPaid = Db::name('pay_order')
|
||||
->where('order_id', (int)$order['id'])
|
||||
->whereIn('status', ['paid', 'refunding', 'refunded', 'refund_failed'])
|
||||
->select();
|
||||
$hasUnsettledRefund = false;
|
||||
$sumRefund = 0.00;
|
||||
foreach ($allPaid as $item) {
|
||||
if (in_array($item['status'], ['refunding', 'refunded'], true)) {
|
||||
$sumRefund = round($sumRefund + (float)($item['refund_amount'] ?: $item['amount']), 2);
|
||||
} else {
|
||||
$hasUnsettledRefund = true;
|
||||
}
|
||||
}
|
||||
Db::name('order')->where('id', (int)$order['id'])->update([
|
||||
'pay_status' => $hasUnsettledRefund ? (int)$order['pay_status'] : 2,
|
||||
'refund_amount' => $sumRefund,
|
||||
'updatetime' => time(),
|
||||
]);
|
||||
}
|
||||
|
||||
$statusLabel = \app\common\library\PaymentService::payOrderStatusLabel($after['status'] ?? '');
|
||||
$refundLabel = \app\common\library\PaymentService::refundStatusLabel($after['refund_status'] ?? 'none');
|
||||
$this->success('微信原路退款请求已提交,当前状态:' . $statusLabel . '(' . $refundLabel . ')');
|
||||
}
|
||||
}
|
||||
|
||||
在新工单中引用
屏蔽一个用户