diff --git a/LumenIM 同步SQL.sql b/LumenIM 同步SQL.sql index ba0faa9..c3451dd 100644 --- a/LumenIM 同步SQL.sql +++ b/LumenIM 同步SQL.sql @@ -57,10 +57,15 @@ ALTER TABLE `lar_chat_records_invite` RENAME `lar_talk_records_invite`; ALTER TABLE `lar_chat_records_file` RENAME `lar_talk_records_file`; # lar_users_friends 数据表同步SQL -ALTER TABLE `lar_users_friends` MODIFY `active` tinyint(3) unsigned DEFAULT '1' COMMENT '主动好友申请方[1:user1;2:user2;]'; -ALTER TABLE `lar_users_friends` MODIFY `status` tinyint(3) DEFAULT '0' COMMENT '好友状态 [-1:双方均解除好友关系;0:正常;1:user1 已删除对方;2:user2 已删除对方;]'; -ALTER TABLE `lar_users_friends` CHANGE `agree_time` `updated_at` datetime DEFAULT NULL COMMENT '更新时间'; -UPDATE `lar_users_friends` SET `status` = CASE WHEN `status` = 0 THEN -1 WHEN `status` = 1 THEN 0 ELSE `status` END; +DELETE from `lar_users_friends` where `status` = 0; +ALTER TABLE `lar_users_friends` CHANGE `user1` `user_id` int(11) unsigned DEFAULT '0' COMMENT '用户id'; +ALTER TABLE `lar_users_friends` CHANGE `user2` `friend_id` int(11) unsigned DEFAULT '0' COMMENT '好友id'; +ALTER TABLE `lar_users_friends` CHANGE `user1_remark` `remark` varchar(20) DEFAULT '' COMMENT '好友的备注'; +ALTER TABLE `lar_users_friends` MODIFY `status` tinyint(3) unsigned DEFAULT '0' COMMENT '好友状态 [0:否;1:是]'; +ALTER TABLE `lar_users_friends` MODIFY `created_at` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间'; +ALTER TABLE `lar_users_friends` CHANGE `agree_time` `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间'; +ALTER TABLE `lar_users_friends` DROP COLUMN `active`; +ALTER TABLE `lar_users_friends` DROP COLUMN `user2_remark`; # lar_users_friends_apply 数据表同步SQL ALTER TABLE `lar_users_friends_apply` MODIFY `status` tinyint(4) unsigned DEFAULT '0' COMMENT '申请状态[0:等待处理;1:已同意;2:已拒绝;]'; diff --git a/app/Command/TestCommand.php b/app/Command/TestCommand.php index 68a7dfd..c0a32da 100644 --- a/app/Command/TestCommand.php +++ b/app/Command/TestCommand.php @@ -23,6 +23,7 @@ use App\Constants\FileMediaType; use App\Model\Group\Group; use App\Model\Group\GroupMember; use App\Model\TalkList; +use App\Model\UsersFriend; use App\Service\TalkService; use Hyperf\Command\Command as HyperfCommand; use Hyperf\Command\Annotation\Command; @@ -177,5 +178,19 @@ class TestCommand extends HyperfCommand //var_dump(FriendRemark::getInstance()); //var_dump(Group::isManager(2054,116)); + + UsersFriend::where('id', '<=', UsersFriend::max('id'))->chunk(100, function ($rows) { + foreach ($rows as $row) { + UsersFriend::create([ + 'user_id' => $row->friend_id, + 'friend_id' => $row->user_id, + 'remark' => $row->user2_remark, + 'status' => 1, + 'created_at' => date('Y-m-d H:i:s'), + 'updated_at' => date('Y-m-d H:i:s'), + ]); + } + }); + } } diff --git a/app/Controller/Api/V1/ContactsController.php b/app/Controller/Api/V1/ContactsController.php index a780ccb..f5a3d40 100644 --- a/app/Controller/Api/V1/ContactsController.php +++ b/app/Controller/Api/V1/ContactsController.php @@ -10,6 +10,7 @@ namespace App\Controller\Api\V1; +use App\Model\UsersFriend; use Hyperf\Di\Annotation\Inject; use Hyperf\HttpServer\Annotation\Controller; use Hyperf\HttpServer\Annotation\RequestMapping; @@ -56,11 +57,11 @@ class ContactsController extends CController */ public function getContacts() { - $rows = $this->contactsService->getContacts($this->uid()); + $rows = UsersFriend::getUserFriends($this->uid()); if ($rows) { $runArr = ServerRunID::getInstance()->getServerRunIdAll(); - foreach ($rows as $row) { - $row->is_online = $this->socketClientService->isOnlineAll($row->id, $runArr); + foreach ($rows as $k => $row) { + $rows[$k]['is_online'] = $this->socketClientService->isOnlineAll($row['id'], $runArr); } } diff --git a/app/Controller/Api/V1/EmoticonController.php b/app/Controller/Api/V1/EmoticonController.php index 9f21fe7..ecbfea4 100644 --- a/app/Controller/Api/V1/EmoticonController.php +++ b/app/Controller/Api/V1/EmoticonController.php @@ -39,11 +39,11 @@ class EmoticonController extends CController /** * 获取用户表情包列表 - * @RequestMapping(path="user-emoticon", methods="get") + * @RequestMapping(path="list", methods="get") * * @return ResponseInterface */ - public function getUserEmoticon() + public function list() { $emoticonList = []; $user_id = $this->uid(); @@ -74,11 +74,11 @@ class EmoticonController extends CController /** * 获取系统表情包 - * @RequestMapping(path="system-emoticon", methods="get") + * @RequestMapping(path="system", methods="get") * * @return ResponseInterface */ - public function getSystemEmoticon() + public function system() { $items = Emoticon::get(['id', 'name', 'icon'])->toArray(); if ($items) { @@ -142,12 +142,12 @@ class EmoticonController extends CController /** * 自定义上传表情包 - * @RequestMapping(path="upload-emoticon", methods="post") + * @RequestMapping(path="upload", methods="post") * * @param Filesystem $filesystem * @return ResponseInterface */ - public function uploadEmoticon(Filesystem $filesystem) + public function upload(Filesystem $filesystem) { $file = $this->request->file('emoticon'); if (!$file->isValid()) { diff --git a/app/Controller/Api/V1/TalkController.php b/app/Controller/Api/V1/TalkController.php index 2b7c623..e5eec54 100644 --- a/app/Controller/Api/V1/TalkController.php +++ b/app/Controller/Api/V1/TalkController.php @@ -14,6 +14,7 @@ use App\Cache\LastMessage; use App\Cache\UnreadTalk; use App\Constants\TalkMsgType; use App\Constants\TalkType; +use App\Support\UserRelation; use Hyperf\Di\Annotation\Inject; use Hyperf\HttpServer\Annotation\Controller; use Hyperf\HttpServer\Annotation\RequestMapping; @@ -22,7 +23,6 @@ use App\Middleware\JWTAuthMiddleware; use Psr\Http\Message\ResponseInterface; use App\Model\User; use App\Model\TalkList; -use App\Model\UsersFriend; use App\Model\Group\Group; use App\Service\TalkService; @@ -41,25 +41,6 @@ class TalkController extends CController */ public $talkService; - /** - * 判断是否是好友或者群成员关系 - * - * @param int $user_id 用户ID - * @param int $receiver_id 接收者ID - * @param int $talk_type 对话类型 - * @return bool - */ - private function isFriendOrGroupMember(int $user_id, int $receiver_id, int $talk_type) - { - if ($talk_type == TalkType::PRIVATE_CHAT) { - return UsersFriend::isFriend($user_id, $receiver_id, true); - } else if ($talk_type == TalkType::GROUP_CHAT) { - return Group::isMember($receiver_id, $user_id); - } - - return false; - } - /** * 获取用户对话列表 * @RequestMapping(path="list", methods="get") @@ -93,14 +74,12 @@ class TalkController extends CController ]); $user_id = $this->uid(); - if (!$this->isFriendOrGroupMember($user_id, $params['receiver_id'], $params['talk_type'])) { + if (!UserRelation::isFriendOrGroupMember($user_id, $params['receiver_id'], $params['talk_type'])) { return $this->response->fail('暂不属于好友关系或群聊成员,无法进行聊天!'); } $result = TalkList::addItem($user_id, $params['receiver_id'], $params['talk_type']); - if (!$result) { - return $this->response->fail('创建失败!'); - } + if (!$result) return $this->response->fail('创建失败!'); $data = [ 'id' => $result['id'], @@ -234,7 +213,7 @@ class TalkController extends CController ]); $user_id = $this->uid(); - if (!$this->isFriendOrGroupMember($user_id, $params['receiver_id'], $params['talk_type'])) { + if (!UserRelation::isFriendOrGroupMember($user_id, $params['receiver_id'], $params['talk_type'])) { return $this->response->fail('暂不属于好友关系或群聊成员,无法查看聊天记录!'); } @@ -289,7 +268,7 @@ class TalkController extends CController ]); $user_id = $this->uid(); - if (!$this->isFriendOrGroupMember($user_id, $params['receiver_id'], $params['talk_type'])) { + if (!UserRelation::isFriendOrGroupMember($user_id, $params['receiver_id'], $params['talk_type'])) { return $this->response->fail('暂不属于好友关系或群聊成员,无法查看聊天记录!'); } diff --git a/app/Controller/Api/V1/TalkMessageController.php b/app/Controller/Api/V1/TalkMessageController.php index 90c5bf8..4d668fe 100644 --- a/app/Controller/Api/V1/TalkMessageController.php +++ b/app/Controller/Api/V1/TalkMessageController.php @@ -10,8 +10,7 @@ use App\Constants\TalkMsgType; use App\Constants\TalkType; use App\Model\EmoticonItem; use App\Model\FileSplitUpload; -use App\Model\Group\Group; -use App\Model\UsersFriend; +use App\Support\UserRelation; use App\Service\EmoticonService; use App\Service\TalkService; use Hyperf\Di\Annotation\Inject; @@ -36,25 +35,6 @@ class TalkMessageController extends CController */ public $talkService; - /** - * 判断是否是好友或者群成员关系 - * - * @param int $user_id 用户ID - * @param int $receiver_id 接收者ID - * @param int $talk_type 对话类型 - * @return bool - */ - private function isFriendOrGroupMember(int $user_id, int $receiver_id, int $talk_type) - { - if ($talk_type == TalkType::PRIVATE_CHAT) { - return UsersFriend::isFriend($user_id, $receiver_id, true); - } else if ($talk_type == TalkType::GROUP_CHAT) { - return Group::isMember($receiver_id, $user_id); - } - - return false; - } - /** * 发送代码块消息 * @RequestMapping(path="code", methods="post") @@ -70,7 +50,7 @@ class TalkMessageController extends CController ]); $user_id = $this->uid(); - if (!$this->isFriendOrGroupMember($user_id, $params['receiver_id'], $params['talk_type'])) { + if (!UserRelation::isFriendOrGroupMember($user_id, $params['receiver_id'], $params['talk_type'])) { return $this->response->fail('暂不属于好友关系或群聊成员,无法发送聊天消息!'); } @@ -85,9 +65,7 @@ class TalkMessageController extends CController 'code' => $params['code'] ]); - if (!$record_id) { - return $this->response->fail('消息发送失败!'); - } + if (!$record_id) return $this->response->fail('消息发送失败!'); // 消息推送队列 push_amqp(new ChatMessageProducer(SocketConstants::EVENT_TALK, [ @@ -118,7 +96,7 @@ class TalkMessageController extends CController ]); $user_id = $this->uid(); - if (!$this->isFriendOrGroupMember($user_id, $params['receiver_id'], $params['talk_type'])) { + if (!UserRelation::isFriendOrGroupMember($user_id, $params['receiver_id'], $params['talk_type'])) { return $this->response->fail('暂不属于好友关系或群聊成员,无法发送聊天消息!'); } @@ -153,9 +131,7 @@ class TalkMessageController extends CController 'original_name' => $file->getClientFilename(), ]); - if (!$record_id) { - return $this->response->fail('图片上传失败!'); - } + if (!$record_id) return $this->response->fail('图片上传失败!'); // 消息推送队列 push_amqp(new ChatMessageProducer(SocketConstants::EVENT_TALK, [ @@ -187,7 +163,7 @@ class TalkMessageController extends CController ]); $user_id = $this->uid(); - if (!$this->isFriendOrGroupMember($user_id, $params['receiver_id'], $params['talk_type'])) { + if (!UserRelation::isFriendOrGroupMember($user_id, $params['receiver_id'], $params['talk_type'])) { return $this->response->fail('暂不属于好友关系或群聊成员,无法发送聊天消息!'); } @@ -217,9 +193,7 @@ class TalkMessageController extends CController 'save_dir' => $save_dir, ]); - if (!$record_id) { - return $this->response->fail('表情发送失败!'); - } + if (!$record_id) return $this->response->fail('表情发送失败!'); // 消息推送队列 push_amqp(new ChatMessageProducer(SocketConstants::EVENT_TALK, [ @@ -260,7 +234,7 @@ class TalkMessageController extends CController ]); $user_id = $this->uid(); - if (!$this->isFriendOrGroupMember($user_id, $params['receiver_id'], $params['talk_type'])) { + if (!UserRelation::isFriendOrGroupMember($user_id, $params['receiver_id'], $params['talk_type'])) { return $this->response->fail('暂不属于好友关系或群聊成员,无法发送聊天消息!'); } @@ -268,9 +242,7 @@ class TalkMessageController extends CController 'url', 'file_suffix', 'file_size' ]); - if (!$emoticon) { - return $this->response->fail('表情不存在!'); - } + if (!$emoticon) return $this->response->fail('表情不存在!'); $record_id = $this->talkService->createEmoticonMessage([ 'talk_type' => $params['talk_type'], @@ -285,9 +257,7 @@ class TalkMessageController extends CController 'original_name' => '图片表情', ]); - if (!$record_id) { - return $this->response->fail('表情发送失败!'); - } + if (!$record_id) return $this->response->fail('表情发送失败!'); // 消息推送队列 push_amqp(new ChatMessageProducer(SocketConstants::EVENT_TALK, [ @@ -341,9 +311,7 @@ class TalkMessageController extends CController $ids = $this->talkService->mergeForwardRecords($user_id, $params['receiver_id'], $params['talk_type'], $params['records_ids'], $items); } - if (!$ids) { - return $this->response->fail('转发失败!'); - } + if (!$ids) return $this->response->fail('转发失败!'); if ($receive_user_ids) { foreach ($receive_user_ids as $v) { @@ -396,15 +364,13 @@ class TalkMessageController extends CController ]); [$isTrue, $message,] = $this->talkService->revokeRecord($this->uid(), $params['record_id']); - if ($isTrue) { - push_amqp(new ChatMessageProducer(SocketConstants::EVENT_REVOKE_TALK, [ - 'record_id' => $params['record_id'] - ])); - } + if (!$isTrue) return $this->response->fail($message); - return $isTrue - ? $this->response->success([], $message) - : $this->response->fail($message); + push_amqp(new ChatMessageProducer(SocketConstants::EVENT_REVOKE_TALK, [ + 'record_id' => $params['record_id'] + ])); + + return $this->response->success([], $message); } /** diff --git a/app/Model/TalkList.php b/app/Model/TalkList.php index b1107d0..40b674d 100644 --- a/app/Model/TalkList.php +++ b/app/Model/TalkList.php @@ -23,6 +23,8 @@ class TalkList extends BaseModel { protected $table = 'talk_list'; + public $timestamps = true; + protected $fillable = [ 'talk_type', 'user_id', diff --git a/app/Model/UsersFriend.php b/app/Model/UsersFriend.php index 96a8742..f155612 100644 --- a/app/Model/UsersFriend.php +++ b/app/Model/UsersFriend.php @@ -4,20 +4,16 @@ declare (strict_types=1); namespace App\Model; -use Hyperf\DbConnection\Db; - /** * 表情包收藏数据表模型 * * @property int $id - * @property int $user1 用户1ID - * @property int $user2 用户2ID - * @property string $user1_remark 用户1好友备注 - * @property string $user2_remark 用户2好友备注 - * @property int $active 主动邀请方[1:user1;2:user2;] - * @property int $status 好友状态[1:好友状态;0:已解除好友关系] - * @property string $agree_time 成为好友时间 - * @property string $created_at 创建时间 + * @property int $user_id 用户ID + * @property int $friend_id 好友ID + * @property string $remark 好友备注 + * @property int $status 好友状态 + * @property string $created_at 创建时间 + * @property string $updated_at 更新时间 * @package App\Model */ class UsersFriend extends BaseModel @@ -25,74 +21,58 @@ class UsersFriend extends BaseModel protected $table = 'users_friends'; protected $fillable = [ - 'user1', - 'user2', - 'user1_remark', - 'user2_remark', - 'active', + 'user_id', + 'friend_id', 'status', - 'agree_time', - 'created_at' + 'created_at', + 'updated_at', ]; protected $casts = [ 'id' => 'integer', - 'user1' => 'integer', - 'user2' => 'integer', - 'active' => 'integer', + 'user_id' => 'integer', + 'friend_id' => 'integer', 'status' => 'integer', - 'created_at' => 'datetime' + 'created_at' => 'datetime', + 'updated_at' => 'datetime', ]; /** * 获取用户所有好友 * - * @param int $uid 用户ID - * @return mixed + * @param int $user_id 用户ID + * @return array */ - public static function getUserFriends(int $uid) + public static function getUserFriends(int $user_id) { - $prefix = config('databases.default.prefix'); - $sql = <<where('user_id', $user_id)->where('users_friends.status', 1) + ->get([ + 'users.id', + 'users.nickname', + 'users.avatar', + 'users.motto', + 'users.gender', + 'users_friends.remark as friend_remark', + ])->toArray(); } /** * 判断用户之间是否存在好友关系 * - * @param int $user_id1 用户1 - * @param int $user_id2 用户2 - * @param bool $cache 是否读取缓存 + * @param int $user_id 用户ID + * @param int $friend_id 好友ID + * @param bool $is_cache 是否允许读取缓存 * @return bool */ - public static function isFriend(int $user_id1, int $user_id2, bool $cache = false) + public static function isFriend(int $user_id, int $friend_id, bool $is_cache = false) { - // 比较大小交换位置 - if ($user_id1 > $user_id2) { - [$user_id1, $user_id2] = [$user_id2, $user_id1]; - } - - $cacheKey = "good_friends:{$user_id1}_$user_id2"; - if ($cache && redis()->get($cacheKey)) { + $cacheKey = "good_friends:{$user_id}_{$friend_id}"; + if ($is_cache && redis()->get($cacheKey)) { return true; } - $isTrue = self::query()->where('user1', $user_id1)->where('user2', $user_id2)->where('status', 0)->exists(); + $isTrue = self::query()->where('user_id', $user_id)->where('friend_id', $friend_id)->where('status', 1)->exists(); if ($isTrue) { redis()->setex($cacheKey, 60 * 5, 1); } @@ -108,10 +88,6 @@ SQL; */ public static function getFriendIds(int $user_id) { - $prefix = config('databases.default.prefix'); - $sql = "SELECT user2 as uid from {$prefix}users_friends where user1 = {$user_id} and `status` = 0 UNION all SELECT user1 as uid from {$prefix}users_friends where user2 = {$user_id} and `status` = 0"; - return array_map(function ($item) { - return $item->uid; - }, Db::select($sql)); + return UsersFriend::where('user_id', $user_id)->where('status', 1)->pluck('friend_id')->toArray(); } } diff --git a/app/Service/ContactsService.php b/app/Service/ContactsService.php index 39600cb..ed9a76e 100644 --- a/app/Service/ContactsService.php +++ b/app/Service/ContactsService.php @@ -35,6 +35,8 @@ class ContactsService extends BaseService */ public function getContacts(int $user_id): array { + + $prefix = config('databases.default.prefix'); $sql = <<read($user_id, $friend_id); + if ($remark) return $remark; + + $remark = UsersFriend::where('user_id', $user_id)->where('friend_id', $friend_id)->value('remark'); + if ($remark) FriendRemark::getInstance()->save($user_id, $friend_id, $remark); + + return (string)$remark; + } + /** * 获取用户的聊天列表 * @@ -70,27 +88,14 @@ class TalkService extends BaseService $data['is_top'] = $item['is_top']; $data['is_disturb'] = $item['is_disturb']; $data['msg_text'] = '......'; - $data['updated_at'] = $item['updated_at']; + $data['updated_at'] = $item['updated_at'] ?: '2020-01-01 00:00:00'; if ($item['talk_type'] == TalkType::PRIVATE_CHAT) { - $data['name'] = $item['nickname']; - $data['avatar'] = $item['user_avatar']; - $data['unread_num'] = UnreadTalk::getInstance()->read($item['receiver_id'], $user_id); - $data['is_online'] = $socketFDService->isOnlineAll($item['receiver_id'], $runIdAll); - - $remark = FriendRemark::getInstance()->read($user_id, $item['receiver_id']); - if ($remark) { - $data['remark_name'] = $remark; - } else { - $info = UsersFriend::select('user1', 'user2', 'user1_remark', 'user2_remark') - ->where('user1', ($user_id < $item['receiver_id']) ? $user_id : $item['receiver_id']) - ->where('user2', ($user_id < $item['receiver_id']) ? $item['receiver_id'] : $user_id)->first(); - if ($info) { - $data['remark_name'] = $info->user1 == $item['receiver_id'] ? $info->user2_remark : $info->user1_remark; - - FriendRemark::getInstance()->save($user_id, (int)$item['receiver_id'], $data['remark_name']); - } - } + $data['name'] = $item['nickname']; + $data['avatar'] = $item['user_avatar']; + $data['unread_num'] = UnreadTalk::getInstance()->read($item['receiver_id'], $user_id); + $data['is_online'] = $socketFDService->isOnlineAll($item['receiver_id'], $runIdAll); + $data['remark_name'] = $this->getFriendRemark($user_id, (int)$item['receiver_id']); } else { $data['name'] = strval($item['group_name']); $data['avatar'] = $item['group_avatar']; @@ -100,8 +105,6 @@ class TalkService extends BaseService if ($records) { $data['msg_text'] = $records['text']; $data['updated_at'] = $records['created_at']; - } else { - $data['updated_at'] = '2020-01-01 00:00:00'; } return $data; diff --git a/app/Support/UserRelation.php b/app/Support/UserRelation.php new file mode 100644 index 0000000..087bb16 --- /dev/null +++ b/app/Support/UserRelation.php @@ -0,0 +1,29 @@ +