From 77cd0103d7a0c62de7d0dff156c5a7ef743b8757 Mon Sep 17 00:00:00 2001 From: gzydong Date: Fri, 27 Nov 2020 19:48:41 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Amqp/Consumer/ChatMessageConsumer.php | 40 ++++++++++++- app/Amqp/Producer/ChatMessageProducer.php | 3 +- app/Bootstrap/ServerStart.php | 1 + app/Cache/ApplyNumCache.php | 2 +- app/Controller/Api/V1/ArticleController.php | 63 ++++++++++++++++++++- app/Controller/Api/V1/AuthController.php | 2 +- app/Controller/Api/V1/GroupController.php | 13 ++++- app/Controller/Api/V1/UsersController.php | 53 +++++++++++++---- app/Model/UsersFriend.php | 11 +++- app/Service/ArticleService.php | 27 +++++++++ app/Service/UploadService.php | 2 +- 11 files changed, 197 insertions(+), 20 deletions(-) diff --git a/app/Amqp/Consumer/ChatMessageConsumer.php b/app/Amqp/Consumer/ChatMessageConsumer.php index 69d1961..cdb5b28 100644 --- a/app/Amqp/Consumer/ChatMessageConsumer.php +++ b/app/Amqp/Consumer/ChatMessageConsumer.php @@ -23,6 +23,8 @@ use App\Service\SocketFDService; use App\Service\SocketRoomService; /** + * 消息推送消费者队列 + * * @Consumer(name="聊天消息消费者",enable=true) */ class ChatMessageConsumer extends ConsumerMessage @@ -58,11 +60,24 @@ class ChatMessageConsumer extends ConsumerMessage */ private $socketRoomService; + /** + * 推送的消息类型推送绑定事件方法 + */ const EVENTS = [ + // 聊天消息事件 'event_talk' => 'onConsumeTalk', + + // 键盘输入事件 'event_keyboard' => 'onConsumeKeyboard', + + // 用户在线状态事件 'event_online_status' => 'onConsumeOnlineStatus', + + // 聊天消息推送事件 'event_revoke_talk' => 'onConsumeRevokeTalk', + + // 好友申请相关事件 + 'event_friend_apply' => 'onConsumeFriendApply' ]; /** @@ -192,7 +207,7 @@ class ChatMessageConsumer extends ConsumerMessage unset($notifyInfo, $userInfo, $membersIds); break; case 4://会话记录消息 - $forward = ['num' => 0,'list' => []]; + $forward = ['num' => 0, 'list' => []]; $forwardInfo = ChatRecordsForward::where('record_id', $result->id)->first(['records_id', 'text']); if ($forwardInfo) { @@ -300,6 +315,7 @@ class ChatMessageConsumer extends ConsumerMessage */ public function onConsumeRevokeTalk(array $data, AMQPMessage $message) { + /** @var ChatRecord */ $record = ChatRecord::where('id', $data['data']['record_id'])->first(['id', 'source', 'user_id', 'receive_id']); $fds = []; @@ -329,4 +345,26 @@ class ChatMessageConsumer extends ConsumerMessage return Result::ACK; } + + /** + * 好友申请消息 + * + * @param array $data + * @param AMQPMessage $message + */ + public function onConsumeFriendApply(array $data, AMQPMessage $message) + { + $fds = $this->socketFDService->findUserFds($data['data']['receive']); + + $fds = array_unique($fds); + $server = server(); + foreach ($fds as $fd) { + $fd = intval($fd); + if ($server->exist($fd)) { + $server->push($fd, json_encode(['event_friend_apply', $data['data']])); + } + } + + return Result::ACK; + } } diff --git a/app/Amqp/Producer/ChatMessageProducer.php b/app/Amqp/Producer/ChatMessageProducer.php index 05091a3..48e76fb 100644 --- a/app/Amqp/Producer/ChatMessageProducer.php +++ b/app/Amqp/Producer/ChatMessageProducer.php @@ -18,7 +18,8 @@ class ChatMessageProducer extends ProducerMessage 'event_talk', 'event_keyboard', 'event_online_status', - 'event_revoke_talk' + 'event_revoke_talk', + 'event_friend_apply' ]; /** diff --git a/app/Bootstrap/ServerStart.php b/app/Bootstrap/ServerStart.php index f0b6949..0d53ca9 100644 --- a/app/Bootstrap/ServerStart.php +++ b/app/Bootstrap/ServerStart.php @@ -23,6 +23,7 @@ class ServerStart extends ServerStartCallback { stdout_log()->info(sprintf('服务运行ID : %s', SERVER_RUN_ID)); + // 维护服务运行状态 $this->setTimeOut(); Timer::tick(15000, function () { $this->setTimeOut(); diff --git a/app/Cache/ApplyNumCache.php b/app/Cache/ApplyNumCache.php index fea2da3..b78b0bd 100644 --- a/app/Cache/ApplyNumCache.php +++ b/app/Cache/ApplyNumCache.php @@ -30,7 +30,7 @@ class ApplyNumCache */ public static function setInc(int $user_id) { - return redis()->hincrby(self::KEY, $user_id, 1); + return redis()->hincrby(self::KEY, strval($user_id), 1); } /** diff --git a/app/Controller/Api/V1/ArticleController.php b/app/Controller/Api/V1/ArticleController.php index 60163a2..164f0b6 100644 --- a/app/Controller/Api/V1/ArticleController.php +++ b/app/Controller/Api/V1/ArticleController.php @@ -4,12 +4,14 @@ declare(strict_types=1); namespace App\Controller\Api\V1; use App\Service\ArticleService; +use App\Service\UploadService; use App\Support\RedisLock; 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 Hyperf\Utils\Str; /** * Class ArticleController @@ -27,6 +29,12 @@ class ArticleController extends CController */ private $articleService; + /** + * @inject + * @var UploadService + */ + private $uploadService; + /** * 获取笔记分类列表 * @@ -313,7 +321,27 @@ class ArticleController extends CController */ public function uploadArticleImage() { + $file = $this->request->file('image'); + if (!$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'); + } + + //获取图片信息 + $imgInfo = getimagesize($file->getRealPath()); + + $path = $this->uploadService->media($file, 'media/images/notes/', create_image_name($ext, $imgInfo[0], $imgInfo[1])); + if (!$path) { + return $this->response->fail(); + } + + return $this->response->success([ + 'save_path' => get_media_url($path) + ]); } /** @@ -409,8 +437,41 @@ class ArticleController extends CController */ public function uploadArticleAnnex() { + $params = $this->request->inputs(['article_id']); + $this->validate($params, [ + 'article_id' => 'required|integer|min:0' + ]); + $file = $this->request->file('annex'); - $file->isValid(); + if (!$file->isValid()) { + return $this->response->fail('上传文件验证失败...'); + } + + $annex = [ + 'file_suffix' => $file->getExtension(), + 'file_size' => $file->getSize(), + 'save_dir' => '', + 'original_name' => $file->getClientFilename() + ]; + + $path = $this->uploadService->media($file, + 'files/notes/' . date('Ymd'), + "[{$annex['file_suffix']}]" . uniqid() . Str::random(16) . '.' . 'tmp' + ); + + if (!$path) { + return $this->response->fail(); + } + + $annex['save_dir'] = $path; + $insId = $this->articleService->insertArticleAnnex($this->uid(), (int)$params['article_id'], $annex); + if (!$insId) { + return $this->response->fail('附件上传失败,请稍后再试...'); + } + + $annex['id'] = $insId; + + return $this->response->success($annex, '笔记附件上传成功...'); } /** diff --git a/app/Controller/Api/V1/AuthController.php b/app/Controller/Api/V1/AuthController.php index b4dd7b0..323b9c0 100644 --- a/app/Controller/Api/V1/AuthController.php +++ b/app/Controller/Api/V1/AuthController.php @@ -183,7 +183,7 @@ class AuthController extends CController /** * 发送验证码 * - * @RequestMapping(path="send-code", methods="post") + * @RequestMapping(path="send-verify-code", methods="post") * * @return \Psr\Http\Message\ResponseInterface */ diff --git a/app/Controller/Api/V1/GroupController.php b/app/Controller/Api/V1/GroupController.php index fd57419..60abde8 100644 --- a/app/Controller/Api/V1/GroupController.php +++ b/app/Controller/Api/V1/GroupController.php @@ -54,25 +54,32 @@ class GroupController extends CController */ public function create() { - $params = $this->request->all(); + $params = $this->request->inputs(['group_name', 'uids']); $this->validate($params, [ 'group_name' => 'required', 'uids' => 'required', ]); $friend_ids = array_filter(explode(',', $params['uids'])); + $friend_ids = array_unique($friend_ids); $user_id = $this->uid(); [$isTrue, $data] = $this->groupService->create($user_id, [ 'name' => $params['group_name'], 'avatar' => $params['avatar'] ?? '', 'profile' => $params['group_profile'] ?? '' - ], array_unique($friend_ids)); + ], $friend_ids); if (!$isTrue) { return $this->response->fail('创建群聊失败,请稍后再试...'); } + // 加入聊天室 + $friend_ids[] = $user_id; + foreach ($friend_ids as $uid) { + $this->socketRoomService->addRoomMember($uid, $data['group_id']); + } + // ...消息推送队列 $this->producer->produce( new ChatMessageProducer('event_talk', [ @@ -134,7 +141,7 @@ class GroupController extends CController return $this->response->fail('邀请好友加入群聊失败...'); } - // 移出聊天室 + // 加入聊天室 foreach ($uids as $uid) { $this->socketRoomService->addRoomMember($uid, $params['group_id']); } diff --git a/app/Controller/Api/V1/UsersController.php b/app/Controller/Api/V1/UsersController.php index 3bf4e34..d7c1920 100644 --- a/app/Controller/Api/V1/UsersController.php +++ b/app/Controller/Api/V1/UsersController.php @@ -18,6 +18,8 @@ use App\Support\SendEmailCode; use App\Service\FriendService; use App\Service\UserService; use App\Service\SocketFDService; +use App\Amqp\Producer\ChatMessageProducer; +use Hyperf\Amqp\Producer; /** * Class UsersController @@ -47,6 +49,12 @@ class UsersController extends CController */ private $socketFDService; + /** + * @Inject + * @var Producer + */ + private $producer; + /** * 获取我的好友列表 * @@ -247,12 +255,27 @@ class UsersController extends CController return $this->response->fail('用户不存在...'); } - if (!$this->friendService->addFriendApply($this->uid(), $params['friend_id'], $params['remarks'])) { + $user_id = $this->uid(); + if (!$this->friendService->addFriendApply($user_id, (int)$params['friend_id'], $params['remarks'])) { return $this->response->fail('发送好友申请失败...'); } + // 好友申请未读消息数自增 + ApplyNumCache::setInc((int)$params['friend_id']); + //判断对方是否在线。如果在线发送消息通知 - // ... + if ($this->socketFDService->isOnlineAll((int)$params['friend_id'])) { + $this->producer->produce( + new ChatMessageProducer('event_friend_apply', [ + 'sender' => $user_id, + 'receive' => (int)$params['friend_id'], + 'type' => 1, + 'status' => 1, + 'remark' => '' + ]) + ); + } + return $this->response->success([], '发送好友申请成功...'); } @@ -270,15 +293,25 @@ class UsersController extends CController 'remarks' => 'present', ]); - $isTrue = $this->friendService->handleFriendApply($this->uid(), $params['apply_id'], $params['remarks']); - //判断是否是同意添加好友 - if ($isTrue) { - //... 推送处理消息 + $isTrue = $this->friendService->handleFriendApply($this->uid(), (int)$params['apply_id'], $params['remarks']); + if (!$isTrue) { + return $this->response->fail('处理失败...'); } - return $isTrue - ? $this->response->success([], '处理成功...') - : $this->response->fail('处理失败...'); + //判断对方是否在线。如果在线发送消息通知 +// if ($this->socketFDService->isOnlineAll((int)$params['friend_id'])) { +// $this->producer->produce( +// new ChatMessageProducer('event_friend_apply', [ +// 'sender' => $user_id, +// 'receive' => (int)$params['friend_id'], +// 'type' => 1, +// 'status' => 1, +// 'remark' => '' +// ]) +// ); +// } + + return $this->response->success([], '处理成功...'); } /** @@ -293,7 +326,7 @@ class UsersController extends CController 'apply_id' => 'required|integer', ]); - $isTrue = $this->friendService->delFriendApply($this->uid(), $params['apply_id']); + $isTrue = $this->friendService->delFriendApply($this->uid(), (int)$params['apply_id']); return $isTrue ? $this->response->success([], '删除成功...') : $this->response->fail('删除失败...'); diff --git a/app/Model/UsersFriend.php b/app/Model/UsersFriend.php index 46f4790..45ffd72 100644 --- a/app/Model/UsersFriend.php +++ b/app/Model/UsersFriend.php @@ -35,7 +35,16 @@ class UsersFriend extends BaseModel * * @var array */ - protected $fillable = []; + protected $fillable = [ + 'user1', + 'user2', + 'user1_remark', + 'user2_remark', + 'active', + 'status', + 'agree_time', + 'created_at' + ]; /** * The attributes that should be cast to native types. diff --git a/app/Service/ArticleService.php b/app/Service/ArticleService.php index 9f86468..6afda8c 100644 --- a/app/Service/ArticleService.php +++ b/app/Service/ArticleService.php @@ -598,4 +598,31 @@ class ArticleService extends BaseService return $info->delete(); } + + /** + * 添加笔记附件 + * + * @param int $user_id 用户id + * @param int $article_id 笔记ID + * @param array $annex 笔记附件信息 + * @return bool + */ + public function insertArticleAnnex(int $user_id, int $article_id, array $annex) + { + if (!Article::where('id', $article_id)->where('user_id', $user_id)->exists()) { + return false; + } + + $result = ArticleAnnex::create([ + 'user_id' => $user_id, + 'article_id' => $article_id, + 'file_suffix' => $annex['file_suffix'], + 'file_size' => $annex['file_size'], + 'save_dir' => $annex['save_dir'], + 'original_name' => $annex['original_name'], + 'created_at' => date('Y-m-d H:i:s') + ]); + + return $result ? $result->id : false; + } } diff --git a/app/Service/UploadService.php b/app/Service/UploadService.php index 4f81504..523466e 100644 --- a/app/Service/UploadService.php +++ b/app/Service/UploadService.php @@ -39,7 +39,7 @@ class UploadService extends BaseService public function media(UploadedFile $file, string $dir, string $filename) { $save_dir = $this->driver($dir); - $this->makeDirectory($dir); + $this->makeDirectory($save_dir); $file->moveTo(sprintf('%s/%s', $save_dir, $filename)); return $file->isMoved() ? sprintf('/%s/%s', trim($dir, '/'), $filename) : false;