feat(好友接待配置): 新增好友接待配置功能及流量池列表获取接口

在api.ts中新增了设置好友接待配置的API接口,并在ChatWindow组件中实现了配置选择功能,允许用户选择接待类型并保存配置。同时,新增了获取流量池列表的接口,优化了用户体验。
This commit is contained in:
超级老白兔
2025-09-23 11:20:35 +08:00
parent c6adee4502
commit 8742560e6c
3 changed files with 130 additions and 49 deletions

View File

@@ -11,7 +11,24 @@ import {
QuickReply,
ChatSettings,
} from "./data";
//流量池
//好友接待配置
export function setFriendInjectConfig(params) {
return request("/v1/kefu/ai/friend/set", params, "POST");
}
export function getTrafficPoolList() {
return request(
"/v1/traffic/pool/getPackage",
{
page: 1,
limit: 9999,
},
"GET",
);
}
// 好友列表
export function getWechatFriendList(params) {
return request("/v1/kefu/wechatFriend/list", params, "GET");

View File

@@ -84,7 +84,7 @@ const Person: React.FC<PersonProps> = ({
3. 鼓励大家积极交流
4. 保持群聊环境和谐
请用温馨友好的语调字数控制在200字以内。`
请用温馨友好的语调字数控制在200字以内。`,
);
const [aiGeneratedContent, setAiGeneratedContent] = useState("");
@@ -907,18 +907,21 @@ const Person: React.FC<PersonProps> = ({
{/* 群公告 - 仅在群聊时显示 */}
{isGroup && (
<Card
title="群公告"
className={styles.profileCard}
>
<Card title="群公告" className={styles.profileCard}>
{/* 群聊简介(原群公告) */}
<div
className={styles.infoValue}
onClick={hasGroupManagePermission() ? () => {
setGroupNoticeValue(contractInfo.notice || "");
setIsGroupNoticeModalVisible(true);
} : undefined}
style={{ cursor: hasGroupManagePermission() ? "pointer" : "default" }}
onClick={
hasGroupManagePermission()
? () => {
setGroupNoticeValue(contractInfo.notice || "");
setIsGroupNoticeModalVisible(true);
}
: undefined
}
style={{
cursor: hasGroupManagePermission() ? "pointer" : "default",
}}
>
<div
style={{
@@ -928,19 +931,19 @@ const Person: React.FC<PersonProps> = ({
}}
>
<div
className={styles.bioText}
style={{
maxHeight: "120px",
overflowY: "auto",
paddingRight: "5px",
flex: 1,
whiteSpace: "pre-wrap",
wordBreak: "break-word",
lineHeight: "1.5",
}}
>
{contractInfo.notice || "点击添加群公告"}
</div>
className={styles.bioText}
style={{
maxHeight: "120px",
overflowY: "auto",
paddingRight: "5px",
flex: 1,
whiteSpace: "pre-wrap",
wordBreak: "break-word",
lineHeight: "1.5",
}}
>
{contractInfo.notice || "点击添加群公告"}
</div>
{hasGroupManagePermission() && (
<Button
type="text"
@@ -1147,7 +1150,7 @@ const Person: React.FC<PersonProps> = ({
<Modal
title={`请求添加${selectedMember?.nickname}为好友`}
visible={isAddFriendModalVisible}
open={isAddFriendModalVisible}
onOk={handleSendFriendRequest}
onCancel={() => setIsAddFriendModalVisible(false)}
okText="确定"
@@ -1200,14 +1203,16 @@ const Person: React.FC<PersonProps> = ({
].filter(Boolean)}
>
{!hasGroupManagePermission() && (
<div style={{
marginBottom: "16px",
padding: "12px",
backgroundColor: "#fff7e6",
border: "1px solid #ffd591",
borderRadius: "6px",
color: "#d46b08"
}}>
<div
style={{
marginBottom: "16px",
padding: "12px",
backgroundColor: "#fff7e6",
border: "1px solid #ffd591",
borderRadius: "6px",
color: "#d46b08",
}}
>
</div>
)}
@@ -1215,19 +1220,26 @@ const Person: React.FC<PersonProps> = ({
<Input.TextArea
value={groupNoticeValue}
onChange={e => setGroupNoticeValue(e.target.value)}
placeholder={hasGroupManagePermission() ? "请输入群公告内容或点击AI编写按钮自动生成" : "仅群主可以修改群公告"}
placeholder={
hasGroupManagePermission()
? "请输入群公告内容或点击AI编写按钮自动生成"
: "仅群主可以修改群公告"
}
rows={8}
style={{
resize: "none",
whiteSpace: "pre-wrap",
wordBreak: "break-word",
lineHeight: "1.5"
lineHeight: "1.5",
}}
disabled={!hasGroupManagePermission()}
/>
</div>
<div style={{ fontSize: "12px", color: "#999", lineHeight: "1.4" }}>
💡 {hasGroupManagePermission() ? "AI编写功能将根据默认模板生成专业的群公告内容您可以在生成后进行个性化修改。" : "只有群主才能编辑群公告内容。"}
💡
{hasGroupManagePermission()
? "AI编写功能将根据默认模板生成专业的群公告内容您可以在生成后进行个性化修改。"
: "只有群主才能编辑群公告内容。"}
</div>
</Modal>
@@ -1238,10 +1250,7 @@ const Person: React.FC<PersonProps> = ({
onCancel={() => setIsAiModalVisible(false)}
width={800}
footer={[
<Button
key="cancel"
onClick={() => setIsAiModalVisible(false)}
>
<Button key="cancel" onClick={() => setIsAiModalVisible(false)}>
</Button>,
<Button
@@ -1274,12 +1283,12 @@ const Person: React.FC<PersonProps> = ({
📝 AI提示词
</div>
<Input.TextArea
value={aiPrompt}
onChange={e => setAiPrompt(e.target.value)}
placeholder="请输入AI生成群公告的提示词..."
rows={6}
style={{ resize: "none" }}
/>
value={aiPrompt}
onChange={e => setAiPrompt(e.target.value)}
placeholder="请输入AI生成群公告的提示词..."
rows={6}
style={{ resize: "none" }}
/>
<div style={{ fontSize: "12px", color: "#999", marginTop: "4px" }}>
💡 AI生成更符合您需求的群公告内容
</div>
@@ -1293,13 +1302,19 @@ const Person: React.FC<PersonProps> = ({
<Input.TextArea
value={aiGeneratedContent}
onChange={e => setAiGeneratedContent(e.target.value)}
placeholder={aiGenerating ? "AI正在生成中请稍候..." : "点击上方'生成内容'按钮AI将根据提示词生成群公告"}
placeholder={
aiGenerating
? "AI正在生成中请稍候..."
: "点击上方'生成内容'按钮AI将根据提示词生成群公告"
}
rows={8}
style={{ resize: "none" }}
disabled={aiGenerating}
/>
{aiGeneratedContent && (
<div style={{ fontSize: "12px", color: "#52c41a", marginTop: "4px" }}>
<div
style={{ fontSize: "12px", color: "#52c41a", marginTop: "4px" }}
>
"确认使用"
</div>
)}

View File

@@ -1,9 +1,11 @@
import React, { useState } from "react";
import { Layout, Button, Avatar, Space, Tooltip } from "antd";
import { Layout, Button, Avatar, Space, Tooltip, Dropdown } from "antd";
import {
UserOutlined,
TeamOutlined,
InfoCircleOutlined,
RobotOutlined,
DownOutlined,
} from "@ant-design/icons";
import { ContractData, weChatGroup } from "@/pages/pc/ckbox/data";
import styles from "./ChatWindow.module.scss";
@@ -11,7 +13,7 @@ import styles from "./ChatWindow.module.scss";
import ProfileCard from "./components/ProfileCard";
import MessageEnter from "./components/MessageEnter";
import MessageRecord from "./components/MessageRecord";
import { setFriendInjectConfig } from "@/pages/pc/ckbox/weChat/api";
const { Header, Content } = Layout;
interface ChatWindowProps {
@@ -24,6 +26,34 @@ const ChatWindow: React.FC<ChatWindowProps> = ({ contract }) => {
setShowProfile(!showProfile);
};
const typeOptions = [
{ value: 0, label: "人工接待" },
{ value: 1, label: "AI辅助" },
{ value: 2, label: "AI接管" },
];
const [currentConfig, setCurrentConfig] = useState({
value: 0,
label: "人工接待",
});
// 处理配置选择
const handleConfigChange = option => {
setCurrentConfig({
value: option.value,
label: option.label,
});
// 保存配置到后端
setFriendInjectConfig({
type: option.value,
wechatAccountId: contract.wechatAccountId,
friendId: contract.id,
}).then(res => {
console.log("配置保存成功:", res);
});
};
return (
<Layout className={styles.chatWindow}>
{/* 聊天主体区域 */}
@@ -45,6 +75,25 @@ const ChatWindow: React.FC<ChatWindowProps> = ({ contract }) => {
</div>
</div>
<Space>
{!contract.chatroomId && (
<Dropdown
menu={{
items: typeOptions.map(option => ({
key: option.value,
label: option.label,
onClick: () => handleConfigChange(option),
})),
}}
trigger={["click"]}
placement="bottomRight"
>
<Button type="default" icon={<RobotOutlined />}>
{currentConfig.label}
<DownOutlined />
</Button>
</Dropdown>
)}
<Tooltip title="个人资料">
<Button
onClick={onToggleProfile}