diff --git a/Touchkebao/src/pages/pc/ckbox/powerCenter/content-management/api.ts b/Touchkebao/src/pages/pc/ckbox/powerCenter/content-management/api.ts index 337c3518..eff8f497 100644 --- a/Touchkebao/src/pages/pc/ckbox/powerCenter/content-management/api.ts +++ b/Touchkebao/src/pages/pc/ckbox/powerCenter/content-management/api.ts @@ -132,9 +132,9 @@ export interface KeywordAddRequest { title: string; keywords: string; content: string; - matchType: string; // 匹配类型:模糊匹配、精确匹配 - priority: string; // 优先级 - replyType: string; // 回复类型:文本回复、模板回复 + type: number; // 匹配类型:模糊匹配、精确匹配 + level: number; // 优先级 + replyType: number; // 回复类型:文本回复、模板回复 status: string; } @@ -143,7 +143,7 @@ export interface KeywordUpdateRequest extends KeywordAddRequest { } export interface KeywordSetStatusRequest { - id: string; + id: number; } // 关键词回复-列表 @@ -157,12 +157,12 @@ export function addKeyword(data: KeywordAddRequest) { } // 关键词回复-详情 -export function getKeywordDetails(id: string) { +export function getKeywordDetails(id: number) { return request("/v1/kefu/content/keywords/details", { id }, "GET"); } // 关键词回复-删除 -export function deleteKeyword(id: string) { +export function deleteKeyword(id: number) { return request("/v1/kefu/content/keywords/del", { id }, "DELETE"); } diff --git a/Touchkebao/src/pages/pc/ckbox/powerCenter/content-management/components/management/KeywordManagement.tsx b/Touchkebao/src/pages/pc/ckbox/powerCenter/content-management/components/management/KeywordManagement.tsx index 99be1aaa..1dc3055f 100644 --- a/Touchkebao/src/pages/pc/ckbox/powerCenter/content-management/components/management/KeywordManagement.tsx +++ b/Touchkebao/src/pages/pc/ckbox/powerCenter/content-management/components/management/KeywordManagement.tsx @@ -4,14 +4,14 @@ import React, { forwardRef, useImperativeHandle, } from "react"; -import { Button, Input, Tag, Switch, message } from "antd"; +import { Button, Input, Tag, Switch, message, Popconfirm } from "antd"; import { SearchOutlined, FilterOutlined, FormOutlined, DeleteOutlined, } from "@ant-design/icons"; -import styles from "../../index.module.scss"; +import styles from "./index.module.scss"; import { getKeywordList, deleteKeyword, @@ -23,15 +23,15 @@ import KeywordModal from "../modals/KeywordModal"; const { Search } = Input; interface KeywordItem { - id: string; + id?: number; + type: number; + replyType: number; title: string; keywords: string; + status: number; content: string; - matchType: string; - priority: string; - replyType: string; - status: string; - enabled: boolean; + materialId: string; + level: number; } const KeywordManagement = forwardRef>( @@ -40,31 +40,52 @@ const KeywordManagement = forwardRef>( const [keywordsList, setKeywordsList] = useState([]); const [loading, setLoading] = useState(false); const [editModalVisible, setEditModalVisible] = useState(false); - const [editingKeywordId, setEditingKeywordId] = useState( + const [editingKeywordId, setEditingKeywordId] = useState( null, ); + //匹配类型 + const getMatchTypeText = (type: number) => { + switch (type) { + case 0: + return "模糊匹配"; + case 1: + return "精确匹配"; + } + }; + + //匹配优先级 + const getPriorityText = (level: number) => { + switch (level) { + case 0: + return "低优先级"; + case 1: + return "中优先级"; + case 2: + return "高优先级"; + } + }; // 回复类型映射 - const getReplyTypeText = (replyType: string) => { + const getReplyTypeText = (replyType: number) => { switch (replyType) { - case "text": - return "文本回复"; - case "template": - return "模板回复"; + case 0: + return "素材回复"; + case 1: + return "自定义"; default: return "未知类型"; } }; // 回复类型颜色 - const getReplyTypeColor = (replyType: string) => { + const getReplyTypeColor = (replyType: number) => { switch (replyType) { - case "text": - return "#1890ff"; - case "template": - return "#722ed1"; + case 0: + return "blue"; + case 1: + return "purple"; default: - return "#8c8c8c"; + return "gray"; } }; @@ -94,26 +115,24 @@ const KeywordManagement = forwardRef>( })); // 关键词管理相关函数 - const handleToggleKeyword = async (id: string) => { + const handleToggleKeyword = async (id: number) => { try { - const response = await setKeywordStatus({ id }); - if (response) { - setKeywordsList(prev => - prev.map(item => - item.id === id ? { ...item, enabled: !item.enabled } : item, - ), - ); - message.success("状态更新成功"); - } else { - message.error(response?.message || "状态更新失败"); - } + await setKeywordStatus({ id }); + setKeywordsList(prev => + prev.map(item => + item.id === id + ? { ...item, status: item.status === 1 ? 0 : 1 } + : item, + ), + ); + message.success("状态更新成功"); } catch (error) { console.error("状态更新失败:", error); message.error("状态更新失败"); } }; - const handleEditKeyword = (id: string) => { + const handleEditKeyword = (id: number) => { setEditingKeywordId(id); setEditModalVisible(true); }; @@ -123,15 +142,11 @@ const KeywordManagement = forwardRef>( fetchKeywords(); // 重新获取数据 }; - const handleDeleteKeyword = async (id: string) => { + const handleDeleteKeyword = async (id: number) => { try { - const response = await deleteKeyword(id); - if (response) { - setKeywordsList(prev => prev.filter(item => item.id !== id)); - message.success("删除成功"); - } else { - message.error(response?.message || "删除失败"); - } + await deleteKeyword(id); + setKeywordsList(prev => prev.filter(item => item.id !== id)); + message.success("删除成功"); } catch (error) { console.error("删除失败:", error); message.error("删除失败"); @@ -169,7 +184,7 @@ const KeywordManagement = forwardRef>( style={{ width: 300 }} prefix={} /> - + {/* */}
@@ -181,41 +196,48 @@ const KeywordManagement = forwardRef>( filteredKeywords.map(item => (
-
{item.title}
-
- {item.matchType} - - 优先级{item.priority} - +
+
+
{item.title}
+ {getMatchTypeText(item.type)} + {getPriorityText(item.level)} +
+
{item.content}
+
+ + {getReplyTypeText(item.replyType)} + +
+
+
+ handleToggleKeyword(item.id)} + className={styles.toggleSwitch} + /> +
-
{item.content}
- - {getReplyTypeText(item.replyType)} - -
-
- handleToggleKeyword(item.id)} - className={styles.toggleSwitch} - /> -
)) diff --git a/Touchkebao/src/pages/pc/ckbox/powerCenter/content-management/components/management/SensitiveWordManagement.tsx b/Touchkebao/src/pages/pc/ckbox/powerCenter/content-management/components/management/SensitiveWordManagement.tsx index 0e2cd1ec..d6f6d184 100644 --- a/Touchkebao/src/pages/pc/ckbox/powerCenter/content-management/components/management/SensitiveWordManagement.tsx +++ b/Touchkebao/src/pages/pc/ckbox/powerCenter/content-management/components/management/SensitiveWordManagement.tsx @@ -27,7 +27,7 @@ interface SensitiveWordItem { title: string; keywords: string; content: string; - operation: string; + operation: number; status: string; enabled: boolean; } @@ -185,12 +185,6 @@ const SensitiveWordManagement = forwardRef>(
{item.title}
- - {item.keywords} -
{getOperationText(item.operation)}
diff --git a/Touchkebao/src/pages/pc/ckbox/powerCenter/content-management/components/management/index.module.scss b/Touchkebao/src/pages/pc/ckbox/powerCenter/content-management/components/management/index.module.scss new file mode 100644 index 00000000..a7624c01 --- /dev/null +++ b/Touchkebao/src/pages/pc/ckbox/powerCenter/content-management/components/management/index.module.scss @@ -0,0 +1,252 @@ +// 关键词管理样式 +.keywordContent { + .searchSection { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 24px; + + :global(.ant-input-search) { + width: 300px; + } + + :global(.ant-btn) { + height: 32px; + border-radius: 6px; + } + } + + .keywordList { + display: flex; + flex-direction: column; + gap: 12px; + } + + .keywordItem { + padding: 16px 20px; + background: #fff; + border: 1px solid #f0f0f0; + border-radius: 8px; + transition: all 0.3s; + + &:hover { + border-color: #d9d9d9; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06); + } + + .itemContent { + display: flex; + justify-content: space-between; + align-items: flex-start; + gap: 16px; + + .leftSection { + flex: 1; + display: flex; + flex-direction: column; + gap: 8px; + + .titleRow { + display: flex; + align-items: center; + gap: 12px; + margin-bottom: 4px; + + .title { + font-size: 16px; + font-weight: 500; + color: #262626; + margin: 0; + } + + .tags { + display: flex; + gap: 8px; + + .matchTag, + .priorityTag { + font-size: 12px; + padding: 2px 8px; + border-radius: 12px; + background: #f0f0f0; + color: #666; + border: none; + } + } + } + + .description { + font-size: 14px; + color: #666; + line-height: 1.5; + margin-bottom: 8px; + } + + .replyTypeTag { + font-size: 12px; + padding: 2px 8px; + border-radius: 20px; + background: #fff; + color: #fff; + } + } + + .rightSection { + display: flex; + flex-direction: column; + align-items: center; + gap: 8px; + + .toggleSwitch { + :global(.ant-switch) { + background-color: #d9d9d9; + } + + :global(.ant-switch-checked) { + background-color: #1890ff; + } + } + + .actionBtn { + width: 28px; + height: 28px; + padding: 0; + border-radius: 4px; + display: flex; + align-items: center; + justify-content: center; + + &:hover { + background-color: #f5f5f5; + } + + .editIcon { + font-size: 14px; + color: #1890ff; + } + + .deleteIcon { + font-size: 14px; + color: #ff4d4f; + } + } + } + } + } +} + +// 响应式设计 +@media (max-width: 768px) { + .container { + padding: 16px; + } + + .headerActions { + flex-direction: column; + align-items: stretch; + + :global(.ant-btn) { + width: 100%; + } + } + + .tabs { + flex-direction: column; + padding: 0; + + .tab { + border-bottom: 1px solid #e8e8e8; + border-radius: 0; + + &:last-child { + border-bottom: none; + } + } + } + + .materialContent { + .searchSection { + flex-direction: column; + gap: 12px; + align-items: stretch; + + :global(.ant-input-search) { + width: 100%; + } + } + + .materialGrid { + grid-template-columns: 1fr; + gap: 16px; + } + } + + .sensitiveContent { + .searchSection { + flex-direction: column; + gap: 12px; + align-items: stretch; + + :global(.ant-input-search) { + width: 100%; + } + } + + .sensitiveItem { + flex-direction: column; + align-items: stretch; + gap: 12px; + + .itemContent { + flex-direction: column; + align-items: flex-start; + gap: 8px; + + .categoryName { + min-width: auto; + } + } + + .itemActions { + justify-content: flex-end; + } + } + } + + .keywordContent { + .searchSection { + flex-direction: column; + gap: 12px; + align-items: stretch; + + :global(.ant-input-search) { + width: 100%; + } + } + + .keywordItem { + .itemContent { + flex-direction: column; + gap: 12px; + + .leftSection { + .titleRow { + flex-direction: column; + align-items: flex-start; + gap: 8px; + + .tags { + flex-wrap: wrap; + } + } + } + + .rightSection { + flex-direction: row; + justify-content: flex-end; + align-items: center; + } + } + } + } +} diff --git a/Touchkebao/src/pages/pc/ckbox/powerCenter/content-management/components/modals/KeywordModal.tsx b/Touchkebao/src/pages/pc/ckbox/powerCenter/content-management/components/modals/KeywordModal.tsx index 209977fb..eeb3cea2 100644 --- a/Touchkebao/src/pages/pc/ckbox/powerCenter/content-management/components/modals/KeywordModal.tsx +++ b/Touchkebao/src/pages/pc/ckbox/powerCenter/content-management/components/modals/KeywordModal.tsx @@ -14,7 +14,7 @@ const { Option } = Select; interface KeywordModalProps { visible: boolean; mode: "add" | "edit"; - keywordId?: string | null; + keywordId?: number | null; onCancel: () => void; onSuccess: () => void; } @@ -31,7 +31,7 @@ const KeywordModal: React.FC = ({ // 获取关键词详情 const fetchKeywordDetails = useCallback( - async (id: string) => { + async (id: number) => { try { const response = await getKeywordDetails(id); if (response) { @@ -40,8 +40,8 @@ const KeywordModal: React.FC = ({ title: keyword.title, keywords: keyword.keywords, content: keyword.content, - matchType: keyword.matchType, - priority: keyword.priority, + type: keyword.type, + level: keyword.level, replyType: keyword.replyType, status: keyword.status, }); @@ -76,8 +76,8 @@ const KeywordModal: React.FC = ({ title: values.title, keywords: values.keywords, content: values.content, - matchType: values.matchType, - priority: values.priority, + type: values.type, + level: values.level, replyType: values.replyType, status: values.status || "1", }; @@ -97,8 +97,8 @@ const KeywordModal: React.FC = ({ title: values.title, keywords: values.keywords, content: values.content, - matchType: values.matchType, - priority: values.priority, + type: values.type, + level: values.level, replyType: values.replyType, status: values.status, }; @@ -141,10 +141,10 @@ const KeywordModal: React.FC = ({ layout="vertical" onFinish={handleSubmit} initialValues={{ - status: "1", - matchType: "模糊匹配", - priority: "1", - replyType: "text", + status: 1, + type: "模糊匹配", + level: 1, + replyType: 0, }} > = ({ @@ -202,8 +200,8 @@ const KeywordModal: React.FC = ({ rules={[{ required: true, message: "请选择回复类型" }]} > @@ -213,8 +211,8 @@ const KeywordModal: React.FC = ({ rules={[{ required: true, message: "请选择状态" }]} > diff --git a/Touchkebao/src/pages/pc/ckbox/powerCenter/content-management/components/modals/SensitiveWordModal.tsx b/Touchkebao/src/pages/pc/ckbox/powerCenter/content-management/components/modals/SensitiveWordModal.tsx index c715e265..5e125b4a 100644 --- a/Touchkebao/src/pages/pc/ckbox/powerCenter/content-management/components/modals/SensitiveWordModal.tsx +++ b/Touchkebao/src/pages/pc/ckbox/powerCenter/content-management/components/modals/SensitiveWordModal.tsx @@ -166,11 +166,11 @@ const SensitiveWordModal: React.FC = ({ rules={[{ required: true, message: "请选择操作类型" }]} > @@ -180,8 +180,8 @@ const SensitiveWordModal: React.FC = ({ rules={[{ required: true, message: "请选择状态" }]} > diff --git a/Touchkebao/src/pages/pc/ckbox/powerCenter/content-management/index.module.scss b/Touchkebao/src/pages/pc/ckbox/powerCenter/content-management/index.module.scss index 72934dce..7fa37698 100644 --- a/Touchkebao/src/pages/pc/ckbox/powerCenter/content-management/index.module.scss +++ b/Touchkebao/src/pages/pc/ckbox/powerCenter/content-management/index.module.scss @@ -291,133 +291,6 @@ } } -// 关键词管理样式 -.keywordContent { - .searchSection { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 24px; - - :global(.ant-input-search) { - width: 300px; - } - - :global(.ant-btn) { - height: 32px; - border-radius: 6px; - } - } - - .keywordList { - display: flex; - flex-direction: column; - gap: 12px; - } - - .keywordItem { - display: flex; - justify-content: space-between; - align-items: flex-start; - padding: 16px 20px; - background: #fff; - border: 1px solid #f0f0f0; - border-radius: 8px; - transition: all 0.3s; - - &:hover { - border-color: #d9d9d9; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06); - } - - .itemContent { - display: flex; - flex-direction: column; - gap: 8px; - flex: 1; - - .title { - font-size: 16px; - font-weight: 500; - color: #262626; - margin: 0; - } - - .tags { - display: flex; - gap: 8px; - margin-bottom: 4px; - - .matchTag, - .priorityTag { - font-size: 12px; - padding: 2px 8px; - border-radius: 12px; - background: #f0f0f0; - color: #666; - border: none; - } - } - - .description { - font-size: 14px; - color: #666; - line-height: 1.5; - margin-bottom: 8px; - } - - .replyTypeTag { - font-size: 12px; - padding: 2px 8px; - border-radius: 4px; - border: none; - align-self: flex-start; - } - } - - .itemActions { - display: flex; - align-items: center; - gap: 8px; - margin-left: 16px; - - .toggleSwitch { - :global(.ant-switch) { - background-color: #d9d9d9; - } - - :global(.ant-switch-checked) { - background-color: #1890ff; - } - } - - .actionBtn { - width: 28px; - height: 28px; - padding: 0; - border-radius: 4px; - display: flex; - align-items: center; - justify-content: center; - - &:hover { - background-color: #f5f5f5; - } - - .editIcon { - font-size: 14px; - color: #1890ff; - } - - .deleteIcon { - font-size: 14px; - color: #ff4d4f; - } - } - } - } -} - // 弹窗中的图片上传组件样式 :global(.material-cover-upload) { .uploadContainer { @@ -525,82 +398,4 @@ } } } - - .materialContent { - .searchSection { - flex-direction: column; - gap: 12px; - align-items: stretch; - - :global(.ant-input-search) { - width: 100%; - } - } - - .materialGrid { - grid-template-columns: 1fr; - gap: 16px; - } - } - - .sensitiveContent { - .searchSection { - flex-direction: column; - gap: 12px; - align-items: stretch; - - :global(.ant-input-search) { - width: 100%; - } - } - - .sensitiveItem { - flex-direction: column; - align-items: stretch; - gap: 12px; - - .itemContent { - flex-direction: column; - align-items: flex-start; - gap: 8px; - - .categoryName { - min-width: auto; - } - } - - .itemActions { - justify-content: flex-end; - } - } - } - - .keywordContent { - .searchSection { - flex-direction: column; - gap: 12px; - align-items: stretch; - - :global(.ant-input-search) { - width: 100%; - } - } - - .keywordItem { - flex-direction: column; - align-items: stretch; - gap: 12px; - - .itemContent { - .tags { - flex-wrap: wrap; - } - } - - .itemActions { - justify-content: flex-end; - margin-left: 0; - } - } - } }