From d40b5a4c1c4f3de03be2009056a7c25d7f5ce0fa Mon Sep 17 00:00:00 2001 From: yml2213 Date: Sat, 19 Sep 2026 14:19:35 +0800 Subject: [PATCH] =?UTF-8?q?feat(worker-platform):=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E6=89=93=E6=89=8B=E6=88=91=E7=9A=84=E5=AF=84=E5=8D=96=E5=8D=A1?= =?UTF-8?q?=E7=89=87=E8=B5=84=E6=96=99=E5=B1=95=E7=A4=BA=EF=BC=8C=E5=89=8D?= =?UTF-8?q?=E7=BD=AE=E5=B1=95=E7=A4=BA=E6=89=93=E6=89=8B=E8=87=AA=E8=BA=AB?= =?UTF-8?q?=E4=B8=8A=E6=9E=B6=E8=B4=A6=E5=8F=B7=E8=B5=84=E6=96=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 后端 consignment-worker-service 在我的寄卖列表中解析并返回打手上架时填写的 sellerInfo(角色名、数字ID、区服系统、微信号/QQ、寄卖留言等); 2. 前端新增 ConsignmentSellerInfoBlock 卖家资料区块,提供角色名/ID高亮与一键复制功能; 3. 寄卖卡片布局升级为前置展示【我的寄卖账号资料】、后置展示【买家加好友资料】,多号上架时号主与买家清晰对应,彻底杜绝登错号加错人。 --- .../consignment-worker-service.ts | 67 ++++++++++ .../pages/worker/WorkerConsignmentPage.tsx | 125 +++++++++++++++++- apps/frontend/src/services/worker.ts | 6 +- apps/frontend/src/styles/worker.css | 80 ++++++++++- apps/frontend/src/types/consignment.ts | 10 ++ 5 files changed, 277 insertions(+), 11 deletions(-) diff --git a/apps/backend/src/services/worker-platform/consignment-worker-service.ts b/apps/backend/src/services/worker-platform/consignment-worker-service.ts index da155628..6be08e8f 100644 --- a/apps/backend/src/services/worker-platform/consignment-worker-service.ts +++ b/apps/backend/src/services/worker-platform/consignment-worker-service.ts @@ -70,6 +70,71 @@ function extractConsignmentGiftEvidenceFromWorkOrder(boundWo?: WorkOrderRow | nu } } +export type ConsignmentSellerInfo = { + characterName: string + characterId: string + sellerContact?: string + sellerPhone?: string + sellerNote?: string + system?: string + serverZone?: string +} + +function extractConsignmentSellerInfoFromSubmission( + sub: Awaited>['items'][number], +): ConsignmentSellerInfo { + const content = toRecord(sub.content_json) || {} + let characterName = String(content.characterName || '').trim() + let characterId = String(content.characterId || '').trim() + + if (!characterName && sub.seller_game_id) { + const raw = String(sub.seller_game_id).trim() + const match = raw.match(/^(.*?)\s*\((.*?)\)$/) + if (match) { + characterName = match[1]?.trim() || raw + if (!characterId) characterId = match[2]?.trim() || '' + } else { + characterName = raw + } + } + + return { + characterName, + characterId, + sellerContact: String(sub.contact_info || '').trim(), + sellerPhone: String(sub.seller_phone || '').trim(), + sellerNote: String(content.sellerNote || '').trim(), + system: sub.system, + serverZone: sub.server_zone, + } +} + +function extractConsignmentSellerInfoFromInventory( + inv: Awaited>['items'][number], +): ConsignmentSellerInfo { + let characterName = '' + let characterId = '' + if (inv.seller_game_id) { + const raw = String(inv.seller_game_id).trim() + const match = raw.match(/^(.*?)\s*\((.*?)\)$/) + if (match) { + characterName = match[1]?.trim() || raw + characterId = match[2]?.trim() || '' + } else { + characterName = raw + } + } + return { + characterName, + characterId, + sellerContact: String(inv.seller_contact || '').trim(), + sellerPhone: String(inv.seller_phone || '').trim(), + sellerNote: String(inv.remark || '').trim(), + system: inv.system, + serverZone: inv.server_zone, + } +} + export function getConsignmentPublishDepositFen() { return getConfiguredConsignmentPublishDepositFen() } @@ -358,6 +423,7 @@ export async function listWorkerConsignments(workerId: number) { friendAddedAt: inv?.bound_work_order_id ? (workOrderById.get(Number(inv.bound_work_order_id))?.friend_added_at ?? null) : null, + sellerInfo: extractConsignmentSellerInfoFromSubmission(sub), buyerInfo: extractConsignmentBuyerInfoFromWorkOrder(boundWo), } }), @@ -397,6 +463,7 @@ export async function listWorkerConsignments(workerId: number) { friendAddedAt: inv.bound_work_order_id ? (workOrderById.get(Number(inv.bound_work_order_id))?.friend_added_at ?? null) : null, + sellerInfo: extractConsignmentSellerInfoFromInventory(inv), buyerInfo: extractConsignmentBuyerInfoFromWorkOrder(boundWo), } }), diff --git a/apps/frontend/src/pages/worker/WorkerConsignmentPage.tsx b/apps/frontend/src/pages/worker/WorkerConsignmentPage.tsx index 6b006664..a6d4c69f 100644 --- a/apps/frontend/src/pages/worker/WorkerConsignmentPage.tsx +++ b/apps/frontend/src/pages/worker/WorkerConsignmentPage.tsx @@ -929,6 +929,119 @@ function SpecTags({ ) } +function ConsignmentSellerInfoBlock({ + sellerInfo, + record, +}: { + sellerInfo?: WorkerConsignmentRecord['sellerInfo'] + record: WorkerConsignmentRecord +}) { + const { message } = App.useApp() + + const copyText = (text: string, label: string) => { + if (!text) return + navigator.clipboard + .writeText(text) + .then(() => message.success(`已复制${label}:${text}`)) + .catch(() => message.error('复制失败,请手动长按复制')) + } + + const characterName = sellerInfo?.characterName || '' + const characterId = sellerInfo?.characterId || '' + const serverZone = sellerInfo?.serverZone || record.serverZone || '' + const system = sellerInfo?.system || record.system || '' + const sellerContact = sellerInfo?.sellerContact || '' + const sellerNote = sellerInfo?.sellerNote || '' + + const copyAll = () => { + const parts: string[] = [] + if (characterName) parts.push(`卖家角色: ${characterName}`) + if (characterId) parts.push(`角色ID: ${characterId}`) + if (serverZone) parts.push(`区服: ${serverZone}`) + if (system) parts.push(`系统: ${system}`) + if (sellerContact) parts.push(`联系方式: ${sellerContact}`) + copyText(parts.join(' | '), '我的寄卖账号资料') + } + + return ( +
+
+ + + + 我的寄卖账号 / 角色资料 + + + +
+ +
+ {characterName ? ( +
+ 我的游戏角色名 + + {characterName} + +
+ ) : null} + + {characterId ? ( +
+ 角色数字ID + + {characterId} + +
+ ) : null} + + {serverZone || system ? ( +
+ 上架区服与系统 + + {system ? {system} : null} + {serverZone ? {serverZone} : null} + +
+ ) : null} + + {sellerContact ? ( +
+ 微信号/QQ + + {sellerContact} + +
+ ) : null} +
+ + {sellerNote ? ( +
+ 寄卖备注:{sellerNote} +
+ ) : null} +
+ ) +} + function ConsignmentBuyerInfoBlock({ buyerInfo, }: { @@ -946,8 +1059,8 @@ function ConsignmentBuyerInfoBlock({ const copyAll = () => { const parts: string[] = [] - if (buyerInfo.gameNickname) parts.push(`角色名: ${buyerInfo.gameNickname}`) - if (buyerInfo.gameId) parts.push(`游戏ID: ${buyerInfo.gameId}`) + if (buyerInfo.gameNickname) parts.push(`买家角色: ${buyerInfo.gameNickname}`) + if (buyerInfo.gameId) parts.push(`角色ID: ${buyerInfo.gameId}`) if (buyerInfo.serverZone) parts.push(`区服: ${buyerInfo.serverZone}`) if (buyerInfo.system) parts.push(`系统: ${buyerInfo.system}`) copyText(parts.join(' | '), '买家加好友资料') @@ -959,7 +1072,7 @@ function ConsignmentBuyerInfoBlock({ - 买家加好友资料 + 买家加好友资料(请在游戏内添加此人)