优化工单资料与审核展示
This commit is contained in:
@@ -82,7 +82,8 @@ export type WorkerCancelRequestRow = {
|
|||||||
created_at: string
|
created_at: string
|
||||||
reviewed_at: string | null
|
reviewed_at: string | null
|
||||||
updated_at: string
|
updated_at: string
|
||||||
work_order_no?: string
|
platform_order_id?: string
|
||||||
|
shop_name?: string
|
||||||
product_name?: string
|
product_name?: string
|
||||||
worker_username?: string
|
worker_username?: string
|
||||||
worker_display_name?: string
|
worker_display_name?: string
|
||||||
@@ -103,6 +104,7 @@ export type WorkerOrderFeedbackRow = {
|
|||||||
updated_at: string
|
updated_at: string
|
||||||
work_order_no?: string
|
work_order_no?: string
|
||||||
product_name?: string
|
product_name?: string
|
||||||
|
shop_name?: string
|
||||||
worker_username?: string
|
worker_username?: string
|
||||||
worker_display_name?: string
|
worker_display_name?: string
|
||||||
share_quantity?: number | null
|
share_quantity?: number | null
|
||||||
|
|||||||
@@ -63,13 +63,22 @@ const WORK_ORDER_SHARE_SELECT = `
|
|||||||
const WORKER_CANCEL_REQUEST_SELECT = `
|
const WORKER_CANCEL_REQUEST_SELECT = `
|
||||||
SELECT
|
SELECT
|
||||||
cr.*,
|
cr.*,
|
||||||
wo.work_order_no,
|
COALESCE(NULLIF(BTRIM(wo.platform_order_id), ''), o.platform_order_id, ft.platform_order_id, '') AS platform_order_id,
|
||||||
|
COALESCE(
|
||||||
|
NULLIF(BTRIM(o.shop_name), ''),
|
||||||
|
NULLIF(BTRIM(o.shop_id), ''),
|
||||||
|
NULLIF(BTRIM(ft.shop_name), ''),
|
||||||
|
NULLIF(BTRIM(ft.shop_id), ''),
|
||||||
|
''
|
||||||
|
) AS shop_name,
|
||||||
wo.product_name,
|
wo.product_name,
|
||||||
wu.username AS worker_username,
|
wu.username AS worker_username,
|
||||||
wu.display_name AS worker_display_name,
|
wu.display_name AS worker_display_name,
|
||||||
wos.quantity AS share_quantity
|
wos.quantity AS share_quantity
|
||||||
FROM worker_order_cancel_requests cr
|
FROM worker_order_cancel_requests cr
|
||||||
INNER JOIN work_orders wo ON wo.id = cr.work_order_id
|
INNER JOIN work_orders wo ON wo.id = cr.work_order_id
|
||||||
|
LEFT JOIN orders o ON o.id = wo.order_id
|
||||||
|
LEFT JOIN fulfillment_tasks ft ON ft.id = wo.task_id
|
||||||
INNER JOIN worker_users wu ON wu.id = cr.worker_id
|
INNER JOIN worker_users wu ON wu.id = cr.worker_id
|
||||||
LEFT JOIN work_order_shares wos ON wos.id = cr.work_order_share_id
|
LEFT JOIN work_order_shares wos ON wos.id = cr.work_order_share_id
|
||||||
`
|
`
|
||||||
@@ -79,11 +88,20 @@ const WORKER_ORDER_FEEDBACK_SELECT = `
|
|||||||
wf.*,
|
wf.*,
|
||||||
COALESCE(NULLIF(BTRIM(wo.platform_order_id), ''), wo.work_order_no) AS work_order_no,
|
COALESCE(NULLIF(BTRIM(wo.platform_order_id), ''), wo.work_order_no) AS work_order_no,
|
||||||
wo.product_name,
|
wo.product_name,
|
||||||
|
COALESCE(
|
||||||
|
NULLIF(BTRIM(o.shop_name), ''),
|
||||||
|
NULLIF(BTRIM(o.shop_id), ''),
|
||||||
|
NULLIF(BTRIM(ft.shop_name), ''),
|
||||||
|
NULLIF(BTRIM(ft.shop_id), ''),
|
||||||
|
''
|
||||||
|
) AS shop_name,
|
||||||
wu.username AS worker_username,
|
wu.username AS worker_username,
|
||||||
wu.display_name AS worker_display_name,
|
wu.display_name AS worker_display_name,
|
||||||
wos.quantity AS share_quantity
|
wos.quantity AS share_quantity
|
||||||
FROM worker_order_feedbacks wf
|
FROM worker_order_feedbacks wf
|
||||||
INNER JOIN work_orders wo ON wo.id = wf.work_order_id
|
INNER JOIN work_orders wo ON wo.id = wf.work_order_id
|
||||||
|
LEFT JOIN orders o ON o.id = wo.order_id
|
||||||
|
LEFT JOIN fulfillment_tasks ft ON ft.id = wo.task_id
|
||||||
INNER JOIN worker_users wu ON wu.id = wf.worker_id
|
INNER JOIN worker_users wu ON wu.id = wf.worker_id
|
||||||
LEFT JOIN work_order_shares wos ON wos.id = wf.work_order_share_id
|
LEFT JOIN work_order_shares wos ON wos.id = wf.work_order_share_id
|
||||||
`
|
`
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ export async function createWorkerAcceptanceAdminNotification(input: {
|
|||||||
export async function createWorkerCancelRequestAdminNotification(input: {
|
export async function createWorkerCancelRequestAdminNotification(input: {
|
||||||
requestId: number
|
requestId: number
|
||||||
workOrderId: number
|
workOrderId: number
|
||||||
workOrderNo: string
|
platformOrderId: string
|
||||||
productName: string
|
productName: string
|
||||||
workerName: string
|
workerName: string
|
||||||
reason: string
|
reason: string
|
||||||
@@ -112,7 +112,7 @@ export async function createWorkerCancelRequestAdminNotification(input: {
|
|||||||
dedupeKey: `worker_cancel_request:${input.requestId}`,
|
dedupeKey: `worker_cancel_request:${input.requestId}`,
|
||||||
title: '有打手撤单申请待审核',
|
title: '有打手撤单申请待审核',
|
||||||
body: [
|
body: [
|
||||||
`订单:${input.workOrderNo || input.workOrderId}`,
|
`订单:${input.platformOrderId || input.workOrderId}`,
|
||||||
`商品:${input.productName || '-'}`,
|
`商品:${input.productName || '-'}`,
|
||||||
`打手:${input.workerName || '-'}`,
|
`打手:${input.workerName || '-'}`,
|
||||||
`原因:${input.reason || '-'}`,
|
`原因:${input.reason || '-'}`,
|
||||||
|
|||||||
@@ -1798,7 +1798,9 @@ export async function submitAdminWorkOrderMaterial(
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
const nextStatus =
|
const nextStatus =
|
||||||
hasActiveShares || workOrder.status === WORK_ORDER_STATUS.IN_PROGRESS
|
hasActiveShares ||
|
||||||
|
workOrder.status === WORK_ORDER_STATUS.OPEN ||
|
||||||
|
workOrder.status === WORK_ORDER_STATUS.IN_PROGRESS
|
||||||
? workOrder.status
|
? workOrder.status
|
||||||
: complete
|
: complete
|
||||||
? WORK_ORDER_STATUS.UNASSIGNED
|
? WORK_ORDER_STATUS.UNASSIGNED
|
||||||
@@ -1814,7 +1816,9 @@ export async function submitAdminWorkOrderMaterial(
|
|||||||
actorType: 'admin',
|
actorType: 'admin',
|
||||||
actorId: actorName,
|
actorId: actorName,
|
||||||
eventType:
|
eventType:
|
||||||
hasActiveShares || workOrder.status === WORK_ORDER_STATUS.IN_PROGRESS
|
hasActiveShares ||
|
||||||
|
workOrder.status === WORK_ORDER_STATUS.OPEN ||
|
||||||
|
workOrder.status === WORK_ORDER_STATUS.IN_PROGRESS
|
||||||
? 'material_updated'
|
? 'material_updated'
|
||||||
: 'material_completed',
|
: 'material_completed',
|
||||||
fromStatus: workOrder.status,
|
fromStatus: workOrder.status,
|
||||||
|
|||||||
@@ -281,8 +281,8 @@ export function mapWorkerCancelRequest(request: {
|
|||||||
reviewed_by: string
|
reviewed_by: string
|
||||||
created_at: string
|
created_at: string
|
||||||
reviewed_at: string | null
|
reviewed_at: string | null
|
||||||
work_order_no?: string
|
platform_order_id?: string
|
||||||
product_name?: string
|
shop_name?: string
|
||||||
worker_username?: string
|
worker_username?: string
|
||||||
worker_display_name?: string
|
worker_display_name?: string
|
||||||
share_quantity?: number | null
|
share_quantity?: number | null
|
||||||
@@ -292,8 +292,8 @@ export function mapWorkerCancelRequest(request: {
|
|||||||
workOrderId: Number(request.work_order_id),
|
workOrderId: Number(request.work_order_id),
|
||||||
shareId: request.work_order_share_id ? Number(request.work_order_share_id) : null,
|
shareId: request.work_order_share_id ? Number(request.work_order_share_id) : null,
|
||||||
workerId: Number(request.worker_id),
|
workerId: Number(request.worker_id),
|
||||||
workOrderNo: String(request.work_order_no || ''),
|
platformOrderId: String(request.platform_order_id || ''),
|
||||||
productName: String(request.product_name || ''),
|
shopName: String(request.shop_name || ''),
|
||||||
workerName: String(request.worker_display_name || request.worker_username || ''),
|
workerName: String(request.worker_display_name || request.worker_username || ''),
|
||||||
shareQuantity: request.share_quantity ? Number(request.share_quantity) : null,
|
shareQuantity: request.share_quantity ? Number(request.share_quantity) : null,
|
||||||
reason: String(request.reason || ''),
|
reason: String(request.reason || ''),
|
||||||
@@ -318,6 +318,7 @@ export function mapWorkerOrderFeedback(feedback: {
|
|||||||
handled_at: string | null
|
handled_at: string | null
|
||||||
work_order_no?: string
|
work_order_no?: string
|
||||||
product_name?: string
|
product_name?: string
|
||||||
|
shop_name?: string
|
||||||
worker_username?: string
|
worker_username?: string
|
||||||
worker_display_name?: string
|
worker_display_name?: string
|
||||||
share_quantity?: number | null
|
share_quantity?: number | null
|
||||||
@@ -329,6 +330,7 @@ export function mapWorkerOrderFeedback(feedback: {
|
|||||||
workerId: Number(feedback.worker_id),
|
workerId: Number(feedback.worker_id),
|
||||||
workOrderNo: String(feedback.work_order_no || ''),
|
workOrderNo: String(feedback.work_order_no || ''),
|
||||||
productName: String(feedback.product_name || ''),
|
productName: String(feedback.product_name || ''),
|
||||||
|
shopName: String(feedback.shop_name || ''),
|
||||||
workerName: String(feedback.worker_display_name || feedback.worker_username || ''),
|
workerName: String(feedback.worker_display_name || feedback.worker_username || ''),
|
||||||
shareQuantity: feedback.share_quantity ? Number(feedback.share_quantity) : null,
|
shareQuantity: feedback.share_quantity ? Number(feedback.share_quantity) : null,
|
||||||
content: String(feedback.content || ''),
|
content: String(feedback.content || ''),
|
||||||
@@ -481,8 +483,8 @@ export function mapWorkOrderAdmin(workOrder: WorkOrderRow, shares?: WorkOrderSha
|
|||||||
canUpdateMaterial:
|
canUpdateMaterial:
|
||||||
workOrder.status === WORK_ORDER_STATUS.PENDING_MATERIAL ||
|
workOrder.status === WORK_ORDER_STATUS.PENDING_MATERIAL ||
|
||||||
workOrder.status === WORK_ORDER_STATUS.UNASSIGNED ||
|
workOrder.status === WORK_ORDER_STATUS.UNASSIGNED ||
|
||||||
workOrder.status === WORK_ORDER_STATUS.IN_PROGRESS ||
|
workOrder.status === WORK_ORDER_STATUS.OPEN ||
|
||||||
(workOrder.status === WORK_ORDER_STATUS.OPEN && hasActiveShares),
|
workOrder.status === WORK_ORDER_STATUS.IN_PROGRESS,
|
||||||
canAccept: status === WORK_ORDER_STATUS.PENDING_ACCEPTANCE,
|
canAccept: status === WORK_ORDER_STATUS.PENDING_ACCEPTANCE,
|
||||||
canMarkProblem:
|
canMarkProblem:
|
||||||
status === WORK_ORDER_STATUS.IN_PROGRESS || status === WORK_ORDER_STATUS.PENDING_ACCEPTANCE,
|
status === WORK_ORDER_STATUS.IN_PROGRESS || status === WORK_ORDER_STATUS.PENDING_ACCEPTANCE,
|
||||||
|
|||||||
@@ -773,6 +773,10 @@ test('mapWorkOrderForWorker 使用个人拼单份数、金额、状态和接单
|
|||||||
})
|
})
|
||||||
|
|
||||||
test('后台拼单聚合状态同时收敛筛选语义和操作能力', () => {
|
test('后台拼单聚合状态同时收敛筛选语义和操作能力', () => {
|
||||||
|
const waitingForClaim = mapWorkOrderAdmin(buildWorkOrderRow({ status: 'open' }))
|
||||||
|
assert.equal(waitingForClaim.status, 'open')
|
||||||
|
assert.equal(waitingForClaim.capabilities.canUpdateMaterial, true)
|
||||||
|
|
||||||
const partial = mapWorkOrderAdmin(
|
const partial = mapWorkOrderAdmin(
|
||||||
buildWorkOrderRow({
|
buildWorkOrderRow({
|
||||||
status: 'open',
|
status: 'open',
|
||||||
|
|||||||
@@ -1867,7 +1867,7 @@ export async function submitWorkerCancelRequest(
|
|||||||
await createWorkerCancelRequestAdminNotification({
|
await createWorkerCancelRequestAdminNotification({
|
||||||
requestId: Number(result.request.id),
|
requestId: Number(result.request.id),
|
||||||
workOrderId: Number(result.request.work_order_id),
|
workOrderId: Number(result.request.work_order_id),
|
||||||
workOrderNo: result.request.work_order_no || '',
|
platformOrderId: result.request.platform_order_id || '',
|
||||||
productName: result.request.product_name || '',
|
productName: result.request.product_name || '',
|
||||||
workerName: worker.display_name || worker.username,
|
workerName: worker.display_name || worker.username,
|
||||||
reason,
|
reason,
|
||||||
|
|||||||
@@ -82,12 +82,12 @@ export default function CancelRequestsPanel() {
|
|||||||
|
|
||||||
const columns: TableColumnsType<WorkerCancelRequest> = [
|
const columns: TableColumnsType<WorkerCancelRequest> = [
|
||||||
{
|
{
|
||||||
title: '订单',
|
title: '订单号 / 店铺',
|
||||||
width: 260,
|
width: 260,
|
||||||
render: (_, request) => (
|
render: (_, request) => (
|
||||||
<div className="cell-stack">
|
<div className="cell-stack">
|
||||||
<Typography.Text strong>{request.productName || '-'}</Typography.Text>
|
<Typography.Text strong>{request.platformOrderId || '-'}</Typography.Text>
|
||||||
<Typography.Text type="secondary">{request.workOrderNo || '-'}</Typography.Text>
|
<Typography.Text type="secondary">{request.shopName || '-'}</Typography.Text>
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ export default function FeedbacksPanel() {
|
|||||||
<div className="cell-stack">
|
<div className="cell-stack">
|
||||||
<Typography.Text strong>{feedback.productName || '-'}</Typography.Text>
|
<Typography.Text strong>{feedback.productName || '-'}</Typography.Text>
|
||||||
<Typography.Text type="secondary">{feedback.workOrderNo || '-'}</Typography.Text>
|
<Typography.Text type="secondary">{feedback.workOrderNo || '-'}</Typography.Text>
|
||||||
|
<Typography.Text type="secondary">{feedback.shopName || '-'}</Typography.Text>
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -919,7 +919,7 @@ export default function WorkOrdersPanel() {
|
|||||||
) : null}
|
) : null}
|
||||||
{row.capabilities?.canUpdateMaterial ? (
|
{row.capabilities?.canUpdateMaterial ? (
|
||||||
<Button icon={<FormOutlined />} onClick={() => openMaterialModal(row)}>
|
<Button icon={<FormOutlined />} onClick={() => openMaterialModal(row)}>
|
||||||
{row.status === 'in_progress' ? '更新资料' : '补资料'}
|
{['open', 'in_progress'].includes(row.status) ? '更新资料' : '补资料'}
|
||||||
</Button>
|
</Button>
|
||||||
) : null}
|
) : null}
|
||||||
{row.capabilities?.canPublish ? (
|
{row.capabilities?.canPublish ? (
|
||||||
@@ -1571,7 +1571,11 @@ export default function WorkOrdersPanel() {
|
|||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
<Modal
|
<Modal
|
||||||
title={materialOrder?.status === 'in_progress' ? '更新订单资料' : '人工补充资料'}
|
title={
|
||||||
|
['open', 'in_progress'].includes(materialOrder?.status || '')
|
||||||
|
? '更新订单资料'
|
||||||
|
: '人工补充资料'
|
||||||
|
}
|
||||||
open={Boolean(materialOrder)}
|
open={Boolean(materialOrder)}
|
||||||
onCancel={() => {
|
onCancel={() => {
|
||||||
setMaterialOrder(null)
|
setMaterialOrder(null)
|
||||||
|
|||||||
@@ -107,8 +107,8 @@ export type WorkerCancelRequest = {
|
|||||||
workOrderId: number
|
workOrderId: number
|
||||||
shareId: number | null
|
shareId: number | null
|
||||||
workerId: number
|
workerId: number
|
||||||
workOrderNo: string
|
platformOrderId: string
|
||||||
productName: string
|
shopName: string
|
||||||
workerName: string
|
workerName: string
|
||||||
shareQuantity: number | null
|
shareQuantity: number | null
|
||||||
reason: string
|
reason: string
|
||||||
@@ -134,6 +134,7 @@ export type WorkerOrderFeedback = {
|
|||||||
workerId: number
|
workerId: number
|
||||||
workOrderNo: string
|
workOrderNo: string
|
||||||
productName: string
|
productName: string
|
||||||
|
shopName: string
|
||||||
workerName: string
|
workerName: string
|
||||||
shareQuantity: number | null
|
shareQuantity: number | null
|
||||||
content: string
|
content: string
|
||||||
|
|||||||
Reference in New Issue
Block a user