文件

724 行
31 KiB
PHP

此文件含有模棱两可的 Unicode 字符

此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。

<?php
namespace app\admin\controller;
use app\common\controller\Backend;
use think\Db;
use Exception;
/**
* 订单管理与调度中心
*
* @icon fa fa-file-text-o
*/
class Order extends Backend
{
/**
* Order模型对象
* @var \app\admin\model\Order
*/
protected $model = null;
protected $relationSearch = true;
protected $searchFields = 'id,order_no,service_name,contact,mobile';
public function _initialize()
{
parent::_initialize();
$this->model = new \app\admin\model\Order;
$this->view->assign("priceTypeList", $this->model->getPriceTypeList());
$this->view->assign("statusList", $this->model->getStatusList());
$this->view->assign("payStatusList", $this->model->getPayStatusList());
$this->view->assign("settleStatusList", $this->model->getSettleStatusList());
$this->view->assign("isReviewList", $this->model->getIsReviewList());
$this->view->assign("hasElevatorList", $this->model->getHasElevatorList());
$this->view->assign("urgentList", $this->model->getUrgentList());
}
public function index()
{
$this->request->filter(['strip_tags', 'trim']);
if (false === $this->request->isAjax()) {
return $this->view->fetch();
}
if ($this->request->request('keyField')) {
return $this->selectpage();
}
[$where, $sort, $order, $offset, $limit] = $this->buildparams();
$list = $this->model
->with(['user', 'master'])
->where($where)
->order($sort, $order)
->paginate($limit);
$rows = $list->items();
if (!empty($rows)) {
$orderIds = array_column($rows, 'id');
$merLinks = Db::name('merchant_order')
->alias('mo')
->join('merchant m', 'm.id = mo.merchant_id', 'LEFT')
->where('mo.order_id', 'in', $orderIds)
->field('mo.order_id, mo.batch_no, m.name as merchant_name')
->select();
$merMap = [];
foreach ($merLinks as $ml) {
$merMap[(int)$ml['order_id']] = $ml;
}
foreach ($rows as &$r) {
$oid = (int)$r['id'];
$r['merchant_name'] = isset($merMap[$oid]) ? (string)$merMap[$oid]['merchant_name'] : '';
$r['batch_no'] = isset($merMap[$oid]) ? (string)$merMap[$oid]['batch_no'] : '';
}
unset($r);
}
return json(['total' => $list->total(), 'rows' => $rows]);
}
/**
* 禁止后台手工凭空新增订单
*/
public function add()
{
$this->error('订单须由客户端或企业商家工作台真实发起,不支持后台手工伪造');
}
/**
* 禁止物理删除业务订单
*/
public function del($ids = "")
{
$this->error('订单关联资金流水与结算凭证,禁止物理删除;如需终止履约请编辑取消工单');
}
/**
* 编辑订单(支持后台派单/改派师傅通知与轨迹联动,以及取消订单自动退回优惠券)
*/
public function edit($ids = null)
{
$row = $this->model->with(['user', 'master'])->where('order.id', (int)$ids)->find();
if (!$row) {
$this->error(__('No Results were found'));
}
if (false === $this->request->isPost()) {
$catName = (int)$row['cat_id'] > 0 ? (string)Db::name('service_cat')->where('id', (int)$row['cat_id'])->value('name') : '';
$this->view->assign('catName', $catName);
$this->view->assign('row', $row);
return $this->view->fetch();
}
$row = $this->model->get($ids);
$params = $this->request->post('row/a', []);
if (!$params) {
$this->error(__('Parameter %s can not be empty', ''));
}
$params = $this->preExcludeFields($params);
// 锁定订单归属与财务结算核心字段,禁止后台编辑工单时意外篡改账务
unset(
$params['order_no'],
$params['user_id'],
$params['cat_id'],
$params['service_id'],
$params['price_type'],
$params['base_amount'],
$params['distance_amount'],
$params['floor_amount'],
$params['diff_amount'],
$params['discount_amount'],
$params['total_amount'],
$params['pay_amount'],
$params['commission_rate'],
$params['commission_snapshot'],
$params['pay_status'],
$params['pay_type'],
$params['pay_time'],
$params['settle_status'],
$params['settle_amount'],
$params['coupon_id'],
$params['verify_code']
);
// 统一转换时间节点字段(留空转为 0,日期字符串转为 Unix 时间戳)
foreach (['appoint_time', 'accept_time', 'arrive_time', 'start_time', 'finish_time'] as $tField) {
if (array_key_exists($tField, $params)) {
$tv = trim((string)$params[$tField]);
$params[$tField] = $tv === '' ? 0 : (is_numeric($tv) ? (int)$tv : ((int)strtotime($tv) ?: 0));
}
}
if (array_key_exists('master_id', $params) && trim((string)$params['master_id']) === '') {
$params['master_id'] = 0;
}
$oldMasterId = (int)$row['master_id'];
$oldStatus = (int)$row['status'];
$newMasterId = isset($params['master_id']) ? (int)$params['master_id'] : $oldMasterId;
$newStatus = isset($params['status']) ? (int)$params['status'] : $oldStatus;
$now = time();
// 若 city-picker 提交空串而原库有城市,保留原城市
if (isset($params['city']) && trim((string)$params['city']) === '' && !empty($row['city'])) {
unset($params['city']);
}
$targetMaster = null;
if ($newMasterId > 0 && $newMasterId !== $oldMasterId && $newStatus !== 9) {
$targetMaster = Db::name('master')->where('id', $newMasterId)->find();
if (!$targetMaster || $targetMaster['verify_status'] !== 'pass') {
$this->error('所选承接师傅不存在或尚未通过实名认证');
}
if (in_array($newStatus, [1, 2], true)) {
$newStatus = 3;
$params['status'] = 3;
}
if (empty($params['accept_time']) || (string)$params['accept_time'] === (string)$row['accept_time']) {
$params['accept_time'] = $now;
}
}
// 后台取消工单前置防资损与原路退款(必须在开启数据库事务之前调用远程退款接口)
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 {
$result = $row->allowField(true)->save($params);
// 1. 后台通过编辑指派或改派了师傅:写轨迹日志与三方站内信
if ($targetMaster && $newMasterId !== $oldMasterId && $newStatus !== 9) {
$actionLabel = $oldMasterId > 0 ? '平台编辑改派师傅' : '平台编辑指派师傅';
$logRemark = $actionLabel . ':指派给【' . $targetMaster['realname'] . '(' . $targetMaster['mobile'] . ')】';
Db::name('order_log')->insert([
'order_id' => (int)$row['id'],
'status' => $newStatus,
'remark' => mb_substr($logRemark, 0, 255),
'operator_type' => 'admin',
'operator_id' => (int)$this->auth->id,
'createtime' => $now,
]);
Db::name('message')->insert([
'receive_type' => 'master',
'receive_id' => $newMasterId,
'type' => 'order',
'title' => '平台派单通知',
'content' => '平台已为您指派工单【' . $row['order_no'] . '】(' . $row['service_name'] . '),请及时联系客户预约上门。',
'order_id' => (int)$row['id'],
'is_read' => 0,
'createtime' => $now,
]);
if ($oldMasterId > 0 && $oldMasterId !== $newMasterId) {
Db::name('message')->insert([
'receive_type' => 'master',
'receive_id' => $oldMasterId,
'type' => 'order',
'title' => '工单改派通知',
'content' => '工单【' . $row['order_no'] . '】已由平台调度改派给其他师傅承接。',
'order_id' => (int)$row['id'],
'is_read' => 0,
'createtime' => $now,
]);
}
if ((int)$row['user_id'] > 0) {
Db::name('message')->insert([
'receive_type' => 'user',
'receive_id' => (int)$row['user_id'],
'type' => 'order',
'title' => '师傅指派成功通知',
'content' => '您的订单【' . $row['order_no'] . '】已安排' . $targetMaster['realname'] . '师傅(' . $targetMaster['mobile'] . ')为您服务。',
'order_id' => (int)$row['id'],
'is_read' => 0,
'createtime' => $now,
]);
}
}
// 2. 后台将订单变更为取消状态(status=9):自动退回已锁定的优惠券并记录轨迹通知
if ($oldStatus !== 9 && $newStatus === 9) {
$this->refundLockedCoupon((int)$row['id'], (int)$row['coupon_id'], $now);
$cancelReason = trim((string)($params['cancel_reason'] ?? $row['cancel_reason'] ?? ''));
Db::name('order_log')->insert([
'order_id' => (int)$row['id'],
'status' => 9,
'remark' => mb_substr('平台运营后台取消工单' . ($cancelReason !== '' ? (':' . $cancelReason) : ''), 0, 255),
'operator_type' => 'admin',
'operator_id' => (int)$this->auth->id,
'createtime' => $now,
]);
if ($oldMasterId > 0) {
Db::name('message')->insert([
'receive_type' => 'master',
'receive_id' => $oldMasterId,
'type' => 'order',
'title' => '工单已取消通知',
'content' => '工单【' . $row['order_no'] . '】已由平台取消' . ($cancelReason !== '' ? (',原因:' . $cancelReason) : '') . '。',
'order_id' => (int)$row['id'],
'is_read' => 0,
'createtime' => $now,
]);
}
if ((int)$row['user_id'] > 0) {
Db::name('message')->insert([
'receive_type' => 'user',
'receive_id' => (int)$row['user_id'],
'type' => 'order',
'title' => '订单取消通知',
'content' => '您的订单【' . $row['order_no'] . '】已取消' . ($cancelReason !== '' ? (',原因:' . $cancelReason) : '') . ',如使用了优惠券已自动退回账户。',
'order_id' => (int)$row['id'],
'is_read' => 0,
'createtime' => $now,
]);
}
} elseif ($oldStatus !== $newStatus && !($targetMaster && $newMasterId !== $oldMasterId)) {
$statusMap = $this->model->getStatusList();
Db::name('order_log')->insert([
'order_id' => (int)$row['id'],
'status' => $newStatus,
'remark' => '平台运营变更工单状态为:' . ($statusMap[$newStatus] ?? ('状态' . $newStatus)),
'operator_type' => 'admin',
'operator_id' => (int)$this->auth->id,
'createtime' => $now,
]);
}
Db::commit();
} catch (Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
if ($result !== false) {
$this->success();
}
$this->error(__('No rows were updated'));
}
/**
* 订单取消时退回已锁定的用户优惠券
*/
protected function refundLockedCoupon($orderId, $userCouponId, $now)
{
$ucRows = Db::name('user_coupon')
->where(function ($q) use ($orderId, $userCouponId) {
if ($userCouponId > 0) {
$q->where('id', $userCouponId)->whereOr('order_id', $orderId);
} else {
$q->where('order_id', $orderId);
}
})
->where('status', 'used')
->select();
foreach ($ucRows as $uc) {
$couponTpl = Db::name('coupon')->where('id', (int)$uc['coupon_id'])->find();
$isExpired = $couponTpl && (int)$couponTpl['end_time'] > 0 && (int)$couponTpl['end_time'] < $now;
Db::name('user_coupon')->where('id', (int)$uc['id'])->update([
'status' => $isExpired ? 'expired' : 'unused',
'order_id' => 0,
'use_time' => null,
]);
}
}
/**
* 人工指派 / 改派师傅
*/
public function dispatch($ids = null)
{
$row = $this->model->with(['user', 'master'])->where('order.id', (int)$ids)->find();
if (!$row) {
$this->error(__('No Results were found'));
}
if ($this->request->isPost()) {
if (in_array((int)$row['status'], [8, 9], true)) {
$this->error('已完成或已取消的工单不支持指派/改派');
}
if ((int)$row['pay_status'] !== 1 && (int)$row['status'] === 0) {
$this->error('该工单尚未完成支付,无法派单');
}
$masterId = (int)$this->request->post('master_id', 0);
$remark = trim((string)$this->request->post('dispatch_remark', ''));
if ($masterId <= 0) {
$this->error('请选择要指派的认证师傅');
}
$targetMaster = Db::name('master')->where('id', $masterId)->find();
if (!$targetMaster || $targetMaster['verify_status'] !== 'pass') {
$this->error('所选师傅不存在或未通过实名认证');
}
$oldMasterId = (int)$row['master_id'];
if ($oldMasterId === $masterId && (int)$row['status'] >= 3) {
$this->error('当前工单已由该师傅承接,无需重复指派');
}
$now = time();
$newStatus = in_array((int)$row['status'], [1, 2], true) ? 3 : (int)$row['status'];
$actionLabel = $oldMasterId > 0 ? '平台改派师傅' : '平台人工指派师傅';
$logRemark = $actionLabel . ':指派给【' . $targetMaster['realname'] . '(' . $targetMaster['mobile'] . ')】' . ($remark !== '' ? (',备注:' . $remark) : '');
Db::startTrans();
try {
$updateData = [
'master_id' => $masterId,
'status' => $newStatus,
'updatetime' => $now,
];
if (empty($row['accept_time']) || $oldMasterId !== $masterId) {
$updateData['accept_time'] = $now;
}
Db::name('order')->where('id', $row['id'])->update($updateData);
Db::name('order_log')->insert([
'order_id' => $row['id'],
'status' => $newStatus,
'remark' => mb_substr($logRemark, 0, 255),
'operator_type' => 'admin',
'operator_id' => (int)$this->auth->id,
'createtime' => $now,
]);
// 通知新接单师傅
Db::name('message')->insert([
'receive_type' => 'master',
'receive_id' => $masterId,
'type' => 'order',
'title' => '平台派单通知',
'content' => '平台已为您指派工单【' . $row['order_no'] . '】(' . $row['service_name'] . '),请及时联系客户预约上门。',
'order_id' => (int)$row['id'],
'is_read' => 0,
'createtime' => $now,
]);
// 若为改派,通知原师傅
if ($oldMasterId > 0 && $oldMasterId !== $masterId) {
Db::name('message')->insert([
'receive_type' => 'master',
'receive_id' => $oldMasterId,
'type' => 'order',
'title' => '工单改派通知',
'content' => '工单【' . $row['order_no'] . '】已由平台调度改派给其他师傅承接。',
'order_id' => (int)$row['id'],
'is_read' => 0,
'createtime' => $now,
]);
}
// 通知下单业主
if ((int)$row['user_id'] > 0) {
Db::name('message')->insert([
'receive_type' => 'user',
'receive_id' => (int)$row['user_id'],
'type' => 'order',
'title' => '师傅指派成功通知',
'content' => '您的订单【' . $row['order_no'] . '】已安排' . $targetMaster['realname'] . '师傅(' . $targetMaster['mobile'] . ')为您服务。',
'order_id' => (int)$row['id'],
'is_read' => 0,
'createtime' => $now,
]);
}
Db::commit();
} catch (Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
$this->success('派单调度成功');
}
// 推荐候选师傅:优先同城在线且实名通过的师傅
$cityKeyword = '';
if (!empty($row['city'])) {
$parts = explode('/', (string)$row['city']);
$cityKeyword = trim((string)(count($parts) > 1 ? $parts[1] : $parts[0]));
$cityKeyword = preg_replace('/市$/u', '', $cityKeyword);
}
$candidateMasters = Db::name('master')
->where('verify_status', 'pass')
->orderRaw("work_status = 'on' DESC, score DESC, order_count DESC")
->limit(12)
->select();
if ($cityKeyword !== '') {
$sameCity = [];
$otherCity = [];
foreach ($candidateMasters as $cm) {
if (mb_strpos((string)$cm['city'], $cityKeyword) !== false) {
$sameCity[] = $cm;
} else {
$otherCity[] = $cm;
}
}
$candidateMasters = array_slice(array_merge($sameCity, $otherCity), 0, 8);
} else {
$candidateMasters = array_slice($candidateMasters, 0, 8);
}
$cmIds = array_column($candidateMasters, 'id');
$cmSkillMap = [];
if (!empty($cmIds)) {
$skRows = Db::name('master_skill')->where('master_id', 'in', $cmIds)->where('status', 'normal')->select();
foreach ($skRows as $sk) {
if (!empty($sk['skill_name'])) {
$cmSkillMap[(int)$sk['master_id']][] = $sk['skill_name'];
}
}
}
foreach ($candidateMasters as &$cm) {
$cm['skills'] = array_slice($cmSkillMap[(int)$cm['id']] ?? [], 0, 3);
}
unset($cm);
$this->view->assign('row', $row);
$this->view->assign('candidateMasters', $candidateMasters);
return $this->view->fetch();
}
/**
* 工单全景详情
*/
public function detail($ids = null)
{
$row = $this->model->with(['user', 'master'])->where('order.id', (int)$ids)->find();
if (!$row) {
$this->error(__('No Results were found'));
}
// 1. 多商品/多工项明细
$goodsList = Db::name('order_goods')->where('order_id', $row['id'])->select();
// 2. 现场施工取证图片 (区分签到、过程、完工、报损)
$mediaList = Db::name('order_media')->where('order_id', $row['id'])->order('id asc')->select();
// 3. 履约轨迹日志
$statusMap = $this->model->getStatusList();
$logList = Db::name('order_log')->where('order_id', $row['id'])->order('createtime asc, id asc')->select();
foreach ($logList as &$lg) {
$lg['status_label'] = isset($statusMap[(int)$lg['status']]) ? $statusMap[(int)$lg['status']] : '状态变更';
}
unset($lg);
// 4. 师傅报价列表
$quoteList = Db::name('order_quote')
->alias('q')
->join('master m', 'q.master_id = m.id', 'LEFT')
->field('q.*, m.realname as master_name, m.mobile as master_mobile, m.score as master_score')
->where('q.order_id', $row['id'])
->order('q.id desc')
->select();
// 5. 客户评价与回复(兼容 JSON 数组或逗号分隔标签)
$review = Db::name('review')->where('order_id', $row['id'])->find();
if ($review) {
$tagsArr = [];
if (!empty($review['tags'])) {
$decoded = json_decode($review['tags'], true);
if (is_array($decoded)) {
$tagsArr = array_filter($decoded);
} else {
$tagsArr = array_filter(explode(',', (string)$review['tags']));
}
}
$review['tags_arr'] = $tagsArr;
}
// 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')
->alias('mo')
->join('merchant m', 'm.id = mo.merchant_id', 'LEFT')
->where('mo.order_id', $row['id'])
->field('mo.batch_no, mo.createtime as bind_time, m.id as merchant_id, m.name as merchant_name, m.contact as merchant_contact, m.mobile as merchant_mobile, m.settle_type')
->find();
// 8. 发票开具关联信息
$invoiceInfo = null;
if (!empty($row['invoice_id'])) {
$invoiceInfo = Db::name('invoice')
->field('id,invoice_sn,title,type,amount,status,invoice_no,issue_time')
->where('id', (int)$row['invoice_id'])
->find();
}
// 9. 售后申诉争议记录
$appealList = Db::name('appeal')
->alias('a')
->join('master m', 'm.id = a.master_id', 'LEFT')
->where('a.order_id', $row['id'])
->field('a.*, m.realname as master_name')
->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,
'mediaList' => $mediaList,
'logList' => $logList,
'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 . ')');
}
}