feat(channel): 支持安全删除渠道并保留历史数据
CI / Frontend (typecheck + lint + build) (push) Successful in 5m31s
CI / Backend (go vet + test) (push) Failing after 11m10s

This commit is contained in:
yml2213
2026-11-06 18:36:07 +08:00
parent 6297ea6634
commit de1ffbf4f6
10 changed files with 135 additions and 23 deletions
+13 -1
View File
@@ -2,7 +2,7 @@ import { useEffect, useMemo, useState } from 'react'
import { Button, Form, message } from 'antd'
import { PlusOutlined } from '@ant-design/icons'
import {
createChannel, createStaff, deleteStaff,
createChannel, createStaff, deleteChannel as deleteChannelApi, deleteStaff,
getChannels, getCustomerTags, getStaff, getTenantSettings,
updateChannel, updateStaff, updateTenantSettings,
type Channel, type CustomerTag, type StaffUser, type TenantSettings, type WelcomeSegment,
@@ -288,6 +288,17 @@ const Settings = () => {
}
}
const handleDeleteChannel = async (channel: Channel) => {
try {
await deleteChannelApi(channel.id)
setChannels(previous => previous.filter(item => item.id !== channel.id))
message.success('渠道已删除,原嵌入代码立即失效')
} catch (e) {
message.error(e instanceof Error ? e.message : '删除失败')
throw e
}
}
const addChannelType = async (t: string) => {
try {
await createChannel({ type: t, name: typeMeta[t].label })
@@ -410,6 +421,7 @@ const Settings = () => {
ensureWebChannel={addWebChannel}
addChannelType={addChannelType}
updateChannelMeta={updateChannelMeta}
deleteChannel={handleDeleteChannel}
/>
)}
@@ -1,6 +1,6 @@
import { useState } from 'react'
import { Button, Empty, Form, Input, Modal, Spin, Switch, message } from 'antd'
import { CopyOutlined, EditOutlined, LinkOutlined, PlusOutlined } from '@ant-design/icons'
import { Button, Empty, Form, Input, Modal, Popconfirm, Spin, Switch, message } from 'antd'
import { CopyOutlined, DeleteOutlined, EditOutlined, LinkOutlined, PlusOutlined } from '@ant-design/icons'
import type { Channel } from '@/services/api'
import { typeMeta } from './channelMeta'
@@ -27,6 +27,7 @@ interface ChannelsSectionProps {
ensureWebChannel: () => void
addChannelType: (t: string) => void
updateChannelMeta: (id: number, data: { name?: string; site_domain?: string }) => Promise<void>
deleteChannel: (channel: Channel) => Promise<void>
}
/** 渠道管理:接入渠道列表与嵌入代码 */
@@ -39,6 +40,7 @@ const ChannelsSection = ({
ensureWebChannel,
addChannelType,
updateChannelMeta,
deleteChannel,
}: ChannelsSectionProps) => {
const [form] = Form.useForm()
const [editing, setEditing] = useState<Channel | null>(null)
@@ -108,12 +110,30 @@ const ChannelsSection = ({
{enabled ? '已启用' : '未启用'}
</span>
</div>
<Switch
checked={enabled}
size="small"
loading={togglingId === ch.id}
onChange={v => toggleChannel(ch, v)}
/>
<div className="flex items-center gap-2 shrink-0">
<Switch
checked={enabled}
size="small"
loading={togglingId === ch.id}
onChange={v => toggleChannel(ch, v)}
/>
<Popconfirm
title={`删除「${ch.name || meta.label}」?`}
description="删除后原渠道 Key 和嵌入代码立即失效,历史会话仍会保留。"
okText="删除"
cancelText="取消"
okButtonProps={{ danger: true }}
onConfirm={() => deleteChannel(ch)}
>
<Button
type="text"
size="small"
danger
icon={<DeleteOutlined />}
title="删除渠道"
/>
</Popconfirm>
</div>
</div>
{ch.type === 'web' && (
<div className="flex items-center gap-2 text-xs mb-2">