289 lines
7.8 KiB
TypeScript
289 lines
7.8 KiB
TypeScript
import { useState } from 'react'
|
|
import { Button, Divider, Input, Popover, Space, Tag, Tooltip, Typography } from 'antd'
|
|
import {
|
|
CheckOutlined,
|
|
CloseCircleOutlined,
|
|
DeleteOutlined,
|
|
EditOutlined,
|
|
ExclamationCircleOutlined,
|
|
MessageOutlined,
|
|
StopOutlined,
|
|
} from '@ant-design/icons'
|
|
import type { RockTokenItem } from '../../api'
|
|
|
|
const { Text } = Typography
|
|
|
|
export interface TokenRemarkCellProps {
|
|
record: RockTokenItem
|
|
onUpdateRemark: (id: number, remark: string, status?: string) => void
|
|
onMarkAbnormal: (id: number, remark?: string) => void
|
|
// 紧凑模式:表格里只渲染一个图标按钮,备注内容通过悬浮提示和弹层查看
|
|
compact?: boolean
|
|
}
|
|
|
|
export function TokenRemarkCell({
|
|
record,
|
|
onUpdateRemark,
|
|
onMarkAbnormal,
|
|
compact,
|
|
}: TokenRemarkCellProps) {
|
|
const [open, setOpen] = useState(false)
|
|
const [inputValue, setInputValue] = useState(record.remark || '')
|
|
|
|
const handleQuickMarkAbnormal = (reason: string) => {
|
|
onMarkAbnormal(record.id, reason)
|
|
setOpen(false)
|
|
}
|
|
|
|
const handleQuickUpdate = (remarkText: string) => {
|
|
onUpdateRemark(record.id, remarkText)
|
|
setOpen(false)
|
|
}
|
|
|
|
const handleSaveCustom = () => {
|
|
onUpdateRemark(record.id, inputValue.trim())
|
|
setOpen(false)
|
|
}
|
|
|
|
const handleClear = () => {
|
|
onUpdateRemark(record.id, '')
|
|
setInputValue('')
|
|
setOpen(false)
|
|
}
|
|
|
|
const content = (
|
|
<div style={{ width: 280 }}>
|
|
<div
|
|
style={{
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
justifyContent: 'space-between',
|
|
marginBottom: 8,
|
|
borderBottom: '1px solid #f1f5f9',
|
|
paddingBottom: 6,
|
|
}}
|
|
>
|
|
<span style={{ fontWeight: 600, fontSize: 13, color: '#0f172a' }}>快速设置备注</span>
|
|
<Text type="secondary" style={{ fontSize: 11 }}>
|
|
#{record.upstream_token_id || record.id}
|
|
</Text>
|
|
</div>
|
|
|
|
<div style={{ marginBottom: 6 }}>
|
|
<Text type="secondary" style={{ fontSize: 11 }}>
|
|
快捷选择(点击直接生效):
|
|
</Text>
|
|
</div>
|
|
|
|
<Space direction="vertical" style={{ width: '100%' }} size={5}>
|
|
<Button
|
|
size="small"
|
|
danger
|
|
block
|
|
style={{
|
|
textAlign: 'left',
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
background: '#fef2f2',
|
|
borderColor: '#fca5a5',
|
|
}}
|
|
icon={<StopOutlined />}
|
|
onClick={() => handleQuickMarkAbnormal('已上报错误 (卡密失效)')}
|
|
>
|
|
<span style={{ fontWeight: 600 }}>已上报错误 (标记失效)</span>
|
|
</Button>
|
|
|
|
<Button
|
|
size="small"
|
|
block
|
|
style={{
|
|
textAlign: 'left',
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
borderColor: '#fdba74',
|
|
color: '#c2410c',
|
|
background: '#fff7ed',
|
|
}}
|
|
icon={<ExclamationCircleOutlined />}
|
|
onClick={() => handleQuickMarkAbnormal('绑定错误-已上报上游')}
|
|
>
|
|
<span>绑定错误 (已上报上游)</span>
|
|
</Button>
|
|
|
|
<Button
|
|
size="small"
|
|
block
|
|
style={{ textAlign: 'left', display: 'flex', alignItems: 'center' }}
|
|
icon={<EditOutlined />}
|
|
onClick={() => handleQuickUpdate('买家UID填错 (待核对)')}
|
|
>
|
|
<span>买家UID填错 (待核对)</span>
|
|
</Button>
|
|
|
|
<Button
|
|
size="small"
|
|
block
|
|
style={{ textAlign: 'left', display: 'flex', alignItems: 'center' }}
|
|
icon={<EditOutlined />}
|
|
onClick={() => handleQuickUpdate('上报处理中 (等待答复)')}
|
|
>
|
|
<span>上报处理中 (等待答复)</span>
|
|
</Button>
|
|
</Space>
|
|
|
|
<Divider style={{ margin: '10px 0 8px 0' }} />
|
|
|
|
<div>
|
|
<div style={{ marginBottom: 4 }}>
|
|
<Text type="secondary" style={{ fontSize: 11 }}>
|
|
自定义备注内容:
|
|
</Text>
|
|
</div>
|
|
<Space.Compact style={{ width: '100%' }}>
|
|
<Input
|
|
size="small"
|
|
placeholder="输入自定义备注..."
|
|
value={inputValue}
|
|
onChange={(e) => setInputValue(e.target.value)}
|
|
onPressEnter={handleSaveCustom}
|
|
/>
|
|
<Button size="small" type="primary" icon={<CheckOutlined />} onClick={handleSaveCustom}>
|
|
保存
|
|
</Button>
|
|
</Space.Compact>
|
|
</div>
|
|
|
|
{record.remark ? (
|
|
<div style={{ marginTop: 8, textAlign: 'right' }}>
|
|
<Button
|
|
size="small"
|
|
type="link"
|
|
danger
|
|
icon={<DeleteOutlined />}
|
|
onClick={handleClear}
|
|
style={{ padding: 0, fontSize: 11 }}
|
|
>
|
|
清空当前备注
|
|
</Button>
|
|
</div>
|
|
) : null}
|
|
</div>
|
|
)
|
|
|
|
const isAbnormalOrReported =
|
|
record.status === 'abnormal' || (record.remark && record.remark.includes('上报'))
|
|
|
|
if (compact) {
|
|
const hasRemark = Boolean(record.remark)
|
|
return (
|
|
<Popover
|
|
content={content}
|
|
trigger="click"
|
|
open={open}
|
|
onOpenChange={(v) => {
|
|
setOpen(v)
|
|
if (v) setInputValue(record.remark || '')
|
|
}}
|
|
placement="bottomLeft"
|
|
>
|
|
<span style={{ display: 'inline-flex' }}>
|
|
<Tooltip
|
|
title={
|
|
hasRemark ? (
|
|
<div style={{ maxWidth: 280, whiteSpace: 'pre-wrap', wordBreak: 'break-word' }}>
|
|
{record.remark}
|
|
<div style={{ marginTop: 4, fontSize: 11, opacity: 0.75 }}>点击修改</div>
|
|
</div>
|
|
) : (
|
|
'添加备注'
|
|
)
|
|
}
|
|
>
|
|
<Button
|
|
size="small"
|
|
type={hasRemark ? 'primary' : 'text'}
|
|
danger={hasRemark && Boolean(isAbnormalOrReported)}
|
|
icon={hasRemark ? <MessageOutlined /> : <EditOutlined />}
|
|
style={{ width: 26, height: 26, padding: 0, fontSize: 12 }}
|
|
/>
|
|
</Tooltip>
|
|
</span>
|
|
</Popover>
|
|
)
|
|
}
|
|
|
|
if (!record.remark) {
|
|
return (
|
|
<Popover
|
|
content={content}
|
|
trigger="click"
|
|
open={open}
|
|
onOpenChange={(v) => {
|
|
setOpen(v)
|
|
if (v) setInputValue('')
|
|
}}
|
|
placement="bottomLeft"
|
|
>
|
|
<span
|
|
style={{
|
|
cursor: 'pointer',
|
|
fontSize: 12,
|
|
color: '#64748b',
|
|
padding: '2px 6px',
|
|
borderRadius: 4,
|
|
border: '1px dashed #cbd5e1',
|
|
display: 'inline-flex',
|
|
alignItems: 'center',
|
|
gap: 4,
|
|
transition: 'all 0.2s',
|
|
}}
|
|
title="点击快速设置备注"
|
|
>
|
|
<EditOutlined style={{ fontSize: 11 }} />
|
|
添加备注
|
|
</span>
|
|
</Popover>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<Popover
|
|
content={content}
|
|
trigger="click"
|
|
open={open}
|
|
onOpenChange={(v) => {
|
|
setOpen(v)
|
|
if (v) setInputValue(record.remark || '')
|
|
}}
|
|
placement="bottomLeft"
|
|
>
|
|
<div
|
|
style={{
|
|
cursor: 'pointer',
|
|
display: 'inline-flex',
|
|
alignItems: 'center',
|
|
maxWidth: 220,
|
|
}}
|
|
title="点击修改或快速设置备注"
|
|
>
|
|
<Tag
|
|
color={isAbnormalOrReported ? 'error' : 'blue'}
|
|
style={{
|
|
maxWidth: '100%',
|
|
overflow: 'hidden',
|
|
textOverflow: 'ellipsis',
|
|
whiteSpace: 'nowrap',
|
|
margin: 0,
|
|
fontSize: 12,
|
|
padding: '2px 6px',
|
|
border: isAbnormalOrReported ? '1px solid #fca5a5' : undefined,
|
|
}}
|
|
icon={isAbnormalOrReported ? <CloseCircleOutlined /> : <EditOutlined />}
|
|
>
|
|
{record.remark}
|
|
</Tag>
|
|
</div>
|
|
</Popover>
|
|
)
|
|
}
|