264 lines
10 KiB
PHP
264 lines
10 KiB
PHP
<?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());
|
||
}
|
||
}
|
||
|
||
} |