From 0b860d3fadfaec4bba2933604460d19b905720df Mon Sep 17 00:00:00 2001 From: gzydong Date: Thu, 28 Jan 2021 20:07:14 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81=E5=8F=8A?= =?UTF-8?q?=E8=B0=83=E6=95=B4=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Controller/Api/V1/ContactsController.php | 306 ++++++ app/Controller/Api/V1/GroupController.php | 1027 +++++++++--------- app/Controller/Api/V1/UsersController.php | 252 +---- app/Service/ContactsService.php | 287 +++++ app/Service/FriendService.php | 205 ---- app/Service/GroupService.php | 711 ++++++------ app/Service/UserService.php | 340 +++--- 7 files changed, 1640 insertions(+), 1488 deletions(-) create mode 100644 app/Controller/Api/V1/ContactsController.php create mode 100644 app/Service/ContactsService.php delete mode 100644 app/Service/FriendService.php diff --git a/app/Controller/Api/V1/ContactsController.php b/app/Controller/Api/V1/ContactsController.php new file mode 100644 index 0000000..c539044 --- /dev/null +++ b/app/Controller/Api/V1/ContactsController.php @@ -0,0 +1,306 @@ + + * @link https://github.com/gzydong/hyperf-chat + */ + +namespace App\Controller\Api\V1; + +use App\Model\UsersFriendsApply; +use Co\Context; +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 Psr\Http\Message\ResponseInterface; +use Hyperf\Amqp\Producer; +use App\Amqp\Producer\ChatMessageProducer; +use App\Service\ContactsService; +use App\Service\SocketClientService; +use App\Service\UserService; +use App\Cache\ApplyNumCache; +use App\Cache\FriendRemarkCache; +use App\Model\UsersChatList; +use App\Constants\SocketConstants; + +/** + * Class ContactsController + * + * @Controller(path="/api/v1/contacts") + * @Middleware(JWTAuthMiddleware::class) + * + * @package App\Controller\Api\V1 + */ +class ContactsController extends CController +{ + /** + * @Inject + * @var ContactsService + */ + private $contactsService; + + /** + * @inject + * @var SocketClientService + */ + private $socketClientService; + + /** + * @Inject + * @var Producer + */ + private $producer; + + /** + * 获取用户联系人列表 + * + * @RequestMapping(path="list", methods="get") + */ + public function getContacts() + { + $rows = $this->contactsService->getContacts($this->uid()); + if ($rows) { + $runArr = $this->socketClientService->getServerRunIdAll(); + foreach ($rows as $k => $row) { + // 查询用户当前是否在线 + $rows[$k]['online'] = $this->socketClientService->isOnlineAll($row['id'], $runArr); + } + } + + return $this->response->success($rows); + } + + /** + * 添加联系人 + * + * @RequestMapping(path="add", methods="post") + * + * @param UserService $userService + * @return ResponseInterface + */ + public function addContact(UserService $userService) + { + $params = $this->request->inputs(['friend_id', 'remarks']); + $this->validate($params, [ + 'friend_id' => 'required|integer', + 'remarks' => 'present|max:50' + ]); + + $user = $userService->findById($params['friend_id']); + if (!$user) { + return $this->response->fail('用户不存在...'); + } + + $user_id = $this->uid(); + if (!$this->contactsService->addContact($user_id, intval($params['friend_id']), $params['remarks'])) { + return $this->response->fail('添加好友申请失败...'); + } + + // 好友申请未读消息数自增 + ApplyNumCache::setInc(intval($params['friend_id'])); + + //判断对方是否在线。如果在线发送消息通知 + if ($this->socketClientService->isOnlineAll(intval($params['friend_id']))) { + $this->producer->produce( + // 消息待完善 + new ChatMessageProducer(SocketConstants::EVENT_FRIEND_APPLY, [ + 'sender' => $user_id, + 'receive' => intval($params['friend_id']), + 'type' => 1, + 'status' => 1, + 'remark' => '' + ]) + ); + } + + return $this->response->success([], '发送好友申请成功...'); + } + + /** + * 删除联系人 + * + * @RequestMapping(path="delete", methods="post") + */ + public function deleteContact() + { + $params = $this->request->inputs(['friend_id']); + $this->validate($params, [ + 'friend_id' => 'required|integer' + ]); + + $user_id = $this->uid(); + if (!$this->contactsService->deleteContact($user_id, intval($params['friend_id']))) { + return $this->response->fail('好友关系解除失败...'); + } + + //删除好友会话列表 + UsersChatList::delItem($user_id, $params['friend_id'], 2); + UsersChatList::delItem($params['friend_id'], $user_id, 2); + + // ... 推送消息(待完善) + + return $this->response->success([], '好友关系解除成功...'); + } + + /** + * 同意添加联系人 + * + * @RequestMapping(path="accept-invitation", methods="post") + */ + public function acceptInvitation() + { + $params = $this->request->inputs(['apply_id', 'remarks']); + $this->validate($params, [ + 'apply_id' => 'required|integer', + 'remarks' => 'present|max:20' + ]); + + $user_id = $this->uid(); + $isTrue = $this->contactsService->acceptInvitation($user_id, intval($params['apply_id']), $params['remarks']); + if (!$isTrue) { + return $this->response->fail('处理失败...'); + } + + $friend_id = $info = UsersFriendsApply::where('id', $params['apply_id']) + ->where('friend_id', $user_id) + ->value('user_id'); + + //判断对方是否在线。如果在线发送消息通知 + if ($this->socketClientService->isOnlineAll($friend_id)) { + // 待完善 + $this->producer->produce( + new ChatMessageProducer(SocketConstants::EVENT_FRIEND_APPLY, [ + 'sender' => $user_id, + 'receive' => $friend_id, + 'type' => 1, + 'status' => 1, + 'remark' => '' + ]) + ); + } + + return $this->response->success([], '处理成功...'); + } + + /** + * 拒绝添加联系人(预留) + * + * @RequestMapping(path="decline-invitation", methods="post") + */ + public function declineInvitation() + { + $params = $this->request->inputs(['apply_id', 'remarks']); + $this->validate($params, [ + 'apply_id' => 'required|integer', + 'remarks' => 'present|max:20' + ]); + + $isTrue = $this->contactsService->declineInvitation($this->uid(), intval($params['apply_id']), $params['remarks']); + + return $isTrue + ? $this->response->success() + : $this->response->fail(); + } + + /** + * 删除联系人申请记录 + * + * @RequestMapping(path="delete-apply", methods="post") + */ + public function deleteContactApply() + { + $params = $this->request->inputs(['apply_id']); + $this->validate($params, [ + 'apply_id' => 'required|integer' + ]); + + $isTrue = $this->contactsService->delContactApplyRecord($this->uid(), intval($params['apply_id'])); + + return $isTrue + ? $this->response->success() + : $this->response->fail(); + } + + /** + * 获取联系人申请未读数 + * + * @RequestMapping(path="apply-unread-num", methods="get") + */ + public function getContactApplyUnreadNum() + { + $num = ApplyNumCache::get($this->uid()); + return $this->response->success([ + 'unread_num' => $num ? $num : 0 + ]); + } + + /** + * 获取联系人申请未读数 + * + * @RequestMapping(path="apply-records", methods="get") + */ + public function getContactApplyRecords() + { + $params = $this->request->inputs(['page', 'page_size']); + $this->validate($params, [ + 'page' => 'present|integer', + 'page_size' => 'present|integer' + ]); + + $page = $this->request->input('page', 1); + $page_size = $this->request->input('page_size', 10); + $user_id = $this->uid(); + + $data = $this->contactsService->getContactApplyRecords($user_id, $page, $page_size); + + ApplyNumCache::del($user_id); + + return $this->response->success($data); + } + + /** + * 搜索联系人 + * + * @RequestMapping(path="search", methods="get") + */ + public function searchContacts() + { + $params = $this->request->inputs(['mobile']); + $this->validate($params, [ + 'mobile' => "present|regex:/^1[3456789][0-9]{9}$/" + ]); + + $result = $this->contactsService->findContact($params['mobile']); + return $this->response->success($result); + } + + /** + * 编辑联系人备注 + * + * @RequestMapping(path="edit-remark", methods="post") + */ + public function editContactRemark() + { + $params = $this->request->inputs(['friend_id', 'remarks']); + $this->validate($params, [ + 'friend_id' => 'required|integer|min:1', + 'remarks' => "required|max:20" + ]); + + $user_id = $this->uid(); + $isTrue = $this->contactsService->editContactRemark($user_id, intval($params['friend_id']), $params['remarks']); + if (!$isTrue) { + return $this->response->fail('备注修改失败...'); + } + + FriendRemarkCache::set($user_id, intval($params['friend_id']), $params['remarks']); + return $this->response->success([], '备注修改成功...'); + } +} diff --git a/app/Controller/Api/V1/GroupController.php b/app/Controller/Api/V1/GroupController.php index 6353496..d7ddf7a 100644 --- a/app/Controller/Api/V1/GroupController.php +++ b/app/Controller/Api/V1/GroupController.php @@ -1,507 +1,520 @@ - - * @link https://github.com/gzydong/hyperf-chat - */ -namespace App\Controller\Api\V1; - -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\Amqp\Producer; -use App\Model\UsersFriend; -use App\Model\UsersChatList; -use App\Model\Group\UsersGroup; -use App\Model\Group\UsersGroupMember; -use App\Model\Group\UsersGroupNotice; -use App\Amqp\Producer\ChatMessageProducer; -use App\Service\SocketRoomService; -use App\Service\GroupService; -use App\Constants\SocketConstants; - -/** - * Class GroupController - * - * @Controller(path="/api/v1/group") - * @Middleware(JWTAuthMiddleware::class) - * - * @package App\Controller\Api\V1 - */ -class GroupController extends CController -{ - /** - * @Inject - * @var GroupService - */ - private $groupService; - - /** - * @Inject - * @var Producer - */ - private $producer; - - /** - * @Inject - * @var SocketRoomService - */ - private $socketRoomService; - - /** - * 创建群组 - * - * @RequestMapping(path="create", methods="post") - * - * @return mixed - */ - public function create() - { - $params = $this->request->inputs(['group_name', 'uids']); - $this->validate($params, [ - 'group_name' => 'required', - 'uids' => 'required|ids' - ]); - - $friend_ids = parse_ids($params['uids']); - - $user_id = $this->uid(); - [$isTrue, $data] = $this->groupService->create($user_id, [ - 'name' => $params['group_name'], - 'avatar' => $params['avatar'] ?? '', - 'profile' => $params['group_profile'] ?? '' - ], $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(SocketConstants::EVENT_TALK, [ - 'sender' => $user_id, //发送者ID - 'receive' => intval($data['group_id']), //接收者ID - 'source' => 2, //接收者类型 1:好友;2:群组 - 'record_id' => intval($data['record_id']) - ]) - ); - - return $this->response->success([ - 'group_id' => $data['group_id'] - ]); - } - - /** - * 解散群组接口 - * - * @RequestMapping(path="dismiss", methods="post") - */ - public function dismiss() - { - $params = $this->request->inputs(['group_id']); - $this->validate($params, [ - 'group_id' => 'required|integer' - ]); - - $isTrue = $this->groupService->dismiss($params['group_id'], $this->uid()); - if (!$isTrue) { - return $this->response->fail('群组解散失败...'); - } - - $this->socketRoomService->delRoom($params['group_id']); - - // ... 推送群消息(后期添加) - - return $this->response->success([], '群组解散成功...'); - } - - /** - * 邀请好友加入群组接口 - * - * @RequestMapping(path="invite", methods="post") - */ - public function invite() - { - $params = $this->request->inputs(['group_id', 'uids']); - $this->validate($params, [ - 'group_id' => 'required|integer', - 'uids' => 'required|ids' - ]); - - $uids = parse_ids($params['uids']); - - $user_id = $this->uid(); - [$isTrue, $record_id] = $this->groupService->invite($user_id, $params['group_id'], $uids); - if (!$isTrue) { - return $this->response->fail('邀请好友加入群聊失败...'); - } - - // 加入聊天室 - foreach ($uids as $uid) { - $this->socketRoomService->addRoomMember($uid, $params['group_id']); - } - - // ...消息推送队列 - $this->producer->produce( - new ChatMessageProducer(SocketConstants::EVENT_TALK, [ - 'sender' => $user_id, //发送者ID - 'receive' => intval($params['group_id']), //接收者ID - 'source' => 2, //接收者类型 1:好友;2:群组 - 'record_id' => $record_id - ]) - ); - - return $this->response->success([], '好友已成功加入群聊...'); - } - - /** - * 退出群组接口 - * - * @RequestMapping(path="secede", methods="post") - */ - public function secede() - { - $params = $this->request->inputs(['group_id']); - $this->validate($params, [ - 'group_id' => 'required|integer' - ]); - - $user_id = $this->uid(); - [$isTrue, $record_id] = $this->groupService->quit($user_id, $params['group_id']); - if (!$isTrue) { - return $this->response->fail('退出群组失败...'); - } - - // 移出聊天室 - $this->socketRoomService->delRoomMember($params['group_id'], $user_id); - - // ...消息推送队列 - $this->producer->produce( - new ChatMessageProducer(SocketConstants::EVENT_TALK, [ - 'sender' => $user_id, //发送者ID - 'receive' => intval($params['group_id']), //接收者ID - 'source' => 2, //接收者类型 1:好友;2:群组 - 'record_id' => $record_id - ]) - ); - - return $this->response->success([], '已成功退出群组...'); - } - - /** - * 编辑群组信息 - * - * @RequestMapping(path="edit", methods="post") - */ - public function editDetail() - { - $params = $this->request->inputs(['group_id', 'group_name', 'group_profile', 'avatar']); - $this->validate($params, [ - 'group_id' => 'required|integer', - 'group_name' => 'required|max:30', - 'group_profile' => 'required|max:100', - 'avatar' => 'present|url' - ]); - - $result = UsersGroup::where('id', $params['group_id'])->where('user_id', $this->uid())->update([ - 'group_name' => $params['group_name'], - 'group_profile' => $params['group_profile'], - 'avatar' => $params['avatar'] - ]); - - // 推送消息通知 - // ... - - return $result - ? $this->response->success([], '群组信息修改成功...') - : $this->response->fail('群组信息修改失败...'); - } - - /** - * 移除指定成员(管理员权限) - * - * @RequestMapping(path="remove-members", methods="post") - */ - public function removeMembers() - { - $params = $this->request->inputs(['group_id', 'members_ids']); - $this->validate($params, [ - 'group_id' => 'required|integer', - 'members_ids' => 'required|array' - ]); - - $user_id = $this->uid(); - if (in_array($user_id, $params['members_ids'])) { - return $this->response->fail('群聊用户移除失败...'); - } - - [$isTrue, $record_id] = $this->groupService->removeMember($params['group_id'], $user_id, $params['members_ids']); - if (!$isTrue) { - return $this->response->fail('群聊用户移除失败...'); - } - - // 移出聊天室 - foreach ($params['members_ids'] as $uid) { - $this->socketRoomService->delRoomMember($params['group_id'], $uid); - } - - // ...消息推送队列 - $this->producer->produce( - new ChatMessageProducer(SocketConstants::EVENT_TALK, [ - 'sender' => $user_id, //发送者ID - 'receive' => intval($params['group_id']), //接收者ID - 'source' => 2, //接收者类型 1:好友;2:群组 - 'record_id' => $record_id - ]) - ); - - return $this->response->success([], '已成功退出群组...'); - } - - /** - * 获取群信息接口 - * - * @RequestMapping(path="detail", methods="get") - */ - public function detail() - { - $group_id = $this->request->input('group_id', 0); - - $user_id = $this->uid(); - $groupInfo = UsersGroup::leftJoin('users', 'users.id', '=', 'users_group.user_id') - ->where('users_group.id', $group_id)->where('users_group.status', 0)->first([ - 'users_group.id', 'users_group.user_id', - 'users_group.group_name', - 'users_group.group_profile', 'users_group.avatar', - 'users_group.created_at', - 'users.nickname' - ]); - - if (!$groupInfo) { - return $this->response->success([]); - } - - $notice = UsersGroupNotice::where('group_id', $group_id) - ->where('is_delete', 0) - ->orderBy('id', 'desc') - ->first(['title', 'content']); - - return $this->response->success([ - 'group_id' => $groupInfo->id, - 'group_name' => $groupInfo->group_name, - 'group_profile' => $groupInfo->group_profile, - 'avatar' => $groupInfo->avatar, - 'created_at' => $groupInfo->created_at, - 'is_manager' => $groupInfo->user_id == $user_id, - 'manager_nickname' => $groupInfo->nickname, - 'visit_card' => UsersGroupMember::visitCard($user_id, $group_id), - 'not_disturb' => UsersChatList::where('uid', $user_id)->where('group_id', $group_id)->where('type', 2)->value('not_disturb') ?? 0, - 'notice' => $notice ? $notice->toArray() : [] - ]); - } - - /** - * 设置用户群名片 - * - * @RequestMapping(path="set-group-card", methods="post") - */ - public function setGroupCard() - { - $params = $this->request->inputs(['group_id', 'visit_card']); - $this->validate($params, [ - 'group_id' => 'required|integer', - 'visit_card' => 'required|max:20' - ]); - - $isTrue = UsersGroupMember::where('group_id', $params['group_id']) - ->where('user_id', $this->uid()) - ->where('status', 0) - ->update(['visit_card' => $params['visit_card']]); - - return $isTrue - ? $this->response->success([], '群名片修改成功...') - : $this->response->error('群名片修改失败...'); - } - - /** - * 获取用户可邀请加入群组的好友列表 - * - * @RequestMapping(path="invite-friends", methods="get") - */ - public function getInviteFriends() - { - $group_id = $this->request->input('group_id', 0); - $friends = UsersFriend::getUserFriends($this->uid()); - if ($group_id > 0 && $friends) { - if ($ids = UsersGroupMember::getGroupMemberIds($group_id)) { - foreach ($friends as $k => $item) { - if (in_array($item['id'], $ids)) unset($friends[$k]); - } - } - - $friends = array_values($friends); - } - - return $this->response->success($friends); - } - - /** - * 获取群组成员列表 - * - * @RequestMapping(path="members", methods="get") - */ - public function getGroupMembers() - { - $user_id = $this->uid(); - $group_id = $this->request->input('group_id', 0); - - // 判断用户是否是群成员 - if (!UsersGroup::isMember($group_id, $user_id)) { - return $this->response->fail('非法操作...'); - } - - $members = UsersGroupMember::select([ - 'users_group_member.id', 'users_group_member.group_owner as is_manager', 'users_group_member.visit_card', - 'users_group_member.user_id', 'users.avatar', 'users.nickname', 'users.gender', - 'users.motto', - ]) - ->leftJoin('users', 'users.id', '=', 'users_group_member.user_id') - ->where([ - ['users_group_member.group_id', '=', $group_id], - ['users_group_member.status', '=', 0], - ])->orderBy('is_manager', 'desc')->get()->toArray(); - - return $this->response->success($members); - } - - /** - * 获取群组公告列表 - * - * @RequestMapping(path="notices", methods="get") - */ - public function getGroupNotices() - { - $user_id = $this->uid(); - $group_id = $this->request->input('group_id', 0); - - // 判断用户是否是群成员 - if (!UsersGroup::isMember($group_id, $user_id)) { - return $this->response->fail('非管理员禁止操作...'); - } - - $rows = UsersGroupNotice::leftJoin('users', 'users.id', '=', 'users_group_notice.user_id') - ->where([ - ['users_group_notice.group_id', '=', $group_id], - ['users_group_notice.is_delete', '=', 0] - ]) - ->orderBy('users_group_notice.id', 'desc') - ->get([ - 'users_group_notice.id', - 'users_group_notice.user_id', - 'users_group_notice.title', - 'users_group_notice.content', - 'users_group_notice.created_at', - 'users_group_notice.updated_at', - 'users.avatar', 'users.nickname', - ])->toArray(); - - return $this->response->success($rows); - } - - /** - * 创建/编辑群公告 - * - * @RequestMapping(path="edit-notice", methods="post") - */ - public function editNotice() - { - $params = $this->request->inputs(['group_id', 'notice_id', 'title', 'content']); - $this->validate($params, [ - 'group_id' => 'required|integer', - 'notice_id' => 'required|integer', - 'title' => 'required|max:50', - 'content' => 'required' - ]); - - $user_id = $this->uid(); - - // 判断用户是否是管理员 - if (!UsersGroup::isManager($user_id, $params['group_id'])) { - return $this->response->fail('非管理员禁止操作...'); - } - - // 判断是否是新增数据 - if (empty($data['notice_id'])) { - $result = UsersGroupNotice::create([ - 'group_id' => $params['group_id'], - 'title' => $params['title'], - 'content' => $params['content'], - 'user_id' => $user_id, - 'created_at' => date('Y-m-d H:i:s'), - 'updated_at' => date('Y-m-d H:i:s') - ]); - - if (!$result) { - return $this->response->fail('添加群公告信息失败...'); - } - - // ... 推送群消息 - return $this->response->success([], '添加群公告信息成功...'); - } - - $result = UsersGroupNotice::where('id', $data['notice_id'])->update([ - 'title' => $data['title'], - 'content' => $data['content'], - 'updated_at' => date('Y-m-d H:i:s') - ]); - - return $result - ? $this->response->success([], '修改群公告信息成功...') - : $this->response->fail('修改群公告信息成功...'); - } - - /** - * 删除群公告(软删除) - * - * @RequestMapping(path="delete-notice", methods="post") - */ - public function deleteNotice() - { - $params = $this->request->inputs(['group_id', 'notice_id']); - $this->validate($params, [ - 'group_id' => 'required|integer', - 'notice_id' => 'required|integer' - ]); - - $user_id = $this->uid(); - - // 判断用户是否是管理员 - if (!UsersGroup::isManager($user_id, $params['group_id'])) { - return $this->response->fail('非法操作...'); - } - - $result = UsersGroupNotice::where('id', $params['notice_id']) - ->where('group_id', $params['group_id']) - ->update([ - 'is_delete' => 1, - 'deleted_at' => date('Y-m-d H:i:s') - ]); - - return $result - ? $this->response->success([], '公告删除成功...') - : $this->response->fail('公告删除失败...'); - } -} + + * @link https://github.com/gzydong/hyperf-chat + */ + +namespace App\Controller\Api\V1; + +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\Amqp\Producer; +use App\Model\UsersFriend; +use App\Model\UsersChatList; +use App\Model\Group\UsersGroup; +use App\Model\Group\UsersGroupMember; +use App\Model\Group\UsersGroupNotice; +use App\Amqp\Producer\ChatMessageProducer; +use App\Service\SocketRoomService; +use App\Service\GroupService; +use App\Constants\SocketConstants; + +/** + * Class GroupController + * + * @Controller(path="/api/v1/group") + * @Middleware(JWTAuthMiddleware::class) + * + * @package App\Controller\Api\V1 + */ +class GroupController extends CController +{ + /** + * @Inject + * @var GroupService + */ + private $groupService; + + /** + * @Inject + * @var Producer + */ + private $producer; + + /** + * @Inject + * @var SocketRoomService + */ + private $socketRoomService; + + /** + * 创建群组 + * + * @RequestMapping(path="create", methods="post") + * + * @return mixed + */ + public function create() + { + $params = $this->request->inputs(['group_name', 'uids']); + $this->validate($params, [ + 'group_name' => 'required', + 'uids' => 'required|ids' + ]); + + $friend_ids = parse_ids($params['uids']); + + $user_id = $this->uid(); + [$isTrue, $data] = $this->groupService->create($user_id, [ + 'name' => $params['group_name'], + 'avatar' => $params['avatar'] ?? '', + 'profile' => $params['group_profile'] ?? '' + ], $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(SocketConstants::EVENT_TALK, [ + 'sender' => $user_id, //发送者ID + 'receive' => intval($data['group_id']), //接收者ID + 'source' => 2, //接收者类型 1:好友;2:群组 + 'record_id' => intval($data['record_id']) + ]) + ); + + return $this->response->success([ + 'group_id' => $data['group_id'] + ]); + } + + /** + * 解散群组接口 + * + * @RequestMapping(path="dismiss", methods="post") + */ + public function dismiss() + { + $params = $this->request->inputs(['group_id']); + $this->validate($params, [ + 'group_id' => 'required|integer' + ]); + + $isTrue = $this->groupService->dismiss($params['group_id'], $this->uid()); + if (!$isTrue) { + return $this->response->fail('群组解散失败...'); + } + + $this->socketRoomService->delRoom($params['group_id']); + + // ... 推送群消息(后期添加) + + return $this->response->success([], '群组解散成功...'); + } + + /** + * 邀请好友加入群组接口 + * + * @RequestMapping(path="invite", methods="post") + */ + public function invite() + { + $params = $this->request->inputs(['group_id', 'uids']); + $this->validate($params, [ + 'group_id' => 'required|integer', + 'uids' => 'required|ids' + ]); + + $uids = parse_ids($params['uids']); + + $user_id = $this->uid(); + [$isTrue, $record_id] = $this->groupService->invite($user_id, $params['group_id'], $uids); + if (!$isTrue) { + return $this->response->fail('邀请好友加入群聊失败...'); + } + + // 加入聊天室 + foreach ($uids as $uid) { + $this->socketRoomService->addRoomMember($uid, $params['group_id']); + } + + // ...消息推送队列 + $this->producer->produce( + new ChatMessageProducer(SocketConstants::EVENT_TALK, [ + 'sender' => $user_id, //发送者ID + 'receive' => intval($params['group_id']), //接收者ID + 'source' => 2, //接收者类型 1:好友;2:群组 + 'record_id' => $record_id + ]) + ); + + return $this->response->success([], '好友已成功加入群聊...'); + } + + /** + * 退出群组接口 + * + * @RequestMapping(path="secede", methods="post") + */ + public function secede() + { + $params = $this->request->inputs(['group_id']); + $this->validate($params, [ + 'group_id' => 'required|integer' + ]); + + $user_id = $this->uid(); + [$isTrue, $record_id] = $this->groupService->quit($user_id, $params['group_id']); + if (!$isTrue) { + return $this->response->fail('退出群组失败...'); + } + + // 移出聊天室 + $this->socketRoomService->delRoomMember($params['group_id'], $user_id); + + // ...消息推送队列 + $this->producer->produce( + new ChatMessageProducer(SocketConstants::EVENT_TALK, [ + 'sender' => $user_id, //发送者ID + 'receive' => intval($params['group_id']), //接收者ID + 'source' => 2, //接收者类型 1:好友;2:群组 + 'record_id' => $record_id + ]) + ); + + return $this->response->success([], '已成功退出群组...'); + } + + /** + * 编辑群组信息 + * + * @RequestMapping(path="edit", methods="post") + */ + public function editDetail() + { + $params = $this->request->inputs(['group_id', 'group_name', 'group_profile', 'avatar']); + $this->validate($params, [ + 'group_id' => 'required|integer', + 'group_name' => 'required|max:30', + 'group_profile' => 'required|max:100', + 'avatar' => 'present|url' + ]); + + $result = UsersGroup::where('id', $params['group_id'])->where('user_id', $this->uid())->update([ + 'group_name' => $params['group_name'], + 'group_profile' => $params['group_profile'], + 'avatar' => $params['avatar'] + ]); + + // 推送消息通知 + // ... + + return $result + ? $this->response->success([], '群组信息修改成功...') + : $this->response->fail('群组信息修改失败...'); + } + + /** + * 移除指定成员(管理员权限) + * + * @RequestMapping(path="remove-members", methods="post") + */ + public function removeMembers() + { + $params = $this->request->inputs(['group_id', 'members_ids']); + $this->validate($params, [ + 'group_id' => 'required|integer', + 'members_ids' => 'required|array' + ]); + + $user_id = $this->uid(); + if (in_array($user_id, $params['members_ids'])) { + return $this->response->fail('群聊用户移除失败...'); + } + + [$isTrue, $record_id] = $this->groupService->removeMember($params['group_id'], $user_id, $params['members_ids']); + if (!$isTrue) { + return $this->response->fail('群聊用户移除失败...'); + } + + // 移出聊天室 + foreach ($params['members_ids'] as $uid) { + $this->socketRoomService->delRoomMember($params['group_id'], $uid); + } + + // ...消息推送队列 + $this->producer->produce( + new ChatMessageProducer(SocketConstants::EVENT_TALK, [ + 'sender' => $user_id, //发送者ID + 'receive' => intval($params['group_id']), //接收者ID + 'source' => 2, //接收者类型 1:好友;2:群组 + 'record_id' => $record_id + ]) + ); + + return $this->response->success([], '已成功退出群组...'); + } + + /** + * 获取群信息接口 + * + * @RequestMapping(path="detail", methods="get") + */ + public function detail() + { + $group_id = $this->request->input('group_id', 0); + + $user_id = $this->uid(); + $groupInfo = UsersGroup::leftJoin('users', 'users.id', '=', 'users_group.user_id') + ->where('users_group.id', $group_id)->where('users_group.status', 0)->first([ + 'users_group.id', 'users_group.user_id', + 'users_group.group_name', + 'users_group.group_profile', 'users_group.avatar', + 'users_group.created_at', + 'users.nickname' + ]); + + if (!$groupInfo) { + return $this->response->success([]); + } + + $notice = UsersGroupNotice::where('group_id', $group_id) + ->where('is_delete', 0) + ->orderBy('id', 'desc') + ->first(['title', 'content']); + + return $this->response->success([ + 'group_id' => $groupInfo->id, + 'group_name' => $groupInfo->group_name, + 'group_profile' => $groupInfo->group_profile, + 'avatar' => $groupInfo->avatar, + 'created_at' => $groupInfo->created_at, + 'is_manager' => $groupInfo->user_id == $user_id, + 'manager_nickname' => $groupInfo->nickname, + 'visit_card' => UsersGroupMember::visitCard($user_id, $group_id), + 'not_disturb' => UsersChatList::where('uid', $user_id)->where('group_id', $group_id)->where('type', 2)->value('not_disturb') ?? 0, + 'notice' => $notice ? $notice->toArray() : [] + ]); + } + + /** + * 设置群名片 + * + * @RequestMapping(path="set-group-card", methods="post") + */ + public function setGroupCard() + { + $params = $this->request->inputs(['group_id', 'visit_card']); + $this->validate($params, [ + 'group_id' => 'required|integer', + 'visit_card' => 'required|max:20' + ]); + + $isTrue = UsersGroupMember::where('group_id', $params['group_id']) + ->where('user_id', $this->uid()) + ->where('status', 0) + ->update(['visit_card' => $params['visit_card']]); + + return $isTrue + ? $this->response->success([], '群名片修改成功...') + : $this->response->error('群名片修改失败...'); + } + + /** + * 获取可邀请加入群组的好友列表 + * + * @RequestMapping(path="invite-friends", methods="get") + */ + public function getInviteFriends() + { + $group_id = $this->request->input('group_id', 0); + $friends = UsersFriend::getUserFriends($this->uid()); + if ($group_id > 0 && $friends) { + if ($ids = UsersGroupMember::getGroupMemberIds($group_id)) { + foreach ($friends as $k => $item) { + if (in_array($item['id'], $ids)) unset($friends[$k]); + } + } + + $friends = array_values($friends); + } + + return $this->response->success($friends); + } + + /** + * 获取群组列表 + * + * @RequestMapping(path="list", methods="get") + */ + public function getGroups() + { + return $this->response->success( + $this->groupService->getGroups($this->uid()) + ); + } + + /** + * 获取群组成员列表 + * + * @RequestMapping(path="members", methods="get") + */ + public function getGroupMembers() + { + $user_id = $this->uid(); + $group_id = $this->request->input('group_id', 0); + + // 判断用户是否是群成员 + if (!UsersGroup::isMember($group_id, $user_id)) { + return $this->response->fail('非法操作...'); + } + + $members = UsersGroupMember::select([ + 'users_group_member.id', 'users_group_member.group_owner as is_manager', 'users_group_member.visit_card', + 'users_group_member.user_id', 'users.avatar', 'users.nickname', 'users.gender', + 'users.motto', + ]) + ->leftJoin('users', 'users.id', '=', 'users_group_member.user_id') + ->where([ + ['users_group_member.group_id', '=', $group_id], + ['users_group_member.status', '=', 0], + ])->orderBy('is_manager', 'desc')->get()->toArray(); + + return $this->response->success($members); + } + + /** + * 获取群组公告列表 + * + * @RequestMapping(path="notices", methods="get") + */ + public function getGroupNotices() + { + $user_id = $this->uid(); + $group_id = $this->request->input('group_id', 0); + + // 判断用户是否是群成员 + if (!UsersGroup::isMember($group_id, $user_id)) { + return $this->response->fail('非管理员禁止操作...'); + } + + $rows = UsersGroupNotice::leftJoin('users', 'users.id', '=', 'users_group_notice.user_id') + ->where([ + ['users_group_notice.group_id', '=', $group_id], + ['users_group_notice.is_delete', '=', 0] + ]) + ->orderBy('users_group_notice.id', 'desc') + ->get([ + 'users_group_notice.id', + 'users_group_notice.user_id', + 'users_group_notice.title', + 'users_group_notice.content', + 'users_group_notice.created_at', + 'users_group_notice.updated_at', + 'users.avatar', 'users.nickname', + ])->toArray(); + + return $this->response->success($rows); + } + + /** + * 创建/编辑群公告 + * + * @RequestMapping(path="edit-notice", methods="post") + */ + public function editNotice() + { + $params = $this->request->inputs(['group_id', 'notice_id', 'title', 'content']); + $this->validate($params, [ + 'group_id' => 'required|integer', + 'notice_id' => 'required|integer', + 'title' => 'required|max:50', + 'content' => 'required' + ]); + + $user_id = $this->uid(); + + // 判断用户是否是管理员 + if (!UsersGroup::isManager($user_id, $params['group_id'])) { + return $this->response->fail('非管理员禁止操作...'); + } + + // 判断是否是新增数据 + if (empty($data['notice_id'])) { + $result = UsersGroupNotice::create([ + 'group_id' => $params['group_id'], + 'title' => $params['title'], + 'content' => $params['content'], + 'user_id' => $user_id, + 'created_at' => date('Y-m-d H:i:s'), + 'updated_at' => date('Y-m-d H:i:s') + ]); + + if (!$result) { + return $this->response->fail('添加群公告信息失败...'); + } + + // ... 推送群消息 + return $this->response->success([], '添加群公告信息成功...'); + } + + $result = UsersGroupNotice::where('id', $data['notice_id'])->update([ + 'title' => $data['title'], + 'content' => $data['content'], + 'updated_at' => date('Y-m-d H:i:s') + ]); + + return $result + ? $this->response->success([], '修改群公告信息成功...') + : $this->response->fail('修改群公告信息成功...'); + } + + /** + * 删除群公告(软删除) + * + * @RequestMapping(path="delete-notice", methods="post") + */ + public function deleteNotice() + { + $params = $this->request->inputs(['group_id', 'notice_id']); + $this->validate($params, [ + 'group_id' => 'required|integer', + 'notice_id' => 'required|integer' + ]); + + $user_id = $this->uid(); + + // 判断用户是否是管理员 + if (!UsersGroup::isManager($user_id, $params['group_id'])) { + return $this->response->fail('非法操作...'); + } + + $result = UsersGroupNotice::where('id', $params['notice_id']) + ->where('group_id', $params['group_id']) + ->update([ + 'is_delete' => 1, + 'deleted_at' => date('Y-m-d H:i:s') + ]); + + return $result + ? $this->response->success([], '公告删除成功...') + : $this->response->fail('公告删除失败...'); + } +} diff --git a/app/Controller/Api/V1/UsersController.php b/app/Controller/Api/V1/UsersController.php index dda6ea1..93b16c5 100644 --- a/app/Controller/Api/V1/UsersController.php +++ b/app/Controller/Api/V1/UsersController.php @@ -16,20 +16,11 @@ use Hyperf\HttpServer\Annotation\Controller; use Hyperf\HttpServer\Annotation\RequestMapping; use Hyperf\HttpServer\Annotation\Middleware; use App\Middleware\JWTAuthMiddleware; -use Hyperf\Amqp\Producer; -use App\Amqp\Producer\ChatMessageProducer; use App\Model\User; -use App\Model\UsersChatList; -use App\Model\UsersFriend; use App\Support\SendEmailCode; use App\Helper\Hash; -use App\Service\FriendService; use App\Service\UserService; -use App\Service\SocketClientService; use App\Service\SmsCodeService; -use App\Cache\ApplyNumCache; -use App\Cache\FriendRemarkCache; -use App\Constants\SocketConstants; use App\Constants\ResponseCode; use Psr\Http\Message\ResponseInterface; @@ -43,83 +34,12 @@ use Psr\Http\Message\ResponseInterface; */ class UsersController extends CController { - /** - * @Inject - * @var FriendService - */ - private $friendService; - /** * @Inject * @var UserService */ private $userService; - /** - * @inject - * @var SocketClientService - */ - private $socketClientService; - - /** - * @Inject - * @var Producer - */ - private $producer; - - /** - * 获取我的好友列表 - * - * @RequestMapping(path="friends", methods="get") - */ - public function getUserFriends() - { - $rows = UsersFriend::getUserFriends($this->uid()); - - $runArr = $this->socketClientService->getServerRunIdAll(); - foreach ($rows as $k => $row) { - $rows[$k]['online'] = $this->socketClientService->isOnlineAll($row['id'], $runArr); - } - - return $this->response->success($rows); - } - - /** - * 解除好友关系 - * - * @RequestMapping(path="remove-friend", methods="post") - */ - public function removeFriend() - { - $params = $this->request->inputs(['friend_id']); - $this->validate($params, [ - 'friend_id' => 'required|integer' - ]); - - $user_id = $this->uid(); - if (!$this->friendService->removeFriend($user_id, $params['friend_id'])) { - return $this->response->fail('好友关系解除成功...'); - } - - //删除好友会话列表 - UsersChatList::delItem($user_id, $params['friend_id'], 2); - UsersChatList::delItem($params['friend_id'], $user_id, 2); - - return $this->response->success([], '好友关系解除成功...'); - } - - /** - * 获取用户群聊列表 - * - * @RequestMapping(path="user-groups", methods="get") - */ - public function getUserGroups() - { - return $this->response->success( - $this->userService->getUserChatGroups($this->uid()) - ); - } - /** * 获取我的信息 * @@ -212,182 +132,16 @@ class UsersController extends CController */ public function searchUserInfo() { - $params = $this->request->inputs(['user_id', 'mobile']); + $params = $this->request->inputs(['user_id']); + $this->validate($params, ['user_id' => 'required|integer']); - if (isset($params['user_id']) && !empty($params['user_id'])) { - $this->validate($params, ['user_id' => 'present|integer']); - $where['uid'] = $params['user_id']; - } else if (isset($params['mobile']) && !empty($params['mobile'])) { - $this->validate($params, ['mobile' => "present|regex:/^1[345789][0-9]{9}$/"]); - $where['mobile'] = $params['mobile']; - } else { - return $this->response->fail('请求参数不正确...', [], ResponseCode::VALIDATION_ERROR); - } - - if ($data = $this->userService->searchUserInfo($where, $this->uid())) { + if ($data = $this->userService->getUserCard($params['user_id'],$this->uid())) { return $this->response->success($data); } return $this->response->fail('查询失败...'); } - /** - * 编辑好友备注信息 - * - * @RequestMapping(path="edit-friend-remark", methods="post") - */ - public function editFriendRemark() - { - $params = $this->request->inputs(['friend_id', 'remarks']); - $this->validate($params, [ - 'friend_id' => 'required|integer|min:1', - 'remarks' => "required|max:20" - ]); - - $user_id = $this->uid(); - $isTrue = $this->friendService->editFriendRemark($user_id, $params['friend_id'], $params['remarks']); - if ($isTrue) { - FriendRemarkCache::set($user_id, (int)$params['friend_id'], $params['remarks']); - } - - return $isTrue - ? $this->response->success([], '备注修改成功...') - : $this->response->fail('备注修改失败...'); - } - - /** - * 发送添加好友申请 - * - * @RequestMapping(path="send-friend-apply", methods="post") - */ - public function sendFriendApply() - { - $params = $this->request->inputs(['friend_id', 'remarks']); - $this->validate($params, [ - 'friend_id' => 'required|integer', - 'remarks' => 'present|max:50' - ]); - - $user = $this->userService->findById($params['friend_id']); - if (!$user) { - return $this->response->fail('用户不存在...'); - } - - $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->socketClientService->isOnlineAll((int)$params['friend_id'])) { - $this->producer->produce( - new ChatMessageProducer(SocketConstants::EVENT_FRIEND_APPLY, [ - 'sender' => $user_id, - 'receive' => (int)$params['friend_id'], - 'type' => 1, - 'status' => 1, - 'remark' => '' - ]) - ); - } - - return $this->response->success([], '发送好友申请成功...'); - } - - /** - * 处理好友的申请 - * - * @RequestMapping(path="handle-friend-apply", methods="post") - */ - public function handleFriendApply() - { - $params = $this->request->inputs(['apply_id', 'remarks']); - $this->validate($params, [ - 'apply_id' => 'required|integer', - 'remarks' => 'present|max:20' - ]); - - $user_id = $this->uid(); - $isTrue = $this->friendService->handleFriendApply($this->uid(), (int)$params['apply_id'], $params['remarks']); - if (!$isTrue) { - return $this->response->fail('处理失败...'); - } - - //判断对方是否在线。如果在线发送消息通知 - if ($this->socketClientService->isOnlineAll((int)$params['friend_id'])) { - // 待修改 - $this->producer->produce( - new ChatMessageProducer(SocketConstants::EVENT_FRIEND_APPLY, [ - 'sender' => $user_id, - 'receive' => (int)$params['friend_id'], - 'type' => 1, - 'status' => 1, - 'remark' => '' - ]) - ); - } - - return $this->response->success([], '处理成功...'); - } - - /** - * 删除好友申请记录 - * - * @RequestMapping(path="delete-friend-apply", methods="post") - */ - public function deleteFriendApply() - { - $params = $this->request->inputs(['apply_id']); - $this->validate($params, [ - 'apply_id' => 'required|integer' - ]); - - $isTrue = $this->friendService->delFriendApply($this->uid(), (int)$params['apply_id']); - return $isTrue - ? $this->response->success([], '删除成功...') - : $this->response->fail('删除失败...'); - } - - /** - * 获取我的好友申请记录 - * - * @RequestMapping(path="friend-apply-records", methods="get") - */ - public function getFriendApplyRecords() - { - $params = $this->request->inputs(['page', 'page_size']); - $this->validate($params, [ - 'page' => 'present|integer', - 'page_size' => 'present|integer' - ]); - - $page = $this->request->input('page', 1); - $page_size = $this->request->input('page_size', 10); - $user_id = $this->uid(); - - $data = $this->friendService->findApplyRecords($user_id, $page, $page_size); - - ApplyNumCache::del($user_id); - - return $this->response->success($data); - } - - /** - * 获取好友申请未读数 - * - * @RequestMapping(path="friend-apply-num", methods="get") - */ - public function getApplyUnreadNum() - { - $num = ApplyNumCache::get($this->uid()); - return $this->response->success([ - 'unread_num' => $num ? $num : 0 - ]); - } - /** * 修改我的密码 * diff --git a/app/Service/ContactsService.php b/app/Service/ContactsService.php new file mode 100644 index 0000000..623ac11 --- /dev/null +++ b/app/Service/ContactsService.php @@ -0,0 +1,287 @@ + + * @link https://github.com/gzydong/hyperf-chat + */ + +namespace App\Service; + +use App\Model\User; +use App\Model\UsersFriend; +use App\Model\UsersFriendsApply; +use App\Traits\PagingTrait; +use Hyperf\DbConnection\Db; +use Exception; + +/** + * ContactsService + * 注:联系人服务层 + * + * @package App\Service + */ +class ContactsService extends BaseService +{ + use PagingTrait; + + /** + * 获取联系人列表 + * + * @param int $user_id 用户ID + * @return array + */ + public function getContacts(int $user_id): array + { + $prefix = config('databases.default.prefix'); + $sql = <<where('friend_id', $friend_id) + ->orderBy('id', 'desc')->first(); + + if (!$result) { + $result = UsersFriendsApply::create([ + 'user_id' => $user_id, + 'friend_id' => $friend_id, + 'status' => 0, + 'remarks' => $remarks, + 'created_at' => date('Y-m-d H:i:s'), + 'updated_at' => date('Y-m-d H:i:s') + ]); + + return $result ? true : false; + } else if ($result->status == 0) { + $result->remarks = $remarks; + $result->updated_at = date('Y-m-d H:i:s'); + $result->save(); + + return true; + } + + return false; + } + + /** + * 删除联系人 + * + * @param int $user_id 用户ID + * @param int $friend_id 好友ID + * @return bool + */ + public function deleteContact(int $user_id, int $friend_id): bool + { + if (!UsersFriend::isFriend($user_id, $friend_id)) { + return false; + } + + $data = ['status' => 0]; + + // 用户ID比大小交换位置 + if ($user_id > $friend_id) { + [$user_id, $friend_id] = [$friend_id, $user_id]; + } + + return (bool)UsersFriend::where('user1', $user_id)->where('user2', $friend_id)->update($data); + } + + /** + * 同意添加联系人 / 联系人申请 + * + * @param int $user_id 用户ID + * @param int $apply_id 联系人申请ID + * @param string $remarks 联系人备注名称 + * @return bool + */ + public function acceptInvitation(int $user_id, int $apply_id, string $remarks = ''): bool + { + $info = UsersFriendsApply::where('id', $apply_id) + ->where('friend_id', $user_id) + ->where('status', 0) + ->orderBy('id', 'desc') + ->first(['user_id', 'friend_id']); + + if (!$info) return false; + + Db::beginTransaction(); + try { + $res = UsersFriendsApply::where('id', $apply_id)->update(['status' => 1, 'updated_at' => date('Y-m-d H:i:s')]); + if (!$res) { + throw new Exception('更新好友申请表信息失败'); + } + + // 判断大小 交换 user1,user2 的位置 + [$user1, $user2] = $info->user_id < $info->friend_id ? [$info->user_id, $info->friend_id] : [$info->friend_id, $info->user_id]; + + // 查询是否存在好友记录 + $friendResult = UsersFriend::where([ + ['user1', '=', $user1], + ['user2', '=', $user2] + ])->first(['id', 'user1', 'user2', 'active', 'status']); + + if ($friendResult) { + $active = ($friendResult->user1 == $info->user_id && $friendResult->user2 == $info->friend_id) ? 1 : 2; + UsersFriend::where('id', $friendResult->id)->update(['active' => $active, 'status' => 1]); + } else { + //好友昵称 + $friend_nickname = User::where('id', $info->friend_id)->value('nickname'); + + UsersFriend::create([ + 'user1' => $user1, + 'user2' => $user2, + 'user1_remark' => $user1 == $user_id ? $remarks : $friend_nickname, + 'user2_remark' => $user2 == $user_id ? $remarks : $friend_nickname, + 'active' => $user1 == $user_id ? 2 : 1, + 'status' => 1, + 'agree_time' => date('Y-m-d H:i:s'), + 'created_at' => date('Y-m-d H:i:s') + ]); + } + + Db::commit(); + } catch (Exception $e) { + Db::rollBack(); + return false; + } + + return true; + } + + /** + * 拒绝添加联系人 / 联系人申请 + * + * @param int $user_id 用户ID + * @param int $apply_id 联系人申请ID + * @param string $remarks 拒绝申请备注信息 + * @return bool + */ + public function declineInvitation(int $user_id, int $apply_id, string $remarks = ''): bool + { + $result = UsersFriendsApply::where([ + ['id', '=', $apply_id], + ['user_id', '=', $user_id], + ['status', '=', 2], + ])->update([ + 'status' => 2, + 'remarks' => $remarks, + 'updated_at' => date('Y-m-d H:i:s') + ]); + + return $result ? true : false; + } + + /** + * 编辑联系人备注 + * + * @param int $user_id 用户ID + * @param int $friend_id 朋友ID + * @param string $remarks 好友备注名称 + * @return bool + */ + public function editContactRemark(int $user_id, int $friend_id, string $remarks): bool + { + $data = []; + if ($user_id > $friend_id) { + [$user_id, $friend_id] = [$friend_id, $user_id]; + $data['user2_remark'] = $remarks; + } else { + $data['user1_remark'] = $remarks; + } + + return (bool)UsersFriend::where('user1', $user_id)->where('user2', $friend_id)->update($data); + } + + /** + * 搜索联系人 + * + * @param string $mobile 用户手机号/登录账号 + * @return array + */ + public function findContact(string $mobile): array + { + $user = User::where('mobile', $mobile)->first(['id', 'nickname', 'mobile', 'avatar', 'gender']); + + return $user ? $user->toArray() : []; + } + + /** + * 获取联系人申请记录 + * + * @param int $user_id 用户ID + * @param int $page 当前分页 + * @param int $page_size 分页大小 + * @return array + */ + public function getContactApplyRecords(int $user_id, $page = 1, $page_size = 30): array + { + $rowsSqlObj = UsersFriendsApply::select([ + 'users_friends_apply.id', + 'users_friends_apply.status', + 'users_friends_apply.remarks', + 'users.nickname', + 'users.avatar', + 'users.mobile', + 'users_friends_apply.user_id', + 'users_friends_apply.friend_id', + 'users_friends_apply.created_at' + ]); + + $rowsSqlObj->leftJoin('users', 'users.id', '=', 'users_friends_apply.user_id'); + $rowsSqlObj->where('users_friends_apply.friend_id', $user_id); + + $count = $rowsSqlObj->count(); + $rows = []; + if ($count > 0) { + $rows = $rowsSqlObj->orderBy('users_friends_apply.id', 'desc')->forPage($page, $page_size)->get()->toArray(); + } + + return $this->getPagingRows($rows, $count, $page, $page_size); + } + + /** + * 删除联系人申请记录 + * + * @param int $user_id 用户ID + * @param int $apply_id 联系人好友申请ID + * @return bool + */ + public function delContactApplyRecord(int $user_id, int $apply_id): bool + { + return (bool)UsersFriendsApply::where('id', $apply_id)->where('friend_id', $user_id)->delete(); + } +} diff --git a/app/Service/FriendService.php b/app/Service/FriendService.php deleted file mode 100644 index 2ce8fdd..0000000 --- a/app/Service/FriendService.php +++ /dev/null @@ -1,205 +0,0 @@ -where('friend_id', $friend_id)->orderBy('id', 'desc')->first(); - if (!$result) { - $result = UsersFriendsApply::create([ - 'user_id' => $user_id, - 'friend_id' => $friend_id, - 'status' => 0, - 'remarks' => $remarks, - 'created_at' => date('Y-m-d H:i:s'), - 'updated_at' => date('Y-m-d H:i:s') - ]); - - return $result ? true : false; - } else if ($result->status == 0) { - $result->remarks = $remarks; - $result->updated_at = date('Y-m-d H:i:s'); - $result->save(); - - return true; - } - - return false; - } - - /** - * 删除好友申请记录 - * - * @param int $user_id 用户ID - * @param int $apply_id 好友申请ID - * @return mixed - */ - public function delFriendApply(int $user_id, int $apply_id) - { - return (bool)UsersFriendsApply::where('id', $apply_id)->where('friend_id', $user_id)->delete(); - } - - /** - * 处理好友的申请 - * - * @param int $user_id 当前用户ID - * @param int $apply_id 申请记录ID - * @param string $remarks 备注信息 - * @return bool - */ - public function handleFriendApply(int $user_id, int $apply_id, $remarks = '') - { - $info = UsersFriendsApply::where('id', $apply_id)->where('friend_id', $user_id)->where('status', 0)->orderBy('id', 'desc')->first(['user_id', 'friend_id']); - if (!$info) { - return false; - } - - Db::beginTransaction(); - try { - $res = UsersFriendsApply::where('id', $apply_id)->update(['status' => 1, 'updated_at' => date('Y-m-d H:i:s')]); - if (!$res) { - throw new \Exception('更新好友申请表信息失败'); - } - - $user1 = $info->user_id; - $user2 = $info->friend_id; - if ($info->user_id > $info->friend_id) { - [$user1, $user2] = [$info->friend_id, $info->user_id]; - } - - //查询是否存在好友记录 - $friendResult = UsersFriend::select('id', 'user1', 'user2', 'active', 'status')->where('user1', '=', $user1)->where('user2', '=', $user2)->first(); - if ($friendResult) { - $active = ($friendResult->user1 == $info->user_id && $friendResult->user2 == $info->friend_id) ? 1 : 2; - if (!UsersFriend::where('id', $friendResult->id)->update(['active' => $active, 'status' => 1])) { - throw new \Exception('更新好友关系信息失败'); - } - } else { - //好友昵称 - $friend_nickname = User::where('id', $info->friend_id)->value('nickname'); - $insRes = UsersFriend::create([ - 'user1' => $user1, - 'user2' => $user2, - 'user1_remark' => $user1 == $user_id ? $remarks : $friend_nickname, - 'user2_remark' => $user2 == $user_id ? $remarks : $friend_nickname, - 'active' => $user1 == $user_id ? 2 : 1, - 'status' => 1, - 'agree_time' => date('Y-m-d H:i:s'), - 'created_at' => date('Y-m-d H:i:s') - ]); - - if (!$insRes) { - throw new \Exception('创建好友关系失败'); - } - } - - Db::commit(); - } catch (\Exception $e) { - Db::rollBack(); - return false; - } - - return true; - } - - /** - * 解除好友关系 - * - * @param int $user_id 用户ID - * @param int $friend_id 好友ID - * @return bool - */ - public function removeFriend(int $user_id, int $friend_id) - { - if (!UsersFriend::isFriend($user_id, $friend_id)) { - return false; - } - - $data = ['status' => 0]; - - // 用户ID比大小交换位置 - if ($user_id > $friend_id) { - [$user_id, $friend_id] = [$friend_id, $user_id]; - } - - return (bool)UsersFriend::where('user1', $user_id)->where('user2', $friend_id)->update($data); - } - - /** - * 获取用户好友申请记录 - * - * @param int $user_id 用户ID - * @param int $page 分页数 - * @param int $page_size 分页大小 - * @return array - */ - public function findApplyRecords(int $user_id, $page = 1, $page_size = 30) - { - $rowsSqlObj = UsersFriendsApply::select([ - 'users_friends_apply.id', - 'users_friends_apply.status', - 'users_friends_apply.remarks', - 'users.nickname', - 'users.avatar', - 'users.mobile', - 'users_friends_apply.user_id', - 'users_friends_apply.friend_id', - 'users_friends_apply.created_at' - ]); - - $rowsSqlObj->leftJoin('users', 'users.id', '=', 'users_friends_apply.user_id'); - $rowsSqlObj->where('users_friends_apply.friend_id', $user_id); - - $count = $rowsSqlObj->count(); - $rows = []; - if ($count > 0) { - $rows = $rowsSqlObj->orderBy('users_friends_apply.id', 'desc')->forPage($page, $page_size)->get()->toArray(); - } - - return $this->getPagingRows($rows, $count, $page, $page_size); - } - - /** - * 编辑好友备注信息 - * - * @param int $user_id 用户ID - * @param int $friend_id 朋友ID - * @param string $remarks 好友备注名称 - * @return bool - */ - public function editFriendRemark(int $user_id, int $friend_id, string $remarks) - { - $data = []; - if ($user_id > $friend_id) { - [$user_id, $friend_id] = [$friend_id, $user_id]; - $data['user2_remark'] = $remarks; - } else { - $data['user1_remark'] = $remarks; - } - - return (bool)UsersFriend::where('user1', $user_id)->where('user2', $friend_id)->update($data); - } -} diff --git a/app/Service/GroupService.php b/app/Service/GroupService.php index 8f6914a..f91fa85 100644 --- a/app/Service/GroupService.php +++ b/app/Service/GroupService.php @@ -1,336 +1,375 @@ - $user_id, - 'group_name' => $group_info['name'], - 'avatar' => $group_info['avatar'], - 'group_profile' => $group_info['profile'], - 'status' => 0, - 'created_at' => date('Y-m-d H:i:s') - ]); - - if (!$insRes) { - throw new Exception('创建群失败'); - } - - foreach ($friend_ids as $k => $uid) { - $groupMember[] = [ - 'group_id' => $insRes->id, - 'user_id' => $uid, - 'group_owner' => $user_id == $uid ? 1 : 0, - 'status' => 0, - 'created_at' => date('Y-m-d H:i:s'), - ]; - - $chatList[] = [ - 'type' => 2, - 'uid' => $uid, - 'friend_id' => 0, - 'group_id' => $insRes->id, - 'status' => 1, - 'created_at' => date('Y-m-d H:i:s'), - 'updated_at' => date('Y-m-d H:i:s') - ]; - } - - if (!Db::table('users_group_member')->insert($groupMember)) { - throw new Exception('创建群成员信息失败'); - } - - if (!Db::table('users_chat_list')->insert($chatList)) { - throw new Exception('创建群成员的聊天列表失败'); - } - - $result = ChatRecord::create([ - 'msg_type' => 3, - 'source' => 2, - 'user_id' => 0, - 'receive_id' => $insRes->id, - 'created_at' => date('Y-m-d H:i:s') - ]); - - if (!$result) { - throw new Exception('创建群成员的聊天列表失败'); - } - - ChatRecordsInvite::create([ - 'record_id' => $result->id, - 'type' => 1, - 'operate_user_id' => $user_id, - 'user_ids' => implode(',', $friend_ids) - ]); - - Db::commit(); - } catch (Exception $e) { - Db::rollBack(); - logger()->error($e); - return [false, 0]; - } - - // 设置群聊消息缓存 - LastMsgCache::set(['created_at' => date('Y-m-d H:i:s'), 'text' => '入群通知'], $insRes->id, 0); - - return [true, ['record_id' => $result->id, 'group_id' => $insRes->id]]; - } - - /** - * 解散群组 - * - * @param int $group_id 群ID - * @param int $user_id 用户ID - * @return bool - */ - public function dismiss(int $group_id, int $user_id) - { - if (!UsersGroup::where('id', $group_id)->where('status', 0)->exists()) { - return false; - } - - //判断执行者是否属于群主 - if (!UsersGroup::isManager($user_id, $group_id)) { - return false; - } - - Db::beginTransaction(); - try { - UsersGroup::where('id', $group_id)->update(['status' => 1]); - UsersGroupMember::where('group_id', $group_id)->update(['status' => 1]); - Db::commit(); - } catch (Exception $e) { - Db::rollBack(); - return false; - } - - return true; - } - - /** - * 邀请加入群组 - * - * @param int $user_id 用户ID - * @param int $group_id 聊天群ID - * @param array $friend_ids 被邀请的用户ID - * @return array - */ - public function invite(int $user_id, int $group_id, $friend_ids = []) - { - $info = UsersGroupMember::select(['id', 'status'])->where('group_id', $group_id)->where('user_id', $user_id)->first(); - - //判断主动邀请方是否属于聊天群成员 - if (!$info && $info->status == 1) { - return [false, 0]; - } - - if (empty($friend_ids)) { - return [false, 0]; - } - - $updateArr = $insertArr = $updateArr1 = $insertArr1 = []; - - $members = UsersGroupMember::where('group_id', $group_id)->whereIn('user_id', $friend_ids)->get(['id', 'user_id', 'status'])->keyBy('user_id')->toArray(); - $chatArr = UsersChatList::where('group_id', $group_id)->whereIn('uid', $friend_ids)->get(['id', 'uid', 'status'])->keyBy('uid')->toArray(); - - foreach ($friend_ids as $uid) { - if (!isset($members[$uid])) {//存在聊天群成员记录 - $insertArr[] = ['group_id' => $group_id, 'user_id' => $uid, 'group_owner' => 0, 'status' => 0, 'created_at' => date('Y-m-d H:i:s')]; - } else if ($members[$uid]['status'] == 1) { - $updateArr[] = $members[$uid]['id']; - } - - if (!isset($chatArr[$uid])) { - $insertArr1[] = ['type' => 2, 'uid' => $uid, 'friend_id' => 0, 'group_id' => $group_id, 'status' => 1, 'created_at' => date('Y-m-d H:i:s'), 'updated_at' => date('Y-m-d H:i:s')]; - } else if ($chatArr[$uid]['status'] == 0) { - $updateArr1[] = $chatArr[$uid]['id']; - } - } - - try { - if ($updateArr) { - UsersGroupMember::whereIn('id', $updateArr)->update(['status' => 0]); - } - - if ($insertArr) { - Db::table('users_group_member')->insert($insertArr); - } - - if ($updateArr1) { - UsersChatList::whereIn('id', $updateArr1)->update(['status' => 1, 'created_at' => date('Y-m-d H:i:s')]); - } - - if ($insertArr1) { - Db::table('users_chat_list')->insert($insertArr1); - } - - $result = ChatRecord::create([ - 'msg_type' => 3, - 'source' => 2, - 'user_id' => 0, - 'receive_id' => $group_id, - 'created_at' => date('Y-m-d H:i:s') - ]); - - if (!$result) throw new Exception('添加群通知记录失败1'); - - $result2 = ChatRecordsInvite::create([ - 'record_id' => $result->id, - 'type' => 1, - 'operate_user_id' => $user_id, - 'user_ids' => implode(',', $friend_ids) - ]); - - if (!$result2) throw new Exception('添加群通知记录失败2'); - - Db::commit(); - } catch (\Exception $e) { - Db::rollBack(); - return [false, 0]; - } - - LastMsgCache::set(['created_at' => date('Y-m-d H:i:s'), 'text' => '入群通知'], $group_id, 0); - return [true, $result->id]; - } - - /** - * 退出群组 - * - * @param int $user_id 用户ID - * @param int $group_id 群组ID - * @return array - */ - public function quit(int $user_id, int $group_id) - { - $record_id = 0; - Db::beginTransaction(); - try { - $res = UsersGroupMember::where('group_id', $group_id)->where('user_id', $user_id)->where('group_owner', 0)->update(['status' => 1]); - if ($res) { - UsersChatList::where('uid', $user_id)->where('type', 2)->where('group_id', $group_id)->update(['status' => 0]); - - $result = ChatRecord::create([ - 'msg_type' => 3, - 'source' => 2, - 'user_id' => 0, - 'receive_id' => $group_id, - 'content' => $user_id, - 'created_at' => date('Y-m-d H:i:s') - ]); - - if (!$result) { - throw new Exception('添加群通知记录失败 : quitGroupChat'); - } - - $result2 = ChatRecordsInvite::create([ - 'record_id' => $result->id, - 'type' => 2, - 'operate_user_id' => $user_id, - 'user_ids' => $user_id - ]); - - if (!$result2) { - throw new Exception('添加群通知记录失败2 : quitGroupChat'); - } - - UsersChatList::where('uid', $user_id)->where('group_id', $group_id)->update(['status' => 0, 'updated_at' => date('Y-m-d H:i:s')]); - - $record_id = $result->id; - } - - Db::commit(); - } catch (Exception $e) { - Db::rollBack(); - return [false, 0]; - } - - return [true, $record_id]; - } - - /** - * 踢出群组(管理员特殊权限) - * - * @param int $group_id 群ID - * @param int $user_id 操作用户ID - * @param array $member_ids 群成员ID - * @return array - */ - public function removeMember(int $group_id, int $user_id, array $member_ids) - { - if (!UsersGroup::isManager($user_id, $group_id)) { - return [false, 0]; - } - - Db::beginTransaction(); - try { - //更新用户状态 - if (!UsersGroupMember::where('group_id', $group_id)->whereIn('user_id', $member_ids)->where('group_owner', 0)->update(['status' => 1])) { - throw new Exception('修改群成员状态失败'); - } - - $result = ChatRecord::create([ - 'msg_type' => 3, - 'source' => 2, - 'user_id' => 0, - 'receive_id' => $group_id, - 'created_at' => date('Y-m-d H:i:s') - ]); - - if (!$result) { - throw new Exception('添加群通知记录失败1'); - } - - $result2 = ChatRecordsInvite::create([ - 'record_id' => $result->id, - 'type' => 3, - 'operate_user_id' => $user_id, - 'user_ids' => implode(',', $member_ids) - ]); - - if (!$result2) { - throw new Exception('添加群通知记录失败2'); - } - - foreach ($member_ids as $member_id) { - UsersChatList::where('uid', $member_id)->where('group_id', $group_id)->update(['status' => 0, 'updated_at' => date('Y-m-d H:i:s')]); - } - - Db::commit(); - } catch (Exception $e) { - Db::rollBack(); - return [false, 0]; - } - - return [true, $result->id]; - } -} +where([ + ['users_group_member.user_id', '=', $user_id], + ['users_group_member.status', '=', 0] + ]) + ->orderBy('id', 'desc') + ->get($fields)->toArray(); + + foreach ($items as $key => $item) { + // 判断当前用户是否是群主 + $items[$key]['isGroupLeader'] = $item['group_user_id'] == $user_id; + + //删除无关字段 + unset($items[$key]['group_user_id']); + + // 是否消息免打扰 + $items[$key]['not_disturb'] = UsersChatList::where([ + ['uid', '=', $user_id], + ['type', '=', 2], + ['group_id', '=', $item['id']] + ])->value('not_disturb'); + } + + return $items; + } + + /** + * 创建群组 + * + * @param int $user_id 用户ID + * @param array $group_info 群聊名称 + * @param array $friend_ids 好友的用户ID + * @return array + */ + public function create(int $user_id, array $group_info, $friend_ids = []) + { + $friend_ids[] = $user_id; + $groupMember = []; + $chatList = []; + + Db::beginTransaction(); + try { + $insRes = UsersGroup::create([ + 'user_id' => $user_id, + 'group_name' => $group_info['name'], + 'avatar' => $group_info['avatar'], + 'group_profile' => $group_info['profile'], + 'status' => 0, + 'created_at' => date('Y-m-d H:i:s') + ]); + + if (!$insRes) { + throw new Exception('创建群失败'); + } + + foreach ($friend_ids as $k => $uid) { + $groupMember[] = [ + 'group_id' => $insRes->id, + 'user_id' => $uid, + 'group_owner' => $user_id == $uid ? 1 : 0, + 'status' => 0, + 'created_at' => date('Y-m-d H:i:s'), + ]; + + $chatList[] = [ + 'type' => 2, + 'uid' => $uid, + 'friend_id' => 0, + 'group_id' => $insRes->id, + 'status' => 1, + 'created_at' => date('Y-m-d H:i:s'), + 'updated_at' => date('Y-m-d H:i:s') + ]; + } + + if (!Db::table('users_group_member')->insert($groupMember)) { + throw new Exception('创建群成员信息失败'); + } + + if (!Db::table('users_chat_list')->insert($chatList)) { + throw new Exception('创建群成员的聊天列表失败'); + } + + $result = ChatRecord::create([ + 'msg_type' => 3, + 'source' => 2, + 'user_id' => 0, + 'receive_id' => $insRes->id, + 'created_at' => date('Y-m-d H:i:s') + ]); + + if (!$result) { + throw new Exception('创建群成员的聊天列表失败'); + } + + ChatRecordsInvite::create([ + 'record_id' => $result->id, + 'type' => 1, + 'operate_user_id' => $user_id, + 'user_ids' => implode(',', $friend_ids) + ]); + + Db::commit(); + } catch (Exception $e) { + Db::rollBack(); + logger()->error($e); + return [false, 0]; + } + + // 设置群聊消息缓存 + LastMsgCache::set(['created_at' => date('Y-m-d H:i:s'), 'text' => '入群通知'], $insRes->id, 0); + + return [true, ['record_id' => $result->id, 'group_id' => $insRes->id]]; + } + + /** + * 解散群组 + * + * @param int $group_id 群ID + * @param int $user_id 用户ID + * @return bool + */ + public function dismiss(int $group_id, int $user_id) + { + if (!UsersGroup::where('id', $group_id)->where('status', 0)->exists()) { + return false; + } + + //判断执行者是否属于群主 + if (!UsersGroup::isManager($user_id, $group_id)) { + return false; + } + + Db::beginTransaction(); + try { + UsersGroup::where('id', $group_id)->update(['status' => 1]); + UsersGroupMember::where('group_id', $group_id)->update(['status' => 1]); + Db::commit(); + } catch (Exception $e) { + Db::rollBack(); + return false; + } + + return true; + } + + /** + * 邀请加入群组 + * + * @param int $user_id 用户ID + * @param int $group_id 聊天群ID + * @param array $friend_ids 被邀请的用户ID + * @return array + */ + public function invite(int $user_id, int $group_id, $friend_ids = []) + { + $info = UsersGroupMember::select(['id', 'status'])->where('group_id', $group_id)->where('user_id', $user_id)->first(); + + //判断主动邀请方是否属于聊天群成员 + if (!$info && $info->status == 1) { + return [false, 0]; + } + + if (empty($friend_ids)) { + return [false, 0]; + } + + $updateArr = $insertArr = $updateArr1 = $insertArr1 = []; + + $members = UsersGroupMember::where('group_id', $group_id)->whereIn('user_id', $friend_ids)->get(['id', 'user_id', 'status'])->keyBy('user_id')->toArray(); + $chatArr = UsersChatList::where('group_id', $group_id)->whereIn('uid', $friend_ids)->get(['id', 'uid', 'status'])->keyBy('uid')->toArray(); + + foreach ($friend_ids as $uid) { + if (!isset($members[$uid])) {//存在聊天群成员记录 + $insertArr[] = ['group_id' => $group_id, 'user_id' => $uid, 'group_owner' => 0, 'status' => 0, 'created_at' => date('Y-m-d H:i:s')]; + } else if ($members[$uid]['status'] == 1) { + $updateArr[] = $members[$uid]['id']; + } + + if (!isset($chatArr[$uid])) { + $insertArr1[] = ['type' => 2, 'uid' => $uid, 'friend_id' => 0, 'group_id' => $group_id, 'status' => 1, 'created_at' => date('Y-m-d H:i:s'), 'updated_at' => date('Y-m-d H:i:s')]; + } else if ($chatArr[$uid]['status'] == 0) { + $updateArr1[] = $chatArr[$uid]['id']; + } + } + + try { + if ($updateArr) { + UsersGroupMember::whereIn('id', $updateArr)->update(['status' => 0]); + } + + if ($insertArr) { + Db::table('users_group_member')->insert($insertArr); + } + + if ($updateArr1) { + UsersChatList::whereIn('id', $updateArr1)->update(['status' => 1, 'created_at' => date('Y-m-d H:i:s')]); + } + + if ($insertArr1) { + Db::table('users_chat_list')->insert($insertArr1); + } + + $result = ChatRecord::create([ + 'msg_type' => 3, + 'source' => 2, + 'user_id' => 0, + 'receive_id' => $group_id, + 'created_at' => date('Y-m-d H:i:s') + ]); + + if (!$result) throw new Exception('添加群通知记录失败1'); + + $result2 = ChatRecordsInvite::create([ + 'record_id' => $result->id, + 'type' => 1, + 'operate_user_id' => $user_id, + 'user_ids' => implode(',', $friend_ids) + ]); + + if (!$result2) throw new Exception('添加群通知记录失败2'); + + Db::commit(); + } catch (\Exception $e) { + Db::rollBack(); + return [false, 0]; + } + + LastMsgCache::set(['created_at' => date('Y-m-d H:i:s'), 'text' => '入群通知'], $group_id, 0); + return [true, $result->id]; + } + + /** + * 退出群组 + * + * @param int $user_id 用户ID + * @param int $group_id 群组ID + * @return array + */ + public function quit(int $user_id, int $group_id) + { + $record_id = 0; + Db::beginTransaction(); + try { + $res = UsersGroupMember::where('group_id', $group_id)->where('user_id', $user_id)->where('group_owner', 0)->update(['status' => 1]); + if ($res) { + UsersChatList::where('uid', $user_id)->where('type', 2)->where('group_id', $group_id)->update(['status' => 0]); + + $result = ChatRecord::create([ + 'msg_type' => 3, + 'source' => 2, + 'user_id' => 0, + 'receive_id' => $group_id, + 'content' => $user_id, + 'created_at' => date('Y-m-d H:i:s') + ]); + + if (!$result) { + throw new Exception('添加群通知记录失败 : quitGroupChat'); + } + + $result2 = ChatRecordsInvite::create([ + 'record_id' => $result->id, + 'type' => 2, + 'operate_user_id' => $user_id, + 'user_ids' => $user_id + ]); + + if (!$result2) { + throw new Exception('添加群通知记录失败2 : quitGroupChat'); + } + + UsersChatList::where('uid', $user_id)->where('group_id', $group_id)->update(['status' => 0, 'updated_at' => date('Y-m-d H:i:s')]); + + $record_id = $result->id; + } + + Db::commit(); + } catch (Exception $e) { + Db::rollBack(); + return [false, 0]; + } + + return [true, $record_id]; + } + + /** + * 踢出群组(管理员特殊权限) + * + * @param int $group_id 群ID + * @param int $user_id 操作用户ID + * @param array $member_ids 群成员ID + * @return array + */ + public function removeMember(int $group_id, int $user_id, array $member_ids) + { + if (!UsersGroup::isManager($user_id, $group_id)) { + return [false, 0]; + } + + Db::beginTransaction(); + try { + //更新用户状态 + if (!UsersGroupMember::where('group_id', $group_id)->whereIn('user_id', $member_ids)->where('group_owner', 0)->update(['status' => 1])) { + throw new Exception('修改群成员状态失败'); + } + + $result = ChatRecord::create([ + 'msg_type' => 3, + 'source' => 2, + 'user_id' => 0, + 'receive_id' => $group_id, + 'created_at' => date('Y-m-d H:i:s') + ]); + + if (!$result) { + throw new Exception('添加群通知记录失败1'); + } + + $result2 = ChatRecordsInvite::create([ + 'record_id' => $result->id, + 'type' => 3, + 'operate_user_id' => $user_id, + 'user_ids' => implode(',', $member_ids) + ]); + + if (!$result2) { + throw new Exception('添加群通知记录失败2'); + } + + foreach ($member_ids as $member_id) { + UsersChatList::where('uid', $member_id)->where('group_id', $group_id)->update(['status' => 0, 'updated_at' => date('Y-m-d H:i:s')]); + } + + Db::commit(); + } catch (Exception $e) { + Db::rollBack(); + return [false, 0]; + } + + return [true, $result->id]; + } +} diff --git a/app/Service/UserService.php b/app/Service/UserService.php index a2f2fc5..3f5b8f3 100644 --- a/app/Service/UserService.php +++ b/app/Service/UserService.php @@ -1,191 +1,149 @@ -first($field); - } - - /** - * 登录逻辑 - * - * @param string $mobile 手机号 - * @param string $password 登录密码 - * @return array|bool - */ - public function login(string $mobile, string $password) - { - if (!$user = User::where('mobile', $mobile)->first()) { - return false; - } - - if (!password_verify($password, $user->password)) { - return false; - } - - return $user->toArray(); - } - - /** - * 账号注册逻辑 - * - * @param array $data 用户数据 - * @return bool - */ - public function register(array $data) - { - Db::beginTransaction(); - try { - $data['password'] = Hash::make($data['password']); - $data['created_at'] = date('Y-m-d H:i:s'); - - $result = User::create($data); - - // 创建用户的默认笔记分类 - ArticleClass::create([ - 'user_id' => $result->id, - 'class_name' => '我的笔记', - 'is_default' => 1, - 'sort' => 1, - 'created_at' => time() - ]); - - Db::commit(); - } catch (\Exception $e) { - Db::rollBack(); - $result = false; - } - - return $result ? true : false; - } - - /** - * 账号重置密码 - * - * @param string $mobile 用户手机好 - * @param string $password 新密码 - * @return mixed - */ - public function resetPassword(string $mobile, string $password) - { - return User::where('mobile', $mobile)->update(['password' => Hash::make($password)]); - } - - /** - * 修改绑定的手机号 - * - * @param int $user_id 用户ID - * @param string $mobile 换绑手机号 - * @return array|bool - */ - public function changeMobile(int $user_id, string $mobile) - { - if (User::where('mobile', $mobile)->value('id')) { - return [false, '手机号已被他人绑定']; - } - - $isTrue = (bool)User::where('id', $user_id)->update(['mobile' => $mobile]); - return [$isTrue, null]; - } - - /** - * 获取用户所在的群聊 - * - * @param int $user_id 用户ID - * @return mixed - */ - public function getUserChatGroups(int $user_id) - { - $items = UsersGroupMember::select(['users_group.id', 'users_group.group_name', 'users_group.avatar', 'users_group.group_profile', 'users_group.user_id as group_user_id']) - ->join('users_group', 'users_group.id', '=', 'users_group_member.group_id') - ->where([ - ['users_group_member.user_id', '=', $user_id], - ['users_group_member.status', '=', 0] - ]) - ->orderBy('id', 'desc')->get()->toarray(); - - foreach ($items as $key => $item) { - // 判断当前用户是否是群主 - $items[$key]['isGroupLeader'] = $item['group_user_id'] == $user_id; - - //删除无关字段 - unset($items[$key]['group_user_id']); - - // 是否消息免打扰 - $items[$key]['not_disturb'] = UsersChatList::where([ - ['uid', '=', $user_id], - ['type', '=', 2], - ['group_id', '=', $item['id']] - ])->value('not_disturb'); - } - - return $items; - } - - /** - * 通过手机号查找用户 - * - * @param array $where 查询条件 - * @param int $user_id 当前登录用户的ID - * @return array - */ - public function searchUserInfo(array $where, int $user_id) - { - $info = User::select(['id', 'mobile', 'nickname', 'avatar', 'gender', 'motto']); - if (isset($where['uid'])) { - $info->where('id', $where['uid']); - } - - if (isset($where['mobile'])) { - $info->where('mobile', $where['mobile']); - } - - $info = $info->first(); - $info = $info ? $info->toArray() : []; - if ($info) { - $info['friend_status'] = 0;//朋友关系状态 0:本人 1:陌生人 2:朋友 - $info['nickname_remark'] = ''; - $info['friend_apply'] = 0; - - // 判断查询信息是否是自己 - if ($info['id'] != $user_id) { - $friend_id = $info['id']; - - $friendInfo = UsersFriend::select('id', 'user1', 'user2', 'active', 'user1_remark', 'user2_remark')->where(function ($query) use ($friend_id, $user_id) { - $query->where('user1', '=', $user_id)->where('user2', '=', $friend_id)->where('status', 1); - })->orWhere(function ($query) use ($friend_id, $user_id) { - $query->where('user1', '=', $friend_id)->where('user2', '=', $user_id)->where('status', 1); - })->first(); - - $info['friend_status'] = $friendInfo ? 2 : 1; - if ($friendInfo) { - $info['nickname_remark'] = ($friendInfo->user1 == $friend_id) ? $friendInfo->user2_remark : $friendInfo->user1_remark; - } else { - $res = UsersFriendsApply::where('user_id', $user_id)->where('friend_id', $info['id'])->where('status', 0)->orderBy('id', 'desc')->exists(); - $info['friend_apply'] = $res ? 1 : 0; - } - } - } - - return $info; - } -} +first($field); + } + + /** + * 登录逻辑 + * + * @param string $mobile 手机号 + * @param string $password 登录密码 + * @return array|bool + */ + public function login(string $mobile, string $password) + { + if (!$user = User::where('mobile', $mobile)->first()) { + return false; + } + + if (!password_verify($password, $user->password)) { + return false; + } + + return $user->toArray(); + } + + /** + * 账号注册逻辑 + * + * @param array $data 用户数据 + * @return bool + */ + public function register(array $data) + { + Db::beginTransaction(); + try { + $data['password'] = Hash::make($data['password']); + $data['created_at'] = date('Y-m-d H:i:s'); + + $result = User::create($data); + + // 创建用户的默认笔记分类 + ArticleClass::create([ + 'user_id' => $result->id, + 'class_name' => '我的笔记', + 'is_default' => 1, + 'sort' => 1, + 'created_at' => time() + ]); + + Db::commit(); + } catch (\Exception $e) { + Db::rollBack(); + $result = false; + } + + return $result ? true : false; + } + + /** + * 账号重置密码 + * + * @param string $mobile 用户手机好 + * @param string $password 新密码 + * @return mixed + */ + public function resetPassword(string $mobile, string $password) + { + return User::where('mobile', $mobile)->update(['password' => Hash::make($password)]); + } + + /** + * 修改绑定的手机号 + * + * @param int $user_id 用户ID + * @param string $mobile 换绑手机号 + * @return array|bool + */ + public function changeMobile(int $user_id, string $mobile) + { + if (User::where('mobile', $mobile)->value('id')) { + return [false, '手机号已被他人绑定']; + } + + $isTrue = (bool)User::where('id', $user_id)->update(['mobile' => $mobile]); + return [$isTrue, null]; + } + + /** + * 通过手机号查找用户 + * + * @param int $friend_id 用户ID + * @param int $me_user_id 当前登录用户的ID + * @return array + */ + public function getUserCard(int $friend_id,int $me_user_id) + { + $info = User::select(['id', 'mobile', 'nickname', 'avatar', 'gender', 'motto'])->where('id', $friend_id)->first(); + if(!$info) return []; + + $info = $info->toArray(); + $info['friend_status'] = 0;//朋友关系状态 0:本人 1:陌生人 2:朋友 + $info['nickname_remark'] = ''; + $info['friend_apply'] = 0; + + // 判断查询信息是否是自己 + if ($friend_id != $me_user_id) { + $friendInfo = UsersFriend:: + where('user1', '=', $friend_id > $me_user_id ? $me_user_id :$friend_id) + ->where('user2', '=', $friend_id < $me_user_id ? $me_user_id :$friend_id) + ->where('status', 1) + ->first(['id', 'user1', 'user2', 'active', 'user1_remark', 'user2_remark']); + + $info['friend_status'] = $friendInfo ? 2 : 1; + if ($friendInfo) { + $info['nickname_remark'] = $friendInfo->user1 == $friend_id ? $friendInfo->user2_remark : $friendInfo->user1_remark; + } else { + $res = UsersFriendsApply::where('user_id', $me_user_id) + ->where('friend_id', $friend_id) + ->where('status', 0) + ->orderBy('id', 'desc') + ->exists(); + + $info['friend_apply'] = $res ? 1 : 0; + } + } + + return $info; + } +}