Browse Source

AI聊天界面接口

master
wanghongjun 4 months ago
parent
commit
d0ba355456
  1. 139
      app/enterprise/controller/Chat.php
  2. 4
      app/enterprise/controller/Im.php
  3. 11
      app/enterprise/model/Message.php
  4. 31
      app/enterprise/model/User.php
  5. 1
      app/lang/en_us.php
  6. 1
      app/lang/zh_cn.php
  7. BIN
      public/static/common/img/ai.png

139
app/enterprise/controller/Chat.php

@ -0,0 +1,139 @@
<?php
namespace app\enterprise\controller;
use app\BaseController;
use app\enterprise\model\Message;
use utils\Curl;
class Chat extends BaseController
{
protected $error = '';
public function sendChat()
{
$content = $this->request->param('content');
// 限制文字内容长度
$text = strip_tags($content);
$textLen = mb_strlen($text);
if ($textLen > 2048) {
return warning(lang('im.msgContentLimit') . $textLen);
}
// 接入聊天内容检测服务
event('GreenText',['content'=>$content,'service'=>"chat_detection"]);
$postData = $this->curlChat($content);
$userInfo = $this->userInfo;
$uid = $userInfo['id'];
$newContent = $postData['choices'][0]['message']['content'];
$newContent = '<p>' . $newContent . "</p>";
if ($this->error) {
return warning($this->error);
}
$chat_identify = '-2-'.$uid;
$data = [
'from_user'=> 1,
'to_user'=> $uid,
'content'=>str_encipher($newContent,true),
'chat_identify'=>'-2-'.$uid,
'create_time'=>time(),
'type'=>'text',
'is_group'=>4,
'is_read'=>1,
'is_top'=>0,
'is_notice'=>1,
'is_last'=>1,
'at'=>[],
'pid'=>0,
'extends'=>['chat'=>$newContent],
];
$data['id']=\utils\Str::getUuid();
Message::update(['is_last'=>0],['chat_identify'=>$chat_identify]);
$message=new Message();
$message->save($data);
$msgId=$message->msg_id;
$msgInfo=$data;
$msgInfo['status']='successd';
$msgInfo['msg_id']=$msgId;
$msgInfo['user_id']=1;
$msgInfo['sendTime']=time()*1000;
$msgInfo['toContactId']='ai_chat';
$msgInfo['to_user']='ai_chat';
$msgInfo['content']=$newContent;
$msgInfo['fromUser']=[
'id'=>'-2',
'avatar'=>getMainHost().'/static/common/img/ai.png',
'displayName'=>lang('system.ai')
];
wsSendMsg($uid,'simple',$msgInfo);
return success('', $msgInfo);
}
protected function curlChat($content)
{
$url = "https://api.siliconflow.cn/v1/chat/completions";
$data = [
'model' => 'deepseek-ai/Deepseek-V3',
'max_tokens' => 512,
'enable_thinking' => true,
'thinking_budget' => 4096,
'min_p' => 0.05,
'temperature' => 0.7,
'top_p' => 0.7,
'frequency_penalty' => 0.5,
'n' => 1,
'stream' => false,
'stop' => [],
'messages' => [
[
'role' => 'system',
'content' => $content
]
],
];
$key = 'sk-tfvzhlgatdoczhfcwgfruetxogmrhcyhhqdirwefadmvfibs';
$header = [
"Authorization: Bearer {$key}",
'Content-Type: application/json'
];
$json_data = json_encode($data);
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => $json_data,
CURLOPT_HTTPHEADER => $header,
]);
// 跳过证书验证(不推荐在生产环境使用)
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
$this->error = "cURL Error #:" . $err;
return false;
}
$response = json_decode($response,true);
if (!is_array($response)) {
$this->error = "cURL Error #:" . $response;
return false;
}
return $response;
}
}

4
app/enterprise/controller/Im.php

