优化快捷回复 CSV 为中文四列模板,操作列改为单行

导入/导出统一为一级分类、二级分类、输入码、内容;列表操作按钮紧凑并排不换行。
This commit is contained in:
yml2213
2026-07-19 00:59:53 +08:00
parent 4b7d8b04ea
commit c6532f2ee3
4 changed files with 156 additions and 54 deletions
+17 -12
View File
@@ -4,8 +4,8 @@ import {
} from 'antd'
import type { ColumnsType } from 'antd/es/table'
import {
PlusOutlined, EditOutlined, DeleteOutlined, CloudUploadOutlined, DownloadOutlined,
ThunderboltOutlined, CheckOutlined, StopOutlined, ImportOutlined, ExportOutlined,
PlusOutlined, CloudUploadOutlined, DownloadOutlined,
ThunderboltOutlined, ImportOutlined, ExportOutlined,
} from '@ant-design/icons'
import {
createQuickReply, deleteQuickReply, downloadQuickReplyTemplate, exportQuickReplies,
@@ -210,33 +210,33 @@ const QuickReplies = () => {
{
title: '操作',
key: 'actions',
width: tab === 'team' && canManageTeam ? 220 : 120,
width: tab === 'team' && canManageTeam ? 168 : 112,
fixed: 'right',
render: (_, row) => (
<Space size={4} wrap>
<div className="flex items-center gap-0.5 whitespace-nowrap">
{canEditRow(row) && (
<Button type="link" size="small" icon={<EditOutlined />} onClick={() => openEdit(row)}>
<Button type="link" size="small" className="!px-1" onClick={() => openEdit(row)}>
</Button>
)}
{tab === 'team' && canManageTeam && row.status === 'draft' && (
<Button type="link" size="small" icon={<CheckOutlined />} onClick={() => void handlePublish(row)}>
<Button type="link" size="small" className="!px-1" onClick={() => void handlePublish(row)}>
</Button>
)}
{tab === 'team' && canManageTeam && row.status === 'published' && (
<Button type="link" size="small" icon={<StopOutlined />} onClick={() => void handleUnpublish(row)}>
<Button type="link" size="small" className="!px-1" onClick={() => void handleUnpublish(row)}>
线
</Button>
)}
{canEditRow(row) && (
<Popconfirm title="确认删除?" onConfirm={() => void handleDelete(row)}>
<Button type="link" size="small" danger icon={<DeleteOutlined />}>
<Button type="link" size="small" danger className="!px-1">
</Button>
</Popconfirm>
)}
</Space>
</div>
),
},
]
@@ -272,16 +272,21 @@ const QuickReplies = () => {
<h1 className="text-base font-semibold text-neutral-900 m-0 truncate"></h1>
</div>
<Space wrap size="small" className="shrink-0">
<Button size="small" icon={<DownloadOutlined />} onClick={() => void handleTemplate()}>
<Button size="small" icon={<DownloadOutlined />} onClick={() => void handleTemplate()} title="下载 CSV 模板(一级分类/二级分类/输入码/内容)">
</Button>
<Button size="small" icon={<ExportOutlined />} onClick={() => void handleExport()}>
</Button>
<Upload
accept=".csv,text/csv"
accept=".csv,text/csv,.xlsx,.xls"
showUploadList={false}
beforeUpload={async file => {
const name = (file as File).name || ''
if (/\.xlsx?$/i.test(name)) {
message.warning('请先将 Excel 另存为 CSV(UTF-8)后再导入;可先下载「导入模板」参考格式')
return false
}
try {
const res = await importQuickReplies(file as File, effectiveTab, 'skip')
const d = res.data
+1 -1
View File
@@ -521,7 +521,7 @@ export const exportQuickReplies = (scope: QuickReplyScope) =>
downloadFile(`/quick-replies/export?scope=${scope}`, `quick_replies_${scope}.csv`)
export const downloadQuickReplyTemplate = () =>
downloadFile('/quick-replies/import-template', 'quick_replies_template.csv')
downloadFile('/quick-replies/import-template', '快捷回复导入模板.csv')
export const importQuickReplies = (file: File, scope: QuickReplyScope, onConflict: 'skip' | 'overwrite' = 'skip') => {
const form = new FormData()