feat(work-order): 新增一次性补资料链接
This commit is contained in:
@@ -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'),
|
||||
|
||||
@@ -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))
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user