接单工单支持编辑与删除,修复编辑押金不生效问题
This commit is contained in:
@@ -661,6 +661,67 @@ export async function updateWorkOrder(
|
|||||||
return getWorkOrderById(workOrderId)
|
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: {
|
export async function grabWorkOrder(input: {
|
||||||
workOrderId: number
|
workOrderId: number
|
||||||
workerId: number
|
workerId: number
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {
|
|||||||
creditAdminWorkerWallet,
|
creditAdminWorkerWallet,
|
||||||
createAdminMockWorkOrder,
|
createAdminMockWorkOrder,
|
||||||
deleteAdminWorkCategory,
|
deleteAdminWorkCategory,
|
||||||
|
deleteAdminWorkOrder,
|
||||||
deleteAdminWorkerLevel,
|
deleteAdminWorkerLevel,
|
||||||
getAdminWorkerFinanceConfig,
|
getAdminWorkerFinanceConfig,
|
||||||
getAdminWorkerPlatformSummary,
|
getAdminWorkerPlatformSummary,
|
||||||
@@ -27,6 +28,7 @@ import {
|
|||||||
submitAdminWorkOrderMaterial,
|
submitAdminWorkOrderMaterial,
|
||||||
syncAdminWorkerOrdersFromSource,
|
syncAdminWorkerOrdersFromSource,
|
||||||
unpublishAdminWorkOrder,
|
unpublishAdminWorkOrder,
|
||||||
|
updateAdminWorkOrder,
|
||||||
updateAdminWorkOrderSharing,
|
updateAdminWorkOrderSharing,
|
||||||
} from '../../services/worker-platform/index.js'
|
} from '../../services/worker-platform/index.js'
|
||||||
import { createJsonHandler, requireAdminRoles } from './session.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(
|
router.post(
|
||||||
'/worker-platform/orders/:workOrderId/publish',
|
'/worker-platform/orders/:workOrderId/publish',
|
||||||
requireAdminRoles(['admin', 'operator']),
|
requireAdminRoles(['admin', 'operator']),
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import {
|
|||||||
createWorkerFinanceRequest,
|
createWorkerFinanceRequest,
|
||||||
createWorkerUser,
|
createWorkerUser,
|
||||||
deleteWorkCategory,
|
deleteWorkCategory,
|
||||||
|
deleteWorkOrder,
|
||||||
deleteWorkerLevel,
|
deleteWorkerLevel,
|
||||||
getWorkerFinanceRequestById,
|
getWorkerFinanceRequestById,
|
||||||
getWorkerFinanceRequestSummary,
|
getWorkerFinanceRequestSummary,
|
||||||
@@ -51,6 +52,7 @@ import {
|
|||||||
reviewWorkerFinanceRequest,
|
reviewWorkerFinanceRequest,
|
||||||
submitWorkOrderShareAcceptance,
|
submitWorkOrderShareAcceptance,
|
||||||
updateWorkOrder,
|
updateWorkOrder,
|
||||||
|
updateWorkOrderBasic,
|
||||||
updateWorkerPassword,
|
updateWorkerPassword,
|
||||||
updateWorkerUser,
|
updateWorkerUser,
|
||||||
upsertWorkCategory,
|
upsertWorkCategory,
|
||||||
@@ -667,6 +669,117 @@ export async function createAdminMockWorkOrder(payload: JsonObject = {}) {
|
|||||||
return { order: mapWorkOrderAdmin(workOrder) }
|
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) {
|
export async function publishAdminWorkOrder(workOrderId: number | string) {
|
||||||
const workOrder = await getRequiredWorkOrder(workOrderId)
|
const workOrder = await getRequiredWorkOrder(workOrderId)
|
||||||
if (workOrder.status !== WORK_ORDER_STATUS.UNASSIGNED) {
|
if (workOrder.status !== WORK_ORDER_STATUS.UNASSIGNED) {
|
||||||
|
|||||||
@@ -345,6 +345,7 @@ export function mapWorkOrderAdmin(workOrder: WorkOrderRow) {
|
|||||||
workOrderNo: workOrder.work_order_no,
|
workOrderNo: workOrder.work_order_no,
|
||||||
platformOrderId: workOrder.platform_order_id,
|
platformOrderId: workOrder.platform_order_id,
|
||||||
productName: workOrder.product_name,
|
productName: workOrder.product_name,
|
||||||
|
categoryId: workOrder.category_id ? Number(workOrder.category_id) : null,
|
||||||
categoryName: workOrder.category_name || '',
|
categoryName: workOrder.category_name || '',
|
||||||
status: workOrder.status,
|
status: workOrder.status,
|
||||||
rewardAmount: Number(workOrder.reward_amount || 0),
|
rewardAmount: Number(workOrder.reward_amount || 0),
|
||||||
|
|||||||
@@ -187,6 +187,14 @@ export function apiPost<T>(url: string, data?: unknown) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function apiPut<T>(url: string, data?: unknown) {
|
||||||
|
return request<T>({
|
||||||
|
method: 'PUT',
|
||||||
|
url,
|
||||||
|
data: data as Record<string, unknown>,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export function apiPostForm<T>(url: string, data: FormData) {
|
export function apiPostForm<T>(url: string, data: FormData) {
|
||||||
return request<T>({
|
return request<T>({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
CheckOutlined,
|
CheckOutlined,
|
||||||
|
DeleteOutlined,
|
||||||
|
EditOutlined,
|
||||||
FormOutlined,
|
FormOutlined,
|
||||||
PlusOutlined,
|
PlusOutlined,
|
||||||
ReloadOutlined,
|
ReloadOutlined,
|
||||||
@@ -41,6 +43,7 @@ import {
|
|||||||
createAdminMockWorkOrder,
|
createAdminMockWorkOrder,
|
||||||
creditAdminWorkerWallet,
|
creditAdminWorkerWallet,
|
||||||
deleteAdminWorkCategory,
|
deleteAdminWorkCategory,
|
||||||
|
deleteAdminWorkOrder,
|
||||||
deleteAdminWorkerLevel,
|
deleteAdminWorkerLevel,
|
||||||
fetchAdminWorkerFinanceConfig,
|
fetchAdminWorkerFinanceConfig,
|
||||||
fetchAdminWorkerFinanceRequests,
|
fetchAdminWorkerFinanceRequests,
|
||||||
@@ -63,6 +66,7 @@ import {
|
|||||||
submitAdminWorkOrderMaterial,
|
submitAdminWorkOrderMaterial,
|
||||||
syncAdminWorkerOrdersFromSource,
|
syncAdminWorkerOrdersFromSource,
|
||||||
unpublishAdminWorkOrder,
|
unpublishAdminWorkOrder,
|
||||||
|
updateAdminWorkOrder,
|
||||||
updateAdminWorkOrderSharing,
|
updateAdminWorkOrderSharing,
|
||||||
} from '@/services/admin'
|
} from '@/services/admin'
|
||||||
import type {
|
import type {
|
||||||
@@ -114,9 +118,18 @@ export default function WorkOrdersPanel() {
|
|||||||
const [materialOrder, setMaterialOrder] = useState<WorkOrder | null>(null)
|
const [materialOrder, setMaterialOrder] = useState<WorkOrder | null>(null)
|
||||||
const [materialScreenshots, setMaterialScreenshots] = useState<UploadedFile[]>([])
|
const [materialScreenshots, setMaterialScreenshots] = useState<UploadedFile[]>([])
|
||||||
const [sharingOrder, setSharingOrder] = useState<WorkOrder | null>(null)
|
const [sharingOrder, setSharingOrder] = useState<WorkOrder | null>(null)
|
||||||
|
const [editOrder, setEditOrder] = useState<WorkOrder | null>(null)
|
||||||
const [problemForm] = Form.useForm()
|
const [problemForm] = Form.useForm()
|
||||||
const [resolutionForm] = Form.useForm()
|
const [resolutionForm] = Form.useForm()
|
||||||
const [materialForm] = Form.useForm()
|
const [materialForm] = Form.useForm()
|
||||||
|
const [editForm] = Form.useForm<{
|
||||||
|
productName?: string
|
||||||
|
platformOrderId?: string
|
||||||
|
categoryId?: number | null
|
||||||
|
rewardAmount?: number
|
||||||
|
requiredDepositAmount?: number
|
||||||
|
fieldsText?: string
|
||||||
|
}>()
|
||||||
const [sharingForm] = Form.useForm<{
|
const [sharingForm] = Form.useForm<{
|
||||||
enabled?: boolean
|
enabled?: boolean
|
||||||
totalQuantity?: number
|
totalQuantity?: number
|
||||||
@@ -129,6 +142,10 @@ export default function WorkOrdersPanel() {
|
|||||||
queryFn: () => fetchAdminWorkOrders({ status, page, pageSize }),
|
queryFn: () => fetchAdminWorkOrders({ status, page, pageSize }),
|
||||||
})
|
})
|
||||||
const ordersPagination = ordersQuery.data?.data.pagination
|
const ordersPagination = ordersQuery.data?.data.pagination
|
||||||
|
const categoriesQuery = useQuery({
|
||||||
|
queryKey: ['admin-worker-platform-categories'],
|
||||||
|
queryFn: () => fetchAdminWorkCategories(),
|
||||||
|
})
|
||||||
const sharingQuery = useQuery({
|
const sharingQuery = useQuery({
|
||||||
queryKey: ['admin-worker-platform-order-sharing', sharingOrder?.workOrderId],
|
queryKey: ['admin-worker-platform-order-sharing', sharingOrder?.workOrderId],
|
||||||
queryFn: () => fetchAdminWorkOrderSharing(Number(sharingOrder?.workOrderId)),
|
queryFn: () => fetchAdminWorkOrderSharing(Number(sharingOrder?.workOrderId)),
|
||||||
@@ -293,6 +310,61 @@ export default function WorkOrdersPanel() {
|
|||||||
setDetailOrder(row)
|
setDetailOrder(row)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function openEditModal(row: WorkOrder) {
|
||||||
|
setEditOrder(row)
|
||||||
|
editForm.setFieldsValue({
|
||||||
|
productName: row.productName,
|
||||||
|
platformOrderId: row.platformOrderId || '',
|
||||||
|
categoryId: row.categoryId ?? undefined,
|
||||||
|
rewardAmount: Math.round(Number(row.rewardAmount || 0)) / 100,
|
||||||
|
requiredDepositAmount:
|
||||||
|
Math.round(Number(row.requiredDepositAmount || 0)) / 100,
|
||||||
|
fieldsText: formatRequirementFieldsText(getRequirementFields(row)),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async function submitEdit(values: {
|
||||||
|
productName?: string
|
||||||
|
platformOrderId?: string
|
||||||
|
categoryId?: number | null
|
||||||
|
rewardAmount?: number
|
||||||
|
requiredDepositAmount?: number
|
||||||
|
fieldsText?: string
|
||||||
|
}) {
|
||||||
|
if (!editOrder) return
|
||||||
|
const succeeded = await runAction(
|
||||||
|
() =>
|
||||||
|
updateAdminWorkOrder(editOrder.workOrderId, {
|
||||||
|
productName: String(values.productName || '').trim(),
|
||||||
|
platformOrderId: String(values.platformOrderId || '').trim(),
|
||||||
|
categoryId: values.categoryId || null,
|
||||||
|
rewardAmount: Number(values.rewardAmount || 0),
|
||||||
|
requiredDepositAmount: Number(values.requiredDepositAmount || 0),
|
||||||
|
fieldsText: String(values.fieldsText || ''),
|
||||||
|
}),
|
||||||
|
'工单信息已保存',
|
||||||
|
)
|
||||||
|
if (!succeeded) return
|
||||||
|
setEditOrder(null)
|
||||||
|
editForm.resetFields()
|
||||||
|
}
|
||||||
|
|
||||||
|
function requestDeleteWorkOrder(row: WorkOrder) {
|
||||||
|
modal.confirm({
|
||||||
|
title: `确认删除工单 ${row.workOrderNo}?`,
|
||||||
|
content:
|
||||||
|
'删除后工单将从列表中移除,且不可恢复。仅未分配、待完善或已取消且无拼单参与的工单可删除。',
|
||||||
|
okText: '确认删除',
|
||||||
|
okButtonProps: { danger: true },
|
||||||
|
cancelText: '取消',
|
||||||
|
onOk: () =>
|
||||||
|
runAction(
|
||||||
|
() => deleteAdminWorkOrder(row.workOrderId),
|
||||||
|
'工单已删除',
|
||||||
|
),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const columns: TableColumnsType<WorkOrder> = [
|
const columns: TableColumnsType<WorkOrder> = [
|
||||||
{
|
{
|
||||||
title: '订单',
|
title: '订单',
|
||||||
@@ -383,6 +455,23 @@ export default function WorkOrdersPanel() {
|
|||||||
render: (_, row) => (
|
render: (_, row) => (
|
||||||
<Space wrap>
|
<Space wrap>
|
||||||
<Button onClick={() => openDetailDrawer(row)}>详情</Button>
|
<Button onClick={() => openDetailDrawer(row)}>详情</Button>
|
||||||
|
{['pending_material', 'unassigned', 'open'].includes(row.status) ? (
|
||||||
|
<Button
|
||||||
|
icon={<EditOutlined />}
|
||||||
|
onClick={() => openEditModal(row)}
|
||||||
|
>
|
||||||
|
编辑
|
||||||
|
</Button>
|
||||||
|
) : null}
|
||||||
|
{['pending_material', 'unassigned', 'cancelled'].includes(row.status) ? (
|
||||||
|
<Button
|
||||||
|
danger
|
||||||
|
icon={<DeleteOutlined />}
|
||||||
|
onClick={() => requestDeleteWorkOrder(row)}
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</Button>
|
||||||
|
) : null}
|
||||||
{['pending_material', 'unassigned', 'open'].includes(row.status) ? (
|
{['pending_material', 'unassigned', 'open'].includes(row.status) ? (
|
||||||
<Button
|
<Button
|
||||||
icon={<TeamOutlined />}
|
icon={<TeamOutlined />}
|
||||||
@@ -710,6 +799,68 @@ export default function WorkOrdersPanel() {
|
|||||||
) : null}
|
) : null}
|
||||||
</Drawer>
|
</Drawer>
|
||||||
|
|
||||||
|
<Modal
|
||||||
|
title={`编辑工单 · ${editOrder?.workOrderNo || ''}`}
|
||||||
|
open={Boolean(editOrder)}
|
||||||
|
onCancel={() => {
|
||||||
|
setEditOrder(null)
|
||||||
|
editForm.resetFields()
|
||||||
|
}}
|
||||||
|
onOk={() => editForm.submit()}
|
||||||
|
destroyOnHidden
|
||||||
|
width={720}
|
||||||
|
>
|
||||||
|
{editOrder ? (
|
||||||
|
<Form form={editForm} layout="vertical" onFinish={submitEdit}>
|
||||||
|
<Form.Item
|
||||||
|
label="商品"
|
||||||
|
name="productName"
|
||||||
|
rules={[{ required: true, message: '请填写商品名称' }]}
|
||||||
|
>
|
||||||
|
<Input />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="平台订单号" name="platformOrderId">
|
||||||
|
<Input placeholder="留空表示无平台订单号" />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="分类" name="categoryId">
|
||||||
|
<Select
|
||||||
|
allowClear
|
||||||
|
placeholder="选择接单分类"
|
||||||
|
options={(categoriesQuery.data?.data.items || [])
|
||||||
|
.filter((category) => category.status === 'active')
|
||||||
|
.map((category) => ({
|
||||||
|
label: category.name,
|
||||||
|
value: category.categoryId,
|
||||||
|
}))}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label="接单金额"
|
||||||
|
name="rewardAmount"
|
||||||
|
rules={[{ required: true, message: '请填写接单金额' }]}
|
||||||
|
tooltip="打手看到的接单报酬"
|
||||||
|
>
|
||||||
|
<InputNumber min={0.01} step={1} addonAfter="元" />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label="冻结押金"
|
||||||
|
name="requiredDepositAmount"
|
||||||
|
rules={[{ required: true, message: '请填写冻结押金' }]}
|
||||||
|
tooltip="抢单时需要冻结的押金,0 表示无需押金"
|
||||||
|
>
|
||||||
|
<InputNumber min={0} step={1} addonAfter="元" />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label="资料字段"
|
||||||
|
name="fieldsText"
|
||||||
|
extra="每行一个字段:key:名称,下拉项用 # 分隔(如 system:系统#安卓,苹果)"
|
||||||
|
>
|
||||||
|
<Input.TextArea rows={5} />
|
||||||
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
|
) : null}
|
||||||
|
</Modal>
|
||||||
|
|
||||||
<Modal
|
<Modal
|
||||||
title="标记问题单"
|
title="标记问题单"
|
||||||
open={Boolean(problemOrder)}
|
open={Boolean(problemOrder)}
|
||||||
@@ -952,6 +1103,18 @@ export default function WorkOrdersPanel() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function formatRequirementFieldsText(fields: CollectField[]): string {
|
||||||
|
return fields
|
||||||
|
.map((field) => {
|
||||||
|
const labelPart = `${field.key}:${field.label}`
|
||||||
|
const options = (field.options || []).filter(Boolean)
|
||||||
|
return options.length > 0
|
||||||
|
? `${labelPart}#${options.join(',')}`
|
||||||
|
: labelPart
|
||||||
|
})
|
||||||
|
.join('\n')
|
||||||
|
}
|
||||||
|
|
||||||
function MockWorkOrderForm({ onCreated }: { onCreated: () => Promise<void> }) {
|
function MockWorkOrderForm({ onCreated }: { onCreated: () => Promise<void> }) {
|
||||||
const { message } = App.useApp()
|
const { message } = App.useApp()
|
||||||
const [loading, setLoading] = useState(false)
|
const [loading, setLoading] = useState(false)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { apiDelete, apiGet, apiPost } from '@/lib/http'
|
import { apiDelete, apiGet, apiPost, apiPut } from '@/lib/http'
|
||||||
import type {
|
import type {
|
||||||
UploadedFile,
|
UploadedFile,
|
||||||
WorkCategory,
|
WorkCategory,
|
||||||
@@ -219,6 +219,29 @@ export function publishAdminWorkOrder(workOrderId: number) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function updateAdminWorkOrder(
|
||||||
|
workOrderId: number,
|
||||||
|
payload: {
|
||||||
|
productName?: string
|
||||||
|
platformOrderId?: string
|
||||||
|
categoryId?: number | null
|
||||||
|
rewardAmount?: number
|
||||||
|
requiredDepositAmount?: number
|
||||||
|
fieldsText?: string
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
return apiPut<{ order: WorkOrder }>(
|
||||||
|
`/api/v1/admin/worker-platform/orders/${workOrderId}`,
|
||||||
|
payload,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function deleteAdminWorkOrder(workOrderId: number) {
|
||||||
|
return apiDelete<{ deleted: boolean }>(
|
||||||
|
`/api/v1/admin/worker-platform/orders/${workOrderId}`,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
export function unpublishAdminWorkOrder(workOrderId: number) {
|
export function unpublishAdminWorkOrder(workOrderId: number) {
|
||||||
return apiPost<{ order: WorkOrder }>(
|
return apiPost<{ order: WorkOrder }>(
|
||||||
`/api/v1/admin/worker-platform/orders/${workOrderId}/unpublish`,
|
`/api/v1/admin/worker-platform/orders/${workOrderId}/unpublish`,
|
||||||
|
|||||||
@@ -208,6 +208,7 @@ export type WorkOrder = {
|
|||||||
workOrderNo: string
|
workOrderNo: string
|
||||||
platformOrderId: string
|
platformOrderId: string
|
||||||
productName: string
|
productName: string
|
||||||
|
categoryId?: number | null
|
||||||
categoryName: string
|
categoryName: string
|
||||||
status: WorkOrderStatus
|
status: WorkOrderStatus
|
||||||
rewardAmount: number
|
rewardAmount: number
|
||||||
|
|||||||
Reference in New Issue
Block a user