增加接单分类和大厅分类配额

This commit is contained in:
yml2213
2026-08-23 17:37:32 +08:00
parent 844f071aab
commit 1cebdd0487
18 changed files with 297 additions and 61 deletions
@@ -1,11 +1,17 @@
import { useQuery, useQueryClient } from '@tanstack/react-query'
import { App, Button, Card, Descriptions, Form, InputNumber, Space } from 'antd'
import { App, Button, Card, Descriptions, Form, InputNumber, Space, Table, Tag } from 'antd'
import { useEffect, useState } from 'react'
import { fetchAdminWorkerHallConfig, saveAdminWorkerHallConfig } from '@/services/admin'
import {
fetchAdminWorkCategories,
fetchAdminWorkerHallConfig,
saveAdminWorkerHallConfig,
} from '@/services/admin'
import type { WorkCategory } from '@/types/worker-platform'
type HallConfigFormValues = {
maxVisibleOrders: number
categoryMaxVisibleOrders: Record<string, number>
}
export default function HallConfigPanel() {
@@ -20,13 +26,25 @@ export default function HallConfigPanel() {
const config = configQuery.data?.data
useEffect(() => {
if (config) form.setFieldsValue({ maxVisibleOrders: config.maxVisibleOrders })
if (config) {
form.setFieldsValue({
maxVisibleOrders: config.maxVisibleOrders,
categoryMaxVisibleOrders: config.categoryMaxVisibleOrders || {},
})
}
}, [config, form])
const categoriesQuery = useQuery({
queryKey: ['admin-worker-platform-categories'],
queryFn: fetchAdminWorkCategories,
})
async function saveConfig(values: HallConfigFormValues) {
setSaving(true)
try {
await saveAdminWorkerHallConfig({ maxVisibleOrders: Number(values.maxVisibleOrders) })
await saveAdminWorkerHallConfig({
maxVisibleOrders: Number(values.maxVisibleOrders),
categoryMaxVisibleOrders: values.categoryMaxVisibleOrders || {},
})
await Promise.all([
queryClient.invalidateQueries({ queryKey: ['admin-worker-hall-config'] }),
queryClient.invalidateQueries({ queryKey: ['admin-worker-platform-summary'] }),
@@ -47,7 +65,7 @@ export default function HallConfigPanel() {
<Descriptions.Item label="等待入厅">{config?.queuedOrderCount || 0}</Descriptions.Item>
<Descriptions.Item label="当前上限">{config?.maxVisibleOrders || '-'}</Descriptions.Item>
</Descriptions>
<Form form={form} layout="inline" onFinish={saveConfig}>
<Form form={form} layout="vertical" onFinish={saveConfig}>
<Form.Item
name="maxVisibleOrders"
label="大厅订单总数"
@@ -60,6 +78,41 @@ export default function HallConfigPanel() {
</Button>
</Form.Item>
<div>
<Tag color="blue"></Tag>
<span style={{ marginLeft: 8, color: '#666' }}>
沿
</span>
</div>
<Table<WorkCategory>
rowKey="categoryId"
size="small"
pagination={false}
loading={categoriesQuery.isLoading}
dataSource={categoriesQuery.data?.data.items || []}
columns={[
{ title: '分类', dataIndex: 'name' },
{
title: '状态',
render: (_, category) => (
<Tag color={category.status === 'active' ? 'green' : 'default'}>
{category.status === 'active' ? '启用' : '停用'}
</Tag>
),
},
{
title: '最多展示',
render: (_, category) => (
<Form.Item
name={['categoryMaxVisibleOrders', String(category.categoryId)]}
style={{ margin: 0 }}
>
<InputNumber min={1} max={500} precision={0} placeholder="跟随总上限" />
</Form.Item>
),
},
]}
/>
</Form>
</Space>
</Card>
@@ -1,9 +1,13 @@
import { PlusOutlined } from '@ant-design/icons'
import { useQuery, useQueryClient } from '@tanstack/react-query'
import { App, AutoComplete, Button, Card, Form, Input, InputNumber, Select, Switch } from 'antd'
import { useState } from 'react'
import { useEffect, useState } from 'react'
import { createAdminMockWorkOrder, fetchAdminMockCustomShops } from '@/services/admin'
import {
createAdminMockWorkOrder,
fetchAdminMockCustomShops,
fetchAdminWorkCategories,
} from '@/services/admin'
import { fetchAdminKuaishouIndustryShops } from '@/services/admin/kuaishou-industry'
import type { WorkOrderStatistics } from '@/types/worker-platform'
import { buildMockWorkOrderShopOptions } from '@/utils/mock-work-order'
@@ -69,6 +73,19 @@ export function MockWorkOrderForm({ onCreated }: { onCreated: () => Promise<void
queryKey: ['admin-mock-custom-shops'],
queryFn: fetchAdminMockCustomShops,
})
const categoriesQuery = useQuery({
queryKey: ['admin-worker-platform-categories'],
queryFn: fetchAdminWorkCategories,
})
const activeCategories = (categoriesQuery.data?.data.items || []).filter(
(category) => category.status === 'active',
)
const defaultCategoryId = activeCategories[0]?.categoryId
useEffect(() => {
if (!form.getFieldValue('categoryId') && defaultCategoryId) {
form.setFieldValue('categoryId', defaultCategoryId)
}
}, [defaultCategoryId, form])
const shopOptions = [
...buildMockWorkOrderShopOptions(shopsQuery.data?.data.shops || []),
...(customShopsQuery.data?.data.items || []).map((name) => ({
@@ -81,6 +98,7 @@ export function MockWorkOrderForm({ onCreated }: { onCreated: () => Promise<void
platformOrderId: string
sellerId: string
productName: string
categoryId?: number
rewardAmount: number
paymentAmount: number
materialComplete?: boolean
@@ -91,9 +109,11 @@ export function MockWorkOrderForm({ onCreated }: { onCreated: () => Promise<void
await createAdminMockWorkOrder({
...values,
acceptanceMode: values.acceptanceMode || 'standard',
categoryId: values.categoryId,
})
message.success('Mock 工单已生成')
form.resetFields()
if (defaultCategoryId) form.setFieldValue('categoryId', defaultCategoryId)
// 自定义店铺由后端记忆,刷新后即可在下拉中选到。
await queryClient.invalidateQueries({ queryKey: ['admin-mock-custom-shops'] })
await onCreated()
@@ -114,6 +134,22 @@ export function MockWorkOrderForm({ onCreated }: { onCreated: () => Promise<void
>
<Input placeholder="请输入订单号" />
</Form.Item>
<Form.Item
className="worker-order-mock-field-category"
label="分类"
name="categoryId"
rules={[{ required: true, message: '请选择接单分类' }]}
>
<Select
allowClear
loading={categoriesQuery.isLoading}
options={activeCategories.map((category) => ({
value: category.categoryId,
label: category.name,
}))}
placeholder="选择接单分类"
/>
</Form.Item>
<Form.Item
className="worker-order-mock-field-shop"
label="店铺"
@@ -203,6 +203,7 @@ export default function WorkOrdersPanel() {
const [createdRange, setCreatedRange] = useState<[string, string] | null>(null)
const [keywordInput, setKeywordInput] = useState('')
const [workerId, setWorkerId] = useState<number | undefined>()
const [categoryId, setCategoryId] = useState<number | undefined>()
const [workerLevelIds, setWorkerLevelIds] = useState<number[]>([])
const [acceptanceMode, setAcceptanceMode] = useState<string | undefined>()
const [giftPhase, setGiftPhase] = useState<string | undefined>()
@@ -279,6 +280,7 @@ export default function WorkOrdersPanel() {
statuses.join(','),
keyword,
workerId,
categoryId,
workerLevelIds.join(','),
targetWorkOrderId,
acceptanceMode || '',
@@ -296,6 +298,7 @@ export default function WorkOrdersPanel() {
acceptanceMode: acceptanceMode || undefined,
giftPhase: giftPhase || undefined,
workOrderId: targetWorkOrderId,
categoryId,
keyword,
workerId,
workerLevelIds:
@@ -346,6 +349,7 @@ export default function WorkOrdersPanel() {
statuses,
keyword,
workerId,
categoryId,
workerLevelIds,
targetWorkOrderId,
acceptanceMode,
@@ -671,6 +675,7 @@ export default function WorkOrdersPanel() {
setKeyword('')
setStatuses([])
setWorkerId(undefined)
setCategoryId(undefined)
setWorkerLevelIds([])
setAcceptanceMode(undefined)
setGiftPhase(undefined)
@@ -1240,6 +1245,23 @@ export default function WorkOrdersPanel() {
setPage(1)
}}
/>
<Select
allowClear
showSearch
optionFilterProp="label"
value={categoryId}
placeholder="全部接单分类"
style={{ width: 180 }}
loading={categoriesQuery.isLoading}
options={(categoriesQuery.data?.data.items || []).map((category) => ({
value: category.categoryId,
label: category.name,
}))}
onChange={(nextCategoryId) => {
setCategoryId(nextCategoryId)
setPage(1)
}}
/>
{showWorkerLevelFilter ? (
<Select
mode="multiple"
@@ -85,7 +85,9 @@ export function fetchAdminWorkerHallConfig() {
return apiGet<WorkerHallConfig>('/api/v1/admin/worker-platform/hall-config')
}
export function saveAdminWorkerHallConfig(payload: Pick<WorkerHallConfig, 'maxVisibleOrders'>) {
export function saveAdminWorkerHallConfig(
payload: Pick<WorkerHallConfig, 'maxVisibleOrders' | 'categoryMaxVisibleOrders'>,
) {
return apiPost<WorkerHallConfig>('/api/v1/admin/worker-platform/hall-config', payload)
}
@@ -574,6 +576,7 @@ export function createAdminMockWorkOrder(payload: {
platformOrderId: string
sellerId: string
productName: string
categoryId?: number
rewardAmount: number
paymentAmount: number
materialComplete?: boolean
+6 -1
View File
@@ -281,6 +281,7 @@ export type WorkerAnnouncementConfig = {
export type WorkerHallConfig = {
maxVisibleOrders: number
categoryMaxVisibleOrders: Record<string, number>
visibleOrderCount: number
queuedOrderCount: number
}
@@ -494,7 +495,11 @@ export type WorkOrderShare = {
}
export type WorkOrderGiftPhase =
'material_required' | 'material_submitted' | 'friend_countdown' | 'gift_ready' | string
| 'material_required'
| 'material_submitted'
| 'friend_countdown'
| 'gift_ready'
| string
/** 好友赠送验收模式的打手本人资料 */
export type BoosterMaterial = {