feat: 支持验收图片暂存
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
-- 019_acceptance_draft.sql —— 验收图片暂存(草稿)。
|
||||
--
|
||||
-- 说明:
|
||||
-- 1. 上传图片与提交验收分离:打手可先把验收图片/说明保存为暂存草稿,
|
||||
-- 不改变工单状态,刷新页面不丢失;提交验收时草稿作为初始内容;
|
||||
-- 2. 已提交验收(pending_acceptance)的工单仍可补充/修改图片,
|
||||
-- 直接更新 acceptance_json(保留原 submitted_at);
|
||||
-- 3. 整单草稿存 work_orders.draft_acceptance_json,
|
||||
-- 拼单草稿存各自 work_order_shares.draft_acceptance_json。
|
||||
|
||||
ALTER TABLE work_orders
|
||||
ADD COLUMN IF NOT EXISTS draft_acceptance_json JSONB NOT NULL DEFAULT '{}'::jsonb;
|
||||
|
||||
ALTER TABLE work_order_shares
|
||||
ADD COLUMN IF NOT EXISTS draft_acceptance_json JSONB NOT NULL DEFAULT '{}'::jsonb;
|
||||
|
||||
COMMENT ON COLUMN work_orders.draft_acceptance_json IS '打手暂存的验收草稿({note, files, imageUrls, updatedAt}),未提交时保存于此,提交后清空';
|
||||
COMMENT ON COLUMN work_order_shares.draft_acceptance_json IS '拼单打手各自暂存的验收草稿({note, files, imageUrls, updatedAt}),提交后清空';
|
||||
@@ -144,6 +144,7 @@ export type WorkOrderShareRow = {
|
||||
share_deposit: number
|
||||
status: string
|
||||
acceptance_json: string | Record<string, unknown>
|
||||
draft_acceptance_json: string | Record<string, unknown>
|
||||
submitted_at: string | null
|
||||
accepted_at: string | null
|
||||
created_at: string
|
||||
@@ -170,6 +171,7 @@ export type WorkOrderRow = {
|
||||
material_json: string | Record<string, unknown>
|
||||
requirement_json: string | Record<string, unknown>
|
||||
acceptance_json: string | Record<string, unknown>
|
||||
draft_acceptance_json: string | Record<string, unknown>
|
||||
problem_note: string
|
||||
sharing_enabled: boolean
|
||||
sharing_total_quantity: number
|
||||
|
||||
@@ -250,12 +250,23 @@ export async function submitWorkOrderShareAcceptance(input: {
|
||||
now: string
|
||||
}): Promise<{ share: WorkOrderShareRow | null; failureReason: 'share_not_found' | 'share_status_invalid' | null }> {
|
||||
return withTransaction(async (client) => {
|
||||
const shareResult = await client.query<WorkOrderShareRow>(
|
||||
`${WORK_ORDER_SHARE_SELECT}
|
||||
WHERE wos.work_order_id = $1 AND wos.worker_id = $2
|
||||
FOR UPDATE`,
|
||||
const lockResult = await client.query<{ id: number }>(
|
||||
`
|
||||
SELECT id
|
||||
FROM work_order_shares
|
||||
WHERE work_order_id = $1 AND worker_id = $2
|
||||
FOR UPDATE
|
||||
`,
|
||||
[input.workOrderId, input.workerId],
|
||||
)
|
||||
const shareId = lockResult.rows[0]?.id || 0
|
||||
if (!shareId) {
|
||||
return { share: null, failureReason: 'share_not_found' }
|
||||
}
|
||||
const shareResult = await client.query<WorkOrderShareRow>(
|
||||
`${WORK_ORDER_SHARE_SELECT} WHERE wos.id = $1 LIMIT 1`,
|
||||
[shareId],
|
||||
)
|
||||
const share = shareResult.rows[0] || null
|
||||
if (!share) {
|
||||
return { share: null, failureReason: 'share_not_found' }
|
||||
@@ -266,7 +277,7 @@ export async function submitWorkOrderShareAcceptance(input: {
|
||||
await client.query(
|
||||
`
|
||||
UPDATE work_order_shares
|
||||
SET status = 'submitted', acceptance_json = $1::jsonb, submitted_at = $2, updated_at = $2
|
||||
SET status = 'submitted', acceptance_json = $1::jsonb, draft_acceptance_json = '{}'::jsonb, submitted_at = $2, updated_at = $2
|
||||
WHERE id = $3
|
||||
`,
|
||||
[input.acceptanceJson, input.now, Number(share.id)],
|
||||
@@ -289,6 +300,90 @@ export async function submitWorkOrderShareAcceptance(input: {
|
||||
})
|
||||
}
|
||||
|
||||
/** 保存整单验收草稿(暂存图片/说明),不改变工单状态 */
|
||||
export async function updateWorkOrderDraftAcceptance(input: {
|
||||
workOrderId: number
|
||||
draftJson: string
|
||||
now: string
|
||||
}): Promise<WorkOrderRow | null> {
|
||||
await query(
|
||||
`
|
||||
UPDATE work_orders
|
||||
SET draft_acceptance_json = $1::jsonb, updated_at = $2
|
||||
WHERE id = $3
|
||||
`,
|
||||
[input.draftJson, input.now, Number(input.workOrderId)],
|
||||
)
|
||||
return getWorkOrderById(input.workOrderId)
|
||||
}
|
||||
|
||||
/** 更新整单已提交的验收资料(保留原 submitted_at,用于提交验收后补充/修改图片) */
|
||||
export async function updateWorkOrderAcceptanceRecord(input: {
|
||||
workOrderId: number
|
||||
acceptanceJson: string
|
||||
now: string
|
||||
}): Promise<WorkOrderRow | null> {
|
||||
await query(
|
||||
`
|
||||
UPDATE work_orders
|
||||
SET acceptance_json = $1::jsonb, updated_at = $2
|
||||
WHERE id = $3
|
||||
`,
|
||||
[input.acceptanceJson, input.now, Number(input.workOrderId)],
|
||||
)
|
||||
return getWorkOrderById(input.workOrderId)
|
||||
}
|
||||
|
||||
/** 保存拼单份额的验收草稿(暂存图片/说明),不改变份额状态 */
|
||||
export async function updateWorkOrderShareDraftAcceptance(input: {
|
||||
workOrderId: number
|
||||
workerId: number
|
||||
draftJson: string
|
||||
now: string
|
||||
}): Promise<WorkOrderShareRow | null> {
|
||||
const result = await query<WorkOrderShareRow>(
|
||||
`${WORK_ORDER_SHARE_SELECT}
|
||||
WHERE wos.work_order_id = $1 AND wos.worker_id = $2`,
|
||||
[Number(input.workOrderId), Number(input.workerId)],
|
||||
)
|
||||
const share = result.rows[0] || null
|
||||
if (!share) return null
|
||||
await query(
|
||||
`
|
||||
UPDATE work_order_shares
|
||||
SET draft_acceptance_json = $1::jsonb, updated_at = $2
|
||||
WHERE id = $3
|
||||
`,
|
||||
[input.draftJson, input.now, Number(share.id)],
|
||||
)
|
||||
return getWorkOrderShareById(share.id)
|
||||
}
|
||||
|
||||
/** 更新拼单份额已提交的验收资料(保留原 submitted_at,用于提交验收后补充/修改图片) */
|
||||
export async function updateWorkOrderShareAcceptanceRecord(input: {
|
||||
workOrderId: number
|
||||
workerId: number
|
||||
acceptanceJson: string
|
||||
now: string
|
||||
}): Promise<WorkOrderShareRow | null> {
|
||||
const result = await query<WorkOrderShareRow>(
|
||||
`${WORK_ORDER_SHARE_SELECT}
|
||||
WHERE wos.work_order_id = $1 AND wos.worker_id = $2`,
|
||||
[Number(input.workOrderId), Number(input.workerId)],
|
||||
)
|
||||
const share = result.rows[0] || null
|
||||
if (!share) return null
|
||||
await query(
|
||||
`
|
||||
UPDATE work_order_shares
|
||||
SET acceptance_json = $1::jsonb, updated_at = $2
|
||||
WHERE id = $3
|
||||
`,
|
||||
[input.acceptanceJson, input.now, Number(share.id)],
|
||||
)
|
||||
return getWorkOrderShareById(share.id)
|
||||
}
|
||||
|
||||
export async function getWorkCategoryByKey(categoryKey: string): Promise<WorkCategoryRow | null> {
|
||||
const result = await query<WorkCategoryRow>(
|
||||
'SELECT * FROM work_categories WHERE category_key = $1 LIMIT 1',
|
||||
@@ -642,6 +737,7 @@ export async function updateWorkOrder(
|
||||
| 'assigned_worker_id'
|
||||
| 'material_json'
|
||||
| 'acceptance_json'
|
||||
| 'draft_acceptance_json'
|
||||
| 'problem_note'
|
||||
| 'reward_amount'
|
||||
| 'sharing_enabled'
|
||||
@@ -666,23 +762,25 @@ export async function updateWorkOrder(
|
||||
assigned_worker_id = $2,
|
||||
material_json = $3::jsonb,
|
||||
acceptance_json = $4::jsonb,
|
||||
problem_note = $5,
|
||||
reward_amount = $6,
|
||||
sharing_enabled = $7,
|
||||
sharing_total_quantity = $8,
|
||||
sharing_unit_reward = $9,
|
||||
published_at = $10,
|
||||
assigned_at = $11,
|
||||
submitted_at = $12,
|
||||
accepted_at = $13,
|
||||
updated_at = $14
|
||||
WHERE id = $15
|
||||
draft_acceptance_json = $5::jsonb,
|
||||
problem_note = $6,
|
||||
reward_amount = $7,
|
||||
sharing_enabled = $8,
|
||||
sharing_total_quantity = $9,
|
||||
sharing_unit_reward = $10,
|
||||
published_at = $11,
|
||||
assigned_at = $12,
|
||||
submitted_at = $13,
|
||||
accepted_at = $14,
|
||||
updated_at = $15
|
||||
WHERE id = $16
|
||||
`,
|
||||
[
|
||||
next.status,
|
||||
next.assigned_worker_id || null,
|
||||
toJsonString(next.material_json),
|
||||
toJsonString(next.acceptance_json),
|
||||
toJsonString(next.draft_acceptance_json),
|
||||
next.problem_note || '',
|
||||
toPositiveInteger(next.reward_amount, 0),
|
||||
next.sharing_enabled === true,
|
||||
|
||||
@@ -20,6 +20,7 @@ import {
|
||||
logoutWorkerSession,
|
||||
registerWorker,
|
||||
sendWorkerSmsCode,
|
||||
saveWorkerOrderAcceptanceDraft,
|
||||
submitWorkerOrderAcceptance,
|
||||
} from '../services/worker-platform/index.js'
|
||||
import { buildNotFoundPayload, createRouteHandler } from '../utils/http.js'
|
||||
@@ -246,6 +247,24 @@ router.post(
|
||||
),
|
||||
)
|
||||
|
||||
router.post(
|
||||
'/orders/:workOrderId/acceptance-draft',
|
||||
requireActiveWorker,
|
||||
createRouteHandler(
|
||||
(req) =>
|
||||
saveWorkerOrderAcceptanceDraft(
|
||||
String(req.params.workOrderId || ''),
|
||||
req.body || {},
|
||||
getRequiredWorkerSession(req),
|
||||
),
|
||||
{
|
||||
successMessage: '验收图片已保存',
|
||||
errorMessage: '保存验收图片失败',
|
||||
scope: '[worker/orders/:workOrderId/acceptance-draft]',
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
router.post(
|
||||
'/orders/:workOrderId/cancel',
|
||||
requireActiveWorker,
|
||||
|
||||
@@ -394,6 +394,7 @@ export function mapWorkOrderAdmin(workOrder: WorkOrderRow) {
|
||||
fields: resolveRequirementFields(workOrder),
|
||||
},
|
||||
acceptance: mapAcceptanceForResponse(workOrder.acceptance_json),
|
||||
draftAcceptance: mapAcceptanceForResponse(workOrder.draft_acceptance_json),
|
||||
problemNote: workOrder.problem_note || '',
|
||||
worker: workOrder.assigned_worker_id
|
||||
? {
|
||||
@@ -443,6 +444,7 @@ export function mapWorkOrderShare(share: WorkOrderShareRow) {
|
||||
shareDeposit: Number(share.share_deposit || 0),
|
||||
status: share.status,
|
||||
acceptance: safeParseJson(share.acceptance_json),
|
||||
draftAcceptance: safeParseJson(share.draft_acceptance_json),
|
||||
submittedAt: share.submitted_at,
|
||||
acceptedAt: share.accepted_at,
|
||||
createdAt: share.created_at,
|
||||
|
||||
@@ -63,6 +63,10 @@ import {
|
||||
settleOverdueWorkOrder,
|
||||
submitWorkOrderShareAcceptance,
|
||||
updateWorkOrder,
|
||||
updateWorkOrderAcceptanceRecord,
|
||||
updateWorkOrderDraftAcceptance,
|
||||
updateWorkOrderShareAcceptanceRecord,
|
||||
updateWorkOrderShareDraftAcceptance,
|
||||
updateWorkerPassword,
|
||||
updateWorkerUser,
|
||||
upsertWorkCategory,
|
||||
@@ -1111,11 +1115,10 @@ export async function submitWorkerOrderAcceptance(
|
||||
})
|
||||
}
|
||||
|
||||
const files = normalizeUploadedFiles(payload.files)
|
||||
const imageUrls = [
|
||||
...files.map((file) => file.url || file.mediumUrl || file.thumbnailUrl).filter(Boolean),
|
||||
...normalizeStringArray(payload.imageUrls),
|
||||
]
|
||||
const { files, imageUrls, note } = resolveAcceptanceImages(
|
||||
payload,
|
||||
workOrder.draft_acceptance_json,
|
||||
)
|
||||
if (imageUrls.length === 0) {
|
||||
throw createHttpError('请上传验收图片', {
|
||||
statusCode: 400,
|
||||
@@ -1123,7 +1126,7 @@ export async function submitWorkerOrderAcceptance(
|
||||
})
|
||||
}
|
||||
const acceptance = {
|
||||
note: String(payload.note || '').trim(),
|
||||
note,
|
||||
files,
|
||||
imageUrls: [...new Set(imageUrls)],
|
||||
submittedAt: now,
|
||||
@@ -1131,6 +1134,7 @@ export async function submitWorkerOrderAcceptance(
|
||||
const updated = await updateWorkOrder(workOrder.id, {
|
||||
status: WORK_ORDER_STATUS.PENDING_ACCEPTANCE,
|
||||
acceptance_json: acceptance,
|
||||
draft_acceptance_json: {},
|
||||
submitted_at: now,
|
||||
updated_at: now,
|
||||
})
|
||||
@@ -1198,11 +1202,10 @@ async function submitWorkerSharingAcceptance(
|
||||
})
|
||||
}
|
||||
const now = nowIso()
|
||||
const files = normalizeUploadedFiles(payload.files)
|
||||
const imageUrls = [
|
||||
...files.map((file) => file.url || file.mediumUrl || file.thumbnailUrl).filter(Boolean),
|
||||
...normalizeStringArray(payload.imageUrls),
|
||||
]
|
||||
const { files, imageUrls, note } = resolveAcceptanceImages(
|
||||
payload,
|
||||
sharingShare.draft_acceptance_json,
|
||||
)
|
||||
if (imageUrls.length === 0) {
|
||||
throw createHttpError('请上传验收图片', {
|
||||
statusCode: 400,
|
||||
@@ -1210,7 +1213,7 @@ async function submitWorkerSharingAcceptance(
|
||||
})
|
||||
}
|
||||
const acceptance = {
|
||||
note: String(payload.note || '').trim(),
|
||||
note,
|
||||
files,
|
||||
imageUrls: [...new Set(imageUrls)],
|
||||
submittedAt: now,
|
||||
@@ -1239,6 +1242,221 @@ async function submitWorkerSharingAcceptance(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从提交/保存验收的载荷中解析图片与说明。
|
||||
* 载荷未带图片时回退到暂存草稿(上传图片与提交验收分离:先暂存、后提交)。
|
||||
*/
|
||||
function resolveAcceptanceImages(payload: JsonObject, draftValue: unknown) {
|
||||
const files = normalizeUploadedFiles(payload.files)
|
||||
const imageUrls = [
|
||||
...files.map((file) => file.url || file.mediumUrl || file.thumbnailUrl).filter(Boolean),
|
||||
...normalizeStringArray(payload.imageUrls),
|
||||
]
|
||||
if (imageUrls.length > 0) {
|
||||
return {
|
||||
files,
|
||||
imageUrls: [...new Set(imageUrls)],
|
||||
note: String(payload.note ?? '').trim(),
|
||||
}
|
||||
}
|
||||
const draft = safeParseJson(draftValue)
|
||||
return {
|
||||
files: normalizeUploadedFiles(draft.files),
|
||||
imageUrls: [...new Set(normalizeStringArray(draft.imageUrls))],
|
||||
note: String(payload.note ?? draft.note ?? '').trim(),
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 暂存验收图片/说明(草稿)。
|
||||
* - 未提交(in_progress / problem / 拼单 joined):写入草稿,不改变工单状态;
|
||||
* - 已提交(pending_acceptance / 拼单 submitted):直接更新已提交的验收资料(保留提交时间)。
|
||||
*/
|
||||
export async function saveWorkerOrderAcceptanceDraft(
|
||||
workOrderId: number | string,
|
||||
payload: JsonObject = {},
|
||||
session: WorkerSession,
|
||||
) {
|
||||
requireActiveWorkerSession(session)
|
||||
const workOrder = await getRequiredWorkOrder(workOrderId)
|
||||
const workerId = Number(session.workerId)
|
||||
const sharingShare = await getWorkOrderShare(workOrder.id, workerId)
|
||||
if (sharingShare) {
|
||||
return saveWorkerSharingAcceptanceDraft(workOrder, sharingShare, payload, session)
|
||||
}
|
||||
if (Number(workOrder.assigned_worker_id || 0) !== workerId) {
|
||||
throw createHttpError('只能操作自己的订单', {
|
||||
statusCode: 403,
|
||||
errorCode: 'work_order_owner_required',
|
||||
})
|
||||
}
|
||||
const now = nowIso()
|
||||
const files = normalizeUploadedFiles(payload.files)
|
||||
const imageUrls = [
|
||||
...files.map((file) => file.url || file.mediumUrl || file.thumbnailUrl).filter(Boolean),
|
||||
...normalizeStringArray(payload.imageUrls),
|
||||
]
|
||||
const worker = await getRequiredWorker(session.workerId)
|
||||
|
||||
if (workOrder.status === WORK_ORDER_STATUS.PENDING_ACCEPTANCE) {
|
||||
if (imageUrls.length === 0) {
|
||||
throw createHttpError('请至少保留一张验收图片', {
|
||||
statusCode: 400,
|
||||
errorCode: 'work_order_acceptance_image_required',
|
||||
})
|
||||
}
|
||||
const previous = safeParseJson(workOrder.acceptance_json)
|
||||
const acceptance = {
|
||||
note: String(payload.note ?? previous.note ?? '').trim(),
|
||||
files,
|
||||
imageUrls: [...new Set(imageUrls)],
|
||||
submittedAt: previous.submittedAt || workOrder.submitted_at || now,
|
||||
updatedAt: now,
|
||||
}
|
||||
const updated = await updateWorkOrderAcceptanceRecord({
|
||||
workOrderId: workOrder.id,
|
||||
acceptanceJson: JSON.stringify(acceptance),
|
||||
now,
|
||||
})
|
||||
await createWorkOrderEvent({
|
||||
workOrderId: workOrder.id,
|
||||
actorType: 'worker',
|
||||
actorId: String(session.workerId),
|
||||
eventType: 'acceptance_updated',
|
||||
fromStatus: workOrder.status,
|
||||
toStatus: workOrder.status,
|
||||
payloadJson: JSON.stringify({ imageCount: imageUrls.length }),
|
||||
now,
|
||||
})
|
||||
return {
|
||||
order: mapWorkOrderForWorker(updated || workOrder, resolveWorkerPermissions(worker)),
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
![WORK_ORDER_STATUS.IN_PROGRESS, WORK_ORDER_STATUS.PROBLEM].includes(workOrder.status as never)
|
||||
) {
|
||||
throw createHttpError('当前状态不能保存验收图片', {
|
||||
statusCode: 409,
|
||||
errorCode: 'work_order_draft_status_invalid',
|
||||
})
|
||||
}
|
||||
const draft = {
|
||||
note: String(payload.note || '').trim(),
|
||||
files,
|
||||
imageUrls: [...new Set(imageUrls)],
|
||||
updatedAt: now,
|
||||
}
|
||||
const updated = await updateWorkOrderDraftAcceptance({
|
||||
workOrderId: workOrder.id,
|
||||
draftJson: JSON.stringify(draft),
|
||||
now,
|
||||
})
|
||||
await createWorkOrderEvent({
|
||||
workOrderId: workOrder.id,
|
||||
actorType: 'worker',
|
||||
actorId: String(session.workerId),
|
||||
eventType: 'acceptance_draft_saved',
|
||||
fromStatus: workOrder.status,
|
||||
toStatus: workOrder.status,
|
||||
payloadJson: JSON.stringify({ imageCount: imageUrls.length }),
|
||||
now,
|
||||
})
|
||||
return {
|
||||
order: mapWorkOrderForWorker(updated || workOrder, resolveWorkerPermissions(worker)),
|
||||
}
|
||||
}
|
||||
|
||||
async function saveWorkerSharingAcceptanceDraft(
|
||||
workOrder: WorkOrderRow,
|
||||
sharingShare: WorkOrderShareRow,
|
||||
payload: JsonObject = {},
|
||||
session: WorkerSession,
|
||||
) {
|
||||
if (workOrder.status === WORK_ORDER_STATUS.ACCEPTED) {
|
||||
throw createHttpError('该拼单已验收完成,不能再修改验收图片', {
|
||||
statusCode: 409,
|
||||
errorCode: 'work_order_sharing_accepted',
|
||||
})
|
||||
}
|
||||
const now = nowIso()
|
||||
const files = normalizeUploadedFiles(payload.files)
|
||||
const imageUrls = [
|
||||
...files.map((file) => file.url || file.mediumUrl || file.thumbnailUrl).filter(Boolean),
|
||||
...normalizeStringArray(payload.imageUrls),
|
||||
]
|
||||
|
||||
if (sharingShare.status === 'submitted') {
|
||||
if (imageUrls.length === 0) {
|
||||
throw createHttpError('请至少保留一张验收图片', {
|
||||
statusCode: 400,
|
||||
errorCode: 'work_order_acceptance_image_required',
|
||||
})
|
||||
}
|
||||
const previous = safeParseJson(sharingShare.acceptance_json)
|
||||
const acceptance = {
|
||||
note: String(payload.note ?? previous.note ?? '').trim(),
|
||||
files,
|
||||
imageUrls: [...new Set(imageUrls)],
|
||||
submittedAt: previous.submittedAt || sharingShare.submitted_at || now,
|
||||
updatedAt: now,
|
||||
}
|
||||
const share = await updateWorkOrderShareAcceptanceRecord({
|
||||
workOrderId: Number(workOrder.id),
|
||||
workerId: Number(session.workerId),
|
||||
acceptanceJson: JSON.stringify(acceptance),
|
||||
now,
|
||||
})
|
||||
await createWorkOrderEvent({
|
||||
workOrderId: workOrder.id,
|
||||
actorType: 'worker',
|
||||
actorId: String(session.workerId),
|
||||
eventType: 'sharing_acceptance_updated',
|
||||
fromStatus: workOrder.status,
|
||||
toStatus: workOrder.status,
|
||||
payloadJson: JSON.stringify({
|
||||
workerId: Number(session.workerId),
|
||||
imageCount: imageUrls.length,
|
||||
}),
|
||||
now,
|
||||
})
|
||||
return { share: share ? mapWorkOrderShare(share) : mapWorkOrderShare(sharingShare) }
|
||||
}
|
||||
|
||||
if (sharingShare.status !== 'joined') {
|
||||
throw createHttpError('当前拼单状态不能保存验收图片', {
|
||||
statusCode: 409,
|
||||
errorCode: 'work_order_sharing_draft_status_invalid',
|
||||
})
|
||||
}
|
||||
const draft = {
|
||||
note: String(payload.note || '').trim(),
|
||||
files,
|
||||
imageUrls: [...new Set(imageUrls)],
|
||||
updatedAt: now,
|
||||
}
|
||||
const share = await updateWorkOrderShareDraftAcceptance({
|
||||
workOrderId: Number(workOrder.id),
|
||||
workerId: Number(session.workerId),
|
||||
draftJson: JSON.stringify(draft),
|
||||
now,
|
||||
})
|
||||
await createWorkOrderEvent({
|
||||
workOrderId: workOrder.id,
|
||||
actorType: 'worker',
|
||||
actorId: String(session.workerId),
|
||||
eventType: 'sharing_acceptance_draft_saved',
|
||||
fromStatus: workOrder.status,
|
||||
toStatus: workOrder.status,
|
||||
payloadJson: JSON.stringify({
|
||||
workerId: Number(session.workerId),
|
||||
imageCount: imageUrls.length,
|
||||
}),
|
||||
now,
|
||||
})
|
||||
return { share: share ? mapWorkOrderShare(share) : mapWorkOrderShare(sharingShare) }
|
||||
}
|
||||
|
||||
export async function collectLookupWorkOrder(payload: JsonObject = {}) {
|
||||
const orderNo = String(payload.orderNo || payload.platformOrderId || '').trim()
|
||||
if (!orderNo) {
|
||||
|
||||
Reference in New Issue
Block a user