diff --git a/app/admin/controller/mall/Order.php b/app/admin/controller/mall/Order.php index 7e3db33..776e4ea 100644 --- a/app/admin/controller/mall/Order.php +++ b/app/admin/controller/mall/Order.php @@ -74,10 +74,18 @@ class Order extends Backend [$where, $alias, $limit, $order] = $this->queryBuilder(); $res = $this->model - ->with(['mallItem' => function ($query) { - $query->field('id,title'); - }]) - ->visible(['mallItem' => ['title']]) + ->with([ + 'mallItem' => function ($query) { + $query->field('id,title'); + }, + 'mallUserAsset' => function ($query) { + $query->field('playx_user_id,username'); + }, + ]) + ->visible([ + 'mallItem' => ['title'], + 'mallUserAsset' => ['username'], + ]) ->alias($alias) ->where($where) ->order($order) diff --git a/app/common/library/MallBonusGrantPush.php b/app/common/library/MallBonusGrantPush.php index 4905c33..1c97278 100644 --- a/app/common/library/MallBonusGrantPush.php +++ b/app/common/library/MallBonusGrantPush.php @@ -49,6 +49,14 @@ final class MallBonusGrantPush ]; } + $memberLogin = trim(strval($asset->username ?? '')); + if ($memberLogin === '') { + return [ + 'ok' => false, + 'message' => 'User username empty', + ]; + } + $item = MallItem::where('id', $order->mall_item_id)->find(); if (!$item) { return [ @@ -79,7 +87,7 @@ final class MallBonusGrantPush 'report_date' => $reportDate, 'angpow' => [ [ - 'member_login' => strval($asset->playx_user_id), + 'member_login' => $memberLogin, 'start_time' => $start, 'end_time' => $end, 'amount' => $order->amount, diff --git a/app/common/model/MallOrder.php b/app/common/model/MallOrder.php index 24906a4..e272371 100644 --- a/app/common/model/MallOrder.php +++ b/app/common/model/MallOrder.php @@ -72,5 +72,13 @@ class MallOrder extends Model { return $this->belongsTo(MallAddress::class, 'mall_address_id', 'id'); } + + /** + * 订单 user_id 存 playX 侧用户标识字符串,与 mall_user_asset.playx_user_id 对齐。 + */ + public function mallUserAsset(): \think\model\relation\BelongsTo + { + return $this->belongsTo(MallUserAsset::class, 'user_id', 'playx_user_id'); + } } diff --git a/app/process/AngpowImportJobs.php b/app/process/AngpowImportJobs.php index 81266ce..7298224 100644 --- a/app/process/AngpowImportJobs.php +++ b/app/process/AngpowImportJobs.php @@ -125,13 +125,17 @@ class AngpowImportJobs if (!$order instanceof MallOrder) { continue; } - $row = $this->buildAngpowRow($order); - if ($row === null) { + $rowResult = $this->buildAngpowRow($order); + if ($rowResult === null) { // 构造失败:直接标为可重试失败 $this->markFailedAttempt($order, 'Build payload failed'); continue; } - $payload['angpow'][] = $row; + if (is_string($rowResult)) { + $this->markFailedAttempt($order, $rowResult); + continue; + } + $payload['angpow'][] = $rowResult; $orderIds[] = $order->id; } @@ -218,7 +222,10 @@ class AngpowImportJobs } } - private function buildAngpowRow(MallOrder $order): ?array + /** + * @return array|string|null 成功返回行数组;用户名缺失返回错误文案字符串;其它构造失败返回 null + */ + private function buildAngpowRow(MallOrder $order): array|string|null { $asset = MallUserAsset::where('playx_user_id', $order->user_id)->find(); if (!$asset) { @@ -233,6 +240,11 @@ class AngpowImportJobs return null; } + $memberLogin = trim(strval($asset->username ?? '')); + if ($memberLogin === '') { + return 'User username empty'; + } + $item = null; if ($order->mallItem) { $item = $order->mallItem; @@ -256,7 +268,7 @@ class AngpowImportJobs $end = gmdate('Y-m-d\TH:i:s\Z', strtotime($order->end_time)); return [ - 'member_login' => strval($asset->playx_user_id), + 'member_login' => $memberLogin, 'start_time' => $start, 'end_time' => $end, 'amount' => $order->amount, diff --git a/web/src/lang/backend/en/mall/order.ts b/web/src/lang/backend/en/mall/order.ts index 0062ce0..af511ba 100644 --- a/web/src/lang/backend/en/mall/order.ts +++ b/web/src/lang/backend/en/mall/order.ts @@ -3,7 +3,7 @@ export default { manual_retry: 'Retry grant', retry_confirm: 'Queue this order for grant retry?', id: 'Order ID', - user_id: 'User ID', + user_id: 'Username', type: 'Type', 'type BONUS': 'Bonus', 'type PHYSICAL': 'Physical', diff --git a/web/src/lang/backend/zh-cn/mall/order.ts b/web/src/lang/backend/zh-cn/mall/order.ts index 5e6bb77..6378622 100644 --- a/web/src/lang/backend/zh-cn/mall/order.ts +++ b/web/src/lang/backend/zh-cn/mall/order.ts @@ -3,7 +3,7 @@ export default { manual_retry: '手动重试', retry_confirm: '确认将该订单加入重试队列?', id: 'ID', - user_id: 'playX-ID', + user_id: '用户名', type: '类型', 'type BONUS': '红利(BONUS)', 'type PHYSICAL': '实物(PHYSICAL)', diff --git a/web/src/views/backend/mall/order/index.vue b/web/src/views/backend/mall/order/index.vue index 186749a..7483532 100644 --- a/web/src/views/backend/mall/order/index.vue +++ b/web/src/views/backend/mall/order/index.vue @@ -60,6 +60,17 @@ const baTable = new baTableClass( operatorPlaceholder: t('Fuzzy query'), sortable: false, operator: 'LIKE', + formatter: (row: TableRow, _column: TableColumn, cellValue: string) => { + const r = row as Record + const rel = r.mallUserAsset ?? r.mall_user_asset + if (rel && typeof rel === 'object' && 'username' in rel) { + const u = (rel as { username?: unknown }).username + if (typeof u === 'string' && u.trim() !== '') { + return u + } + } + return (cellValue ?? row.user_id ?? '').toString() + }, }, { label: t('mall.order.type'),