接单工单支持置顶,抢单大厅优先展示

- 新增 work_orders.pinned_at 字段与迁移
- 管理端对已发布(待抢单)订单提供置顶/取消置顶操作,置顶订单带标记
- 抢单大厅按置顶时间优先排序,打手端卡片展示置顶标签
This commit is contained in:
yml2213
2026-08-16 15:57:25 +08:00
parent 737f9ddcbe
commit 8d07b06d52
12 changed files with 121 additions and 11 deletions
@@ -4,6 +4,7 @@ import {
EditOutlined,
FormOutlined,
PlusOutlined,
PushpinOutlined,
ReloadOutlined,
SearchOutlined,
SendOutlined,
@@ -63,6 +64,7 @@ import {
fetchAdminWorkerUsers,
fetchAdminWorkOrders,
markAdminWorkOrderProblem,
pinAdminWorkOrder,
publishAdminWorkOrder,
reviewAdminWorkerFinanceRequest,
resolveAdminProblemWorkOrder,
@@ -693,11 +695,16 @@ export default function WorkOrdersPanel() {
},
{
title: '状态',
width: 130,
width: 150,
render: (_, row) => (
<Tag color={resolveStatusColor(row.status)}>
{formatStatus(row.status)}
</Tag>
<Space wrap size={4}>
<Tag color={resolveStatusColor(row.status)}>
{formatStatus(row.status)}
</Tag>
{row.status === 'open' && row.pinnedAt ? (
<Tag color="gold" icon={<PushpinOutlined />}></Tag>
) : null}
</Space>
),
},
{
@@ -795,6 +802,20 @@ export default function WorkOrdersPanel() {
</Button>
) : null}
{row.status === 'open' ? (
<Button
icon={<PushpinOutlined />}
title={row.pinnedAt ? '取消置顶' : '置顶后抢单大厅优先展示'}
onClick={() =>
runAction(
() => pinAdminWorkOrder(row.workOrderId, !row.pinnedAt),
row.pinnedAt ? '已取消置顶' : '已置顶,抢单大厅优先展示',
)
}
>
{row.pinnedAt ? '取消置顶' : '置顶'}
</Button>
) : null}
{row.status === 'open' ? (
<Button
danger
@@ -1,4 +1,4 @@
import { ClockCircleOutlined, ReloadOutlined, SearchOutlined, TrophyOutlined } from '@ant-design/icons'
import { ClockCircleOutlined, PushpinOutlined, ReloadOutlined, SearchOutlined, TrophyOutlined } from '@ant-design/icons'
import { useQuery, useQueryClient } from '@tanstack/react-query'
import {
Alert,
@@ -367,6 +367,11 @@ export default function WorkerHallPage() {
{/* 卡片头部: 分类 + 拼单/时限标签 + 订单号 */}
<div className="worker-hall-mobile-card-top">
<div className="worker-hall-mobile-card-tags">
{order.pinnedAt ? (
<Tag color="gold" icon={<PushpinOutlined />} className="worker-hall-mobile-tag">
</Tag>
) : null}
{order.categoryName ? (
<Tag color="blue" className="worker-hall-mobile-tag">
{order.categoryName}
@@ -610,6 +615,11 @@ export default function WorkerHallPage() {
return (
<article key={order.workOrderId} className="worker-hall-card">
<div className="worker-hall-card-title">
{order.pinnedAt ? (
<Tag color="gold" icon={<PushpinOutlined />} className="worker-hall-pinned-tag">
</Tag>
) : null}
<strong
className="worker-hall-card-title-text"
title={order.productName || '未命名商品'}
@@ -283,6 +283,13 @@ export function unpublishAdminWorkOrder(workOrderId: number) {
)
}
export function pinAdminWorkOrder(workOrderId: number, pinned: boolean) {
return apiPost<{ order: WorkOrder }>(
`/api/v1/admin/worker-platform/orders/${workOrderId}/pin`,
{ pinned },
)
}
export function fetchAdminWorkOrderSharing(workOrderId: number) {
return apiGet<{ order: WorkOrder; shares: WorkOrderShare[] }>(
`/api/v1/admin/worker-platform/orders/${workOrderId}/sharing`,
+5
View File
@@ -580,6 +580,11 @@
min-width: 0;
}
.worker-hall-pinned-tag {
width: fit-content;
margin: 0 0 2px;
}
.worker-hall-card-title .ant-typography {
margin: 0;
font-size: 12px;
@@ -260,6 +260,8 @@ export type WorkOrder = {
displayName: string
}
publishedAt: string | null
/** 置顶时间;非空表示该工单在抢单大厅置顶展示 */
pinnedAt?: string | null
assignedAt: string | null
submittedAt: string | null
acceptedAt: string | null