优化模板匹配展示并修复映射迁移

This commit is contained in:
yml2213
2026-08-18 15:04:42 +08:00
parent 7ccf3a6cee
commit cf874b5429
4 changed files with 150 additions and 40 deletions
@@ -29,11 +29,12 @@ import { useState } from 'react'
import {
deleteAdminWorkProductRule,
fetchAdminWorkCategories,
fetchAdminWorkProductRuleMappings,
fetchAdminWorkProductRules,
reprocessAdminKuaishouWorkOrderMatches,
saveAdminWorkProductRule,
} from '@/services/admin'
import type { CollectField, WorkProductRule } from '@/types/worker-platform'
import type { CollectField, WorkProductRule, WorkProductRuleMapping } from '@/types/worker-platform'
import { ADMIN_DEFAULT_PAGE_SIZE, buildAdminTablePagination } from '@/utils/admin-pagination'
import { formatMoney } from './shared'
@@ -59,12 +60,23 @@ export default function ProductRulesPanel() {
pageSize,
}),
})
const mappingsQuery = useQuery({
queryKey: ['admin-worker-platform-product-mappings'],
queryFn: () => fetchAdminWorkProductRuleMappings(),
})
const categoriesQuery = useQuery({
queryKey: ['admin-worker-platform-categories'],
queryFn: () => fetchAdminWorkCategories(),
})
const rules = rulesQuery.data?.data.items || []
const mappings = mappingsQuery.data?.data.items || []
const mappingsByRuleId = new Map<number, WorkProductRuleMapping[]>()
for (const mapping of mappings) {
const ruleMappings = mappingsByRuleId.get(mapping.ruleId) || []
ruleMappings.push(mapping)
mappingsByRuleId.set(mapping.ruleId, ruleMappings)
}
const rulesPagination = rulesQuery.data?.data.pagination
const categoryCounts = new Map(
(rulesQuery.data?.data.categoryCounts || []).map((item) => [
@@ -240,6 +252,9 @@ export default function ProductRulesPanel() {
await queryClient.invalidateQueries({
queryKey: ['admin-worker-platform-product-rules'],
})
await queryClient.invalidateQueries({
queryKey: ['admin-worker-platform-product-mappings'],
})
} catch (error) {
message.error(error instanceof Error ? error.message : '删除失败')
}
@@ -288,7 +303,7 @@ export default function ProductRulesPanel() {
{
title: '模板 / 商品',
key: 'rule',
width: '29%',
width: '34%',
render: (_, row) => (
<div className="cell-stack">
<Typography.Text strong title={row.productName || row.ruleKey}>
@@ -307,40 +322,10 @@ export default function ProductRulesPanel() {
</div>
),
},
{
title: '平台 / 店铺',
key: 'platformShop',
width: '13%',
render: (_, row) => {
const shopId = String(row.shopId || '')
return (
<div className="cell-stack">
<Typography.Text style={{ fontSize: 12 }}>{row.platform || 'kuaishou'}</Typography.Text>
{shopId ? (
<Tag color="geekblue" style={{ margin: 0, fontSize: 11, lineHeight: '18px' }}>
{shopId}
</Tag>
) : (
<Tag style={{ margin: 0, fontSize: 11, lineHeight: '18px' }}></Tag>
)}
</div>
)
},
},
{
title: 'SKU',
dataIndex: 'skuCode',
width: '11%',
render: (value) => (
<Typography.Text code style={{ fontSize: 12 }}>
{String(value || '-')}
</Typography.Text>
),
},
{
title: '分类',
dataIndex: 'categoryName',
width: '11%',
width: '12%',
render: (value) =>
value ? (
<Tag color="cyan" style={{ margin: 0 }}>
@@ -350,10 +335,37 @@ export default function ProductRulesPanel() {
<Typography.Text type="secondary">-</Typography.Text>
),
},
{
title: '已匹配商品',
key: 'productMappings',
width: '18%',
render: (_, row) => {
const ruleMappings = mappingsByRuleId.get(row.ruleId) || []
const enabledCount = ruleMappings.filter((mapping) => mapping.enabled).length
const disabledCount = ruleMappings.length - enabledCount
return ruleMappings.length > 0 ? (
<div className="cell-stack">
<Tag
color={enabledCount > 0 ? 'green' : 'default'}
style={{ margin: 0, width: 'fit-content' }}
>
{enabledCount > 0 ? `已匹配 ${enabledCount}` : '映射已停用'}
</Tag>
{disabledCount > 0 ? (
<Typography.Text type="secondary" style={{ fontSize: 11 }}>
{disabledCount}
</Typography.Text>
) : null}
</div>
) : (
<Tag style={{ margin: 0, color: '#8c8c8c' }}></Tag>
)
},
},
{
title: '接单金额',
key: 'reward',
width: '13%',
width: '14%',
render: (_, row) => (
<div className="cell-stack">
<Typography.Text strong style={{ color: '#3f8600', fontSize: 13 }}>
@@ -370,7 +382,7 @@ export default function ProductRulesPanel() {
{
title: '匹配',
dataIndex: 'matchType',
width: '8%',
width: '9%',
render: (value) => (
<Tag color={value === 'exact' ? 'blue' : 'orange'} style={{ margin: 0 }}>
{value === 'exact' ? '精确' : '包含'}
@@ -380,7 +392,7 @@ export default function ProductRulesPanel() {
{
title: '状态',
key: 'status',
width: '6%',
width: '7%',
render: (_, row) => (
<Space direction="vertical" size={2}>
<Switch
@@ -730,12 +742,18 @@ export default function ProductRulesPanel() {
<Table<WorkProductRule>
rowKey="ruleId"
loading={rulesQuery.isLoading}
loading={rulesQuery.isLoading || mappingsQuery.isLoading}
dataSource={rules}
columns={columns}
rowClassName={(row) =>
editingRule?.ruleId === row.ruleId ? 'product-rule-row-active' : ''
}
rowClassName={(row) => {
const hasMappings = (mappingsByRuleId.get(row.ruleId) || []).length > 0
return [
editingRule?.ruleId === row.ruleId ? 'product-rule-row-active' : '',
hasMappings ? 'product-rule-row-mapped' : '',
]
.filter(Boolean)
.join(' ')
}}
onRow={(row) => ({
onClick: () => editRule(row),
title: '点击编辑此规则',