接单平台新增拼单与取消接单能力

拼单功能:
- 工单/物品规则支持拼单配置(启用、总数量、单价),总价=单价×数量三方联动,启用拼单时工单金额自动同步拼单总价
- 拼单参与按数量冻结比例押金,验收通过后按份额结算报酬,升级统计按数量计入
- 抢单大厅拼单入口:紫色渐变大按钮带单价展示,拼单进度/剩余份数,弹窗输入数量实时预估报酬与押金
- 我的订单展示拼单份额(数量×单价、状态),拼单者各自提交验收,全部提交后管理员统一验收
- 新增 work_order_shares 表与迁移 008

取消接单:
- 进行中订单可取消(押金全额退还、工单回大厅),30 天内限 5 次防滥用
This commit is contained in:
yml2213
2026-08-01 16:31:27 +08:00
parent 52a85f7f9e
commit c33e859e96
12 changed files with 1745 additions and 61 deletions
@@ -8,6 +8,7 @@ import {
deleteAdminWorkerLevel,
getAdminWorkerFinanceConfig,
getAdminWorkerPlatformSummary,
getAdminWorkOrderSharing,
listAdminWorkerFinanceRequests,
listAdminWorkCategories,
listAdminWorkProductRules,
@@ -26,6 +27,7 @@ import {
submitAdminWorkOrderMaterial,
syncAdminWorkerOrdersFromSource,
unpublishAdminWorkOrder,
updateAdminWorkOrderSharing,
} from '../../services/worker-platform/worker-platform-service.js'
import { createJsonHandler, requireAdminRoles } from './session.js'
@@ -349,6 +351,35 @@ router.post(
}),
)
router.get(
'/worker-platform/orders/:workOrderId/sharing',
requireAdminRoles(['admin', 'operator', 'support']),
createJsonHandler((req) => getAdminWorkOrderSharing(String(req.params.workOrderId || '')), {
successMessage: 'ok',
errorMessage: '读取拼单信息失败',
scope: '[admin/worker-platform/orders/:workOrderId/sharing]',
}),
)
router.post(
'/worker-platform/orders/:workOrderId/sharing',
requireAdminRoles(['admin', 'operator']),
createJsonHandler(
(req) => updateAdminWorkOrderSharing(String(req.params.workOrderId || ''), req.body || {}),
{
successMessage: '拼单配置已保存',
errorMessage: '保存拼单配置失败',
scope: '[admin/worker-platform/orders/:workOrderId/sharing]',
audit: (req, data) => ({
action: 'work_order_sharing_config_updated',
targetType: 'work_order',
targetId: String(req.params.workOrderId || ''),
data: data && typeof data === 'object' ? (data as Record<string, unknown>) : {},
}),
},
),
)
router.post(
'/worker-platform/orders/:workOrderId/problem',
requireAdminRoles(['admin', 'operator', 'support']),
+33
View File
@@ -4,12 +4,14 @@ import { createRateLimitMiddleware, getBodyFieldRateLimitKey } from '../middlewa
import { uploadSingleFile } from './file-upload.js'
import { uploadFileAsset } from '../services/file-storage/file-storage-service.js'
import {
cancelWorkerOrder,
changeWorkerPassword,
createWorkerRechargeRequest,
createWorkerWithdrawRequest,
getWorkerProfile,
getWorkerSessionSummary,
grabWorkerHallOrder,
joinWorkerSharingOrder,
listWorkerProfileFinanceRequests,
listWorkerProfileWalletLedgers,
listWorkerHallOrders,
@@ -182,6 +184,24 @@ router.post(
),
)
router.post(
'/hall/orders/:workOrderId/join-sharing',
requireActiveWorker,
createRouteHandler(
(req) =>
joinWorkerSharingOrder(
String(req.params.workOrderId || ''),
req.body || {},
getRequiredWorkerSession(req),
),
{
successMessage: '拼单成功',
errorMessage: '拼单失败',
scope: '[worker/hall/orders/:workOrderId/join-sharing]',
},
),
)
router.get(
'/orders',
requireActiveWorker,
@@ -210,6 +230,19 @@ router.post(
),
)
router.post(
'/orders/:workOrderId/cancel',
requireActiveWorker,
createRouteHandler(
(req) => cancelWorkerOrder(String(req.params.workOrderId || ''), getRequiredWorkerSession(req)),
{
successMessage: '已取消接单',
errorMessage: '取消接单失败',
scope: '[worker/orders/:workOrderId/cancel]',
},
),
)
router.use((req, res) => {
res.status(404).json(buildNotFoundPayload(req))
})