- 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 行代码逐字命中
96 lines
2.9 KiB
TypeScript
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>
|
|
)
|
|
}
|