feat(consignment): 寄售匹配成功后向卖家端与客服后台透出买家加好友资料
This commit is contained in:
@@ -41,6 +41,8 @@ export type ConsignmentInventoryRow = {
|
||||
gift_evidence_json?: string | Record<string, unknown> | null
|
||||
gift_work_order_no?: string | null
|
||||
gift_work_order_status?: string | null
|
||||
bound_work_order_material_json?: string | Record<string, unknown> | null
|
||||
bound_work_order_requirement_json?: string | Record<string, unknown> | null
|
||||
worker_id?: string | number | null
|
||||
worker_name?: string
|
||||
worker_phone?: string
|
||||
@@ -194,7 +196,9 @@ export async function listConsignmentInventories(filters: {
|
||||
cs.screenshots_json AS submission_screenshots_json,
|
||||
wo.acceptance_json AS gift_evidence_json,
|
||||
wo.work_order_no AS gift_work_order_no,
|
||||
wo.status AS gift_work_order_status
|
||||
wo.status AS gift_work_order_status,
|
||||
wo.material_json AS bound_work_order_material_json,
|
||||
wo.requirement_json AS bound_work_order_requirement_json
|
||||
FROM consignment_inventories ci
|
||||
LEFT JOIN work_categories wc ON wc.id = ci.category_id
|
||||
LEFT JOIN consignment_submissions cs ON cs.id = ci.source_submission_id
|
||||
@@ -309,7 +313,9 @@ export async function getConsignmentInventoryById(
|
||||
cs.screenshots_json AS submission_screenshots_json,
|
||||
wo.acceptance_json AS gift_evidence_json,
|
||||
wo.work_order_no AS gift_work_order_no,
|
||||
wo.status AS gift_work_order_status
|
||||
wo.status AS gift_work_order_status,
|
||||
wo.material_json AS bound_work_order_material_json,
|
||||
wo.requirement_json AS bound_work_order_requirement_json
|
||||
FROM consignment_inventories ci
|
||||
LEFT JOIN work_categories wc ON wc.id = ci.category_id
|
||||
LEFT JOIN consignment_submissions cs ON cs.id = ci.source_submission_id
|
||||
|
||||
@@ -29,6 +29,7 @@ import {
|
||||
releaseConsignmentPublishDepositBySubmissionWithClient,
|
||||
} from '../../repositories/worker-platform/consignment-deposit-repo.js'
|
||||
import { publishWorkerWalletRealtimeChange } from '../realtime/realtime-event-service.js'
|
||||
import { extractConsignmentBuyerInfo } from './work-order-material-mappers.js'
|
||||
|
||||
function throwConsignmentDepositHttpError(error: unknown, restock: boolean): never {
|
||||
const code = getConsignmentDepositErrorCode(error)
|
||||
@@ -192,6 +193,10 @@ export function mapConsignmentInventory(row: ConsignmentInventoryRow) {
|
||||
/** 唯一锚点:卖家端看到的「寄卖单号」就是它,客服端也用同一个号 */
|
||||
sourceSubmissionNo: row.source_submission_no || '',
|
||||
...mapConsignmentEvidence(row),
|
||||
buyerInfo: extractConsignmentBuyerInfo({
|
||||
materialJson: row.bound_work_order_material_json,
|
||||
requirementJson: row.bound_work_order_requirement_json,
|
||||
}),
|
||||
workerId: row.worker_id ? Number(row.worker_id) : null,
|
||||
workerName: row.worker_name || '',
|
||||
workerPhone: row.worker_phone || '',
|
||||
|
||||
@@ -23,6 +23,7 @@ import { getConsignmentPublishDepositFen as getConfiguredConsignmentPublishDepos
|
||||
import { confirmAdminWorkOrderFriendAdded } from './admin-work-order-gift-service.js'
|
||||
import { submitWorkerOrderAcceptance } from './worker-acceptance-service.js'
|
||||
import type { WorkerSession } from './worker-session-context-service.js'
|
||||
import { extractConsignmentBuyerInfoFromWorkOrder } from './work-order-material-mappers.js'
|
||||
|
||||
export function getConsignmentPublishDepositFen() {
|
||||
return getConfiguredConsignmentPublishDepositFen()
|
||||
@@ -276,6 +277,9 @@ export async function listWorkerConsignments(workerId: number) {
|
||||
const items = [
|
||||
...submissionsRes.items.map((sub) => {
|
||||
const inv = inventoryBySubmission.get(Number(sub.id))
|
||||
const boundWo = inv?.bound_work_order_id
|
||||
? workOrderById.get(Number(inv.bound_work_order_id))
|
||||
: undefined
|
||||
const stage = resolveStage(String(sub.status || ''), inv)
|
||||
return {
|
||||
/** 唯一锚点:提报单号贯穿发布→审核→在库→匹配→冷却→赠送→结算 */
|
||||
@@ -305,10 +309,14 @@ 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,
|
||||
buyerInfo: extractConsignmentBuyerInfoFromWorkOrder(boundWo),
|
||||
}
|
||||
}),
|
||||
...orphanInventories.map((inv) => {
|
||||
// 手动入库已停用:没有提报单的货不该再出现,这里只做兜底展示(不显示内部仓库号、不给操作能力)
|
||||
const boundWo = inv.bound_work_order_id
|
||||
? workOrderById.get(Number(inv.bound_work_order_id))
|
||||
: undefined
|
||||
const stage = resolveStage('approved', inv)
|
||||
return {
|
||||
consignmentNo: '客服手工入库',
|
||||
@@ -336,6 +344,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,
|
||||
buyerInfo: extractConsignmentBuyerInfoFromWorkOrder(boundWo),
|
||||
}
|
||||
}),
|
||||
].sort((a, b) => Date.parse(String(b.createdAt || '')) - Date.parse(String(a.createdAt || '')))
|
||||
|
||||
@@ -9,6 +9,87 @@ import {
|
||||
normalizeSubmittedFields,
|
||||
normalizeUploadedFiles,
|
||||
} from './worker-input-normalizers.js'
|
||||
import { normalizeRequirementFields } from './work-order-requirement-fields.js'
|
||||
|
||||
export interface ConsignmentBuyerInfo {
|
||||
gameNickname: string
|
||||
gameId: string
|
||||
serverZone?: string
|
||||
system?: string
|
||||
fieldItems: Array<{ key: string; label: string; value: string }>
|
||||
screenshots: string[]
|
||||
}
|
||||
|
||||
export function extractConsignmentBuyerInfo(input: {
|
||||
materialJson: unknown
|
||||
requirementJson?: unknown
|
||||
}): ConsignmentBuyerInfo | null {
|
||||
const material = safeParseJson(input.materialJson)
|
||||
const collect = safeParseJson(material.collect)
|
||||
const fields = normalizeSubmittedFields(collect.fields || material.fields)
|
||||
const requirementFields = normalizeRequirementFields(safeParseJson(input.requirementJson).fields)
|
||||
|
||||
const gameNickname = String(
|
||||
fields.gameNickname || fields.roleName || fields.nickname || fields.game_nickname || '',
|
||||
).trim()
|
||||
const gameId = String(
|
||||
fields.gameId || fields.characterId || fields.uid || fields.game_id || '',
|
||||
).trim()
|
||||
const serverZone = String(fields.serverZone || fields.zone || fields.server_zone || '').trim()
|
||||
const system = String(fields.system || fields.os || '').trim()
|
||||
|
||||
const fieldItems: Array<{ key: string; label: string; value: string }> = []
|
||||
const usedKeys = new Set<string>()
|
||||
for (const req of requirementFields) {
|
||||
usedKeys.add(req.key)
|
||||
const val = String(fields[req.key] || '').trim()
|
||||
if (val) {
|
||||
fieldItems.push({ key: req.key, label: req.label, value: val })
|
||||
}
|
||||
}
|
||||
for (const [k, v] of Object.entries(fields)) {
|
||||
if (!usedKeys.has(k) && String(v || '').trim()) {
|
||||
fieldItems.push({ key: k, label: k, value: String(v).trim() })
|
||||
}
|
||||
}
|
||||
|
||||
const rawScreenshots = Array.isArray(collect.screenshots) ? collect.screenshots : []
|
||||
const screenshots = rawScreenshots
|
||||
.map((item) => {
|
||||
if (typeof item === 'string' && item.trim()) {
|
||||
return refreshStoredFileUrl(item.trim())
|
||||
}
|
||||
if (item && typeof item === 'object') {
|
||||
const norm = normalizeUploadedFiles([item])[0]
|
||||
return norm ? refreshUploadedFileUrls(norm)?.url : (item as { url?: string }).url || null
|
||||
}
|
||||
return null
|
||||
})
|
||||
.filter((url): url is string => typeof url === 'string' && url.length > 0)
|
||||
|
||||
if (!gameNickname && !gameId && fieldItems.length === 0 && screenshots.length === 0) {
|
||||
return null
|
||||
}
|
||||
|
||||
return {
|
||||
gameNickname,
|
||||
gameId,
|
||||
serverZone,
|
||||
system,
|
||||
fieldItems,
|
||||
screenshots,
|
||||
}
|
||||
}
|
||||
|
||||
export function extractConsignmentBuyerInfoFromWorkOrder(
|
||||
workOrder: WorkOrderRow | undefined | null,
|
||||
): ConsignmentBuyerInfo | null {
|
||||
if (!workOrder) return null
|
||||
return extractConsignmentBuyerInfo({
|
||||
materialJson: workOrder.material_json,
|
||||
requirementJson: workOrder.requirement_json,
|
||||
})
|
||||
}
|
||||
|
||||
export function mapAcceptanceForResponse(value: unknown) {
|
||||
const acceptance = safeParseJson(value)
|
||||
@@ -29,3 +110,4 @@ export function resolveCollectSubmittedFieldValues(workOrder: WorkOrderRow) {
|
||||
: {}
|
||||
return normalizeSubmittedFields(collect.fields)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user