代码提交同步
This commit is contained in:
41
Touchkebao/src/api/ai.ts
Normal file
41
Touchkebao/src/api/ai.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import axios from "axios";
|
||||
import { useUserStore } from "@/store/module/user";
|
||||
|
||||
/**
|
||||
* AI文本生成接口
|
||||
* @param {string} content - 提示词内容
|
||||
* @returns {Promise<string>} - AI生成的文本内容
|
||||
*/
|
||||
export async function generateAiText(content: string): Promise<string> {
|
||||
try {
|
||||
// 获取用户token
|
||||
const { token } = useUserStore.getState();
|
||||
|
||||
// 获取AI接口基础URL
|
||||
const apiBaseUrl = (import.meta as any).env?.VITE_API_BASE_URL || "/api";
|
||||
const fullUrl = `${apiBaseUrl}/v1/ai/doubao/text`;
|
||||
|
||||
// 发送POST请求
|
||||
const response = await axios.post(
|
||||
fullUrl,
|
||||
{
|
||||
content,
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: token ? `Bearer ${token}` : undefined,
|
||||
},
|
||||
timeout: 30000, // AI生成可能需要更长时间
|
||||
}
|
||||
);
|
||||
|
||||
// 返回生成的文本内容
|
||||
// 根据接口返回格式:data.choices[0].message.content
|
||||
return response?.data?.data?.choices?.[0]?.message?.content || "";
|
||||
} catch (error: any) {
|
||||
const errorMessage =
|
||||
error.response?.data?.message || error.message || "AI生成失败";
|
||||
throw new Error(errorMessage);
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,7 @@ import { useCkChatStore } from "@/store/module/ckchat/ckchat";
|
||||
import { useWebSocketStore } from "@/store/module/websocket/websocket";
|
||||
import styles from "./Person.module.scss";
|
||||
import { useWeChatStore } from "@/store/module/weChat/weChat";
|
||||
import { generateAiText } from "@/api/ai";
|
||||
import TwoColumnSelection from "@/components/TwoColumnSelection/TwoColumnSelection";
|
||||
import TwoColumnMemberSelection from "@/components/MemberSelection/TwoColumnMemberSelection";
|
||||
import { FriendSelectionItem } from "@/components/FriendSelection/data";
|
||||
@@ -72,6 +73,20 @@ const Person: React.FC<PersonProps> = ({
|
||||
const [isGroupNoticeModalVisible, setIsGroupNoticeModalVisible] =
|
||||
useState(false);
|
||||
const [confirmLoading, setConfirmLoading] = useState(false);
|
||||
const [aiGenerating, setAiGenerating] = useState(false);
|
||||
const [isAiModalVisible, setIsAiModalVisible] = useState(false);
|
||||
const [aiPrompt, setAiPrompt] = useState(
|
||||
`请为我们的微信群生成一个友好、专业的群公告。
|
||||
|
||||
群公告应该包含:
|
||||
1. 欢迎新成员加入
|
||||
2. 群聊的基本规则和礼仪
|
||||
3. 鼓励大家积极交流
|
||||
4. 保持群聊环境和谐
|
||||
|
||||
请用温馨友好的语调,字数控制在200字以内。`
|
||||
);
|
||||
const [aiGeneratedContent, setAiGeneratedContent] = useState("");
|
||||
|
||||
const currentGroupMembers = useWeChatStore(
|
||||
state => state.currentGroupMembers,
|
||||
@@ -285,6 +300,10 @@ const Person: React.FC<PersonProps> = ({
|
||||
|
||||
// 处理群名称保存
|
||||
const handleSaveGroupName = () => {
|
||||
if (!hasGroupManagePermission()) {
|
||||
messageApi.error("只有群主才能修改群名称");
|
||||
return;
|
||||
}
|
||||
sendCommand("CmdChatroomOperate", {
|
||||
wechatAccountId: contract.wechatAccountId,
|
||||
wechatChatroomId: contract.id,
|
||||
@@ -298,12 +317,20 @@ const Person: React.FC<PersonProps> = ({
|
||||
|
||||
// 点击编辑群名称按钮
|
||||
const handleEditGroupName = () => {
|
||||
if (!hasGroupManagePermission()) {
|
||||
messageApi.error("只有群主才能修改群名称");
|
||||
return;
|
||||
}
|
||||
setGroupNameValue(contractInfo.name || "");
|
||||
setIsEditingGroupName(true);
|
||||
};
|
||||
|
||||
// 处理群公告保存
|
||||
const handleSaveGroupNotice = () => {
|
||||
if (!hasGroupManagePermission()) {
|
||||
messageApi.error("只有群主才能修改群公告");
|
||||
return;
|
||||
}
|
||||
setConfirmLoading(true);
|
||||
sendCommand("CmdChatroomOperate", {
|
||||
wechatAccountId: contract.wechatAccountId,
|
||||
@@ -320,8 +347,46 @@ const Person: React.FC<PersonProps> = ({
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
// 打开AI编写弹框
|
||||
const handleOpenAiModal = () => {
|
||||
if (!hasGroupManagePermission()) {
|
||||
messageApi.error("只有群主才能使用AI编写功能");
|
||||
return;
|
||||
}
|
||||
setIsAiModalVisible(true);
|
||||
setAiGeneratedContent(""); // 清空之前生成的内容
|
||||
};
|
||||
|
||||
// 处理AI生成群公告
|
||||
const handleAiGenerateNotice = async () => {
|
||||
setAiGenerating(true);
|
||||
try {
|
||||
// 调用AI接口生成群公告
|
||||
const aiResponse = await generateAiText(aiPrompt);
|
||||
|
||||
setAiGeneratedContent(aiResponse);
|
||||
messageApi.success("AI生成群公告成功!");
|
||||
} catch (error: any) {
|
||||
console.error("AI生成失败:", error);
|
||||
messageApi.error(error.message || "AI生成失败,请重试");
|
||||
} finally {
|
||||
setAiGenerating(false);
|
||||
}
|
||||
};
|
||||
|
||||
// 确认使用AI生成的内容
|
||||
const handleConfirmAiContent = () => {
|
||||
setGroupNoticeValue(aiGeneratedContent);
|
||||
setIsAiModalVisible(false);
|
||||
messageApi.success("已应用AI生成的群公告内容");
|
||||
};
|
||||
|
||||
// 点击编辑群公告按钮
|
||||
const handleEditGroupNotice = () => {
|
||||
if (!hasGroupManagePermission()) {
|
||||
messageApi.error("只有群主才能修改群公告");
|
||||
return;
|
||||
}
|
||||
setGroupNoticeValue(contract.notice || "");
|
||||
setIsGroupNoticeModalVisible(true);
|
||||
};
|
||||
@@ -585,12 +650,14 @@ const Person: React.FC<PersonProps> = ({
|
||||
{contractInfo.nickname || contractInfo.name}
|
||||
</h4>
|
||||
</Tooltip>
|
||||
<Button
|
||||
type="text"
|
||||
size="small"
|
||||
icon={<EditOutlined />}
|
||||
onClick={handleEditGroupName}
|
||||
/>
|
||||
{hasGroupManagePermission() && (
|
||||
<Button
|
||||
type="text"
|
||||
size="small"
|
||||
icon={<EditOutlined />}
|
||||
onClick={handleEditGroupName}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@@ -835,20 +902,20 @@ const Person: React.FC<PersonProps> = ({
|
||||
</Card>
|
||||
)}
|
||||
|
||||
{/* 个人简介或群公告 */}
|
||||
<Card
|
||||
title={isGroup ? "群公告" : "个人简介"}
|
||||
className={styles.profileCard}
|
||||
>
|
||||
{isGroup ? (
|
||||
// 群聊简介(原群公告)
|
||||
{/* 群公告 - 仅在群聊时显示 */}
|
||||
{isGroup && (
|
||||
<Card
|
||||
title="群公告"
|
||||
className={styles.profileCard}
|
||||
>
|
||||
{/* 群聊简介(原群公告) */}
|
||||
<div
|
||||
className={styles.infoValue}
|
||||
onClick={() => {
|
||||
onClick={hasGroupManagePermission() ? () => {
|
||||
setGroupNoticeValue(contractInfo.notice || "");
|
||||
setIsGroupNoticeModalVisible(true);
|
||||
}}
|
||||
style={{ cursor: "pointer" }}
|
||||
} : undefined}
|
||||
style={{ cursor: hasGroupManagePermission() ? "pointer" : "default" }}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
@@ -858,29 +925,31 @@ const Person: React.FC<PersonProps> = ({
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className={styles.bioText}
|
||||
style={{
|
||||
maxHeight: "120px",
|
||||
overflowY: "auto",
|
||||
paddingRight: "5px",
|
||||
flex: 1,
|
||||
}}
|
||||
>
|
||||
{contractInfo.notice || "点击添加群公告"}
|
||||
</div>
|
||||
<Button
|
||||
type="text"
|
||||
size="small"
|
||||
icon={<EditOutlined />}
|
||||
style={{ marginLeft: "8px" }}
|
||||
/>
|
||||
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"
|
||||
size="small"
|
||||
icon={<EditOutlined />}
|
||||
style={{ marginLeft: "8px" }}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
// 个人简介
|
||||
<p className={styles.bioText}>{contractInfo.bio}</p>
|
||||
)}
|
||||
</Card>
|
||||
</Card>
|
||||
)}
|
||||
|
||||
{isGroup && (
|
||||
<Card title="群成员" className={styles.profileCard}>
|
||||
@@ -1103,22 +1172,136 @@ const Person: React.FC<PersonProps> = ({
|
||||
>
|
||||
取消
|
||||
</Button>,
|
||||
hasGroupManagePermission() && (
|
||||
<Button
|
||||
key="ai-generate"
|
||||
onClick={handleOpenAiModal}
|
||||
style={{
|
||||
background: "linear-gradient(135deg, #667eea 0%, #764ba2 100%)",
|
||||
border: "none",
|
||||
color: "white",
|
||||
}}
|
||||
>
|
||||
🤖 AI编写
|
||||
</Button>
|
||||
),
|
||||
<Button
|
||||
key="submit"
|
||||
type="primary"
|
||||
loading={confirmLoading}
|
||||
onClick={handleSaveGroupNotice}
|
||||
disabled={!hasGroupManagePermission()}
|
||||
>
|
||||
确定
|
||||
</Button>,
|
||||
].filter(Boolean)}
|
||||
>
|
||||
{!hasGroupManagePermission() && (
|
||||
<div style={{
|
||||
marginBottom: "16px",
|
||||
padding: "12px",
|
||||
backgroundColor: "#fff7e6",
|
||||
border: "1px solid #ffd591",
|
||||
borderRadius: "6px",
|
||||
color: "#d46b08"
|
||||
}}>
|
||||
⚠️ 您不是群主,无法修改群公告
|
||||
</div>
|
||||
)}
|
||||
<div style={{ marginBottom: "12px" }}>
|
||||
<Input.TextArea
|
||||
value={groupNoticeValue}
|
||||
onChange={e => setGroupNoticeValue(e.target.value)}
|
||||
placeholder={hasGroupManagePermission() ? "请输入群公告内容,或点击AI编写按钮自动生成" : "仅群主可以修改群公告"}
|
||||
rows={8}
|
||||
style={{
|
||||
resize: "none",
|
||||
whiteSpace: "pre-wrap",
|
||||
wordBreak: "break-word",
|
||||
lineHeight: "1.5"
|
||||
}}
|
||||
disabled={!hasGroupManagePermission()}
|
||||
/>
|
||||
</div>
|
||||
<div style={{ fontSize: "12px", color: "#999", lineHeight: "1.4" }}>
|
||||
💡 提示:{hasGroupManagePermission() ? "AI编写功能将根据默认模板生成专业的群公告内容,您可以在生成后进行个性化修改。" : "只有群主才能编辑群公告内容。"}
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
{/* AI编写群公告弹框 */}
|
||||
<Modal
|
||||
title="AI编写群公告"
|
||||
open={isAiModalVisible}
|
||||
onCancel={() => setIsAiModalVisible(false)}
|
||||
width={800}
|
||||
footer={[
|
||||
<Button
|
||||
key="cancel"
|
||||
onClick={() => setIsAiModalVisible(false)}
|
||||
>
|
||||
取消
|
||||
</Button>,
|
||||
<Button
|
||||
key="generate"
|
||||
type="primary"
|
||||
loading={aiGenerating}
|
||||
onClick={handleAiGenerateNotice}
|
||||
disabled={!aiPrompt.trim()}
|
||||
style={{
|
||||
background: "linear-gradient(135deg, #667eea 0%, #764ba2 100%)",
|
||||
border: "none",
|
||||
}}
|
||||
>
|
||||
{aiGenerating ? "生成中..." : "🤖 生成内容"}
|
||||
</Button>,
|
||||
<Button
|
||||
key="confirm"
|
||||
type="primary"
|
||||
onClick={handleConfirmAiContent}
|
||||
disabled={!aiGeneratedContent}
|
||||
>
|
||||
确认使用
|
||||
</Button>,
|
||||
]}
|
||||
>
|
||||
<Input.TextArea
|
||||
value={groupNoticeValue}
|
||||
onChange={e => setGroupNoticeValue(e.target.value)}
|
||||
placeholder="请输入内容"
|
||||
rows={6}
|
||||
/>
|
||||
<div style={{ display: "flex", flexDirection: "column", gap: "16px" }}>
|
||||
{/* 提示词区域 */}
|
||||
<div>
|
||||
<div style={{ marginBottom: "8px", fontWeight: "500" }}>
|
||||
📝 AI提示词
|
||||
</div>
|
||||
<Input.TextArea
|
||||
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>
|
||||
</div>
|
||||
|
||||
{/* 生成内容区域 */}
|
||||
<div>
|
||||
<div style={{ marginBottom: "8px", fontWeight: "500" }}>
|
||||
🤖 AI生成的群公告
|
||||
</div>
|
||||
<Input.TextArea
|
||||
value={aiGeneratedContent}
|
||||
onChange={e => setAiGeneratedContent(e.target.value)}
|
||||
placeholder={aiGenerating ? "AI正在生成中,请稍候..." : "点击上方'生成内容'按钮,AI将根据提示词生成群公告"}
|
||||
rows={8}
|
||||
style={{ resize: "none" }}
|
||||
disabled={aiGenerating}
|
||||
/>
|
||||
{aiGeneratedContent && (
|
||||
<div style={{ fontSize: "12px", color: "#52c41a", marginTop: "4px" }}>
|
||||
✅ 内容已生成,您可以编辑后点击"确认使用"应用到群公告
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
{/* 群管理弹窗组件 */}
|
||||
|
||||
Reference in New Issue
Block a user