接单工单支持编辑与删除,修复编辑押金不生效问题

This commit is contained in:
yml2213
2026-08-01 18:35:12 +08:00
parent fddb757078
commit de33bfa74c
8 changed files with 408 additions and 1 deletions
@@ -661,6 +661,67 @@ export async function updateWorkOrder(
return getWorkOrderById(workOrderId)
}
export async function updateWorkOrderBasic(
workOrderId: number | string,
patch: {
productName?: string
platformOrderId?: string
categoryId?: number | null
rewardAmount?: number
requiredDepositAmount?: number
depositThresholdAmount?: number
requirementJson?: string
updatedAt: string
},
): Promise<WorkOrderRow | null> {
const current = await getWorkOrderById(workOrderId)
if (!current) return null
await query(
`
UPDATE work_orders
SET
platform_order_id = $1,
product_name = $2,
category_id = $3,
reward_amount = $4,
required_deposit_amount = $5,
deposit_threshold_amount = $6,
requirement_json = $7::jsonb,
updated_at = $8
WHERE id = $9
`,
[
String((patch.platformOrderId ?? current.platform_order_id) || '').trim(),
String((patch.productName ?? current.product_name) || '').trim(),
patch.categoryId === undefined ? current.category_id : patch.categoryId,
toPositiveInteger(patch.rewardAmount ?? current.reward_amount, 0),
toPositiveInteger(
patch.requiredDepositAmount ?? current.required_deposit_amount,
0,
),
toPositiveInteger(
patch.depositThresholdAmount ?? current.deposit_threshold_amount,
0,
),
toJsonString(patch.requirementJson ?? current.requirement_json),
patch.updatedAt,
Number(workOrderId),
],
)
return getWorkOrderById(workOrderId)
}
export async function deleteWorkOrder(workOrderId: number | string): Promise<boolean> {
const result = await query(
`
DELETE FROM work_orders
WHERE id = $1
`,
[Number(workOrderId)],
)
return Number(result.rowCount || 0) > 0
}
export async function grabWorkOrder(input: {
workOrderId: number
workerId: number
@@ -5,6 +5,7 @@ import {
creditAdminWorkerWallet,
createAdminMockWorkOrder,
deleteAdminWorkCategory,
deleteAdminWorkOrder,
deleteAdminWorkerLevel,
getAdminWorkerFinanceConfig,
getAdminWorkerPlatformSummary,
@@ -27,6 +28,7 @@ import {
submitAdminWorkOrderMaterial,
syncAdminWorkerOrdersFromSource,
unpublishAdminWorkOrder,
updateAdminWorkOrder,
updateAdminWorkOrderSharing,
} from '../../services/worker-platform/index.js'
import { createJsonHandler, requireAdminRoles } from './session.js'
@@ -319,6 +321,41 @@ router.post(
),
)
router.put(
'/worker-platform/orders/:workOrderId',
requireAdminRoles(['admin', 'operator']),
createJsonHandler(
(req) => updateAdminWorkOrder(String(req.params.workOrderId || ''), req.body || {}),
{
successMessage: '工单信息已保存',
errorMessage: '保存工单信息失败',
scope: '[admin/worker-platform/orders/:workOrderId]',
audit: (req, data) => ({
action: 'work_order_updated',
targetType: 'work_order',
targetId: String(req.params.workOrderId || ''),
data: data && typeof data === 'object' ? (data as Record<string, unknown>) : {},
}),
},
),
)
router.delete(
'/worker-platform/orders/:workOrderId',
requireAdminRoles(['admin', 'operator']),
createJsonHandler((req) => deleteAdminWorkOrder(String(req.params.workOrderId || '')), {
successMessage: '工单已删除',
errorMessage: '删除工单失败',
scope: '[admin/worker-platform/orders/:workOrderId]',
audit: (req, data) => ({
action: 'work_order_deleted',
targetType: 'work_order',
targetId: String(req.params.workOrderId || ''),
data: data && typeof data === 'object' ? (data as Record<string, unknown>) : {},
}),
}),
)
router.post(
'/worker-platform/orders/:workOrderId/publish',
requireAdminRoles(['admin', 'operator']),
@@ -19,6 +19,7 @@ import {
createWorkerFinanceRequest,
createWorkerUser,
deleteWorkCategory,
deleteWorkOrder,
deleteWorkerLevel,
getWorkerFinanceRequestById,
getWorkerFinanceRequestSummary,
@@ -51,6 +52,7 @@ import {
reviewWorkerFinanceRequest,
submitWorkOrderShareAcceptance,
updateWorkOrder,
updateWorkOrderBasic,
updateWorkerPassword,
updateWorkerUser,
upsertWorkCategory,
@@ -667,6 +669,117 @@ export async function createAdminMockWorkOrder(payload: JsonObject = {}) {
return { order: mapWorkOrderAdmin(workOrder) }
}
export async function updateAdminWorkOrder(
workOrderId: number | string,
payload: JsonObject = {},
) {
const workOrder = await getRequiredWorkOrder(workOrderId)
if (
![
WORK_ORDER_STATUS.PENDING_MATERIAL,
WORK_ORDER_STATUS.UNASSIGNED,
WORK_ORDER_STATUS.OPEN,
].includes(workOrder.status as never)
) {
throw createHttpError('只有待完善、未分配或待抢单的工单可以编辑', {
statusCode: 409,
errorCode: 'work_order_edit_status_invalid',
})
}
if (workOrder.assigned_worker_id) {
throw createHttpError('工单已被打手接走,不能编辑', {
statusCode: 409,
errorCode: 'work_order_edit_assigned_invalid',
})
}
const fields = normalizeRequirementFieldsFromPayload(payload)
const rewardAmount =
payload.rewardAmount === undefined
? workOrder.reward_amount
: normalizeAmountFen(payload.rewardAmount, workOrder.reward_amount)
const requiredDepositAmount =
payload.requiredDepositAmount === undefined
? workOrder.required_deposit_amount
: normalizeAmountFen(payload.requiredDepositAmount, workOrder.required_deposit_amount)
const depositThresholdAmount =
payload.depositThresholdAmount === undefined
? workOrder.deposit_threshold_amount
: normalizeAmountFen(payload.depositThresholdAmount, workOrder.deposit_threshold_amount)
const categoryId =
payload.categoryId === undefined || payload.categoryId === null || payload.categoryId === ''
? workOrder.category_id
: normalizeOptionalId(payload.categoryId) ?? workOrder.category_id
const now = nowIso()
const updated = await updateWorkOrderBasic(workOrder.id, {
productName: String(payload.productName ?? workOrder.product_name).trim(),
platformOrderId: String(
payload.platformOrderId ?? workOrder.platform_order_id ?? '',
).trim(),
categoryId,
rewardAmount,
requiredDepositAmount,
depositThresholdAmount,
requirementJson: JSON.stringify({ fields }),
updatedAt: now,
})
await createWorkOrderEvent({
workOrderId: workOrder.id,
actorType: 'admin',
actorId: '',
eventType: 'edited',
fromStatus: workOrder.status,
toStatus: workOrder.status,
payloadJson: JSON.stringify({
productName: updated?.product_name,
rewardAmount,
requiredDepositAmount,
fields,
}),
now,
})
return { order: mapWorkOrderAdmin(updated || workOrder) }
}
export async function deleteAdminWorkOrder(workOrderId: number | string) {
const workOrder = await getRequiredWorkOrder(workOrderId)
if (
![
WORK_ORDER_STATUS.PENDING_MATERIAL,
WORK_ORDER_STATUS.UNASSIGNED,
WORK_ORDER_STATUS.CANCELLED,
].includes(workOrder.status as never)
) {
throw createHttpError('只有待完善、未分配或已取消的工单可以删除', {
statusCode: 409,
errorCode: 'work_order_delete_status_invalid',
})
}
if (workOrder.assigned_worker_id) {
throw createHttpError('工单已被打手接走,不能删除', {
statusCode: 409,
errorCode: 'work_order_delete_assigned_invalid',
})
}
const shares = await listWorkOrderShares(workOrder.id)
const activeShares = shares.filter((share) => share.status !== 'cancelled')
if (activeShares.length > 0) {
throw createHttpError('工单存在参与中的拼单,不能删除', {
statusCode: 409,
errorCode: 'work_order_delete_has_shares',
})
}
const deleted = await deleteWorkOrder(workOrder.id)
if (!deleted) {
throw createHttpError('工单删除失败', {
statusCode: 500,
errorCode: 'work_order_delete_failed',
})
}
return { deleted: true }
}
export async function publishAdminWorkOrder(workOrderId: number | string) {
const workOrder = await getRequiredWorkOrder(workOrderId)
if (workOrder.status !== WORK_ORDER_STATUS.UNASSIGNED) {
@@ -345,6 +345,7 @@ export function mapWorkOrderAdmin(workOrder: WorkOrderRow) {
workOrderNo: workOrder.work_order_no,
platformOrderId: workOrder.platform_order_id,
productName: workOrder.product_name,
categoryId: workOrder.category_id ? Number(workOrder.category_id) : null,
categoryName: workOrder.category_name || '',
status: workOrder.status,
rewardAmount: Number(workOrder.reward_amount || 0),