代码提交同步
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace app\ai\controller;
|
||||
|
||||
use app\common\util\JwtUtil;
|
||||
use think\facade\Env;
|
||||
|
||||
class DouBaoAI
|
||||
@@ -31,12 +32,17 @@ class DouBaoAI
|
||||
{
|
||||
$this->__init();
|
||||
|
||||
$content = input('content','');
|
||||
if (empty($content)){
|
||||
return json_encode(['code' => 500, 'msg' => '提示词缺失']);
|
||||
}
|
||||
|
||||
// 发送请求
|
||||
$params = [
|
||||
'model' => 'doubao-1-5-pro-32k-250115',
|
||||
'messages' => [
|
||||
['role' => 'system', 'content' => '你是人工智能助手.'],
|
||||
['role' => 'user', 'content' => '厦门天气'],
|
||||
['role' => 'user', 'content' => $content],
|
||||
],
|
||||
/*'extra_headers' => [
|
||||
'x-is-encrypted' => true
|
||||
|
||||
28
Server/application/chukebao/config/route.php
Normal file
28
Server/application/chukebao/config/route.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 设备管理模块路由配置
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
use think\facade\Route;
|
||||
|
||||
// 定义RESTful风格的API路由
|
||||
Route::group('v1/', function () {
|
||||
|
||||
Route::group('kefu/', function () {
|
||||
|
||||
});
|
||||
|
||||
|
||||
})->middleware(['jwt']);
|
||||
|
||||
|
||||
// 客服登录
|
||||
Route::group('v1/kefu', function () {
|
||||
Route::post('login', 'app\chukebao\controller\LoginController@index'); // 获取好友列表
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return [];
|
||||
101
Server/application/chukebao/controller/LoginController.php
Normal file
101
Server/application/chukebao/controller/LoginController.php
Normal file
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
namespace app\chukebao\controller;
|
||||
|
||||
use app\common\controller\BaseController;
|
||||
use app\common\util\JwtUtil;
|
||||
use Exception;
|
||||
use library\ResponseHelper;
|
||||
use app\api\controller\UserController;
|
||||
use think\Db;
|
||||
|
||||
/**
|
||||
* 认证控制器
|
||||
* 处理用户登录和身份验证
|
||||
*/
|
||||
class LoginController extends BaseController
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* 用户登录
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function index($username = '', $password = '',$verifySessionId = '',$verifyCode = '')
|
||||
{
|
||||
|
||||
$username = !empty($username) ? $username : $this->request->param('account', '');
|
||||
$password = !empty($password) ? $password : $this->request->param('password', '');
|
||||
$verifySessionId =!empty($verifySessionId) ? $verifySessionId : $this->request->param('verifySessionId', '');
|
||||
$verifyCode = !empty($verifyCode) ? $verifyCode : $this->request->param('verifyCode', '');
|
||||
|
||||
if (empty($username) || empty($password)) {
|
||||
return ResponseHelper::error('请输入账号密码');
|
||||
}
|
||||
|
||||
// 验证账号是否存在(支持账号或手机号登录)
|
||||
$user = Db::name('users')
|
||||
->where(function ($query) use ($username) {
|
||||
$query->where('account', $username)->whereOr('phone', $username);
|
||||
})
|
||||
->where('passwordMd5', md5($password))
|
||||
->find();
|
||||
|
||||
if (empty($user)) {
|
||||
return ResponseHelper::error('账号不存在或密码错误');
|
||||
}
|
||||
|
||||
if($user['status'] != 1){
|
||||
return ResponseHelper::error('账号已禁用');
|
||||
}
|
||||
|
||||
|
||||
//登录参数
|
||||
$params = [
|
||||
'grant_type' => 'password',
|
||||
'username' => $user['account'],
|
||||
'password' => !empty($user['passwordLocal']) ? localDecrypt($user['passwordLocal']) : $password
|
||||
];
|
||||
|
||||
try {
|
||||
// 调用登录接口获取token
|
||||
$headerData = ['client:kefu-client'];
|
||||
if (!empty($verifySessionId) && !empty($verifyCode)){
|
||||
$headerData[] = 'verifysessionid:'.$verifySessionId;
|
||||
$headerData[] = 'verifycode:'.$verifyCode;
|
||||
}
|
||||
$header = setHeader($headerData, '', 'plain');
|
||||
$result = requestCurl('https://s2.siyuguanli.com:9991/token', $params, 'POST', $header);
|
||||
$result = handleApiResponse($result);
|
||||
|
||||
if (isset($result['access_token']) && !empty($result['access_token'])) {
|
||||
$userData['kefuData']['token'] = $result;
|
||||
$headerData = ['client:kefu-client'];
|
||||
$header = setHeader($headerData, $result['access_token']);
|
||||
$result2 = requestCurl('https://s2.siyuguanli.com:9991/api/account/self', [], 'GET', $header, 'json');
|
||||
$self = handleApiResponse($result2);
|
||||
$userData['kefuData']['self'] = $self;
|
||||
}else{
|
||||
return ResponseHelper::error($result['error_description']);
|
||||
}
|
||||
|
||||
unset($user['passwordMd5'],$user['deleteTime'],$user['passwordLocal']);
|
||||
$userData['member'] = $user;
|
||||
|
||||
// 生成JWT令牌
|
||||
$expired = 86400 * 30;
|
||||
$token = JwtUtil::createToken($user, $expired);
|
||||
$token_expired = time() + $expired;
|
||||
|
||||
|
||||
$userData['token'] = $token;
|
||||
$userData['token_expired'] = $token_expired;
|
||||
|
||||
|
||||
return ResponseHelper::success($userData, '登录成功');
|
||||
} catch (Exception $e) {
|
||||
return ResponseHelper::error($e->getMessage(), $e->getCode());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -138,7 +138,7 @@ class PasswordLoginController extends BaseController
|
||||
$params['typeId']
|
||||
);
|
||||
//同时登录客服系统
|
||||
if (!empty($userData['member']['passwordLocal'])){
|
||||
/* if (!empty($userData['member']['passwordLocal'])){
|
||||
$params = [
|
||||
'grant_type' => 'password',
|
||||
'username' => $userData['member']['account'],
|
||||
@@ -157,7 +157,7 @@ class PasswordLoginController extends BaseController
|
||||
$self = handleApiResponse($result);
|
||||
$userData['kefuData']['self'] = $self;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
return ResponseHelper::success($userData, '登录成功');
|
||||
} catch (Exception $e) {
|
||||
return ResponseHelper::error($e->getMessage(), $e->getCode());
|
||||
|
||||
@@ -145,12 +145,6 @@ Route::group('v1/', function () {
|
||||
})->middleware(['jwt']);
|
||||
|
||||
|
||||
// 客服登录
|
||||
Route::group('v1/kefu', function () {
|
||||
Route::post('login', 'app\cunkebao\controller\KeFuLoginController@index'); // 获取好友列表
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
Route::group('v1/api/scenarios', function () {
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\cunkebao\controller;
|
||||
|
||||
use app\common\controller\BaseController;
|
||||
use Exception;
|
||||
use library\ResponseHelper;
|
||||
use app\api\controller\UserController;
|
||||
|
||||
/**
|
||||
* 认证控制器
|
||||
* 处理用户登录和身份验证
|
||||
*/
|
||||
class KeFuLoginController extends BaseController
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* 用户登录
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function index($username = '', $password = '',$verifySessionId = '',$verifyCode = '')
|
||||
{
|
||||
$username = !empty($username) ? $username : $this->request->param('username', '');
|
||||
$password = !empty($password) ? $password : $this->request->param('password', '');
|
||||
|
||||
$verifySessionId =!empty($verifySessionId) ? $verifySessionId : $this->request->param('verifySessionId', '');
|
||||
$verifyCode = !empty($verifyCode) ? $verifyCode : $this->request->param('verifyCode', '');
|
||||
|
||||
|
||||
if (empty($username) || empty($password)) {
|
||||
return ResponseHelper::error('请输入账号密码');
|
||||
}
|
||||
|
||||
|
||||
//登录参数
|
||||
$params = [
|
||||
'grant_type' => 'password',
|
||||
'username' => $username,
|
||||
'password' => $password
|
||||
];
|
||||
|
||||
if (!empty($verifySessionId) && !empty($verifyCode)){
|
||||
$params[] = 'verifysessionid:' . $verifySessionId;
|
||||
$params[] = 'verifycode:' . $verifyCode;
|
||||
}
|
||||
|
||||
|
||||
//获取验证码
|
||||
// $UserController = new UserController();
|
||||
// $verifyCode = $UserController->getVerifyCode(true);
|
||||
// $verifyCode = json_decode($verifyCode, true);
|
||||
// if ($verifyCode['code'] != 200) {
|
||||
// exit_data($verifyCode);
|
||||
// }
|
||||
|
||||
try {
|
||||
// 调用登录接口获取token
|
||||
$headerData = ['client:kefu-client'];
|
||||
$header = setHeader($headerData, '', 'plain');
|
||||
$result = requestCurl('https://s2.siyuguanli.com:9991/token', $params, 'POST', $header);
|
||||
$token = handleApiResponse($result);
|
||||
$userData['kefuData']['token'] = $token;
|
||||
if (isset($token['access_token']) && !empty($token['access_token'])) {
|
||||
$headerData = ['client:kefu-client'];
|
||||
$header = setHeader($headerData, $token['access_token']);
|
||||
$result = requestCurl('https://s2.siyuguanli.com:9991/api/account/self', [], 'GET', $header, 'json');
|
||||
$self = handleApiResponse($result);
|
||||
$userData['kefuData']['self'] = $self;
|
||||
}
|
||||
|
||||
return ResponseHelper::success($userData, '登录成功');
|
||||
} catch (Exception $e) {
|
||||
return ResponseHelper::error($e->getMessage(), $e->getCode());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -36,7 +36,10 @@ include __DIR__ . '/../application/superadmin/config/route.php';
|
||||
// 加载CozeAI模块路由配置
|
||||
include __DIR__ . '/../application/cozeai/config/route.php';
|
||||
|
||||
// 加载OpenAiAI模块路由配置
|
||||
// 加载AI模块路由配置
|
||||
include __DIR__ . '/../application/ai/config/route.php';
|
||||
|
||||
// 加载存客宝模块路由配置
|
||||
include __DIR__ . '/../application/chukebao/config/route.php';
|
||||
|
||||
return [];
|
||||
|
||||
7634
Touchkebao/package-lock.json
generated
Normal file
7634
Touchkebao/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
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