diff --git a/.env.example b/.env.example index 8b2e916..032b4ec 100644 --- a/.env.example +++ b/.env.example @@ -41,10 +41,3 @@ MAIL_PASSWORD=xxxx MAIL_FROM_ADDRESS=xxxx@163.com MAIL_FROM_NAME="xxxxx" MAIL_ENCRYPTION=ssl - -# ---- Rabbit MQ 配置 ---- -AMQP_HOST=127.0.0.1 -AMQP_PORT=5672 -AMQP_USER=guest -AMQP_PASSWORD=guest -AMQP_VHOST=/im diff --git a/README.md b/README.md index a197a89..6cc0908 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,6 @@ Lumen-IM 是一个网页版在线即时聊天项目,前端使用 Element-ui + - JSON - PDO - Redis >= 5.0.0 - - AMQP ## 4、相关文档 [Hyperf 框架](https://hyperf.wiki/2.0/#/README) @@ -32,11 +31,11 @@ Lumen-IM 是一个网页版在线即时聊天项目,前端使用 Element-ui + ## 5、项目安装 1. 下载源码包 2. 安装框架依赖包执行 `compsoer install` 命令 [项目根目录下执行] -2. 拷贝项目根目录下 .env.example 文件为 .env 并正确配置相关参数(mysql、redis、rabbitmq) +2. 拷贝项目根目录下 .env.example 文件为 .env 并正确配置相关参数(mysql、redis) 3. 执行数据库迁移文件命令生成相关数据表 `php bin/hyperf.php migrate` 4. 启动运行项目 `php bin/hyperf.php start` -注 :[项目运行之前请确保 Mysql、Redis、RabbitMQ 及 Nginx 服务] +注 :[项目运行之前请确保 Mysql、Redis 及 Nginx 服务] ## Nginx 相关配置(代理 swoole 服务) ##### 配置 Http 服务 @@ -129,7 +128,7 @@ server { ``` ### 注意事项 -1. 请确保 PHP 安装 openssl、redis、amqp 扩展 +1. 请确保 PHP 安装 openssl、redis 扩展 2. 请确保 Swoole 扩展开启 openssl 扩展 ``` [root@iZuf6cs69fbc86cwpu9iv3Z vhost]# php --ri swoole diff --git a/app/Amqp/Producer/ChatMessageProducer.php b/app/Amqp/Producer/ChatMessageProducer.php deleted file mode 100644 index 792ad8a..0000000 --- a/app/Amqp/Producer/ChatMessageProducer.php +++ /dev/null @@ -1,62 +0,0 @@ - - * @link https://github.com/gzydong/hyperf-chat - */ - -namespace App\Amqp\Producer; - -use App\Constants\SocketConstants; -use Hyperf\Amqp\Message\ProducerMessage; -use Hyperf\Amqp\Message\Type; - -/** - * 消息生产者 - * - * @package App\Amqp\Producer - */ -class ChatMessageProducer extends ProducerMessage -{ - /** - * 交换机类型 - * - * @var string - */ - public $type = Type::FANOUT; - - /** - * 交换机名称 - * - * @var string - */ - public $exchange = SocketConstants::CONSUMER_MESSAGE_EXCHANGE; - - /** - * 实例化处理 - * - * @param string $event 事件名 - * @param array $data 数据 - * @param array $options 其它参数 - */ - public function __construct(string $event, array $data, array $options = []) - { - $message = [ - 'uuid' => uniqid((strval(mt_rand(0, 1000)))), - 'event' => $event, - 'data' => $data, - 'options' => $options - ]; - - $this->payload = $message; - } - - public function getPayload() - { - return $this->payload; - } -} diff --git a/app/Constants/RedisSubscribeChan.php b/app/Constants/RedisSubscribeChan.php new file mode 100644 index 0000000..b38a557 --- /dev/null +++ b/app/Constants/RedisSubscribeChan.php @@ -0,0 +1,8 @@ +socketClientService->isOnlineAll($params['friend_id'])) { - push_amqp(new ChatMessageProducer(SocketConstants::EVENT_FRIEND_APPLY, [ - 'apply_id' => $result->id, - 'type' => 1, - ])); + MessageProducer::publish( + MessageProducer::create(SocketConstants::EVENT_FRIEND_APPLY, [ + 'apply_id' => $result->id, + 'type' => 1, + ]) + ); } return $this->response->success([], '发送好友申请成功...'); @@ -101,10 +104,12 @@ class ContactsApplyController extends CController // 判断对方是否在线。如果在线发送消息通知 if ($this->socketClientService->isOnlineAll($friend_id)) { - push_amqp(new ChatMessageProducer(SocketConstants::EVENT_FRIEND_APPLY, [ - 'apply_id' => (int)$params['apply_id'], - 'type' => 2, - ])); + MessageProducer::publish( + MessageProducer::create(SocketConstants::EVENT_FRIEND_APPLY, [ + 'apply_id' => (int)$params['apply_id'], + 'type' => 2, + ]) + ); } return $this->response->success([], '处理成功...'); diff --git a/app/Controller/Api/V1/GroupController.php b/app/Controller/Api/V1/GroupController.php index 815c807..d7b87a5 100644 --- a/app/Controller/Api/V1/GroupController.php +++ b/app/Controller/Api/V1/GroupController.php @@ -13,6 +13,7 @@ namespace App\Controller\Api\V1; use App\Cache\SocketRoom; use App\Constants\TalkType; use App\Service\UserService; +use App\Support\MessageProducer; use Hyperf\Di\Annotation\Inject; use Hyperf\HttpServer\Annotation\Controller; use Hyperf\HttpServer\Annotation\RequestMapping; @@ -76,13 +77,14 @@ class GroupController extends CController SocketRoom::getInstance()->addRoomMember(strval($data['group_id']), $uid); } - // ... 消息推送队列 - push_amqp(new ChatMessageProducer(SocketConstants::EVENT_TALK, [ - 'sender_id' => $user_id, - 'receiver_id' => (int)$data['group_id'], - 'talk_type' => TalkType::GROUP_CHAT, - 'record_id' => (int)$data['record_id'] - ])); + MessageProducer::publish( + MessageProducer::create(SocketConstants::EVENT_TALK, [ + 'sender_id' => $user_id, + 'receiver_id' => (int)$data['group_id'], + 'talk_type' => TalkType::GROUP_CHAT, + 'record_id' => (int)$data['record_id'] + ]) + ); return $this->response->success([ 'group_id' => $data['group_id'] @@ -141,13 +143,14 @@ class GroupController extends CController SocketRoom::getInstance()->addRoomMember($params['group_id'], $uid); } - // 消息推送队列 - push_amqp(new ChatMessageProducer(SocketConstants::EVENT_TALK, [ - 'sender_id' => $user_id, - 'receiver_id' => (int)$params['group_id'], - 'talk_type' => TalkType::GROUP_CHAT, - 'record_id' => $record_id - ])); + MessageProducer::publish( + MessageProducer::create(SocketConstants::EVENT_TALK, [ + 'sender_id' => $user_id, + 'receiver_id' => (int)$params['group_id'], + 'talk_type' => TalkType::GROUP_CHAT, + 'record_id' => $record_id + ]) + ); return $this->response->success([], '好友已成功加入群聊...'); } @@ -174,13 +177,14 @@ class GroupController extends CController // 移出聊天室 SocketRoom::getInstance()->delRoomMember($params['group_id'], $user_id); - // 消息推送队列 - push_amqp(new ChatMessageProducer(SocketConstants::EVENT_TALK, [ - 'sender_id' => $user_id, - 'receiver_id' => (int)$params['group_id'], - 'talk_type' => TalkType::GROUP_CHAT, - 'record_id' => $record_id - ])); + MessageProducer::publish( + MessageProducer::create(SocketConstants::EVENT_TALK, [ + 'sender_id' => $user_id, + 'receiver_id' => (int)$params['group_id'], + 'talk_type' => TalkType::GROUP_CHAT, + 'record_id' => $record_id + ]) + ); return $this->response->success([], '已成功退出群组...'); } @@ -245,13 +249,14 @@ class GroupController extends CController SocketRoom::getInstance()->delRoomMember($params['group_id'], strval($uid)); } - // 消息推送队列 - push_amqp(new ChatMessageProducer(SocketConstants::EVENT_TALK, [ - 'sender_id' => $user_id, - 'receiver_id' => (int)$params['group_id'], - 'talk_type' => TalkType::GROUP_CHAT, - 'record_id' => $record_id - ])); + MessageProducer::publish( + MessageProducer::create(SocketConstants::EVENT_TALK, [ + 'sender_id' => $user_id, + 'receiver_id' => (int)$params['group_id'], + 'talk_type' => TalkType::GROUP_CHAT, + 'record_id' => $record_id + ]) + ); return $this->response->success([], '已成功退出群组...'); } diff --git a/app/Controller/Api/V1/TalkMessageController.php b/app/Controller/Api/V1/TalkMessageController.php index 4d668fe..93e4608 100644 --- a/app/Controller/Api/V1/TalkMessageController.php +++ b/app/Controller/Api/V1/TalkMessageController.php @@ -10,6 +10,7 @@ use App\Constants\TalkMsgType; use App\Constants\TalkType; use App\Model\EmoticonItem; use App\Model\FileSplitUpload; +use App\Support\MessageProducer; use App\Support\UserRelation; use App\Service\EmoticonService; use App\Service\TalkService; @@ -67,13 +68,14 @@ class TalkMessageController extends CController if (!$record_id) return $this->response->fail('消息发送失败!'); - // 消息推送队列 - push_amqp(new ChatMessageProducer(SocketConstants::EVENT_TALK, [ - 'sender_id' => $user_id, - 'receiver_id' => (int)$params['receiver_id'], - 'talk_type' => (int)$params['talk_type'], - 'record_id' => $record_id - ])); + MessageProducer::publish( + MessageProducer::create(SocketConstants::EVENT_TALK, [ + 'sender_id' => $user_id, + 'receiver_id' => (int)$params['receiver_id'], + 'talk_type' => (int)$params['talk_type'], + 'record_id' => $record_id + ]) + ); LastMessage::getInstance()->save((int)$params['talk_type'], $user_id, (int)$params['receiver_id'], [ 'text' => '[代码消息]', @@ -133,13 +135,14 @@ class TalkMessageController extends CController if (!$record_id) return $this->response->fail('图片上传失败!'); - // 消息推送队列 - push_amqp(new ChatMessageProducer(SocketConstants::EVENT_TALK, [ - 'sender_id' => $user_id, - 'receiver_id' => (int)$params['receiver_id'], - 'talk_type' => (int)$params['talk_type'], - 'record_id' => $record_id, - ])); + MessageProducer::publish( + MessageProducer::create(SocketConstants::EVENT_TALK, [ + 'sender_id' => $user_id, + 'receiver_id' => (int)$params['receiver_id'], + 'talk_type' => (int)$params['talk_type'], + 'record_id' => $record_id, + ]) + ); LastMessage::getInstance()->save((int)$params['talk_type'], $user_id, (int)$params['receiver_id'], [ 'text' => '[图片消息]', @@ -195,13 +198,14 @@ class TalkMessageController extends CController if (!$record_id) return $this->response->fail('表情发送失败!'); - // 消息推送队列 - push_amqp(new ChatMessageProducer(SocketConstants::EVENT_TALK, [ - 'sender_id' => $user_id, - 'receiver_id' => (int)$params['receiver_id'], - 'talk_type' => (int)$params['talk_type'], - 'record_id' => $record_id - ])); + MessageProducer::publish( + MessageProducer::create(SocketConstants::EVENT_TALK, [ + 'sender_id' => $user_id, + 'receiver_id' => (int)$params['receiver_id'], + 'talk_type' => (int)$params['talk_type'], + 'record_id' => $record_id + ]) + ); LastMessage::getInstance()->save((int)$params['talk_type'], $user_id, (int)$params['receiver_id'], [ 'text' => '[文件消息]', @@ -259,13 +263,14 @@ class TalkMessageController extends CController if (!$record_id) return $this->response->fail('表情发送失败!'); - // 消息推送队列 - push_amqp(new ChatMessageProducer(SocketConstants::EVENT_TALK, [ - 'sender_id' => $user_id, - 'receiver_id' => (int)$params['receiver_id'], - 'talk_type' => (int)$params['talk_type'], - 'record_id' => $record_id - ])); + MessageProducer::publish( + MessageProducer::create(SocketConstants::EVENT_TALK, [ + 'sender_id' => $user_id, + 'receiver_id' => (int)$params['receiver_id'], + 'talk_type' => (int)$params['talk_type'], + 'record_id' => $record_id + ]) + ); LastMessage::getInstance()->save((int)$params['talk_type'], $user_id, (int)$params['receiver_id'], [ 'text' => '[表情包消息]', @@ -321,12 +326,14 @@ class TalkMessageController extends CController // 消息推送队列 foreach ($ids as $value) { - push_amqp(new ChatMessageProducer(SocketConstants::EVENT_TALK, [ - 'sender_id' => $user_id, - 'receiver_id' => $value['receiver_id'], - 'talk_type' => $value['talk_type'], - 'record_id' => $value['record_id'], - ])); + MessageProducer::publish( + MessageProducer::create(SocketConstants::EVENT_TALK, [ + 'sender_id' => $user_id, + 'receiver_id' => $value['receiver_id'], + 'talk_type' => $value['talk_type'], + 'record_id' => $value['record_id'], + ]) + ); } return $this->response->success([], '转发成功...'); @@ -366,9 +373,11 @@ class TalkMessageController extends CController [$isTrue, $message,] = $this->talkService->revokeRecord($this->uid(), $params['record_id']); if (!$isTrue) return $this->response->fail($message); - push_amqp(new ChatMessageProducer(SocketConstants::EVENT_REVOKE_TALK, [ - 'record_id' => $params['record_id'] - ])); + MessageProducer::publish( + MessageProducer::create(SocketConstants::EVENT_REVOKE_TALK, [ + 'record_id' => $params['record_id'] + ]) + ); return $this->response->success([], $message); } diff --git a/app/Controller/WebSocketController.php b/app/Controller/WebSocketController.php index 9ed4c5f..9d6a14a 100644 --- a/app/Controller/WebSocketController.php +++ b/app/Controller/WebSocketController.php @@ -12,6 +12,8 @@ declare(strict_types=1); namespace App\Controller; use App\Cache\SocketRoom; +use App\Service\Message\ReceiveHandleService; +use App\Support\MessageProducer; use Hyperf\Di\Annotation\Inject; use App\Constants\SocketConstants; use Hyperf\Contract\OnCloseInterface; @@ -22,9 +24,7 @@ use Swoole\Websocket\Frame; use Swoole\Http\Response; use Swoole\WebSocket\Server; use App\Service\SocketClientService; -use App\Service\MessageHandleService; use App\Model\Group\GroupMember; -use App\Amqp\Producer\ChatMessageProducer; /** * Class WebSocketController @@ -41,9 +41,9 @@ class WebSocketController implements OnMessageInterface, OnOpenInterface, OnClos /** * @inject - * @var MessageHandleService + * @var ReceiveHandleService */ - private $messageHandleService; + private $receiveHandleService; /** * 消息事件绑定 @@ -84,11 +84,12 @@ class WebSocketController implements OnMessageInterface, OnOpenInterface, OnClos } if (!$isOnline) { - // 推送消息至队列 - push_amqp(new ChatMessageProducer(SocketConstants::EVENT_ONLINE_STATUS, [ - 'user_id' => $user_id, - 'status' => 1, - ])); + MessageProducer::publish( + MessageProducer::create(SocketConstants::EVENT_ONLINE_STATUS, [ + 'user_id' => $user_id, + 'status' => 1, + ]) + ); } } @@ -108,7 +109,7 @@ class WebSocketController implements OnMessageInterface, OnOpenInterface, OnClos // 回调事件处理函数 call_user_func_array([ - $this->messageHandleService, + $this->receiveHandleService, self::EVENTS[$result['event']] ], [$server, $frame, $result['data']]); } @@ -132,11 +133,12 @@ class WebSocketController implements OnMessageInterface, OnOpenInterface, OnClos // 判断是否存在异地登录 $isOnline = $this->socketClientService->isOnlineAll($user_id); if (!$isOnline) { - // 推送消息至队列 - push_amqp(new ChatMessageProducer(SocketConstants::EVENT_ONLINE_STATUS, [ - 'user_id' => $user_id, - 'status' => 0, - ])); + MessageProducer::publish( + MessageProducer::create(SocketConstants::EVENT_ONLINE_STATUS, [ + 'user_id' => $user_id, + 'status' => 0, + ]) + ); } } } diff --git a/app/Process/RedisWebsocketSubscribe.php b/app/Process/RedisWebsocketSubscribe.php index 2d51e5a..cde1c2b 100644 --- a/app/Process/RedisWebsocketSubscribe.php +++ b/app/Process/RedisWebsocketSubscribe.php @@ -4,21 +4,7 @@ declare(strict_types=1); namespace App\Process; -use App\Cache\SocketRoom; -use App\Constants\SocketConstants; -use App\Constants\TalkMsgType; -use App\Constants\TalkType; -use App\Model\Chat\TalkRecords; -use App\Model\Chat\TalkRecordsCode; -use App\Model\Chat\TalkRecordsFile; -use App\Model\Chat\TalkRecordsForward; -use App\Model\Chat\TalkRecordsInvite; -use App\Model\Group\Group; -use App\Model\User; -use App\Model\UsersFriendsApply; -use App\Service\SocketClientService; -use App\Service\UserService; -use Hyperf\Amqp\Result; +use App\Service\Message\SubscribeHandleService; use Hyperf\Process\AbstractProcess; use Hyperf\Process\Annotation\Process; @@ -35,35 +21,13 @@ class RedisWebsocketSubscribe extends AbstractProcess private $chans = ['websocket']; /** - * 消息事件与回调事件绑定 - * - * @var array + * @var SubscribeHandleService */ - const EVENTS = [ - // 聊天消息事件 - SocketConstants::EVENT_TALK => 'onConsumeTalk', - - // 键盘输入事件 - SocketConstants::EVENT_KEYBOARD => 'onConsumeKeyboard', - - // 用户在线状态事件 - SocketConstants::EVENT_ONLINE_STATUS => 'onConsumeOnlineStatus', - - // 聊天消息推送事件 - SocketConstants::EVENT_REVOKE_TALK => 'onConsumeRevokeTalk', - - // 好友申请相关事件 - SocketConstants::EVENT_FRIEND_APPLY => 'onConsumeFriendApply' - ]; - - /** - * @var SocketClientService - */ - private $socketClientService; + private $handleService; public function handle(): void { - $this->socketClientService = container()->get(SocketClientService::class); + $this->handleService = container()->get(SubscribeHandleService::class); redis()->subscribe($this->chans, [$this, 'subscribe']); } @@ -80,306 +44,13 @@ class RedisWebsocketSubscribe extends AbstractProcess //echo PHP_EOL . "chan : $chan , msg : $message"; $data = json_decode($message, true); - $this->{self::EVENTS[$data['event']]}($data); + if (!isset(SubscribeHandleService::EVENTS[$data['event']])) return; + + $this->handleService->{SubscribeHandleService::EVENTS[$data['event']]}($data); } public function isEnable($server): bool { return true; } - - /** - * 对话聊天消息 - * - * @param array $data 队列消息 - * @return string - */ - public function onConsumeTalk(array $data): string - { - $talk_type = $data['data']['talk_type']; - $sender_id = $data['data']['sender_id']; - $receiver_id = $data['data']['receiver_id']; - $record_id = $data['data']['record_id']; - - $fds = []; - $groupInfo = null; - - if ($talk_type == TalkType::PRIVATE_CHAT) { - $fds = array_merge( - $this->socketClientService->findUserFds($sender_id), - $this->socketClientService->findUserFds($receiver_id) - ); - } else if ($talk_type == TalkType::GROUP_CHAT) { - foreach (SocketRoom::getInstance()->getRoomMembers(strval($receiver_id)) as $uid) { - $fds = array_merge($fds, $this->socketClientService->findUserFds(intval($uid))); - } - - $groupInfo = Group::where('id', $receiver_id)->first(['group_name', 'avatar']); - } - - // 客户端ID去重 - if (!$fds = array_unique($fds)) { - return Result::ACK; - } - - $result = TalkRecords::leftJoin('users', 'users.id', '=', 'talk_records.user_id') - ->where('talk_records.id', $record_id) - ->first([ - 'talk_records.id', - 'talk_records.talk_type', - 'talk_records.msg_type', - 'talk_records.user_id', - 'talk_records.receiver_id', - 'talk_records.content', - 'talk_records.is_revoke', - 'talk_records.created_at', - 'users.nickname', - 'users.avatar', - ]); - - if (!$result) return Result::ACK; - - $file = $code_block = $forward = $invite = []; - - switch ($result->msg_type) { - case TalkMsgType::FILE_MESSAGE: - $file = TalkRecordsFile::where('record_id', $result->id)->first([ - 'id', 'record_id', 'user_id', 'file_source', 'file_type', - 'save_type', 'original_name', 'file_suffix', 'file_size', 'save_dir' - ]); - - $file = $file ? $file->toArray() : []; - $file && $file['file_url'] = get_media_url($file['save_dir']); - break; - - case TalkMsgType::FORWARD_MESSAGE: - $forward = ['num' => 0, 'list' => []]; - $forwardInfo = TalkRecordsForward::where('record_id', $result->id)->first(['records_id', 'text']); - if ($forwardInfo) { - $forward = [ - 'num' => count(parse_ids($forwardInfo->records_id)), - 'list' => json_decode($forwardInfo->text, true) ?? [] - ]; - } - break; - - case TalkMsgType::CODE_MESSAGE: - $code_block = TalkRecordsCode::where('record_id', $result->id)->first(['record_id', 'code_lang', 'code']); - $code_block = $code_block ? $code_block->toArray() : []; - break; - - case TalkMsgType::GROUP_INVITE_MESSAGE: - $notifyInfo = TalkRecordsInvite::where('record_id', $result->id)->first([ - 'record_id', 'type', 'operate_user_id', 'user_ids' - ]); - - $userInfo = User::where('id', $notifyInfo->operate_user_id)->first(['nickname', 'id']); - $invite = [ - 'type' => $notifyInfo->type, - 'operate_user' => ['id' => $userInfo->id, 'nickname' => $userInfo->nickname], - 'users' => User::whereIn('id', parse_ids($notifyInfo->user_ids))->get(['id', 'nickname'])->toArray() - ]; - - unset($notifyInfo, $userInfo); - break; - } - - $notify = [ - 'sender_id' => $sender_id, - 'receiver_id' => $receiver_id, - 'talk_type' => $talk_type, - 'data' => $this->formatTalkMessage([ - 'id' => $result->id, - 'talk_type' => $result->talk_type, - 'msg_type' => $result->msg_type, - "user_id" => $result->user_id, - "receiver_id" => $result->receiver_id, - 'avatar' => $result->avatar, - 'nickname' => $result->nickname, - 'group_name' => $groupInfo ? $groupInfo->group_name : '', - 'group_avatar' => $groupInfo ? $groupInfo->avatar : '', - "created_at" => $result->created_at, - "content" => $result->content, - "file" => $file, - "code_block" => $code_block, - 'forward' => $forward, - 'invite' => $invite - ]) - ]; - - $this->socketPushNotify($fds, json_encode([SocketConstants::EVENT_TALK, $notify])); - - return Result::ACK; - } - - /** - * 键盘输入事件消息 - * - * @param array $data 队列消息 - * @return string - */ - public function onConsumeKeyboard(array $data): string - { - $fds = $this->socketClientService->findUserFds($data['data']['receiver_id']); - - $this->socketPushNotify($fds, json_encode([SocketConstants::EVENT_KEYBOARD, $data['data']])); - - return Result::ACK; - } - - /** - * 用户上线或下线消息 - * - * @param array $data 队列消息 - * @return string - */ - public function onConsumeOnlineStatus(array $data): string - { - $user_id = (int)$data['data']['user_id']; - $status = (int)$data['data']['status']; - - $fds = []; - - $ids = container()->get(UserService::class)->getFriendIds($user_id); - foreach ($ids as $friend_id) { - $fds = array_merge($fds, $this->socketClientService->findUserFds(intval($friend_id))); - } - - $this->socketPushNotify(array_unique($fds), json_encode([ - SocketConstants::EVENT_ONLINE_STATUS, [ - 'user_id' => $user_id, - 'status' => $status - ] - ])); - - return Result::ACK; - } - - /** - * 撤销聊天消息 - * - * @param array $data 队列消息 - * @return string - */ - public function onConsumeRevokeTalk(array $data): string - { - $record = TalkRecords::where('id', $data['data']['record_id'])->first(['id', 'talk_type', 'user_id', 'receiver_id']); - - $fds = []; - if ($record->talk_type == TalkType::PRIVATE_CHAT) { - $fds = array_merge($fds, $this->socketClientService->findUserFds($record->user_id)); - $fds = array_merge($fds, $this->socketClientService->findUserFds($record->receiver_id)); - } else if ($record->talk_type == TalkType::GROUP_CHAT) { - $userIds = SocketRoom::getInstance()->getRoomMembers(strval($record->receiver_id)); - foreach ($userIds as $uid) { - $fds = array_merge($fds, $this->socketClientService->findUserFds((int)$uid)); - } - } - - $fds = array_unique($fds); - $this->socketPushNotify($fds, json_encode([SocketConstants::EVENT_REVOKE_TALK, [ - 'talk_type' => $record->talk_type, - 'sender_id' => $record->user_id, - 'receiver_id' => $record->receiver_id, - 'record_id' => $record->id, - ]])); - - return Result::ACK; - } - - /** - * 好友申请消息 - * - * @param array $data 队列消息 - * @return string - */ - public function onConsumeFriendApply(array $data): string - { - $data = $data['data']; - - $applyInfo = UsersFriendsApply::where('id', $data['apply_id'])->first(); - if (!$applyInfo) return Result::ACK; - - $fds = $this->socketClientService->findUserFds($data['type'] == 1 ? $applyInfo->friend_id : $applyInfo->user_id); - - if ($data['type'] == 1) { - $msg = [ - 'sender_id' => $applyInfo->user_id, - 'receiver_id' => $applyInfo->friend_id, - 'remark' => $applyInfo->remark, - ]; - } else { - $msg = [ - 'sender_id' => $applyInfo->friend_id, - 'receiver_id' => $applyInfo->user_id, - 'status' => $applyInfo->status, - 'remark' => $applyInfo->remark, - ]; - } - - $friendInfo = User::select(['id', 'avatar', 'nickname', 'mobile', 'motto'])->find($data['type'] == 1 ? $applyInfo->user_id : $applyInfo->friend_id); - - $msg['friend'] = [ - 'user_id' => $friendInfo->id, - 'avatar' => $friendInfo->avatar, - 'nickname' => $friendInfo->nickname, - 'mobile' => $friendInfo->mobile, - ]; - - $this->socketPushNotify(array_unique($fds), json_encode([SocketConstants::EVENT_FRIEND_APPLY, $msg])); - - return Result::ACK; - } - - /** - * WebSocket 消息推送 - * - * @param $fds - * @param $message - */ - private function socketPushNotify($fds, $message) - { - $server = server(); - foreach ($fds as $fd) { - $server->exist(intval($fd)) && $server->push(intval($fd), $message); - } - } - - /** - * 格式化对话的消息体 - * - * @param array $data 对话的消息 - * @return array - */ - private function formatTalkMessage(array $data): array - { - $message = [ - "id" => 0, // 消息记录ID - "talk_type" => 1, // 消息来源[1:好友私信;2:群聊] - "msg_type" => 1, // 消息类型 - "user_id" => 0, // 发送者用户ID - "receiver_id" => 0, // 接收者ID[好友ID或群ID] - - // 发送消息人的信息 - "nickname" => "",// 用户昵称 - "avatar" => "",// 用户头像 - "group_name" => "",// 群组名称 - "group_avatar" => "",// 群组头像 - - // 不同的消息类型 - "file" => [], - "code_block" => [], - "forward" => [], - "invite" => [], - - // 消息创建时间 - "content" => '',// 文本消息 - "created_at" => "", - - // 消息属性 - "is_revoke" => 0, // 消息是否撤销 - ]; - - return array_merge($message, array_intersect_key($data, $message)); - } } diff --git a/app/Service/GroupService.php b/app/Service/GroupService.php index 4cf9c81..5062fc3 100644 --- a/app/Service/GroupService.php +++ b/app/Service/GroupService.php @@ -223,6 +223,7 @@ class GroupService extends BaseService } } + Db::beginTransaction(); try { if ($updateArr) { GroupMember::whereIn('id', $updateArr)->update([ diff --git a/app/Service/MessageHandleService.php b/app/Service/Message/ReceiveHandleService.php similarity index 76% rename from app/Service/MessageHandleService.php rename to app/Service/Message/ReceiveHandleService.php index 4b169c0..cdc1955 100644 --- a/app/Service/MessageHandleService.php +++ b/app/Service/Message/ReceiveHandleService.php @@ -1,29 +1,33 @@ socketClientService = $clientService; + } + /** * 对话消息 * @@ -81,12 +85,14 @@ class MessageHandleService 'created_at' => $result->created_at ]); - push_amqp(new ChatMessageProducer(SocketConstants::EVENT_TALK, [ - 'sender_id' => $result->user_id, - 'receiver_id' => $result->receiver_id, - 'talk_type' => $result->talk_type, - 'record_id' => $result->id - ])); + MessageProducer::publish( + MessageProducer::create(SocketConstants::EVENT_TALK, [ + 'sender_id' => $result->user_id, + 'receiver_id' => $result->receiver_id, + 'talk_type' => $result->talk_type, + 'record_id' => $result->id + ]) + ); } /** @@ -99,9 +105,11 @@ class MessageHandleService */ public function onKeyboard($server, Frame $frame, $data) { - push_amqp(new ChatMessageProducer(SocketConstants::EVENT_KEYBOARD, [ - 'sender_id' => intval($data['sender_id']), - 'receiver_id' => intval($data['receiver_id']), - ])); + MessageProducer::publish( + MessageProducer::create(SocketConstants::EVENT_KEYBOARD, [ + 'sender_id' => intval($data['sender_id']), + 'receiver_id' => intval($data['receiver_id']), + ]) + ); } } diff --git a/app/Amqp/Consumer/ChatMessageConsumer.php b/app/Service/Message/SubscribeHandleService.php similarity index 70% rename from app/Amqp/Consumer/ChatMessageConsumer.php rename to app/Service/Message/SubscribeHandleService.php index 0c6a395..07073da 100644 --- a/app/Amqp/Consumer/ChatMessageConsumer.php +++ b/app/Service/Message/SubscribeHandleService.php @@ -1,70 +1,25 @@ - * @link https://github.com/gzydong/hyperf-chat - */ -namespace App\Amqp\Consumer; +namespace App\Service\Message; +use App\Cache\SocketRoom; +use App\Constants\SocketConstants; use App\Constants\TalkMsgType; use App\Constants\TalkType; -use App\Model\UsersFriendsApply; -use App\Service\UserService; -use Hyperf\Amqp\Annotation\Consumer; -use Hyperf\Amqp\Result; -use Hyperf\Amqp\Message\ConsumerMessage; -use Hyperf\Amqp\Message\Type; -use Hyperf\Amqp\Builder\QueueBuilder; -use PhpAmqpLib\Message\AMQPMessage; -use App\Model\User; use App\Model\Chat\TalkRecords; use App\Model\Chat\TalkRecordsCode; use App\Model\Chat\TalkRecordsFile; -use App\Model\Chat\TalkRecordsInvite; use App\Model\Chat\TalkRecordsForward; +use App\Model\Chat\TalkRecordsInvite; use App\Model\Group\Group; +use App\Model\User; +use App\Model\UsersFriendsApply; use App\Service\SocketClientService; -use App\Constants\SocketConstants; -use App\Cache\Repository\LockRedis; -use App\Cache\SocketRoom; +use App\Service\UserService; +use Hyperf\Amqp\Result; -/** - * 消息推送消费者队列 - * @Consumer(name="ConsumerChat",enable=false) - */ -class ChatMessageConsumer extends ConsumerMessage +class SubscribeHandleService { - /** - * 交换机名称 - * - * @var string - */ - public $exchange = SocketConstants::CONSUMER_MESSAGE_EXCHANGE; - - /** - * 交换机类型 - * - * @var string - */ - public $type = Type::FANOUT; - - /** - * 路由key - * - * @var string - */ - public $routingKey = 'consumer:im:message'; - - /** - * @var SocketClientService - */ - private $socketClientService; - /** * 消息事件与回调事件绑定 * @@ -88,60 +43,22 @@ class ChatMessageConsumer extends ConsumerMessage ]; /** - * ChatMessageConsumer constructor. - * - * @param SocketClientService $socketClientService + * @var SocketClientService */ - public function __construct(SocketClientService $socketClientService) + private $clientService; + + public function __construct(SocketClientService $clientService) { - $this->socketClientService = $socketClientService; - - // 动态设置 Rabbit MQ 消费队列名称 - $this->setQueue('queue:im_message:' . SERVER_RUN_ID); - } - - /** - * 重写创建队列生成类 - * 注释:设置自动删除队列 - * - * @return QueueBuilder - */ - public function getQueueBuilder(): QueueBuilder - { - return parent::getQueueBuilder()->setAutoDelete(true); - } - - /** - * 消费队列消息 - * - * @param $data - * @param AMQPMessage $message - * @return string - */ - public function consumeMessage($data, AMQPMessage $message): string - { - if (isset($data['event'])) { - // [加锁]防止消息重复消费 - $lockName = sprintf('ws-message:%s-%s', SERVER_RUN_ID, $data['uuid']); - if (!LockRedis::getInstance()->lock($lockName, 60)) { - return Result::ACK; - } - - // 调用对应事件绑定的回调方法 - return $this->{self::EVENTS[$data['event']]}($data, $message); - } - - return Result::ACK; + $this->clientService = $clientService; } /** * 对话聊天消息 * - * @param array $data 队列消息 - * @param AMQPMessage $message + * @param array $data 队列消息 * @return string */ - public function onConsumeTalk(array $data, AMQPMessage $message): string + public function onConsumeTalk(array $data): string { $talk_type = $data['data']['talk_type']; $sender_id = $data['data']['sender_id']; @@ -153,12 +70,12 @@ class ChatMessageConsumer extends ConsumerMessage if ($talk_type == TalkType::PRIVATE_CHAT) { $fds = array_merge( - $this->socketClientService->findUserFds($sender_id), - $this->socketClientService->findUserFds($receiver_id) + $this->clientService->findUserFds($sender_id), + $this->clientService->findUserFds($receiver_id) ); } else if ($talk_type == TalkType::GROUP_CHAT) { foreach (SocketRoom::getInstance()->getRoomMembers(strval($receiver_id)) as $uid) { - $fds = array_merge($fds, $this->socketClientService->findUserFds(intval($uid))); + $fds = array_merge($fds, $this->clientService->findUserFds(intval($uid))); } $groupInfo = Group::where('id', $receiver_id)->first(['group_name', 'avatar']); @@ -166,7 +83,7 @@ class ChatMessageConsumer extends ConsumerMessage // 客户端ID去重 if (!$fds = array_unique($fds)) { - return Result::ACK; + return true; } $result = TalkRecords::leftJoin('users', 'users.id', '=', 'talk_records.user_id') @@ -184,7 +101,7 @@ class ChatMessageConsumer extends ConsumerMessage 'users.avatar', ]); - if (!$result) return Result::ACK; + if (!$result) return true; $file = $code_block = $forward = $invite = []; @@ -256,33 +173,31 @@ class ChatMessageConsumer extends ConsumerMessage $this->socketPushNotify($fds, json_encode([SocketConstants::EVENT_TALK, $notify])); - return Result::ACK; + return true; } /** * 键盘输入事件消息 * - * @param array $data 队列消息 - * @param AMQPMessage $message + * @param array $data 队列消息 * @return string */ - public function onConsumeKeyboard(array $data, AMQPMessage $message): string + public function onConsumeKeyboard(array $data): string { - $fds = $this->socketClientService->findUserFds($data['data']['receiver_id']); + $fds = $this->clientService->findUserFds($data['data']['receiver_id']); $this->socketPushNotify($fds, json_encode([SocketConstants::EVENT_KEYBOARD, $data['data']])); - return Result::ACK; + return true; } /** * 用户上线或下线消息 * - * @param array $data 队列消息 - * @param AMQPMessage $message + * @param array $data 队列消息 * @return string */ - public function onConsumeOnlineStatus(array $data, AMQPMessage $message): string + public function onConsumeOnlineStatus(array $data): string { $user_id = (int)$data['data']['user_id']; $status = (int)$data['data']['status']; @@ -291,7 +206,7 @@ class ChatMessageConsumer extends ConsumerMessage $ids = container()->get(UserService::class)->getFriendIds($user_id); foreach ($ids as $friend_id) { - $fds = array_merge($fds, $this->socketClientService->findUserFds(intval($friend_id))); + $fds = array_merge($fds, $this->clientService->findUserFds(intval($friend_id))); } $this->socketPushNotify(array_unique($fds), json_encode([ @@ -301,28 +216,27 @@ class ChatMessageConsumer extends ConsumerMessage ] ])); - return Result::ACK; + return true; } /** * 撤销聊天消息 * - * @param array $data 队列消息 - * @param AMQPMessage $message + * @param array $data 队列消息 * @return string */ - public function onConsumeRevokeTalk(array $data, AMQPMessage $message): string + public function onConsumeRevokeTalk(array $data): string { $record = TalkRecords::where('id', $data['data']['record_id'])->first(['id', 'talk_type', 'user_id', 'receiver_id']); $fds = []; if ($record->talk_type == TalkType::PRIVATE_CHAT) { - $fds = array_merge($fds, $this->socketClientService->findUserFds($record->user_id)); - $fds = array_merge($fds, $this->socketClientService->findUserFds($record->receiver_id)); + $fds = array_merge($fds, $this->clientService->findUserFds($record->user_id)); + $fds = array_merge($fds, $this->clientService->findUserFds($record->receiver_id)); } else if ($record->talk_type == TalkType::GROUP_CHAT) { $userIds = SocketRoom::getInstance()->getRoomMembers(strval($record->receiver_id)); foreach ($userIds as $uid) { - $fds = array_merge($fds, $this->socketClientService->findUserFds((int)$uid)); + $fds = array_merge($fds, $this->clientService->findUserFds((int)$uid)); } } @@ -334,24 +248,23 @@ class ChatMessageConsumer extends ConsumerMessage 'record_id' => $record->id, ]])); - return Result::ACK; + return true; } /** * 好友申请消息 * - * @param array $data 队列消息 - * @param AMQPMessage $message + * @param array $data 队列消息 * @return string */ - public function onConsumeFriendApply(array $data, AMQPMessage $message): string + public function onConsumeFriendApply(array $data): string { $data = $data['data']; $applyInfo = UsersFriendsApply::where('id', $data['apply_id'])->first(); - if (!$applyInfo) return Result::ACK; + if (!$applyInfo) return true; - $fds = $this->socketClientService->findUserFds($data['type'] == 1 ? $applyInfo->friend_id : $applyInfo->user_id); + $fds = $this->clientService->findUserFds($data['type'] == 1 ? $applyInfo->friend_id : $applyInfo->user_id); if ($data['type'] == 1) { $msg = [ @@ -379,7 +292,7 @@ class ChatMessageConsumer extends ConsumerMessage $this->socketPushNotify(array_unique($fds), json_encode([SocketConstants::EVENT_FRIEND_APPLY, $msg])); - return Result::ACK; + return true; } /** diff --git a/app/Support/MessageProducer.php b/app/Support/MessageProducer.php new file mode 100644 index 0000000..ea20986 --- /dev/null +++ b/app/Support/MessageProducer.php @@ -0,0 +1,34 @@ + uniqid((strval(mt_rand(0, 1000)))), + 'event' => $event, + 'data' => $data, + 'options' => $options + ]; + } + + /** + * @param array $message + */ + public static function publish(array $message) + { + push_redis_subscribe(RedisSubscribeChan::WEBSOCKET_CHAN, $message); + } +} diff --git a/app/helper.php b/app/helper.php index b0d3048..82fd991 100644 --- a/app/helper.php +++ b/app/helper.php @@ -251,7 +251,6 @@ function parse_ids($ids) */ function push_amqp(ProducerMessage $message, bool $confirm = false, int $timeout = 5) { - push_redis_subscribe('websocket', $message->getPayload()); return container()->get(Producer::class)->produce($message, $confirm, $timeout); } diff --git a/composer.json b/composer.json index 669ac01..43acbeb 100644 --- a/composer.json +++ b/composer.json @@ -27,7 +27,6 @@ "hyperf/redis": "~2.0.0", "hyperf/database": "~2.0.0", "hyperf/async-queue": "~2.0.0", - "hyperf/amqp": "~2.0.0", "hyperf/websocket-server": "^2.0", "hyperf/constants": "^2.0", "hyperf/validation": "^2.0", diff --git a/config/autoload/amqp.php b/config/autoload/amqp.php deleted file mode 100644 index 9ccfbf7..0000000 --- a/config/autoload/amqp.php +++ /dev/null @@ -1,38 +0,0 @@ - [ - 'host' => env('AMQP_HOST','127.0.0.1'), - 'port' => intval(env('AMQP_PORT',5672)), - 'user' => env('AMQP_USER','guest'), - 'password' => env('AMQP_PASSWORD','guest'), - 'vhost' => env('AMQP_VHOST','/'), - 'pool' => [ - 'min_connections' => 1, - 'max_connections' => 10, - 'connect_timeout' => 10.0, - 'wait_timeout' => 3.0, - 'heartbeat' => -1, - ], - 'params' => [ - 'insist' => false, - 'login_method' => 'AMQPLAIN', - 'login_response' => null, - 'locale' => 'en_US', - 'connection_timeout' => 3.0, - 'read_write_timeout' => 8.0, - 'context' => null, - 'keepalive' => false, - 'heartbeat' => 3, - ], - ], -]; diff --git a/migrations/2020_11_04_152602_create_users_table.php b/migrations/2020_11_04_152602_create_users_table.php index fb06c40..ec3e661 100644 --- a/migrations/2020_11_04_152602_create_users_table.php +++ b/migrations/2020_11_04_152602_create_users_table.php @@ -17,10 +17,11 @@ class CreateUsersTable extends Migration $table->string('mobile', 11)->default('')->unique()->comment('手机号'); $table->string('nickname', 20)->default('')->comment('用户昵称'); $table->string('avatar', 255)->default('')->comment('用户头像地址'); - $table->unsignedTinyInteger('gender')->default(0)->comment('用户性别[0:未知;1:男;2:女]'); + $table->unsignedTinyInteger('gender')->default(0)->comment('用户性别[0:未知;1:男;2:女;]'); $table->string('password', 255)->default('')->comment('用户密码'); $table->string('motto', 100)->default('')->comment('用户座右铭'); $table->string('email', 30)->default('')->comment('用户邮箱'); + $table->unsignedTinyInteger('is_robot')->default(0)->comment('是否机器人[0:否;1:是;]'); $table->dateTime('created_at')->nullable()->comment('注册时间'); $table->dateTime('updated_at')->nullable()->comment('更新时间'); diff --git a/migrations/2020_11_04_153251_create_article_annex_table.php b/migrations/2020_11_04_153251_create_article_annex_table.php index abb6f82..3ce57b4 100644 --- a/migrations/2020_11_04_153251_create_article_annex_table.php +++ b/migrations/2020_11_04_153251_create_article_annex_table.php @@ -17,16 +17,16 @@ class CreateArticleAnnexTable extends Migration $table->unsignedInteger('user_id')->unsigned()->comment('上传文件的用户ID'); $table->unsignedInteger('article_id')->default(0)->comment('笔记ID'); $table->string('file_suffix', 10)->default('')->comment('文件后缀名'); - $table->bigInteger('file_size')->default(0)->unsigned()->comment('文件大小(单位字节)'); - $table->string('save_dir', 500)->nullable()->comment('文件保存地址(相对地址)'); - $table->string('original_name', 100)->nullable()->comment('原文件名'); - $table->tinyInteger('status')->default(1)->unsigned()->comment('附件状态[1:正常;2:已删除]'); + $table->unsignedBigInteger('file_size')->default(0)->comment('文件大小(单位字节)'); + $table->string('save_dir', 500)->nullable(false)->default('')->comment('文件保存地址(相对地址)'); + $table->string('original_name', 100)->nullable(false)->default('')->comment('原文件名'); + $table->unsignedTinyInteger('status')->default(1)->comment('附件状态[1:正常;2:已删除]'); $table->dateTime('created_at')->nullable(true)->comment('附件上传时间'); $table->dateTime('deleted_at')->nullable(true)->comment('附件删除时间'); - $table->charset = 'utf8'; + $table->charset = 'utf8'; $table->collation = 'utf8_general_ci'; - $table->engine = 'InnoDB'; + $table->engine = 'InnoDB'; $table->index(['user_id', 'article_id'], 'idx_user_id_article_id'); }); diff --git a/migrations/2020_11_04_153337_create_emoticon_table.php b/migrations/2020_11_04_153337_create_emoticon_table.php index 22b9837..27f406e 100644 --- a/migrations/2020_11_04_153337_create_emoticon_table.php +++ b/migrations/2020_11_04_153337_create_emoticon_table.php @@ -22,6 +22,8 @@ class CreateEmoticonTable extends Migration $table->charset = 'utf8'; $table->collation = 'utf8_general_ci'; + + $table->unique(['name'], 'uk_name'); }); $prefix = config('databases.default.prefix'); diff --git a/migrations/2020_11_04_153358_create_file_split_upload_table.php b/migrations/2020_11_04_153358_create_file_split_upload_table.php index df6b987..ce98cd1 100644 --- a/migrations/2020_11_04_153358_create_file_split_upload_table.php +++ b/migrations/2020_11_04_153358_create_file_split_upload_table.php @@ -15,7 +15,7 @@ class CreateFileSplitUploadTable extends Migration $table->unsignedInteger('id', true)->comment('临时文件ID'); $table->unsignedTinyInteger('file_type')->default(2)->comment('数据类型[1:合并文件;2:拆分文件]'); $table->unsignedInteger('user_id')->default(0)->comment('上传的用户ID'); - $table->string('hash_name', 30)->default('')->comment('临时文件hash名'); + $table->string('hash_name', 32)->default('')->comment('临时文件hash名'); $table->string('original_name', 100)->default('')->comment('原文件名'); $table->unsignedTinyInteger('split_index')->default(0)->comment('当前索引块'); $table->unsignedTinyInteger('split_num')->default(0)->comment('总上传索引块'); diff --git a/migrations/2020_11_04_153408_create_user_login_log_table.php b/migrations/2020_11_04_153408_create_user_login_log_table.php deleted file mode 100644 index ef0c70d..0000000 --- a/migrations/2020_11_04_153408_create_user_login_log_table.php +++ /dev/null @@ -1,35 +0,0 @@ -unsignedInteger('id', true)->comment('登录日志ID'); - $table->unsignedInteger('user_id')->default(0)->comment('用户ID'); - $table->string('ip', 20)->comment('登录地址IP'); - $table->dateTime('created_at')->nullable(true)->comment('登录时间'); - - $table->charset = 'utf8'; - $table->collation = 'utf8_general_ci'; - }); - - $prefix = config('databases.default.prefix'); - DB::statement("ALTER TABLE `{$prefix}user_login_log` comment '用户登录日志表'"); - } - - /** - * Reverse the migrations. - */ - public function down(): void - { - Schema::dropIfExists('user_login_log'); - } -} diff --git a/migrations/2020_11_04_153421_create_talk_list_table.php b/migrations/2020_11_04_153421_create_talk_list_table.php new file mode 100644 index 0000000..8a06a52 --- /dev/null +++ b/migrations/2020_11_04_153421_create_talk_list_table.php @@ -0,0 +1,45 @@ +unsignedInteger('id', true)->comment('聊天列表ID'); + $table->unsignedTinyInteger('talk_type')->default(1)->comment('聊天类型[1:私信;2:群聊;]'); + $table->unsignedInteger('user_id')->default(0)->comment('用户ID'); + $table->unsignedInteger('receiver_id')->default(0)->comment('接收者ID(用户ID 或 群ID)'); + $table->unsignedTinyInteger('is_top')->default(0)->comment('是否置顶[0:否;1:是]'); + $table->unsignedTinyInteger('is_robot')->default(0)->comment('是否机器人[0:否;1:是;]'); + $table->unsignedTinyInteger('is_delete')->default(0)->comment('是否删除[0:否;1:是;]'); + $table->unsignedTinyInteger('is_disturb')->default(0)->comment('消息免打扰[0:否;1:是;]'); + $table->dateTime('created_at')->nullable(true)->comment('创建时间'); + $table->dateTime('updated_at')->nullable(true)->comment('更新时间'); + + $table->charset = 'utf8'; + $table->collation = 'utf8_general_ci'; + $table->engine = 'InnoDB'; + + $table->index(['user_id', 'receiver_id', 'talk_type'], 'idx_user_id_receiver_id_talk_type'); + }); + + $prefix = config('databases.default.prefix'); + DB::statement("ALTER TABLE `{$prefix}talk_list` comment '用户聊天列表'"); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('talk_list'); + } +} diff --git a/migrations/2020_11_04_153421_create_users_chat_list_table.php b/migrations/2020_11_04_153421_create_users_chat_list_table.php deleted file mode 100644 index eb88717..0000000 --- a/migrations/2020_11_04_153421_create_users_chat_list_table.php +++ /dev/null @@ -1,44 +0,0 @@ -unsignedInteger('id', true)->comment('聊天列表ID'); - $table->unsignedTinyInteger('type')->default(1)->comment('聊天类型[1:好友;2:群聊]'); - $table->unsignedInteger('uid')->default(0)->comment('用户ID'); - $table->unsignedInteger('friend_id')->default(0)->comment('朋友的用户ID'); - $table->unsignedInteger('group_id')->default(0)->comment('聊天分组ID'); - $table->unsignedInteger('status')->default(1)->default(1)->comment('状态[0:已删除;1:正常]'); - $table->unsignedTinyInteger('is_top')->default(0)->comment('是否置顶[0:否;1:是]'); - $table->unsignedTinyInteger('not_disturb')->default(0)->comment('是否消息免打扰[0:否;1:是]'); - $table->dateTime('created_at')->nullable(true)->comment('创建时间'); - $table->dateTime('updated_at')->nullable(true)->comment('更新时间'); - - $table->charset = 'utf8'; - $table->collation = 'utf8_general_ci'; - $table->engine = 'InnoDB'; - - $table->index(['uid', 'friend_id', 'group_id', 'type'], 'idx_uid_type_friend_id_group_id'); - }); - - $prefix = config('databases.default.prefix'); - DB::statement("ALTER TABLE `{$prefix}users_chat_list` comment '用户聊天列表'"); - } - - /** - * Reverse the migrations. - */ - public function down(): void - { - Schema::dropIfExists('users_chat_list'); - } -} diff --git a/migrations/2020_11_04_153431_create_chat_records_table.php b/migrations/2020_11_04_153431_create_chat_records_table.php deleted file mode 100644 index f9c990d..0000000 --- a/migrations/2020_11_04_153431_create_chat_records_table.php +++ /dev/null @@ -1,42 +0,0 @@ -unsignedInteger('id', true)->comment('聊天记录ID'); - $table->tinyInteger('source')->unsigned()->default(1)->comment('消息来源[1:好友消息;2:群聊消息]'); - $table->tinyInteger('msg_type')->unsigned()->default(1)->comment('消息类型[1:文本消息;2:文件消息;3:系统提示好友入群消息或系统提示好友退群消息;4:会话记录转发]'); - $table->unsignedInteger('user_id')->default(0)->comment('发送消息的用户ID[0:代表系统消息]'); - $table->unsignedInteger('receive_id')->default(0)->comment('接收消息的用户ID或群聊ID'); - $table->text('content')->nullable(true)->charset('utf8mb4')->comment('文本消息'); - $table->tinyInteger('is_revoke')->default(0)->comment('是否撤回消息[0:否;1:是]'); - $table->dateTime('created_at')->nullable(true)->comment('发送消息的时间'); - - $table->charset = 'utf8'; - $table->collation = 'utf8_general_ci'; - $table->engine = 'InnoDB'; - - $table->index(['user_id', 'receive_id'], 'idx_userid_receiveid'); - }); - - $prefix = config('databases.default.prefix'); - DB::statement("ALTER TABLE `{$prefix}chat_records` comment '用户聊天记录表'"); - } - - /** - * Reverse the migrations. - */ - public function down(): void - { - Schema::dropIfExists('chat_records'); - } -} diff --git a/migrations/2020_11_04_153431_create_talk_records_table.php b/migrations/2020_11_04_153431_create_talk_records_table.php new file mode 100644 index 0000000..9a0ca7a --- /dev/null +++ b/migrations/2020_11_04_153431_create_talk_records_table.php @@ -0,0 +1,48 @@ +unsignedBigInteger('id', true)->comment('聊天记录ID'); + $table->unsignedTinyInteger('talk_type')->unsigned()->default(1)->comment('对话类型[1:私信;2:群聊;]'); + $table->unsignedTinyInteger('msg_type')->unsigned()->default(1)->comment('消息类型[1:文本消息;2:文件消息;3:会话消息;4:代码消息;5:投票消息;6:群公告;7:好友申请;8:登录通知;9:入群消息/退群消息;]'); + $table->unsignedInteger('user_id')->default(0)->comment('发送者ID(0:代表系统消息 >0: 用户ID)'); + $table->unsignedInteger('receiver_id')->default(0)->comment('接收者ID(用户ID 或 群ID)'); + $table->tinyInteger('is_revoke')->default(0)->comment('是否撤回消息[0:否;1:是]'); + $table->tinyInteger('is_mark')->default(0)->comment('是否重要消息[0:否;1:是;]'); + $table->tinyInteger('is_read')->default(0)->comment('是否已读[0:否;1:是;]'); + $table->unsignedBigInteger('quote_id')->default(0)->comment('引用消息ID'); + $table->text('content')->nullable(true)->charset('utf8mb4')->comment('文本消息 {@nickname@}'); + $table->string('warn_users', 200)->default('')->comment('@好友 、 多个用英文逗号 “,” 拼接 (0:代表所有人)'); + $table->dateTime('created_at')->nullable(true)->comment('创建时间'); + $table->dateTime('updated_at')->nullable(true)->comment('更新时间'); + + $table->charset = 'utf8'; + $table->collation = 'utf8_general_ci'; + $table->engine = 'InnoDB'; + + $table->index(['user_id', 'receiver_id'], 'idx_user_id_receiver_id'); + }); + + $prefix = config('databases.default.prefix'); + DB::statement("ALTER TABLE `{$prefix}talk_records` comment '用户聊天记录表'"); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('talk_records'); + } +} diff --git a/migrations/2020_11_04_153442_create_chat_records_file_table.php b/migrations/2020_11_04_153442_create_talk_records_file_table.php similarity index 85% rename from migrations/2020_11_04_153442_create_chat_records_file_table.php rename to migrations/2020_11_04_153442_create_talk_records_file_table.php index 3f706a4..29badb2 100644 --- a/migrations/2020_11_04_153442_create_chat_records_file_table.php +++ b/migrations/2020_11_04_153442_create_talk_records_file_table.php @@ -4,14 +4,15 @@ use Hyperf\Database\Schema\Schema; use Hyperf\Database\Schema\Blueprint; use Hyperf\Database\Migrations\Migration; use Hyperf\DbConnection\Db; -class CreateChatRecordsFileTable extends Migration + +class CreateTalkRecordsFileTable extends Migration { /** * Run the migrations. */ public function up(): void { - Schema::create('chat_records_file', function (Blueprint $table) { + Schema::create('talk_records_file', function (Blueprint $table) { $table->unsignedInteger('id', true)->comment('文件ID'); $table->unsignedInteger('record_id')->default(0)->comment('消息记录ID'); $table->unsignedInteger('user_id')->default(0)->comment('上传文件的用户ID'); @@ -25,15 +26,15 @@ class CreateChatRecordsFileTable extends Migration $table->tinyInteger('is_delete')->default(0)->unsigned()->comment('文件是否已删除[0:否;1:已删除]'); $table->dateTime('created_at')->nullable(true)->comment('创建时间'); - $table->charset = 'utf8'; + $table->charset = 'utf8'; $table->collation = 'utf8_general_ci'; - $table->engine = 'InnoDB'; + $table->engine = 'InnoDB'; $table->unique(['record_id'], 'idx_record_id'); }); $prefix = config('databases.default.prefix'); - DB::statement("ALTER TABLE `{$prefix}chat_records_file` comment '用户聊天记录_文件消息表'"); + DB::statement("ALTER TABLE `{$prefix}talk_records_file` comment '用户聊天记录_文件消息表'"); } /** @@ -41,6 +42,6 @@ class CreateChatRecordsFileTable extends Migration */ public function down(): void { - Schema::dropIfExists('chat_records_file'); + Schema::dropIfExists('talk_records_file'); } } diff --git a/migrations/2020_11_04_153453_create_chat_records_delete_table.php b/migrations/2020_11_04_153453_create_talk_records_delete_table.php similarity index 74% rename from migrations/2020_11_04_153453_create_chat_records_delete_table.php rename to migrations/2020_11_04_153453_create_talk_records_delete_table.php index 9cd4ef9..29a47a1 100644 --- a/migrations/2020_11_04_153453_create_chat_records_delete_table.php +++ b/migrations/2020_11_04_153453_create_talk_records_delete_table.php @@ -5,28 +5,28 @@ use Hyperf\Database\Schema\Blueprint; use Hyperf\Database\Migrations\Migration; use Hyperf\DbConnection\Db; -class CreateChatRecordsDeleteTable extends Migration +class CreateTalkRecordsDeleteTable extends Migration { /** * Run the migrations. */ public function up(): void { - Schema::create('chat_records_delete', function (Blueprint $table) { + Schema::create('talk_records_delete', function (Blueprint $table) { $table->unsignedInteger('id', true)->comment('聊天删除记录ID'); $table->unsignedInteger('record_id')->default(0)->comment('聊天记录ID'); $table->unsignedInteger('user_id')->default(0)->comment('用户ID'); $table->dateTime('created_at')->nullable(true)->comment('删除时间'); - $table->charset = 'utf8'; + $table->charset = 'utf8'; $table->collation = 'utf8_general_ci'; - $table->engine = 'InnoDB'; + $table->engine = 'InnoDB'; $table->index(['record_id', 'user_id'], 'idx_record_user_id'); }); $prefix = config('databases.default.prefix'); - DB::statement("ALTER TABLE `{$prefix}chat_records_delete` comment '用户聊天记录_删除记录表'"); + DB::statement("ALTER TABLE `{$prefix}talk_records_delete` comment '用户聊天记录_删除记录表'"); } /** @@ -34,6 +34,6 @@ class CreateChatRecordsDeleteTable extends Migration */ public function down(): void { - Schema::dropIfExists('chat_records_delete_file'); + Schema::dropIfExists('talk_records_delete'); } } diff --git a/migrations/2020_11_04_153504_create_chat_records_forward_table.php b/migrations/2020_11_04_153504_create_talk_records_forward_table.php similarity index 83% rename from migrations/2020_11_04_153504_create_chat_records_forward_table.php rename to migrations/2020_11_04_153504_create_talk_records_forward_table.php index 383f859..0946244 100644 --- a/migrations/2020_11_04_153504_create_chat_records_forward_table.php +++ b/migrations/2020_11_04_153504_create_talk_records_forward_table.php @@ -4,14 +4,14 @@ use Hyperf\Database\Schema\Schema; use Hyperf\Database\Schema\Blueprint; use Hyperf\Database\Migrations\Migration; use Hyperf\DbConnection\Db; -class CreateChatRecordsForwardTable extends Migration +class CreateTalkRecordsForwardTable extends Migration { /** * Run the migrations. */ public function up(): void { - Schema::create('chat_records_forward', function (Blueprint $table) { + Schema::create('talk_records_forward', function (Blueprint $table) { $table->unsignedInteger('id', true)->comment('合并转发ID'); $table->unsignedInteger('record_id')->default(0)->comment('消息记录ID'); $table->unsignedInteger('user_id')->default(0)->comment('转发用户ID'); @@ -27,7 +27,7 @@ class CreateChatRecordsForwardTable extends Migration }); $prefix = config('databases.default.prefix'); - DB::statement("ALTER TABLE `{$prefix}chat_records_forward` comment '用户聊天记录_转发信息表'"); + DB::statement("ALTER TABLE `{$prefix}talk_records_forward` comment '用户聊天记录_转发信息表'"); } /** @@ -35,6 +35,6 @@ class CreateChatRecordsForwardTable extends Migration */ public function down(): void { - Schema::dropIfExists('chat_records_forward'); + Schema::dropIfExists('talk_records_forward'); } } diff --git a/migrations/2020_11_04_153516_create_chat_records_invite_table.php b/migrations/2020_11_04_153516_create_talk_records_invite_table.php similarity index 77% rename from migrations/2020_11_04_153516_create_chat_records_invite_table.php rename to migrations/2020_11_04_153516_create_talk_records_invite_table.php index f3223c0..6d06ecd 100644 --- a/migrations/2020_11_04_153516_create_chat_records_invite_table.php +++ b/migrations/2020_11_04_153516_create_talk_records_invite_table.php @@ -4,29 +4,30 @@ use Hyperf\Database\Schema\Schema; use Hyperf\Database\Schema\Blueprint; use Hyperf\Database\Migrations\Migration; use Hyperf\DbConnection\Db; -class CreateChatRecordsInviteTable extends Migration + +class CreateTalkRecordsInviteTable extends Migration { /** * Run the migrations. */ public function up(): void { - Schema::create('chat_records_invite', function (Blueprint $table) { + Schema::create('talk_records_invite', function (Blueprint $table) { $table->unsignedInteger('id', true)->comment('入群或退群通知ID'); $table->unsignedInteger('record_id')->default(0)->comment('消息记录ID'); $table->tinyInteger('type')->default(1)->comment('通知类型[1:入群通知;2:自动退群;3:管理员踢群]'); $table->unsignedInteger('operate_user_id')->default(0)->comment('操作人的用户ID(邀请人)'); $table->string('user_ids', 255)->default('')->comment("用户ID,多个用','分割"); - $table->charset = 'utf8'; + $table->charset = 'utf8'; $table->collation = 'utf8_general_ci'; - $table->engine = 'InnoDB'; + $table->engine = 'InnoDB'; $table->index(['record_id'], 'idx_recordid'); }); $prefix = config('databases.default.prefix'); - DB::statement("ALTER TABLE `{$prefix}chat_records_invite` comment '用户聊天记录_入群或退群消息表'"); + DB::statement("ALTER TABLE `{$prefix}talk_records_invite` comment '用户聊天记录_入群或退群消息表'"); } /** @@ -34,6 +35,6 @@ class CreateChatRecordsInviteTable extends Migration */ public function down(): void { - Schema::dropIfExists('chat_records_invite'); + Schema::dropIfExists('talk_records_invite'); } } diff --git a/migrations/2020_11_04_153529_create_chat_records_code_table.php b/migrations/2020_11_04_153529_create_talk_records_code_table.php similarity index 78% rename from migrations/2020_11_04_153529_create_chat_records_code_table.php rename to migrations/2020_11_04_153529_create_talk_records_code_table.php index d3ed216..e76fe00 100644 --- a/migrations/2020_11_04_153529_create_chat_records_code_table.php +++ b/migrations/2020_11_04_153529_create_talk_records_code_table.php @@ -4,14 +4,15 @@ use Hyperf\Database\Schema\Schema; use Hyperf\Database\Schema\Blueprint; use Hyperf\Database\Migrations\Migration; use Hyperf\DbConnection\Db; -class CreateChatRecordsCodeTable extends Migration + +class CreateTalkRecordsCodeTable extends Migration { /** * Run the migrations. */ public function up(): void { - Schema::create('chat_records_code', function (Blueprint $table) { + Schema::create('talk_records_code', function (Blueprint $table) { $table->unsignedInteger('id', true)->comment('入群或退群通知ID'); $table->unsignedInteger('record_id')->default(0)->comment('消息记录ID'); $table->unsignedInteger('user_id')->default(0)->comment('上传文件的用户ID'); @@ -19,15 +20,15 @@ class CreateChatRecordsCodeTable extends Migration $table->text('code')->charset('utf8mb4')->comment('代码片段内容'); $table->dateTime('created_at')->nullable(true)->comment('创建时间'); - $table->charset = 'utf8'; + $table->charset = 'utf8'; $table->collation = 'utf8_general_ci'; - $table->engine = 'InnoDB'; + $table->engine = 'InnoDB'; $table->index(['record_id'], 'idx_recordid'); }); $prefix = config('databases.default.prefix'); - DB::statement("ALTER TABLE `{$prefix}chat_records_code` comment '用户聊天记录_代码块消息表'"); + DB::statement("ALTER TABLE `{$prefix}talk_records_code` comment '用户聊天记录_代码块消息表'"); } /** @@ -35,6 +36,6 @@ class CreateChatRecordsCodeTable extends Migration */ public function down(): void { - Schema::dropIfExists('chat_records_code'); + Schema::dropIfExists('talk_records_code'); } } diff --git a/migrations/2020_11_04_153553_create_users_friends_table.php b/migrations/2020_11_04_153553_create_users_friends_table.php index ac0dacd..de152e1 100644 --- a/migrations/2020_11_04_153553_create_users_friends_table.php +++ b/migrations/2020_11_04_153553_create_users_friends_table.php @@ -14,21 +14,18 @@ class CreateUsersFriendsTable extends Migration { Schema::create('users_friends', function (Blueprint $table) { $table->unsignedInteger('id', true)->comment('关系ID'); - $table->unsignedInteger('user1')->default(0)->comment('用户1(user1 一定比 user2 小)'); - $table->unsignedInteger('user2')->default(0)->comment('用户2(user1 一定比 user2 小)'); - $table->string('user1_remark', 20)->default('')->comment('好友备注'); - $table->string('user2_remark', 20)->default('')->comment('好友备注'); - $table->unsignedTinyInteger('active')->default(1)->default(1)->comment('主动邀请方[1:user1;2:user2]'); - $table->unsignedTinyInteger('status')->default(1)->comment('好友状态[0:已解除好友关系;1:好友状态]'); - $table->dateTime('agree_time')->comment('成为好友时间'); + $table->unsignedInteger('user_id')->default(0)->comment('用户ID'); + $table->unsignedInteger('friend_id')->default(0)->comment('好友ID'); + $table->string('remark', 30)->default('')->comment('好友备注'); + $table->unsignedTinyInteger('status')->default(0)->comment('好友状态[0:否;1:是;]'); $table->dateTime('created_at')->nullable(true)->comment('创建时间'); + $table->dateTime('updated_at')->nullable(true)->comment('更新时间'); - $table->charset = 'utf8'; + $table->charset = 'utf8'; $table->collation = 'utf8_general_ci'; - $table->engine = 'InnoDB'; + $table->engine = 'InnoDB'; - $table->index(['user1', 'user2'], 'idx_user1_user2'); - $table->index(['user2', 'user1'], 'idx_user2_user1'); + $table->index(['user_id', 'friend_id'], 'idx_user_id_friend_id'); }); $prefix = config('databases.default.prefix'); diff --git a/migrations/2020_11_04_153605_create_users_friends_apply_table.php b/migrations/2020_11_04_153605_create_users_friends_apply_table.php index 6403f8a..533927a 100644 --- a/migrations/2020_11_04_153605_create_users_friends_apply_table.php +++ b/migrations/2020_11_04_153605_create_users_friends_apply_table.php @@ -4,6 +4,7 @@ use Hyperf\Database\Schema\Schema; use Hyperf\Database\Schema\Blueprint; use Hyperf\Database\Migrations\Migration; use Hyperf\DbConnection\Db; + class CreateUsersFriendsApplyTable extends Migration { /** @@ -14,15 +15,16 @@ class CreateUsersFriendsApplyTable extends Migration Schema::create('users_friends_apply', function (Blueprint $table) { $table->unsignedInteger('id', true)->comment('申请ID'); $table->unsignedInteger('user_id')->default(0)->comment('申请人ID'); - $table->unsignedInteger('friend_id')->default(0)->comment('被申请人'); - $table->unsignedTinyInteger('status')->default(0)->comment('申请状态[0:等待处理;1:已同意]'); - $table->string('remarks', 50)->default('')->comment('申请人备注信息'); + $table->unsignedInteger('friend_id')->default(0)->comment('好友ID'); + $table->unsignedTinyInteger('status')->default(0)->comment('申请状态[0:等待处理;1:已同意;2:已拒绝;]'); + $table->string('remark', 50)->default('')->comment('备注信息'); + $table->string('reason', 50)->default('')->comment('拒绝的原因'); $table->dateTime('created_at')->nullable()->comment('申请时间'); - $table->dateTime('updated_at')->nullable()->comment('处理时间'); + $table->dateTime('updated_at')->nullable()->comment('更新时间'); - $table->charset = 'utf8'; + $table->charset = 'utf8'; $table->collation = 'utf8_general_ci'; - $table->engine = 'InnoDB'; + $table->engine = 'InnoDB'; $table->index(['user_id'], 'idx_user_id'); $table->index(['friend_id'], 'idx_friend_id'); diff --git a/migrations/2020_11_04_153616_create_group_table.php b/migrations/2020_11_04_153616_create_group_table.php index 9e9eb4d..08c0967 100644 --- a/migrations/2020_11_04_153616_create_group_table.php +++ b/migrations/2020_11_04_153616_create_group_table.php @@ -25,9 +25,9 @@ class CreateGroupTable extends Migration $table->dateTime('created_at')->nullable()->comment('创建时间'); $table->dateTime('dismissed_at')->nullable()->comment('解散时间'); - $table->charset = 'utf8'; + $table->charset = 'utf8'; $table->collation = 'utf8_general_ci'; - $table->engine = 'InnoDB'; + $table->engine = 'InnoDB'; }); $prefix = config('databases.default.prefix'); diff --git a/migrations/2020_11_04_153626_create_group_member_table.php b/migrations/2020_11_04_153626_create_group_member_table.php index c6fa3bf..6a33b83 100644 --- a/migrations/2020_11_04_153626_create_group_member_table.php +++ b/migrations/2020_11_04_153626_create_group_member_table.php @@ -23,12 +23,12 @@ class CreateGroupMemberTable extends Migration $table->dateTime('created_at')->nullable()->comment('入群时间'); $table->dateTime('deleted_at')->nullable()->comment('退群时间'); - $table->charset = 'utf8'; + $table->charset = 'utf8'; $table->collation = 'utf8_general_ci'; - $table->engine = 'InnoDB'; + $table->engine = 'InnoDB'; $table->unique(['group_id', 'user_id'], 'uk_group_id_user_id'); - $table->index(['user_id', 'group_id'], 'idx_user_id_group_id'); + $table->index(['user_id'], 'idx_user_id'); }); $prefix = config('databases.default.prefix'); diff --git a/migrations/2020_11_04_153636_create_group_notice_table.php b/migrations/2020_11_04_153636_create_group_notice_table.php index 65de7fd..2f7442a 100644 --- a/migrations/2020_11_04_153636_create_group_notice_table.php +++ b/migrations/2020_11_04_153636_create_group_notice_table.php @@ -26,9 +26,9 @@ class CreateGroupNoticeTable extends Migration $table->dateTime('updated_at')->nullable()->comment('更新时间'); $table->dateTime('deleted_at')->nullable()->comment('删除时间'); - $table->charset = 'utf8'; + $table->charset = 'utf8'; $table->collation = 'utf8_general_ci'; - $table->engine = 'InnoDB'; + $table->engine = 'InnoDB'; $table->index(['group_id', 'is_delete', 'is_top', 'updated_at'], 'idx_group_id_is_delete_is_top_updated_at'); });