love_php/app/Http/Controllers/ChatController.php
2026-04-02 09:20:51 +08:00

264 lines
10 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Http\Controllers;
use App\Contracts\UserContract;
use App\Models\App\MsgHistory;
use App\Models\BadWord;
use App\Models\ChatMessage;
use App\Models\MessageLinkman;
use App\Models\Notice;
use App\Services\ChatSessionService;
use App\Services\IMService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Validator;
use Log;
class ChatController extends Controller
{
use \App\Traits\ChatMessage;
protected $userCon;
public function __construct(UserContract $userCon)
{
$this->userCon = $userCon;
}
public function session(Request $request, ChatSessionService $s)
{
try {
$user = auth()->user();
//好友请求数
$friend_count = $this->userCon->systemNoticeCount($type = 'friend') ?: 0;
//系统消息未读数
$system_count = $this->userCon->newNoticeCount($user->id);
//关注消息未读数
$follow_count = $this->userCon->systemNoticeCount($type = 'follow') ?: 0;
//来访未读数
$preview_count = $this->userCon->visitCount($user->id);
//是否真人认证
$my_real_approved = $user->is_real_approved;
//系统通知
$system_notice = Notice::where(['user_id' => auth()->id(), 'send_user_id' => 1])->select('content', 'type', 'type_id', 'created_at')->orderByDesc('id', 'desc')->first();
if ($system_notice) {
$system_notice->count = Notice::where(['user_id' => auth()->id(), 'send_user_id' => 1, 'status' => 0])->count();
}
$session = $s->session();
return $this->success('ok', compact('friend_count', 'system_count', 'follow_count',
'preview_count', 'my_real_approved', 'system_notice', 'session'));
} catch (\Exception $e) {
$this->getError($e);
return $this->failure($e->getMessage() . '---' . $e->getLine());
}
}
/**
* 会话
*/
public function sessionV2(Request $request, ChatSessionService $s)
{
// Log::info("获取聊天联系人");
try {
$user = auth()->user();
//好友请求数
$friend_count = $this->userCon->systemNoticeCount($type = 'friend') ?: 0;
//系统消息未读数
$system_count = $this->userCon->newNoticeCount($user->id);
//关注消息未读数
$follow_count = $this->userCon->systemNoticeCount($type = 'follow') ?: 0;
//来访未读数
$preview_count = $this->userCon->visitCount($user->id);
//是否真人认证
$my_real_approved = $user->is_real_approved;
//系统通知
$system_notice = Notice::where(['user_id' => auth()->id(), 'send_user_id' => 1])->select('content', 'type', 'type_id', 'created_at')->orderByDesc('id', 'desc')->first();
if ($system_notice) {
$system_notice->count = Notice::where(['user_id' => auth()->id(), 'send_user_id' => 1, 'status' => 0])->count();
}
$session = $s->session();
return $this->success('ok', compact('friend_count', 'system_count', 'follow_count',
'preview_count', 'my_real_approved', 'system_notice', 'session'));
} catch (\Exception $e) {
$this->getError($e);
return $this->failure($e->getMessage() . '---' . $e->getLine());
}
}
public function searchLinkingAndTeam(Request $request)
{
$user = auth()->user();
$keyword = $request->keyword;
$teams = \DB::table("teams as t")->leftJoin("user_team as ut", 'ut.team_id', '=', 't.id')
->where("ut.user_id", $user->id);
if ($keyword) {
$teams = $teams->where("t.tname","like","%". $keyword ."%");
}
$teams = $teams->selectRaw("ufutx_t.tid as id, ufutx_t.tname as name, ufutx_t.icon as pic, 'group_chat' as chat_type, '' as type");
$linkings = \DB::table('users as u')->leftJoin("linkings as l", 'l.user_linking_id', '=', 'u.id' )
->where("l.user_id", $user->id);
if ($keyword) {
$linkings = $linkings->where("u.nickname","like","%". $keyword ."%");
}
$linkings = $linkings->selectRaw("ufutx_u.id, ufutx_u.nickname as name, ufutx_u.photo as pic, 'linkmen' as chat_type, ufutx_u.type as type")->union($teams)->paginate();
return $this->success("ok", $linkings);
}
/**
* 发送消息
* @param Request $request
* @return \Illuminate\Http\JsonResponse|string
*/
public function sendMessage(Request $request)
{
try {
$user = auth()->user();
$params = $request->all();
$validator = Validator::make($params, [
'to_user_id' => 'required',
'type' => 'required'
], [
'to_user_id.required' => '接收者id不能为空',
]);
$error = $validator->errors()->first();
if ($error) {
return $this->failure($error);
}
$to_user_id = $request->input('to_user_id');
$type = $request->input('type');//类型text文本 picture图片
if (!in_array($type, ['text', 'picture'])) {
return $this->failure('未知类型');
}
$content = $request->input('content', '');
if ($type == 'text' && !strlen($content)) {
return $this->failure('文本不能为空');
}
$together = [$user->id, $to_user_id];
//双方的历史消息数
$history_count = ChatMessage::query()->whereIn('user_id', $together)
->whereIn('other_user_id', $together)
->count();
//1.加好友,第一条发送内容为图片,提醒用户:注意交友安全
//2.第一条发送内容发送敏感词后3条内容内有图片也提醒用户注意交友安全
//由于加好友的时候发送过一条申请的消息记录 发到云信了 所以历史消息数从1开始判断
$cache_key = "chat:monitor:{$user->id}_to_{$to_user_id}";
$warning = false;//提示注意交友安全的状态
$first_bad_word = Redis::get($cache_key);//第一条消息是否是敏感词
$map1 = $type == 'picture' && $history_count == 1;
$map2 = false;
if ($type == 'picture' && $first_bad_word) {
$first_id = ChatMessage::query()->whereIn('user_id', $together)
->whereIn('other_user_id', $together)
->orderBy('id')
->value('id');
$history_count = ChatMessage::query()->where('user_id', $user->id)
->where('other_user_id', $to_user_id)
->where('id', '!=', $first_id)
->count();
if (in_array($history_count, [0, 1, 2])) {
$map2 = true;
} else {
Redis::del($cache_key);
}
}
if ($map1 || $map2) {
$warning = true;
}
if ($user->id != 69938) {
if ($type == 'text') {
$bad_word = BadWord::whereRaw("instr('$content',content) > 0")->first();
if ($history_count == 1) {
Redis::set($cache_key, 1);
}
if ($bad_word) {
return $this->failure('检测到有敏感词,发送失败');
} else {
$content = $this->filterContent($content);
}
}
}
// 增加联系人信息
MessageLinkman::firstOrCreate(['user_id'=>$user->id, 'other_user_id'=>$params['to_user_id']]);
MessageLinkman::firstOrCreate(['user_id'=>$params['to_user_id'], 'other_user_id'=>$user->id]);
return $this->success('ok', compact('content', 'warning'));
} catch (\Exception $e) {
return $this->failure();
}
}
/**
* 消息撤回
* @param Request $request
* @return \Illuminate\Http\JsonResponse|string
*/
public function messageRecall(Request $request)
{
try {
$user = auth()->user();
$msg_id = $request->input('msg_id');
$type = $request->input('type');
$from = $user->id;
$to = $request->input('to');
if (!in_array($type, ['linkmen', 'group_chat'])) {
return $this->failure('参数错误');
}
$msg = null;
switch ($type) {
case 'linkmen'://单聊
$type = 7;
$where = ['user_id' => $from, 'other_user_id' => $to, 'msgid' => $msg_id];
$msg = ChatMessage::where($where)->first();
break;
case 'group_chat'://群聊
$type = 8;
$where = ['user_id' => $from, 'team_id' => $to, 'msgid' => $msg_id];
$msg = MsgHistory::where($where)->first();
break;
}
if (!$msg) {
return $this->failure('已过有效期,无法撤回');
}
if ($msg->is_recall) {
return $this->failure('该消息已撤回');
}
$im_service = new IMService(env('IM_APP_KEY'), env('IM_APP_SECRET'));
$res = $im_service->messageRecall($msg_id, $type, $from, $to);
$code = $res['code'] ?? null;
if ($code == 414) {
return $this->failure('已过有效期,无法撤回');
}
if ($code == 200) {
$msg->is_recall = 1;
$msg->save();
}
return $this->success('ok');
} catch (\Exception $e) {
$this->getError($e);
return $this->failure($e->getMessage());
}
}
}