feat(work-order): 新增一次性补资料链接

This commit is contained in:
2026-11-01 10:46:31 +08:00
parent fba0a13d44
commit 15956e704f
26 changed files with 1768 additions and 4 deletions
@@ -13,6 +13,7 @@ import {
getAdminWorkerPlatformNotificationConfig,
getAdminWorkerPlatformSummary,
getAdminWorkerProductMatchConfig,
getWorkerMaterialLinkConfig,
listAdminKuaishouMatchSources,
listAdminWorkCategories,
listAdminWorkProductMatchLogs,
@@ -29,6 +30,7 @@ import {
saveAdminWorkerLevel,
saveAdminWorkerPlatformNotificationConfig,
saveAdminWorkerProductMatchConfig,
saveWorkerMaterialLinkConfig,
syncAdminWorkProductRulePrice,
testAdminKuaishouProductMatch,
testAdminProductMatchByOrderItem,
@@ -293,6 +295,32 @@ router.post(
}),
)
router.get(
'/worker-platform/material-link-config',
requireAdminRoles(['admin', 'operator']),
createJsonHandler(() => getWorkerMaterialLinkConfig(), {
successMessage: 'ok',
errorMessage: '读取补资料链接配置失败',
scope: '[admin/worker-platform/material-link-config]',
}),
)
router.post(
'/worker-platform/material-link-config',
requireAdminRoles(['admin', 'operator']),
createJsonHandler((req) => saveWorkerMaterialLinkConfig(req.body || {}), {
successMessage: '补资料链接配置已保存',
errorMessage: '保存补资料链接配置失败',
scope: '[admin/worker-platform/material-link-config]',
audit: (_req, data) => ({
action: 'worker_material_link_config_saved',
targetType: 'work_order_material_link_config',
targetId: 'work_order_material_link',
data: data && typeof data === 'object' ? (data as Record<string, unknown>) : {},
}),
}),
)
router.post(
'/worker-platform/announcement',
requireAdminRoles(['admin']),
@@ -9,6 +9,7 @@ import {
completeAdminWorkOrderGiftCooldown,
confirmAdminWorkOrderFriendAdded,
createAdminMockWorkOrder,
createAdminWorkOrderMaterialLink,
deleteAdminMockCustomShop,
deleteAdminWorkOrder,
getAdminWorkOrderEvents,
@@ -181,6 +182,36 @@ router.post(
),
)
router.post(
'/worker-platform/orders/:workOrderId/material-link',
requireAdminPermission('worker_order.update_material'),
createJsonHandler(
(req) =>
createAdminWorkOrderMaterialLink(
String(req.params.workOrderId || ''),
req.adminSession?.displayName || req.adminSession?.username || '',
),
{
successMessage: '补资料链接已生成',
errorMessage: '生成补资料链接失败',
scope: '[admin/worker-platform/orders/:workOrderId/material-link]',
audit: (req, data) => ({
action: 'work_order_material_link_created',
targetType: 'work_order',
targetId: String(req.params.workOrderId || ''),
// 审计只记录有效期与是否复用,绝不落 token。
data:
data && typeof data === 'object'
? {
expiresAt: (data as Record<string, unknown>).expiresAt,
reused: (data as Record<string, unknown>).reused,
}
: {},
}),
},
),
)
router.put(
'/worker-platform/orders/:workOrderId',
requireAdminPermission('worker_order.edit'),
+75 -1
View File
@@ -1,9 +1,16 @@
import { Router } from 'express'
import { createRateLimitMiddleware, getBodyFieldRateLimitKey } from '../middleware/rate-limit.js'
import {
createRateLimitMiddleware,
getBodyFieldRateLimitKey,
getParamRateLimitKey,
} from '../middleware/rate-limit.js'
import {
collectLookupWorkOrder,
collectSubmitWorkOrder,
getPublicWorkOrderMaterialLink,
getPublicWorkOrderMaterialLinkUploadContext,
submitPublicWorkOrderMaterialLink,
} from '../services/worker-platform/index.js'
import { uploadFileAsset } from '../services/file-storage/file-storage-service.js'
import { buildNotFoundPayload, createRouteHandler } from '../utils/http.js'
@@ -18,6 +25,27 @@ const collectRateLimit = createRateLimitMiddleware({
key: getBodyFieldRateLimitKey('orderNo'),
})
const materialLinkReadRateLimit = createRateLimitMiddleware({
scope: 'collect:link:read',
windowMs: 60_000,
max: 120,
key: getParamRateLimitKey('token'),
})
const materialLinkWriteRateLimit = createRateLimitMiddleware({
scope: 'collect:link:write',
windowMs: 60_000,
max: 20,
key: getParamRateLimitKey('token'),
})
const materialLinkUploadRateLimit = createRateLimitMiddleware({
scope: 'collect:link:upload',
windowMs: 60_000,
max: 30,
key: getParamRateLimitKey('token'),
})
router.post(
'/lookup',
collectRateLimit,
@@ -59,6 +87,52 @@ router.post(
),
)
router.get(
'/link/:token',
materialLinkReadRateLimit,
createRouteHandler((req) => getPublicWorkOrderMaterialLink(String(req.params.token || '')), {
errorMessage: '读取补资料链接失败',
scope: '[collect/link/:token]',
}),
)
router.post(
'/link/:token/submit',
materialLinkWriteRateLimit,
createRouteHandler(
(req) => submitPublicWorkOrderMaterialLink(String(req.params.token || ''), req.body || {}),
{
successMessage: '资料已提交',
errorMessage: '提交补资料失败',
scope: '[collect/link/:token/submit]',
},
),
)
router.post(
'/link/:token/upload',
materialLinkUploadRateLimit,
uploadSingleFile,
createRouteHandler(
async (req) => {
const { order } = await getPublicWorkOrderMaterialLinkUploadContext(
String(req.params.token || ''),
)
return uploadFileAsset({
file: req.file,
scene: req.body?.scene || 'collect-material',
uploaderType: 'collect',
uploaderId: `work-order-${order.id}`,
})
},
{
successMessage: '文件已上传',
errorMessage: '文件上传失败',
scope: '[collect/link/:token/upload]',
},
),
)
router.use((req, res) => {
res.status(404).json(buildNotFoundPayload(req))
})