Files
affiliate_dash/frontend/src/pages/platformRock/VoucherPreviewModal.tsx
T
yml2213 b1089f37b2 refactor(web): 拆分 PlatformRock 大屏为容器 + 9 个子组件(1306 → 最大 335 行)
- PlatformRock.tsx 335 行:保留全部 state、loadData/loadTokens、useEffect、
  handler 与顶层布局;默认导出名不变,App.tsx 的 lazy 导入未改
- platformRock/ 子目录:tokenColumns 329、RockStrategyCard 267、
  PurchaseTokenModal 183、RockTokenTable 156、RockMetricCards 124、
  VoucherPreviewModal 95、RockTokenFilterBar 76、UidEditModal 47、types.ts 6

state 归属与更新时机、请求次数与参数、useEffect 依赖语义均未改变;子组件 props
显式声明类型,无 any;行级异步 handler 随表格下沉,state setter 经显式类型 props 传入。

验证:
- SSR 快照 renderToString 拆分前后字节一致(40920 bytes)
- jsdom 交互差分:拆分前后 23 个检查点的 DOM 快照与 API 调用日志完全一致
  (覆盖采购、UID 修正、解冻、释放、熔断、筛选/搜索/翻页、保存配置、连通性测试)
- 原文件应保留的 230 行代码逐字命中
2026-10-06 19:43:29 +08:00

96 lines
2.9 KiB
TypeScript

import { Button, Modal, Space, Typography, message } from 'antd'
import { CopyOutlined, DownloadOutlined, SafetyCertificateOutlined } from '@ant-design/icons'
import { copyVoucherDataUrlToClipboard } from '../../utils/voucher'
const { Text } = Typography
export interface VoucherPreviewModalProps {
open: boolean
previewVoucherUrl: string
onClose: () => void
}
export function VoucherPreviewModal({
open,
previewVoucherUrl,
onClose,
}: VoucherPreviewModalProps) {
return (
<Modal
title={
<Space>
<SafetyCertificateOutlined style={{ color: '#10b981' }} />
<span>发货到账存证凭据 (高清预览)</span>
</Space>
}
open={open}
onCancel={onClose}
footer={[
<Button key="close" onClick={onClose}>
关闭
</Button>,
<Button
key="download"
icon={<DownloadOutlined />}
onClick={() => {
if (!previewVoucherUrl) return
const link = document.createElement('a')
link.href = previewVoucherUrl
link.download = `发货凭证_${Date.now()}.png`
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
message.success('凭据图片已下载')
}}
>
下载凭证图
</Button>,
<Button
key="copy"
type="primary"
icon={<CopyOutlined />}
style={{
background: 'linear-gradient(135deg, #059669 0%, #10b981 100%)',
borderColor: '#059669',
}}
onClick={async () => {
if (!previewVoucherUrl) return
const copied = await copyVoucherDataUrlToClipboard(previewVoucherUrl)
if (copied) {
message.success('发货结果图片已复制到剪贴板!可直接在聊天窗粘贴 (Ctrl+V)')
} else {
message.info('请右键下方图片选择「复制图片」')
}
}}
>
复制图片到剪贴板
</Button>,
]}
width={420}
destroyOnClose
centered
>
<div style={{ textAlign: 'center', padding: '12px 0' }}>
{previewVoucherUrl ? (
<img
src={previewVoucherUrl}
alt="发货凭证大图"
style={{
maxWidth: '100%',
maxHeight: 520,
borderRadius: 16,
boxShadow: '0 8px 30px rgba(0, 0, 0, 0.25)',
objectFit: 'contain',
}}
/>
) : (
<div style={{ padding: 40, color: '#94a3b8' }}>正在生成高清凭据图...</div>
)}
<div style={{ marginTop: 12, fontSize: 12, color: '#64748b' }}>
💡 提示:点击「复制图片到剪贴板」后,可直接在微信/QQ等客服聊天窗口按 <Text code>Ctrl + V</Text> 发送。
</div>
</div>
</Modal>
)
}