feat(consignment): 寄卖配置、内部匹配与打手端升级

This commit is contained in:
2026-11-05 15:39:40 +08:00
parent f94b914ab1
commit 2ef16ddcc7
34 changed files with 3705 additions and 350 deletions
@@ -26,6 +26,12 @@ import {
fulfillWorkOrderWithConsignment,
revokeWorkOrderConsignmentFulfillment,
} from '../../../services/worker-platform/consignment-fulfillment-service.js'
import {
archiveAdminConsignmentProfile,
listAdminConsignmentProfiles,
publishAdminConsignmentProfile,
saveAdminConsignmentProfile,
} from '../../../services/worker-platform/consignment-profile-service.js'
import { createJsonHandler, requireAdminPermission } from '../session.js'
import {
normalizeConsignmentDepositHandling,
@@ -37,11 +43,102 @@ import {
listWorkOrderInventoryMatchOptions,
} from '../../../services/worker-platform/consignment-fulfillment-service.js'
import { listPendingPistolMatches } from '../../../services/worker-platform/consignment-pending-match-service.js'
import {
listConsignmentMatchCandidatesForWorkOrder,
matchConsignmentWorkOrderManually,
} from '../../../services/worker-platform/consignment-match-engine-service.js'
const router = Router()
// ---------------- 库存管理与统计 ----------------
// ---------------- 分类级寄卖配置 ----------------
router.get(
'/worker-platform/consignment/profiles',
requireAdminPermission('consignment.view'),
createJsonHandler(() => listAdminConsignmentProfiles(), {
successMessage: 'ok',
errorMessage: '读取寄卖配置失败',
scope: '[admin/consignment/profiles]',
}),
)
router.post(
'/worker-platform/consignment/profiles',
requireAdminPermission('consignment.manage'),
createJsonHandler(
(req) =>
saveAdminConsignmentProfile({
...(req.body || {}),
adminUserId: req.adminSession?.userId ?? null,
}),
{
successMessage: '寄卖配置已保存',
errorMessage: '保存寄卖配置失败',
scope: '[admin/consignment/profiles/save]',
},
),
)
router.post(
'/worker-platform/consignment/profiles/:id/publish',
requireAdminPermission('consignment.manage'),
createJsonHandler(
(req) =>
publishAdminConsignmentProfile(String(req.params.id || ''), req.adminSession?.userId ?? null),
{
successMessage: '寄卖配置已发布',
errorMessage: '发布寄卖配置失败',
scope: '[admin/consignment/profiles/publish]',
},
),
)
router.post(
'/worker-platform/consignment/profiles/:id/archive',
requireAdminPermission('consignment.manage'),
createJsonHandler((req) => archiveAdminConsignmentProfile(String(req.params.id || '')), {
successMessage: '寄卖配置已归档',
errorMessage: '归档寄卖配置失败',
scope: '[admin/consignment/profiles/archive]',
}),
)
// ---------------- 内部匹配(手动/自动共用) ----------------
router.get(
'/worker-platform/consignment/match-candidates',
requireAdminPermission('consignment.fulfill'),
createJsonHandler(
(req) => listConsignmentMatchCandidatesForWorkOrder(Number(req.query.workOrderId || 0)),
{
successMessage: 'ok',
errorMessage: '读取可匹配寄卖库存失败',
scope: '[admin/consignment/match-candidates]',
},
),
)
router.post(
'/worker-platform/consignment/match',
requireAdminPermission('consignment.fulfill'),
createJsonHandler(
(req) =>
matchConsignmentWorkOrderManually({
workOrderId: Number(req.body?.workOrderId || 0),
inventoryIds: Array.isArray(req.body?.inventoryIds)
? req.body.inventoryIds.map((id: unknown) => Number(id))
: [],
actorName: req.adminSession?.displayName || req.adminSession?.username || 'admin',
}),
{
successMessage: '寄卖库存已匹配',
errorMessage: '匹配寄卖库存失败',
scope: '[admin/consignment/match]',
},
),
)
// ---------------- 库存管理与统计 ----------------
router.get(
'/worker-platform/consignment/inventories',
requireAdminPermission('consignment.view'),
@@ -6,13 +6,46 @@ import {
listWorkerConsignments,
publishWorkerConsignment,
submitWorkerConsignmentGiftEvidence,
updateWorkerConsignmentSalePrice,
} from '../../services/worker-platform/consignment-worker-service.js'
import { fetchWorkerConsignmentContacts } from '../../services/worker-platform/consignment-contact-service.js'
import { listWorkerConsignmentProfiles } from '../../services/worker-platform/consignment-profile-service.js'
import { sendRouteError } from '../../utils/http.js'
import { getRequiredWorkerSession, requireActiveWorker } from './session.js'
const router = Router()
/**
* GET /api/v1/worker/consignment/profiles
* 打手端寄卖页按已发布的分类配置动态生成 tab。
*/
router.get('/consignment/profiles', async (_req, res) => {
try {
const result = await listWorkerConsignmentProfiles()
res.json({ ok: true, data: { profiles: result } })
} catch (error) {
sendRouteError(res, error, '获取寄卖配置失败', '[worker/consignment/profiles]')
}
})
/**
* PATCH /api/v1/worker/consignment/items/:submissionId/price
* 打手修改在售寄卖售价(仅本人、未售出)。
*/
router.patch('/consignment/items/:submissionId/price', requireActiveWorker, async (req, res) => {
try {
const session = getRequiredWorkerSession(req)
const result = await updateWorkerConsignmentSalePrice(
session.workerId,
String(req.params.submissionId || ''),
req.body?.salePriceFen ?? req.body?.priceFen,
)
res.json({ ok: true, data: result })
} catch (error) {
sendRouteError(res, error, '修改寄卖售价失败', '[worker/consignment/price]')
}
})
/**
* GET /api/v1/worker/consignment/contacts
* 打手发布寄卖时的「对接客服」下拉:只返回启用中的名单