feat(rock): 发货记录表格新增时间与备注列并支持上报失效联动
- 做了什么: 1. 数据库新增 013_rock_tokens_remark.sql 迁移,rock_tokens 表补充 remark 字段并在 ListTokens 中支持备注模糊检索; 2. 后端扩展 UpdateTokenRemark、MarkTokenAbnormal 接口,同时优化 ResetMismatchToken 支持 mismatch 与 abnormal 状态的解冻重置; 3. 前端 RockTokenTable 新增「流转时间」列(入库/绑错/发货/绑定/提货)与「备注」列(TokenRemarkCell 浮窗快捷预设选择与自定义输入); 4. 快捷选择「已上报」或点击「上报失效」自动将链接标记为 abnormal 作废,从可用库存池中剔除,防止被新订单领走; 5. 优化操作列与顶部筛选栏:mismatch 增加「上报失效」与警示重置;abnormal 状态明确显示已失效并提供强制恢复;筛选栏新增「已上报失效」Tab。 - 为什么: 解决绑定错误上报 0868 上游后无法记录备注、且原「解冻重置」容易误将已作废卡密放回可用库存池导致后续订单报错的问题。 - 验证方式: 1. 后端单元测试 TestRockService_TokenRemarkAndAbnormal 与 TestRock 测试集通过; 2. make fmt、go vet 通过; 3. 前端 oxlint 检查通过 (0 errors, 0 warnings),npm run build 生产构建通过。
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
import { Button, Popconfirm, Space, Tag, Tooltip, Typography } from 'antd'
|
||||
import { CopyOutlined, EyeOutlined, UndoOutlined } from '@ant-design/icons'
|
||||
import { CopyOutlined, EyeOutlined, StopOutlined, UndoOutlined } from '@ant-design/icons'
|
||||
import type { ColumnsType } from 'antd/es/table'
|
||||
import type { RockTokenItem } from '../../api'
|
||||
import { formatDateTime } from '../../utils/time'
|
||||
import { TokenRemarkCell } from './TokenRemarkCell'
|
||||
import type { UidEditState } from './types'
|
||||
|
||||
const { Text } = Typography
|
||||
@@ -13,6 +15,8 @@ export interface TokenColumnHandlers {
|
||||
onEditUid: (state: UidEditState) => void
|
||||
onResetToken: (id: number) => void
|
||||
onReleaseToken: (id: number) => void
|
||||
onUpdateRemark: (id: number, remark: string, status?: string) => void
|
||||
onMarkAbnormal: (id: number, remark?: string) => void
|
||||
}
|
||||
|
||||
export function buildTokenColumns({
|
||||
@@ -22,6 +26,8 @@ export function buildTokenColumns({
|
||||
onEditUid,
|
||||
onResetToken,
|
||||
onReleaseToken,
|
||||
onUpdateRemark,
|
||||
onMarkAbnormal,
|
||||
}: TokenColumnHandlers): ColumnsType<RockTokenItem> {
|
||||
return [
|
||||
{
|
||||
@@ -98,11 +104,62 @@ export function buildTokenColumns({
|
||||
⚠️ 绑定错误 (阻断)
|
||||
</Tag>
|
||||
)
|
||||
case 'abnormal':
|
||||
return (
|
||||
<Tag
|
||||
color="default"
|
||||
style={{
|
||||
fontWeight: 600,
|
||||
padding: '2px 8px',
|
||||
color: '#b91c1c',
|
||||
background: '#fef2f2',
|
||||
border: '1px solid #fca5a5',
|
||||
}}
|
||||
>
|
||||
🚫 已上报失效
|
||||
</Tag>
|
||||
)
|
||||
default:
|
||||
return <Tag>{status}</Tag>
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '流转时间',
|
||||
width: 175,
|
||||
render: (_, record) => (
|
||||
<Space direction="vertical" size={2}>
|
||||
<div style={{ fontSize: 12, color: '#334155' }}>
|
||||
<span style={{ color: '#94a3b8' }}>入库: </span>
|
||||
{formatDateTime(record.created_at)}
|
||||
</div>
|
||||
{record.mismatch_at && (
|
||||
<div style={{ fontSize: 11, color: '#e11d48' }}>
|
||||
<span>⚠️ 绑错: </span>
|
||||
{formatDateTime(record.mismatch_at)}
|
||||
</div>
|
||||
)}
|
||||
{record.redeemed_at && (
|
||||
<div style={{ fontSize: 11, color: '#16a34a' }}>
|
||||
<span>✅ 发货: </span>
|
||||
{formatDateTime(record.redeemed_at)}
|
||||
</div>
|
||||
)}
|
||||
{!record.redeemed_at && record.bound_at && (
|
||||
<div style={{ fontSize: 11, color: '#0284c7' }}>
|
||||
<span>🔗 绑定: </span>
|
||||
{formatDateTime(record.bound_at)}
|
||||
</div>
|
||||
)}
|
||||
{!record.bound_at && !record.mismatch_at && record.claimed_at && (
|
||||
<div style={{ fontSize: 11, color: '#6366f1' }}>
|
||||
<span>📦 提货: </span>
|
||||
{formatDateTime(record.claimed_at)}
|
||||
</div>
|
||||
)}
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '关联业务工单',
|
||||
dataIndex: 'assigned_order_no',
|
||||
@@ -179,6 +236,17 @@ export function buildTokenColumns({
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '备注',
|
||||
width: 200,
|
||||
render: (_, record) => (
|
||||
<TokenRemarkCell
|
||||
record={record}
|
||||
onUpdateRemark={onUpdateRemark}
|
||||
onMarkAbnormal={onMarkAbnormal}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '发货结果图片',
|
||||
key: 'voucher',
|
||||
@@ -273,7 +341,7 @@ export function buildTokenColumns({
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
width: 168,
|
||||
width: 180,
|
||||
fixed: 'right',
|
||||
render: (_, record) => {
|
||||
if (record.status === 'mismatch') {
|
||||
@@ -294,19 +362,50 @@ export function buildTokenColumns({
|
||||
修改 UID
|
||||
</Button>
|
||||
<Popconfirm
|
||||
title="确定解冻重置该 Token?"
|
||||
description="重置后将清除原订单绑定与错误标记,重新释放为可用通用库存。已扫码的链接放回库存后,其他订单领走就会废掉。"
|
||||
okText="确认解冻"
|
||||
title="确定将该链接标记为已上报失效?"
|
||||
description="上报给上游后该链接将永久作废,系统不会再将其作为可用库存分配给任何新订单。"
|
||||
okText="确认上报失效"
|
||||
cancelText="取消"
|
||||
okButtonProps={{ danger: true }}
|
||||
onConfirm={() => onMarkAbnormal(record.id, '绑定错误-已上报上游 (已失效)')}
|
||||
>
|
||||
<Button size="small" danger icon={<StopOutlined />}>
|
||||
上报失效
|
||||
</Button>
|
||||
</Popconfirm>
|
||||
<Popconfirm
|
||||
title="确定解冻重置该 Token 回库存?"
|
||||
description="注意:仅在确认卡密未作废、未上报上游时操作。重置后将清除原订单绑定与错误标记,重新释放为可用库存。若已上报上游请点击【上报失效】。"
|
||||
okText="确认重置回库存"
|
||||
cancelText="取消"
|
||||
onConfirm={() => onResetToken(record.id)}
|
||||
>
|
||||
<Button size="small" danger ghost icon={<UndoOutlined />}>
|
||||
<Button size="small" ghost style={{ color: '#64748b', borderColor: '#cbd5e1' }} icon={<UndoOutlined />}>
|
||||
解冻重置
|
||||
</Button>
|
||||
</Popconfirm>
|
||||
</Space>
|
||||
)
|
||||
}
|
||||
if (record.status === 'abnormal') {
|
||||
return (
|
||||
<Space direction="vertical" size={4}>
|
||||
<Text type="secondary" style={{ fontSize: 11 }}>已失效作废</Text>
|
||||
<Popconfirm
|
||||
title="确定强制恢复为可用库存?"
|
||||
description="警告:该链接曾标记为已上报失效。若上游已作废该卡密,重新放回库存将导致下一单提货失败!请确保卡密真实可用。"
|
||||
okText="强制恢复回库存"
|
||||
cancelText="取消"
|
||||
okButtonProps={{ danger: true }}
|
||||
onConfirm={() => onResetToken(record.id)}
|
||||
>
|
||||
<Button size="small" icon={<UndoOutlined />} style={{ fontSize: 11 }}>
|
||||
恢复回库存
|
||||
</Button>
|
||||
</Popconfirm>
|
||||
</Space>
|
||||
)
|
||||
}
|
||||
if (record.status === 'using' && !record.bound_at && !record.actual_role_id) {
|
||||
return (
|
||||
<Popconfirm
|
||||
|
||||
Reference in New Issue
Block a user