feat(split-order): 完善分账订单管理功能

- 添加订单关联关系,支持查询原始订单信息
- 实现分账订单列表的搜索过滤功能,支持买家、订单号、状态等多维度筛选
- 优化前端页面展示,添加分页、样式美化和交互提示
- 增加重试分账和查询状态的操作确认提示
- 格式化显示买家信息、金额和时间等数据字段
- 支持汇付和微信两种分账通道的状态显示
```
这个提交包含在:
可乐加冰
2026-10-02 15:39:03 +08:00
父节点 9a487d18c3
当前提交 339c8f508c
共有 4 个文件被更改,包括 392 次插入 和 25 次删除

查看文件

@@ -6,11 +6,21 @@ use app\admin\controller\shopro\Base;
use addons\shopro\library\split\Config as SplitConfig;
use addons\shopro\library\split\SplitExecutor;
use addons\shopro\library\split\ProfitSharingService;
use app\admin\model\shopro\order\Order as ShopOrder;
use app\admin\model\shopro\user\User as ShopUser;
class Order extends Base
{
protected $model = null;
protected $statusMap = [
0 => '待分账',
1 => '分账中',
2 => '成功',
3 => '部分成功',
4 => '失败',
];
public function _initialize()
{
parent::_initialize();
@@ -21,14 +31,143 @@ class Order extends Base
{
$this->request->filter(['strip_tags']);
if ($this->request->isAjax()) {
list($where, $sort, $order, $offset, $limit) = $this->custombuildparams();
$total = $this->model->where($where)->count();
$list = $this->model->with('receivers')->where($where)->order($sort, $order)->limit($offset, $limit)->select();
$nobuildfields = ['buyer_keyword', 'order_sn', 'status', 'channel', 'createtime'];
list($where, $sort, $order, $offset, $limit) = $this->custombuildparams(null, $nobuildfields);
$query = $this->buildSearch();
$total = $query->where($where)->count();
$list = $this->buildSearch()
->with([
'receivers',
'order' => function ($q) {
$q->field('id,order_sn,user_id,pay_fee,paytime,status');
},
'order.user' => function ($q) {
$q->field('id,nickname,mobile');
},
])
->where($where)
->order($sort, $order)
->limit($offset, $limit)
->select();
$list = $this->formatSplitOrderList($list);
return $this->success('操作成功', null, ['total' => $total, 'rows' => $list]);
}
$this->assignconfig('splitHuifuOnly', (new SplitConfig())->isHuifuMode());
return $this->view->fetch();
}
protected function buildSearch()
{
$filter = (array) json_decode($this->request->get('filter', ''), true);
$query = $this->model;
if (!empty($filter['order_sn'])) {
$orderIds = ShopOrder::where('order_sn', 'like', '%' . trim($filter['order_sn']) . '%')->column('id');
$query = $query->where('order_id', 'in', $orderIds ?: [0]);
}
if (!empty($filter['buyer_keyword'])) {
$kw = trim($filter['buyer_keyword']);
$userIds = ShopUser::where('nickname|mobile', 'like', '%' . $kw . '%')->column('id');
$orderIds = $userIds
? ShopOrder::where('user_id', 'in', $userIds)->column('id')
: [];
$query = $query->where('order_id', 'in', $orderIds ?: [0]);
}
if (isset($filter['status']) && $filter['status'] !== '') {
$query = $query->where('status', intval($filter['status']));
}
if (!empty($filter['channel'])) {
$query = $query->where('channel', $filter['channel']);
}
if (!empty($filter['createtime'])) {
$parts = explode(' - ', $filter['createtime']);
if (count($parts) === 2) {
$start = strtotime($parts[0]);
$end = strtotime($parts[1] . ' 23:59:59');
if ($start && $end) {
$query = $query->where('createtime', 'between', [$start, $end]);
}
}
}
return $query;
}
protected function formatSplitOrderList($list)
{
$rows = [];
foreach ($list as $item) {
$data = is_array($item) ? $item : $item->toArray();
$order = $data['order'] ?? null;
$user = is_array($order) ? ($order['user'] ?? null) : null;
$status = intval($data['status'] ?? 0);
$channel = $data['channel'] ?? 'wechat';
$buyerNickname = $user['nickname'] ?? '';
$buyerMobile = $user['mobile'] ?? '';
$receivers = $data['receivers'] ?? [];
$lines = [];
foreach ($receivers as $recv) {
$r = is_array($recv) ? $recv : (method_exists($recv, 'toArray') ? $recv->toArray() : []);
$lines[] = sprintf(
'%s ¥%s',
$this->roleTypeLabel($r['role_type'] ?? ''),
number_format(floatval($r['amount'] ?? 0), 2, '.', '')
);
}
$data['buyer_nickname'] = $buyerNickname;
$data['buyer_mobile'] = $buyerMobile;
$data['buyer_display'] = $this->formatBuyerDisplay(
$buyerNickname,
$buyerMobile,
is_array($order) ? intval($order['user_id'] ?? 0) : 0
);
$data['status_text'] = $this->statusMap[$status] ?? '-';
$data['channel_text'] = $channel === 'huifu' ? '汇付' : '微信';
$data['createtime_text'] = !empty($data['createtime'])
? date('Y-m-d H:i:s', $data['createtime'])
: '-';
$data['order_paytime_text'] = (is_array($order) && !empty($order['paytime']))
? date('Y-m-d H:i:s', $order['paytime'])
: '-';
$data['receiver_summary'] = $lines ? implode(';', $lines) : '—';
unset($data['order']);
$rows[] = $data;
}
return $rows;
}
protected function formatBuyerDisplay($nickname, $mobile, $userId)
{
$nickname = trim((string) $nickname);
$mobile = trim((string) $mobile);
if ($nickname !== '') {
return $mobile !== '' ? ($nickname . '(' . $mobile . ')') : $nickname;
}
if ($mobile !== '') {
return $mobile;
}
return $userId ? ('用户#' . $userId) : '—';
}
protected function roleTypeLabel($type)
{
$map = [
'platform' => '平台',
'promoter' => '推广员',
'regional_agent' => '区域公司',
];
return $map[$type] ?? ($type ?: '接收方');
}
public function retry($ids = null)
{
$id = $ids ?: $this->request->post('id');