hyperf-chat/app/Controller/Api/V1/TalkMessageController.php

444 lines
15 KiB
PHP
Raw Normal View History

2021-07-05 21:52:44 +08:00
<?php
2021-07-29 23:30:42 +08:00
declare(strict_types=1);
2021-07-05 21:52:44 +08:00
namespace App\Controller\Api\V1;
2021-07-21 23:31:41 +08:00
use App\Cache\UnreadTalkCache;
2021-07-20 23:12:18 +08:00
use App\Constants\TalkEventConstant;
use App\Constants\TalkModeConstant;
use App\Event\TalkEvent;
2021-07-05 21:52:44 +08:00
use App\Model\EmoticonItem;
use App\Model\FileSplitUpload;
2021-08-14 17:31:21 +08:00
use App\Service\TalkForwardService;
2021-07-08 23:44:43 +08:00
use App\Service\TalkMessageService;
2021-07-06 23:32:14 +08:00
use App\Support\UserRelation;
2021-07-05 21:52:44 +08:00
use App\Service\EmoticonService;
use App\Service\TalkService;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\RequestMapping;
use Hyperf\HttpServer\Annotation\Middleware;
use App\Middleware\JWTAuthMiddleware;
use League\Flysystem\Filesystem;
2021-09-11 12:41:28 +08:00
use Psr\Http\Message\ResponseInterface;
2021-07-05 21:52:44 +08:00
/**
* Class TalkController
* @Controller(prefix="/api/v1/talk/message")
* @Middleware(JWTAuthMiddleware::class)
*
* @package App\Controller\Api\V1
*/
class TalkMessageController extends CController
{
/**
* @Inject
* @var TalkService
*/
public $talkService;
2021-07-08 23:44:43 +08:00
/**
* @Inject
* @var TalkMessageService
*/
public $talkMessageService;
2021-08-09 20:58:13 +08:00
/**
* 发送文本消息
2021-09-11 12:41:28 +08:00
*
2021-08-09 20:58:13 +08:00
* @RequestMapping(path="text", methods="post")
*/
2021-09-11 12:41:28 +08:00
public function text(): ResponseInterface
2021-08-09 20:58:13 +08:00
{
2021-08-09 21:58:36 +08:00
$params = $this->request->inputs(['talk_type', 'receiver_id', 'text']);
$this->validate($params, [
'talk_type' => 'required|in:1,2',
'receiver_id' => 'required|integer|min:1',
'text' => 'required|max:65535',
]);
2021-09-11 12:41:28 +08:00
di()->get(TalkMessageService::class)->insertText([
2021-08-09 21:58:36 +08:00
'talk_type' => $params['talk_type'],
'user_id' => $this->uid(),
'receiver_id' => $params['receiver_id'],
'content' => $params['text'],
]);
return $this->response->success();
2021-08-09 20:58:13 +08:00
}
2021-07-05 21:52:44 +08:00
/**
* 发送代码块消息
2021-09-11 12:41:28 +08:00
*
2021-07-05 21:52:44 +08:00
* @RequestMapping(path="code", methods="post")
*/
2021-09-11 12:41:28 +08:00
public function code(): ResponseInterface
2021-07-05 21:52:44 +08:00
{
$params = $this->request->inputs(['talk_type', 'receiver_id', 'lang', 'code']);
$this->validate($params, [
'talk_type' => 'required|in:1,2',
'receiver_id' => 'required|integer|min:1',
'lang' => 'required',
'code' => 'required'
]);
$user_id = $this->uid();
2021-07-29 23:30:42 +08:00
if (!UserRelation::isFriendOrGroupMember($user_id, (int)$params['receiver_id'], (int)$params['talk_type'])) {
2021-07-05 21:52:44 +08:00
return $this->response->fail('暂不属于好友关系或群聊成员,无法发送聊天消息!');
}
2021-09-11 12:41:28 +08:00
$isTrue = $this->talkMessageService->insertCode([
2021-07-05 21:52:44 +08:00
'talk_type' => $params['talk_type'],
'user_id' => $user_id,
'receiver_id' => $params['receiver_id'],
], [
'user_id' => $user_id,
'code_lang' => $params['lang'],
'code' => $params['code']
]);
2021-07-13 22:53:13 +08:00
if (!$isTrue) return $this->response->fail('消息发送失败!');
2021-07-05 21:52:44 +08:00
return $this->response->success();
}
/**
* 发送图片消息
2021-09-11 12:41:28 +08:00
*
2021-07-05 21:52:44 +08:00
* @RequestMapping(path="image", methods="post")
*/
2021-09-11 12:41:28 +08:00
public function image(Filesystem $filesystem): ResponseInterface
2021-07-05 21:52:44 +08:00
{
$params = $this->request->inputs(['talk_type', 'receiver_id']);
$this->validate($params, [
'talk_type' => 'required|in:1,2',
'receiver_id' => 'required|integer|min:1'
]);
$user_id = $this->uid();
2021-07-29 23:30:42 +08:00
if (!UserRelation::isFriendOrGroupMember($user_id, (int)$params['receiver_id'], (int)$params['talk_type'])) {
2021-07-05 21:52:44 +08:00
return $this->response->fail('暂不属于好友关系或群聊成员,无法发送聊天消息!');
}
$file = $this->request->file('image');
if (!$file || !$file->isValid()) {
return $this->response->fail();
}
$ext = $file->getExtension();
if (!in_array($ext, ['jpg', 'png', 'jpeg', 'gif', 'webp'])) {
return $this->response->fail('图片格式错误目前仅支持jpg、png、jpeg、gif和webp');
}
try {
$path = 'media/images/talks/' . date('Ymd') . '/' . create_image_name($ext, getimagesize($file->getRealPath()));
$filesystem->write($path, file_get_contents($file->getRealPath()));
} catch (\Exception $e) {
return $this->response->fail();
}
// 创建图片消息记录
2021-09-11 12:41:28 +08:00
$isTrue = $this->talkMessageService->insertFile([
2021-07-05 21:52:44 +08:00
'talk_type' => $params['talk_type'],
'user_id' => $user_id,
'receiver_id' => $params['receiver_id'],
], [
'user_id' => $user_id,
'file_suffix' => $ext,
'file_size' => $file->getSize(),
'save_dir' => $path,
'original_name' => $file->getClientFilename(),
]);
2021-07-13 22:53:13 +08:00
if (!$isTrue) return $this->response->fail('图片上传失败!');
2021-07-05 21:52:44 +08:00
return $this->response->success();
}
/**
* 发送文件消息
2021-09-11 12:41:28 +08:00
*
2021-07-05 21:52:44 +08:00
* @RequestMapping(path="file", methods="post")
*/
2021-09-11 12:41:28 +08:00
public function file(Filesystem $filesystem): ResponseInterface
2021-07-05 21:52:44 +08:00
{
$params = $this->request->inputs(['talk_type', 'receiver_id', 'hash_name']);
$this->validate($params, [
'talk_type' => 'required|in:1,2',
'receiver_id' => 'required|integer|min:1',
'hash_name' => 'required',
]);
$user_id = $this->uid();
2021-07-29 23:30:42 +08:00
if (!UserRelation::isFriendOrGroupMember($user_id, (int)$params['receiver_id'], (int)$params['talk_type'])) {
2021-07-05 21:52:44 +08:00
return $this->response->fail('暂不属于好友关系或群聊成员,无法发送聊天消息!');
}
$file = FileSplitUpload::where('user_id', $user_id)->where('hash_name', $params['hash_name'])->where('file_type', 1)->first();
if (!$file || empty($file->save_dir)) {
return $this->response->fail('文件不存在...');
}
try {
$save_dir = "files/talks/" . date('Ymd') . '/' . create_random_filename($file->file_ext);
$filesystem->copy($file->save_dir, $save_dir);
} catch (\Exception $e) {
return $this->response->fail('文件不存在...');
}
2021-09-11 12:41:28 +08:00
$isTrue = $this->talkMessageService->insertFile([
2021-07-05 21:52:44 +08:00
'talk_type' => $params['talk_type'],
'user_id' => $user_id,
'receiver_id' => $params['receiver_id']
], [
'user_id' => $user_id,
'file_source' => 1,
'original_name' => $file->original_name,
'file_suffix' => $file->file_ext,
'file_size' => $file->file_size,
'save_dir' => $save_dir,
]);
2021-07-13 22:53:13 +08:00
if (!$isTrue) return $this->response->fail('表情发送失败!');
2021-07-05 21:52:44 +08:00
return $this->response->success();
}
/**
* 发送投票消息
2021-09-11 12:41:28 +08:00
*
2021-07-05 21:52:44 +08:00
* @RequestMapping(path="vote", methods="post")
*/
2021-09-11 12:41:28 +08:00
public function vote(): ResponseInterface
2021-07-05 21:52:44 +08:00
{
2021-07-12 23:19:58 +08:00
$params = $this->request->all();
$this->validate($params, [
'receiver_id' => 'required|integer|min:1',
'mode' => 'required|integer|in:0,1',
'title' => 'required',
2021-07-17 21:27:48 +08:00
'options' => 'required|array',
2021-07-12 23:19:58 +08:00
]);
2021-07-05 21:52:44 +08:00
2021-07-12 23:19:58 +08:00
$user_id = $this->uid();
2021-07-29 23:30:42 +08:00
if (!UserRelation::isFriendOrGroupMember($user_id, (int)$params['receiver_id'], TalkModeConstant::GROUP_CHAT)) {
2021-07-17 00:07:24 +08:00
return $this->response->fail('暂不属于好友关系或群聊成员,无法发送聊天消息!');
}
2021-07-12 23:19:58 +08:00
2021-09-11 12:41:28 +08:00
$isTrue = $this->talkMessageService->insertVote([
2021-07-20 23:12:18 +08:00
'talk_type' => TalkModeConstant::GROUP_CHAT,
2021-07-12 23:19:58 +08:00
'user_id' => $user_id,
'receiver_id' => $params['receiver_id'],
], [
2021-07-17 21:27:48 +08:00
'user_id' => $user_id,
'title' => $params['title'],
'answer_mode' => $params['mode'],
'answer_option' => $params['options'],
2021-07-12 23:19:58 +08:00
]);
2021-07-13 22:53:13 +08:00
if (!$isTrue) return $this->response->fail('发起投票失败!');
return $this->response->success();
2021-07-05 21:52:44 +08:00
}
2021-07-17 00:07:24 +08:00
/**
* 投票处理
2021-09-11 12:41:28 +08:00
*
2021-07-17 00:07:24 +08:00
* @RequestMapping(path="vote/handle", methods="post")
*/
2021-09-11 12:41:28 +08:00
public function handleVote(): ResponseInterface
2021-07-17 00:07:24 +08:00
{
$params = $this->request->inputs(['record_id', 'options']);
$this->validate($params, [
'record_id' => 'required|integer|min:1',
2021-07-17 21:27:48 +08:00
'options' => 'required',
2021-07-17 00:07:24 +08:00
]);
2021-07-18 23:41:25 +08:00
$params['options'] = array_filter(explode(',', $params['options']));
if (!$params['options']) {
return $this->response->fail('投票失败,请稍后再试!');
}
2021-07-19 23:58:14 +08:00
[$isTrue, $cache] = $this->talkMessageService->handleVote($this->uid(), $params);
2021-07-17 00:07:24 +08:00
if (!$isTrue) return $this->response->fail('投票失败,请稍后再试!');
2021-07-19 23:58:14 +08:00
return $this->response->success($cache);
2021-07-17 00:07:24 +08:00
}
2021-07-05 21:52:44 +08:00
/**
* 发送表情包消息
2021-09-11 12:41:28 +08:00
*
2021-07-05 21:52:44 +08:00
* @RequestMapping(path="emoticon", methods="post")
*/
2021-09-11 12:41:28 +08:00
public function emoticon(): ResponseInterface
2021-07-05 21:52:44 +08:00
{
$params = $this->request->inputs(['talk_type', 'receiver_id', 'emoticon_id']);
$this->validate($params, [
'talk_type' => 'required|in:1,2',
'receiver_id' => 'required|integer|min:1',
'emoticon_id' => 'required|integer|min:1',
]);
$user_id = $this->uid();
2021-07-29 23:30:42 +08:00
if (!UserRelation::isFriendOrGroupMember($user_id, (int)$params['receiver_id'], (int)$params['talk_type'])) {
2021-07-05 21:52:44 +08:00
return $this->response->fail('暂不属于好友关系或群聊成员,无法发送聊天消息!');
}
2021-07-09 19:40:43 +08:00
$emoticon = EmoticonItem::where('id', $params['emoticon_id'])->where('user_id', $user_id)->first();
2021-07-05 21:52:44 +08:00
2021-07-06 23:32:14 +08:00
if (!$emoticon) return $this->response->fail('表情不存在!');
2021-07-05 21:52:44 +08:00
2021-09-11 12:41:28 +08:00
$isTrue = $this->talkMessageService->insertFile([
2021-07-05 21:52:44 +08:00
'talk_type' => $params['talk_type'],
'user_id' => $user_id,
'receiver_id' => $params['receiver_id'],
], [
'user_id' => $user_id,
'file_suffix' => $emoticon->file_suffix,
'file_size' => $emoticon->file_size,
'save_dir' => $emoticon->url,
'original_name' => '图片表情',
]);
2021-07-13 22:53:13 +08:00
if (!$isTrue) return $this->response->fail('表情发送失败!');
2021-07-05 21:52:44 +08:00
return $this->response->success();
}
/**
* 转发消息记录
2021-09-11 12:41:28 +08:00
*
2021-07-05 21:52:44 +08:00
* @RequestMapping(path="forward", methods="post")
*/
2021-09-11 12:41:28 +08:00
public function forward(TalkForwardService $forwardService): ResponseInterface
2021-07-05 21:52:44 +08:00
{
2021-09-11 12:41:28 +08:00
$params = $this->request->inputs([
'talk_type', 'receiver_id', 'records_ids', 'forward_mode', 'receive_user_ids', 'receive_group_ids'
]);
2021-07-05 21:52:44 +08:00
$this->validate($params, [
'talk_type' => 'required|in:1,2',
'receiver_id' => 'required|integer|min:1',
'records_ids' => 'required', // 聊天记录ID多个逗号拼接
'forward_mode' => 'required|in:1,2',// 转发方方式[1:逐条转发;2:合并转发;]
]);
2021-08-14 17:31:21 +08:00
$user_id = $this->uid();
// 判断好友或者群关系
if (!UserRelation::isFriendOrGroupMember($user_id, (int)$params['receiver_id'], (int)$params['talk_type'])) {
return $this->response->fail('暂不属于好友关系或群聊成员,无法发送聊天消息!');
}
2021-07-05 21:52:44 +08:00
$receive_user_ids = $receive_group_ids = [];
2021-08-14 17:31:21 +08:00
$func = function (array $ids, int $talk_type) {
return array_map(function ($id) use ($talk_type) {
return ['talk_type' => $talk_type, 'id' => (int)$id];
}, $ids);
};
2021-07-05 21:52:44 +08:00
if (isset($params['receive_user_ids']) && !empty($params['receive_user_ids'])) {
2021-08-14 17:31:21 +08:00
$receive_user_ids = $func($params['receive_user_ids'], TalkModeConstant::PRIVATE_CHAT);
2021-07-05 21:52:44 +08:00
}
if (isset($params['receive_group_ids']) && !empty($params['receive_group_ids'])) {
2021-08-14 17:31:21 +08:00
$receive_group_ids = $func($params['receive_group_ids'], TalkModeConstant::GROUP_CHAT);
2021-07-05 21:52:44 +08:00
}
2021-08-14 17:31:21 +08:00
// 需要转发的好友或者群组
2021-07-05 21:52:44 +08:00
$items = array_merge($receive_user_ids, $receive_group_ids);
2021-08-14 17:31:21 +08:00
if ($params['forward_mode'] == 1) {// 逐条转发
$ids = $forwardService->multiSplitForward($user_id, (int)$params['receiver_id'], (int)$params['talk_type'], $params['records_ids'], $items);
2021-07-05 21:52:44 +08:00
} else {// 合并转发
2021-08-14 17:31:21 +08:00
$ids = $forwardService->multiMergeForward($user_id, (int)$params['receiver_id'], (int)$params['talk_type'], $params['records_ids'], $items);
2021-07-05 21:52:44 +08:00
}
2021-07-06 23:32:14 +08:00
if (!$ids) return $this->response->fail('转发失败!');
2021-07-05 21:52:44 +08:00
if ($receive_user_ids) {
foreach ($receive_user_ids as $v) {
2021-07-21 23:31:41 +08:00
UnreadTalkCache::getInstance()->increment($user_id, $v['id']);
2021-07-05 21:52:44 +08:00
}
}
// 消息推送队列
foreach ($ids as $value) {
2021-07-20 23:12:18 +08:00
event()->dispatch(new TalkEvent(TalkEventConstant::EVENT_TALK, [
2021-07-12 23:19:58 +08:00
'sender_id' => $user_id,
'receiver_id' => $value['receiver_id'],
'talk_type' => $value['talk_type'],
'record_id' => $value['record_id'],
]));
2021-07-05 21:52:44 +08:00
}
return $this->response->success([], '转发成功...');
}
/**
* 收藏聊天图片
2021-09-11 12:41:28 +08:00
*
2021-07-05 21:52:44 +08:00
* @RequestMapping(path="collect", methods="post")
*/
2021-09-11 12:41:28 +08:00
public function collect(EmoticonService $service): ResponseInterface
2021-07-05 21:52:44 +08:00
{
$params = $this->request->inputs(['record_id']);
$this->validate($params, [
'record_id' => 'required|integer'
]);
2021-08-14 17:31:21 +08:00
[$isTrue, $data] = $service->collect($this->uid(), (int)$params['record_id']);
2021-07-05 21:52:44 +08:00
if (!$isTrue) return $this->response->fail('添加表情失败!');
return $this->response->success([
'emoticon' => $data
]);
}
/**
* 撤销聊天记录
2021-09-11 12:41:28 +08:00
*
2021-07-05 21:52:44 +08:00
* @RequestMapping(path="revoke", methods="post")
*/
2021-09-11 12:41:28 +08:00
public function revoke(): ResponseInterface
2021-07-05 21:52:44 +08:00
{
$params = $this->request->inputs(['record_id']);
$this->validate($params, [
2021-07-09 19:40:43 +08:00
'record_id' => 'required|integer|min:1'
2021-07-05 21:52:44 +08:00
]);
2021-08-14 17:31:21 +08:00
[$isTrue, $message,] = $this->talkService->revokeRecord($this->uid(), (int)$params['record_id']);
2021-07-06 23:32:14 +08:00
if (!$isTrue) return $this->response->fail($message);
2021-07-05 21:52:44 +08:00
2021-07-06 23:32:14 +08:00
return $this->response->success([], $message);
2021-07-05 21:52:44 +08:00
}
/**
* 删除聊天记录
2021-09-11 12:41:28 +08:00
*
2021-07-05 21:52:44 +08:00
* @RequestMapping(path="delete", methods="post")
*/
2021-09-11 12:41:28 +08:00
public function delete(): ResponseInterface
2021-07-05 21:52:44 +08:00
{
$params = $this->request->inputs(['talk_type', 'receiver_id', 'record_id']);
$this->validate($params, [
'talk_type' => 'required|in:1,2',
'receiver_id' => 'required|integer|min:1',
'record_id' => 'required|ids',
]);
$isTrue = $this->talkService->removeRecords(
$this->uid(),
2021-08-14 17:31:21 +08:00
(int)$params['talk_type'],
(int)$params['receiver_id'],
2021-07-05 21:52:44 +08:00
parse_ids($params['record_id'])
);
return $isTrue
? $this->response->success([], '删除成功...')
: $this->response->fail('删除失败!');
}
}