diff --git a/Touchkebao/src/pages/pc/ckbox/weChat/components/ChatWindow/components/ProfileCard/components/QuickWords/api.ts b/Touchkebao/src/pages/pc/ckbox/weChat/components/ChatWindow/components/ProfileCard/components/QuickWords/api.ts new file mode 100644 index 00000000..a1a12a52 --- /dev/null +++ b/Touchkebao/src/pages/pc/ckbox/weChat/components/ChatWindow/components/ProfileCard/components/QuickWords/api.ts @@ -0,0 +1,96 @@ +import request from "@/api/request"; +// 快捷回复项接口 +export interface QuickWordsReply { + id: number; + groupId: number; + userId: number; + title: string; + msgType: number; + content: string; + createTime: string; + lastUpdateTime: string; + sortIndex: string; + updateTime: string | null; + isDel: number; + delTime: string | null; +} + +// 快捷回复组接口 +export interface QuickWordsItem { + id: number; + groupName: string; + sortIndex: string; + parentId: number; + replyType: string; + replys: any | null; + companyId: number; + userId: number; + replies: QuickWordsReply[]; + children: QuickWordsItem[]; +} + +//好友接待配置 +export function setFriendInjectConfig(params: any): Promise { + return request("/v1/kefu/reply/list", params, "GET"); +} + +export interface AddReplyRequest { + id?: string; + content?: string; + groupId?: string; + /** + * 1文本 3图片 43视频 49链接 等 + */ + msgType?: string[]; + /** + * 默认50 + */ + sortIndex?: string; + title?: string; + [property: string]: any; +} + +// 添加快捷回复 +export function addReply(params: AddReplyRequest): Promise { + return request("/v1/kefu/reply/addReply", params, "POST"); +} + +// 更新快捷回复 +export function updateReply(params: AddReplyRequest): Promise { + return request("/v1/kefu/reply/updateReply", params, "POST"); +} + +// 删除快捷回复 +export function deleteReply(params: { id: string }): Promise { + return request("/v1/kefu/reply/deleteReply", params, "DELETE"); +} + +export interface AddGroupRequest { + id?: string; + groupName?: string; + parentId?: string; + /** + * 0 公共 1私有 2部门 + */ + replyType?: string[]; + /** + * 默认50 + */ + sortIndex?: string; + [property: string]: any; +} + +// 添加快捷回复组 +export function addGroup(params: AddGroupRequest): Promise { + return request("/v1/kefu/reply/addGroup", params, "POST"); +} + +// 更新快捷回复组 +export function updateGroup(params: AddGroupRequest): Promise { + return request("/v1/kefu/reply/updateGroup", params, "POST"); +} + +// 删除快捷回复组 +export function deleteGroup(params: { id: string }): Promise { + return request("/v1/kefu/reply/deleteGroup", params, "DELETE"); +} diff --git a/Touchkebao/src/pages/pc/ckbox/weChat/components/ChatWindow/components/ProfileCard/components/QuickWords/index.tsx b/Touchkebao/src/pages/pc/ckbox/weChat/components/ChatWindow/components/ProfileCard/components/QuickWords/index.tsx index 915dc873..b0eda51e 100644 --- a/Touchkebao/src/pages/pc/ckbox/weChat/components/ChatWindow/components/ProfileCard/components/QuickWords/index.tsx +++ b/Touchkebao/src/pages/pc/ckbox/weChat/components/ChatWindow/components/ProfileCard/components/QuickWords/index.tsx @@ -1,135 +1,563 @@ -import React, { useMemo, useState } from "react"; -import { Card, Input, Button, Space, List, Tag } from "antd"; +import React, { useMemo, useState, useEffect, useCallback } from "react"; +import { + Card, + Input, + Button, + Space, + Tabs, + Tree, + Modal, + Form, + Select, + message, + Tooltip, + Spin, +} from "antd"; +import { + PlusOutlined, + ReloadOutlined, + EditOutlined, + DeleteOutlined, + FileTextOutlined, + PictureOutlined, + PlayCircleOutlined, +} from "@ant-design/icons"; +import { + QuickWordsItem, + QuickWordsReply, + setFriendInjectConfig, + addReply, + updateReply, + deleteReply, + updateGroup, + deleteGroup, + AddReplyRequest, + AddGroupRequest, +} from "./api"; -export interface QuickWordItem { - id: string | number; - text?: string; // 兼容旧结构 - title?: string; - content?: string; - tag?: string; // 分类/标签 - usageCount?: number; +// 消息类型枚举 +export enum MessageType { + TEXT = 1, + IMAGE = 3, + VIDEO = 43, + LINK = 49, +} + +// 快捷语类型枚举 +export enum QuickWordsType { + PERSONAL = 1, // 个人 + PUBLIC = 0, // 公共 + DEPARTMENT = 2, // 部门 } export interface QuickWordsProps { - title?: string; - words: QuickWordItem[]; - onInsert?: (text: string) => void; - onAdd?: (text: string) => void; - onRemove?: (id: string | number) => void; + onInsert?: (reply: QuickWordsReply) => void; } -const QuickWords: React.FC = ({ - title = "快捷语录", - words, - onInsert, - - onRemove, -}) => { - const [keyword, setKeyword] = useState(""); - const sorted = useMemo( - () => - [...(words || [])].sort((a, b) => - String(a.id).localeCompare(String(b.id)), - ), - [words], +const QuickWords: React.FC = ({ onInsert }) => { + const [activeTab, setActiveTab] = useState( + QuickWordsType.PUBLIC, ); + const [keyword, setKeyword] = useState(""); + const [loading, setLoading] = useState(false); + const [quickWordsData, setQuickWordsData] = useState([]); + const [expandedKeys, setExpandedKeys] = useState([]); + const [selectedKeys, setSelectedKeys] = useState([]); + + // 模态框状态 + const [addModalVisible, setAddModalVisible] = useState(false); + const [editModalVisible, setEditModalVisible] = useState(false); + const [groupModalVisible, setGroupModalVisible] = useState(false); + const [editingItem, setEditingItem] = useState(null); + const [editingGroup, setEditingGroup] = useState(null); + const [form] = Form.useForm(); + const [groupForm] = Form.useForm(); + + // 获取快捷语数据 + const fetchQuickWords = useCallback(async () => { + setLoading(true); + try { + const data = await setFriendInjectConfig({ replyType: activeTab }); + setQuickWordsData(data || []); + } catch (error) { + message.error("获取快捷语数据失败"); + } finally { + setLoading(false); + } + }, [activeTab]); + + // 初始化数据 + useEffect(() => { + fetchQuickWords(); + }, [fetchQuickWords]); + + // 获取消息类型图标 + const getMessageTypeIcon = (msgType: number) => { + switch (msgType) { + case MessageType.TEXT: + return ; + case MessageType.IMAGE: + return ; + case MessageType.VIDEO: + return ; + default: + return ; + } + }; + + // 将数据转换为Tree组件需要的格式 + const convertToTreeData = (data: QuickWordsItem[]): any[] => { + return data.map(item => ({ + key: `group-${item.id}`, + title: ( +
+ {item.groupName} +
+ +
+
+ ), + children: [ + ...item.replies.map(reply => ({ + key: `reply-${reply.id}`, + title: ( +
+
+ {getMessageTypeIcon(reply.msgType)} + {reply.title} +
+
+ + + + +
+
+ ), + isLeaf: true, + })), + ...convertToTreeData(item.children || []), + ], + })); + }; + + // 处理添加快捷回复 + const handleAddReply = async (values: AddReplyRequest) => { + try { + await addReply({ + ...values, + groupId: selectedKeys[0]?.toString().replace("group-", "") || "", + replyType: [activeTab.toString()], + }); + message.success("添加快捷回复成功"); + setAddModalVisible(false); + form.resetFields(); + fetchQuickWords(); + } catch (error) { + message.error("添加快捷回复失败"); + } + }; + + // 处理编辑快捷回复 + const handleEditReply = (reply: QuickWordsReply) => { + setEditingItem(reply); + form.setFieldsValue({ + title: reply.title, + content: reply.content, + msgType: [reply.msgType.toString()], + }); + setEditModalVisible(true); + }; + + // 处理更新快捷回复 + const handleUpdateReply = async (values: AddReplyRequest) => { + if (!editingItem) return; + + try { + await updateReply({ + ...values, + id: editingItem.id.toString(), + }); + message.success("更新快捷回复成功"); + setEditModalVisible(false); + setEditingItem(null); + form.resetFields(); + fetchQuickWords(); + } catch (error) { + message.error("更新快捷回复失败"); + } + }; + + // 处理删除快捷回复 + const handleDeleteReply = async (id: number) => { + Modal.confirm({ + title: "确认删除", + content: "确定要删除这个快捷回复吗?", + onOk: async () => { + try { + await deleteReply({ id: id.toString() }); + message.success("删除成功"); + fetchQuickWords(); + } catch (error) { + message.error("删除失败"); + } + }, + }); + }; + + // 处理编辑分组 + const handleEditGroup = (group: QuickWordsItem) => { + setEditingGroup(group); + groupForm.setFieldsValue({ + groupName: group.groupName, + replyType: [group.replyType], + }); + setGroupModalVisible(true); + }; + + // 处理更新分组 + const handleUpdateGroup = async (values: AddGroupRequest) => { + if (!editingGroup) return; + + try { + await updateGroup({ + ...values, + id: editingGroup.id.toString(), + }); + message.success("更新分组成功"); + setGroupModalVisible(false); + setEditingGroup(null); + groupForm.resetFields(); + fetchQuickWords(); + } catch (error) { + message.error("更新分组失败"); + } + }; + + // 处理删除分组 + const handleDeleteGroup = async (id: number) => { + Modal.confirm({ + title: "确认删除", + content: "确定要删除这个分组吗?删除后该分组下的所有快捷回复也会被删除。", + onOk: async () => { + try { + await deleteGroup({ id: id.toString() }); + message.success("删除成功"); + fetchQuickWords(); + } catch (error) { + message.error("删除失败"); + } + }, + }); + }; + + // 过滤数据 + const filteredData = useMemo(() => { + if (!keyword.trim()) return quickWordsData; + + const filterData = (data: QuickWordsItem[]): QuickWordsItem[] => { + return data + .map(item => ({ + ...item, + replies: item.replies.filter( + reply => + reply.title.toLowerCase().includes(keyword.toLowerCase()) || + reply.content.toLowerCase().includes(keyword.toLowerCase()), + ), + children: filterData(item.children || []), + })) + .filter( + item => + item.replies.length > 0 || + item.children.length > 0 || + item.groupName.toLowerCase().includes(keyword.toLowerCase()), + ); + }; + + return filterData(quickWordsData); + }, [quickWordsData, keyword]); + + const treeData = convertToTreeData(filteredData); return ( - - - setKeyword(e.target.value)} - onSearch={v => setKeyword(v)} - /> + + setActiveTab(Number(key) as QuickWordsType)} + items={[ + { + key: QuickWordsType.PERSONAL.toString(), + label: "个人快捷语", + }, + { + key: QuickWordsType.PUBLIC.toString(), + label: "公共快捷语", + }, + { + key: QuickWordsType.DEPARTMENT.toString(), + label: "部门快捷语", + }, + ]} + /> - { - const text = `${item.title || ""}${item.content || ""}${item.text || ""}`; - return text.toLowerCase().includes(keyword.trim().toLowerCase()); - })} - renderItem={item => { - const displayTitle = item.title || item.text || "未命名"; - const displayContent = item.content || item.text || ""; - return ( - +
+ setKeyword(e.target.value)} + style={{ flex: 1 }} + /> + +
+ + + + +
+ + {/* 添加快捷回复模态框 */} + { + setAddModalVisible(false); + form.resetFields(); + }} + footer={null} + > +
+ + + + + + + + + + + + + + + + - )} - - - - - ); - }} - /> - + 取消 + + + +
+
+ + {/* 编辑快捷回复模态框 */} + { + setEditModalVisible(false); + setEditingItem(null); + form.resetFields(); + }} + footer={null} + > +
+ + + + + + + + + + + + + + + + + + +
+
+ + {/* 编辑分组模态框 */} + { + setGroupModalVisible(false); + setEditingGroup(null); + groupForm.resetFields(); + }} + footer={null} + > +
+ + + + + + + + + + +
+
); };