@ -361,6 +361,10 @@ class Im extends BaseController
if ($v['status'] == 2) {
$status_str = "failed";
}
if ($v['is_group'] == 4) {
$staticUser = User::staticUser();
$fromUser = $staticUser['aiChat'];
}
$data[] = [
'msg_id' => $v['msg_id'],
'id' => $v['id'],

11
app/enterprise/model/Message.php

@ -48,7 +48,7 @@ class Message extends BaseModel
public function sendMessage($param,$globalConfig=false){
$is_group = $param['is_group'] ?? 0;
$uid=self::$uid;
if($param['toContactId']==-1){
if($param['toContactId']==-1 || $param['toContactId']==-2){
$is_group=0;
}
// 如果是系统账号,直接禁言
@ -77,7 +77,7 @@ class Message extends BaseModel
event('GreenText',['content'=>$param['content'],'service'=>"chat_detection"]);
}
$chatSetting = $globalConfig['chatInfo'];
if($param['toContactId']!=-1){
if($param['toContactId']!=-1 && $param['toContactId']!=-2){
if ($is_group == 0) {
$kefuUser = [];
$status = $chatSetting['autoAddUser']['status'] ?? 0;
@ -185,6 +185,11 @@ class Message extends BaseModel
$atList=GroupUser::where([['group_id','=',$toContactId],['status','=',1],['user_id','<>',$param['user_id']]])->column('user_id');
}
$at=$atList ? implode(',',$atList) : null;
if ($toContactId==-1) {
$is_group = 3;
}elseif ($toContactId==-2) {
$is_group = 4;
}
$data=[
'from_user'=>$param['user_id'],
'to_user'=>$toContactId,
@ -194,7 +199,7 @@ class Message extends BaseModel
'chat_identify'=>$chat_identify,
'create_time'=>time(),
'type'=>$param['type'],
'is_group'=>$toContactId==-1 ? 3 : $is_group,
'is_group'=>$is_group,
'is_read'=>$is_group ? 1 : 0,
'file_id'=>$param['file_id'] ?? 0,
"file_cate"=>$param['file_cate'] ?? 0,

31
app/enterprise/model/User.php

@ -40,6 +40,12 @@ class User extends BaseModel
'displayName'=>lang('system.favor'),
'avatar'=>getMainHost().'/static/common/img/file_transfer.png',
'name_py'=>'wodeshoucang',
],
'aiChat'=>[
'id'=>-2,
'displayName'=>lang('system.ai'),
'avatar'=>getMainHost().'/static/common/img/ai.png',
'name_py'=>'aiduihua',
]
];
}
@ -285,6 +291,7 @@ class User extends BaseModel
$staticList=self::staticUser();
$adminNotice=$staticList['adminNotice'];
$fileTransfer=$staticList['fileTransfer'];
$aiChat=$staticList['aiChat'];
$count=Message::where(['chat_identify'=>$adminNotice['id']])->count();
$createTime=Message::where(['chat_identify'=>$adminNotice['id']])->order('id desc')->value('create_time');
$sendTime=0;
@ -296,6 +303,12 @@ class User extends BaseModel
$fileSendTime=$fileLast['create_time'] ?? '';
$content =$fileLast['content'] ?? '';
$friend=Friend::where(['create_user'=>$uid,'friend_user_id'=>$fileTransfer['id']])->find();
// AI
$ai_chat_identify=chat_identify($uid,$aiChat['id']);
$aiFileLast=Message::where(['is_last'=>1,'chat_identify'=>$ai_chat_identify])->find();
$aiFileSendTime=$aiFileLast['create_time'] ?? '';
$aiContent =$aiFileLast['content'] ?? '';
$aiFriend=Friend::where(['create_user'=>$uid,'friend_user_id'=>$fileTransfer['id']])->find();
$notice=[
[
'id'=>$adminNotice['id'],
@ -333,6 +346,24 @@ class User extends BaseModel
'is_online'=>0,
'index'=>"[1]系统消息",
],
[
'id'=>$aiChat['id'],
'user_id'=>$aiChat['id'],
'displayName'=>$aiChat['displayName'],
'realname'=>$aiChat['displayName'],
'name_py'=>$aiChat['name_py'],
'avatar'=>$aiChat['avatar'],
'lastContent'=> str_encipher($aiContent,false) ?: '传输你的文件',
'unread'=>0,
'lastSendTime'=>((is_string($aiFileSendTime) ? strtotime($aiFileSendTime) : $aiFileSendTime) * 1000) ?: time() * 1000,
'is_group'=>4,
'setting'=>[],
'type'=>'text',
'is_top'=>$aiFriend['is_top'] ?? 0,
'is_notice'=>$aiFriend['is_notice'] ?? 1,
'is_online'=>0,
'index'=>"[1]系统消息",
],
];
return $notice;

1
app/lang/en_us.php

@ -30,6 +30,7 @@ return [
'message'=>"System Message",
'announce'=>"{:num} announcements",
'transFile'=>"Transfer your files",
'ai'=>"AI dialogue",
],
'messageType' => [
'other' => "[Unsupported message type]",

1
app/lang/zh_cn.php

@ -29,6 +29,7 @@ return [
'message'=>"系统消息",
'announce'=>"{:num} 宣布",
'transFile'=>"传输您的文件",
'ai'=>"AI对话",
],
'messageType'=>[
'other'=>"[暂不支持的消息类型]",

BIN
public/static/common/img/ai.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Loading…
Cancel
Save