```
feat(split-order): 完善分账订单管理功能 - 添加订单关联关系,支持查询原始订单信息 - 实现分账订单列表的搜索过滤功能,支持买家、订单号、状态等多维度筛选 - 优化前端页面展示,添加分页、样式美化和交互提示 - 增加重试分账和查询状态的操作确认提示 - 格式化显示买家信息、金额和时间等数据字段 - 支持汇付和微信两种分账通道的状态显示 ```
这个提交包含在:
@@ -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');
|
||||
|
||||
在新工单中引用
屏蔽一个用户