// +---------------------------------------------------------------------- namespace App\Services\Api; use App\Models\GroupModel; use App\Models\GroupUserSettingModel; use App\Models\MemberModel; use App\Services\BaseService; use App\Services\ConfigService; use App\Services\RedisService; use Illuminate\Support\Facades\DB; /** * 群聊服务管理-服务类 * @author laravel开发员 * @since 2020/11/11 * @package App\Services\Api */ class GroupService extends BaseService { // 静态对象 protected static $instance = null; /** * 构造函数 * @author laravel开发员 * @since 2020/11/11 * MessageService constructor. */ public function __construct() { $this->model = new GroupModel(); } /** * 静态入口 * @return static|null */ public static function make() { if (!self::$instance) { self::$instance = (new static()); } return self::$instance; } /** * 群聊列表 * @param $userId * @param $params * @param int $pageSize * @return array */ public function getDataList($userId, $params, $pageSize = 0) { $page = request()->post('page', 1); $cacheKey = "caches:messages:group_{$page}_" . md5($userId . json_encode($params) . $pageSize); $datas = RedisService::get($cacheKey); if ($datas) { return $datas; } $where = ['a.status' => 1, 'a.mark' => 1]; $field = ['a.id','a.user_id', 'a.name', 'a.group_users', 'a.thumb', 'a.status']; $model = $this->model->from('groups as a') ->where($where) ->where(function ($query) use ($params, $userId) { $query->where(['a.user_id'=> $userId]); }); $datas = $model->select($field) ->orderBy('a.create_time', 'desc') ->paginate($pageSize > 0 ? $pageSize : 9999999); $datas = $datas ? $datas->toArray() : []; if ($datas) { foreach ($datas['data'] as &$item) { $item['users'] = []; $groupUsers = $item['group_users']? explode(',', $item['group_users']) : []; $item['user_count'] = $groupUsers? count($groupUsers) : 1; $item['thumb']= $item['thumb']? get_image_url($item['thumb']) : ''; if($item['thumb'] == '' ){ $userIds = $groupUsers? array_slice($groupUsers,0,9) : [$userId]; $item['users'] = $this->getGroupUsers($item['id'], $userIds); } } unset($item); RedisService::set($cacheKey, $datas, rand(5, 10)); } return [ 'list' => isset($datas['data']) ? $datas['data'] : [], 'total' => isset($datas['total']) ? $datas['total'] : 0, 'pageSize' => $pageSize ]; } /** * 群聊默认头像用户 * @param $groupId * @param int $num * @return array|mixed */ public function getGroupUsers($groupId,$userIds, $type=1) { $cacheKey = "caches:groups:users_{$groupId}_".md5(json_encode($userIds)); $data = RedisService::get($cacheKey); if($data){ return $data; } $data = MemberModel::from('member as a') ->leftJoin('groups_user_setting as b',function($join) use($groupId){ $join->on('b.user_id','=','a.id')->where(['b.group_id'=> $groupId,'b.mark'=>1]); }) ->where(['a.status'=>1,'a.mark'=>1]) ->whereIn('a.id', $userIds) ->select(['a.id','a.nickname','a.avatar','b.nickname as group_nickname']) ->get(); $data = $data? $data->toArray() :[]; if($data){ foreach ($data as &$item){ $item['avatar'] = $item['avatar']? $item['avatar'] : '/images/member/logo.png'; $item['avatar_base64'] = $item['avatar'] && $type==1?getImageContent($item['avatar']):''; $item['avatar'] = get_image_url($item['avatar']); $item['nickname'] = $item['group_nickname']? $item['group_nickname'] : $item['nickname']; } array_multisort($userIds,SORT_ASC, $data); RedisService::set($cacheKey, $data, rand(300, 600)); } return $data; } /** * 创建群聊 * @param $userId * @param $params * @return array|false */ public function create($userId, $params) { $userIds = isset($params['user_ids'])? $params['user_ids'] : []; if(!is_array($userIds) || count($userIds)<=0){ $this->error = 3401; return false; } $userCount = ConfigService::make()->getConfigByCode('group_user_count',500); if(count($userIds) > $userCount){ $this->error = web_lang(3402,['num'=> $userCount]); return false; } // 验证账户 $userInfo = MemberModel::where(['id'=> $userId,'mark'=>1]) ->select(['id','nickname','username','status']) ->first(); $status = isset($userInfo['status'])? $userInfo['status'] : 0; $nickname = isset($userInfo['nickname'])? $userInfo['nickname'] : ''; if(empty($userInfo) || $status != 1){ $this->error = 2024; return false; } $users = MemberModel::where(['status'=>1,'mark'=>1])->whereIn('id', $userIds) ->select(['id','nickname','avatar']) ->get(); $users = $users? $users->toArray() : []; if(empty($users)){ $this->error = 3403; return false; } // 群成员 $ids = [$userId]; $names = [$nickname]; $message = []; $groupId = GroupModel::count('id')+1; $groupUsers = []; foreach ($users as $k => $item){ $ids[] = $item['id']; $groupUsers[] = [ 'user_id'=> $item['id'], 'group_id'=> $groupId, 'create_time'=> time(), 'status'=> 1, 'mark'=>1 ]; if($k<=3){ $names[] = $item['nickname']; } if($k<=10){ $message[] = $item['nickname']; } } if(empty($ids)){ $this->error = 3403; return false; } DB::beginTransaction(); $data= [ 'name'=> isset($params['name'])? trim($params['name']) : '', 'thumb'=> isset($params['thumb'])? trim($params['thumb']) : '', 'user_id'=> $userId, 'manage_users'=> $userId, 'group_users'=> $ids? implode(',', $ids) : '', 'chat_status'=> 1, 'friend_status'=> 1, 'status'=> 1, 'mark'=> 1, 'description'=> isset($params['description'])? trim($params['description']) : '', 'create_time'=>time(), ]; if(!$groupId = $this->model->insertGetId($data)){ DB::rollBack(); $this->error = 3404; return false; } // 群成员设置) if($groupUsers && !GroupUserSettingModel::insert($groupUsers)){ DB::rollBack(); $this->error = 3404; return false; } // 建群消息 $message = $message? implode('、', $message).(count($message)>10?'...':'') : ''; $message = $message? "{$message}" : '您创建了一个群聊'; MessageService::make()->pushGroupMessage($groupId,'建群消息',$message,6); DB::commit(); $this->error = 3405; return ['group_id'=> $groupId]; } /** * 群聊详情 * @param $userId * @param $groupId * @return array */ public function getInfo($userId, $groupId) { $info = $this->model->with(['member'])->where(['id'=> $groupId,'mark'=>1])->first(); $info = $info? $info->toArray() : []; if($info){ $info['users'] = []; $info['is_manage'] = 0; $groupUsers = $info['group_users']? explode(',', $info['group_users']) : []; $manageUsers = $info['manage_users']? explode(',', $info['manage_users']) : []; $info['user_count'] = $groupUsers? count($groupUsers) : 1; $info['thumb'] = $info['thumb']? get_image_url($info['thumb']) : ''; $info['users'] = $this->getGroupUsers($groupId, $groupUsers, 1); $info['manages'] = $this->getGroupUsers($groupId, $manageUsers, 2); $info['user_setting'] = GroupUserSettingModel::where(['group_id'=> $groupId,'user_id'=>$userId,'mark'=>1])->first(); if(in_array($userId, $manageUsers)){ $info['is_manage'] = 1; } $data = ['gid'=> $groupId,'scene'=>'group']; $qrcode = MemberService::make()->makeQrcode(json_encode($data)); $info['qrcode'] = $qrcode? get_image_url($qrcode):''; $info['qrcode_base64'] = $qrcode?getImageContent($qrcode):''; if($id = GroupUserSettingModel::where(['user_id'=> $userId,'group_id'=> $groupId,'mark'=>1])->value('id')){ GroupUserSettingModel::where(['id'=> $id])->update(['read_time'=>time()]); }else{ GroupUserSettingModel::insertGetId(['user_id'=> $userId,'group_id'=> $groupId,'read_time'=>time(),'create_time'=>time(),'mark'=>1]); } } return $info; } /** * 邀请入群 * @param $userId * @param $groupId * @return bool */ public function invite($userId, $groupId) { $info = $this->model->where(['id'=> $groupId,'mark'=>1])->first(); $info = $info? $info->toArray() : []; $status = isset($info['status'])? $info['status'] : 0; $friendStatus = isset($info['friend_status'])? $info['friend_status'] : 0; $groupUsers = isset($info['group_users'])? $info['group_users'] : ''; $groupUsers = $groupUsers? explode(',', $groupUsers) : []; if(empty($info)){ $this->error = 3410; return false; } if($status != 1 || $friendStatus==2){ $this->error = 3411; return false; } $userCount = ConfigService::make()->getConfigByCode('group_user_count',500); if(count($groupUsers) >= $userCount){ $this->error = 3413; return false; } if(in_array($userId, $groupUsers)){ $this->error = 3414; return true; } // 验证账户 $userInfo = MemberModel::where(['id'=> $userId,'mark'=>1]) ->select(['id','nickname','username','status']) ->first(); $status = isset($userInfo['status'])? $userInfo['status'] : 0; $nickname = isset($userInfo['nickname'])? $userInfo['nickname'] : ''; if(empty($userInfo) || $status != 1){ $this->error = 2024; return false; } $groupUsers[] = $userId; if($this->model->where(['id'=> $groupId])->update(['group_users'=> implode(',', $groupUsers),'update_time'=>time()])){ $setting = [ 'user_id'=> $userId, 'group_id'=> $groupId, 'create_time'=> time(), 'status'=> 1, 'mark'=>1 ]; GroupUserSettingModel::insertGetId($setting); // 邀请消息 MessageService::make()->pushGroupMessage($groupId,'二维码邀请入群消息', $nickname,6); $this->error = 3415; return true; } $this->error = 3416; return false; } /** * 保存设置 * @param $userId * @param $params * @return bool */ public function saveData($userId, $params) { $groupId = isset($params['group_id'])? $params['group_id'] : 0; $updateData = [ 'update_time'=>time(), ]; if(isset($params['show_nickname']) && $params['show_nickname']){ $updateData['show_nickname'] = intval($params['show_nickname']); } if(isset($params['friend_status']) && $params['friend_status']){ $updateData['friend_status'] = intval($params['friend_status']); } if(isset($params['chat_status']) && $params['chat_status']){ $updateData['chat_status'] = intval($params['chat_status']); } if(isset($params['name']) && $params['name']){ $updateData['name'] = $params['name']; } if(isset($params['description']) && $params['description']){ $updateData['description'] = $params['description']; } $setting = ['update_time'=>time()]; if(isset($params['show_name']) && $params['show_name']){ $setting['show_nickname'] = intval($params['show_name']); } if(isset($params['nickname']) && $params['nickname']){ $setting['nickname'] = trim($params['nickname']); } $this->model->where(['id'=> $groupId])->update($updateData); GroupUserSettingModel::where(['user_id'=> $userId,'group_id'=> $groupId])->update($setting); if(isset($updateData['chat_status'])){ MessageService::make()->pushGroupMessage($groupId,$updateData['chat_status'] != 1?'本群已开启禁言,仅管理员可发言':'本群已禁言', '',6); } return true; } /** * 添加群成员 * @param $userId * @param $params * @return bool */ public function addUser($userId, $params) { $groupId = isset($params['group_id'])? $params['group_id'] : 0; $ids = isset($params['ids'])? $params['ids'] : []; $info = $this->model->where(['id'=> $groupId,'mark'=>1])->first(); $info = $info? $info->toArray() : []; $groupUsers = isset($info['group_users'])? $info['group_users'] : ''; $groupUsers = $groupUsers? explode(',', $groupUsers) : []; if(empty($info)){ $this->error = 3410; return false; } if(empty($ids) || !is_array($ids)){ $this->error = 3450; return false; } $users = MemberModel::whereIn('id', $ids)->where(['mark'=>1])->select(['id','nickname'])->get(); $users = $users? $users->toArray() : []; if(empty($users)){ $this->error = 3451; return false; } // 加入 $names = []; $settingData = []; $count = count($groupUsers); foreach ($users as $item){ $id = $item['id']; if (($key = array_search($id, $groupUsers)) === false) { $names[] = $item['nickname']; $groupUsers[] = $id; $settingData[] = [ 'user_id'=> $id, 'group_id'=> $groupId, 'create_time'=> time(), 'status'=> 1, 'mark'=>1 ]; } } if(count($groupUsers) <= $count){ $this->error = 3451; return false; } // 群消息 DB::beginTransaction(); if(!$this->model->where(['id'=> $groupId])->update(['group_users'=> implode(',', $groupUsers),'update_time'=> time()])){ DB::rollBack(); $this->error = 1003; return false; } if($settingData && !GroupUserSettingModel::insert($settingData)){ DB::rollBack(); $this->error = 1003; return false; } MessageService::make()->pushGroupMessage($groupId,'被邀请进入群聊', implode('、', $names),6); DB::commit(); $this->error = 1002; return true; } /** * 踢出成员 * @param $userId * @param $params * @return bool */ public function decUser($userId, $params) { $groupId = isset($params['group_id'])? $params['group_id'] : 0; $ids = isset($params['ids'])? $params['ids'] : []; $info = $this->model->where(['id'=> $groupId,'mark'=>1])->first(); $info = $info? $info->toArray() : []; $groupUsers = isset($info['group_users'])? $info['group_users'] : ''; $groupUsers = $groupUsers? explode(',', $groupUsers) : []; if(empty($info)){ $this->error = 3410; return false; } if(empty($ids) || !is_array($ids)){ $this->error = 3420; return false; } $users = MemberModel::whereIn('id', $ids)->where(['mark'=>1])->select(['id','nickname'])->get(); $users = $users? $users->toArray() : []; if(empty($users)){ $this->error = 3421; return false; } // 踢出 $names = []; foreach ($users as $item){ $id = $item['id']; if (($key = array_search($id, $groupUsers)) !== false) { $names[] = $item['nickname']; unset($groupUsers[$key]); } } // 群消息 DB::beginTransaction(); if(!$this->model->where(['id'=> $groupId])->update(['group_users'=> implode(',', $groupUsers),'update_time'=> time()])){ DB::rollBack(); $this->error = 1003; return false; } if(!GroupUserSettingModel::where(['group_id'=> $groupId])->whereIn('user_id',$ids)->update(['mark'=>0,'update_time'=> time()])){ DB::rollBack(); $this->error = 1003; return false; } MessageService::make()->pushGroupMessage($groupId,'被踢出群聊', implode('、', $names),6); DB::commit(); $this->error = 1002; return true; } /** * 群管理员设置 * @param $userId * @param $groupId * @return bool */ public function addManage($userId, $params) { $groupId = isset($params['group_id'])? $params['group_id'] : 0; $ids = isset($params['ids'])? $params['ids'] : []; $info = $this->model->where(['id'=> $groupId,'mark'=>1])->first(); $info = $info? $info->toArray() : []; $status = isset($info['status'])? $info['status'] : 0; $manageUsers = isset($info['manage_users'])? $info['manage_users'] : ''; $manageUsers = $manageUsers? explode(',', $manageUsers) : []; if(empty($info) || $status != 1){ $this->error = 3410; return false; } if ($info['user_id'] != $userId){ $this->error = 3422; return false; } $users = MemberModel::whereIn('id', $ids)->where(['mark'=>1])->select(['id','nickname'])->get(); $users = $users? $users->toArray() : []; if(empty($users)){ $this->error = 3451; return false; } // 加入 $names = []; $count = count($manageUsers); foreach ($users as $item){ $id = $item['id']; if (($key = array_search($id, $manageUsers)) === false) { $names[] = $item['nickname']; $manageUsers[] = $id; } } if(count($manageUsers) <= $count){ $this->error = 3421; return false; } // 群消息 DB::beginTransaction(); if(!$this->model->where(['id'=> $groupId])->update(['manage_users'=> implode(',', $manageUsers),'update_time'=> time()])){ DB::rollBack(); $this->error = 1003; return false; } MessageService::make()->pushGroupMessage($groupId,'被设置为管理员', implode('、', $names),6); DB::commit(); $this->error = 1002; return true; } /** * 删除群管理员 * @param $userId * @param $groupId * @return bool */ public function decManage($userId, $params) { $groupId = isset($params['group_id'])? $params['group_id'] : 0; $uid = isset($params['id'])? $params['id'] : 0; $info = $this->model->where(['id'=> $groupId,'mark'=>1])->first(); $info = $info? $info->toArray() : []; $status = isset($info['status'])? $info['status'] : 0; $manageUsers = isset($info['manage_users'])? $info['manage_users'] : ''; $manageUsers = $manageUsers? explode(',', $manageUsers) : []; if(empty($info) || $status != 1){ $this->error = 3410; return false; } if ($info['user_id'] != $userId){ $this->error = 3422; return false; } $userInfo = MemberModel::where(['id'=> $uid,'mark'=>1])->select(['id','nickname'])->first(); $nickname = isset($userInfo['nickname'])? $userInfo['nickname'] : ''; if(empty($userInfo)){ $this->error = 3451; return false; } if(!in_array($uid, $manageUsers)){ $this->error = 3423; return false; } if (($key = array_search($uid, $manageUsers)) !== false) { unset($manageUsers[$key]); } // 群消息 DB::beginTransaction(); if(!$this->model->where(['id'=> $groupId])->update(['manage_users'=> implode(',', $manageUsers),'update_time'=> time()])){ DB::rollBack(); $this->error = 1003; return false; } if($nickname){ MessageService::make()->pushGroupMessage($groupId,'被取消管理员权限', $nickname,6); } DB::commit(); $this->error = 1002; return true; } /** * 清空群聊聊天记录 * @param $userId * @param $groupId * @return bool */ public function exitGroup($userId, $groupId) { $info = $this->model->where(['id'=> $groupId,'mark'=>1])->first(); $info = $info? $info->toArray() : []; $groupUsers = isset($info['group_users'])? $info['group_users'] : ''; $groupUsers = $groupUsers? explode(',', $groupUsers) : []; if(empty($info)){ $this->error = 3410; return false; } if(!in_array($userId, $groupUsers)){ $this->error = 3417; return true; } if (($key = array_search($userId, $groupUsers)) !== false) { unset($groupUsers[$key]); } $this->model->where(['id'=> $groupId])->update(['group_users'=> implode(',', $groupUsers),'update_time'=> time()]); GroupUserSettingModel::where(['user_id'=> $userId,'group_id'=> $groupId])->update(['mark'=>0,'update_time'=> time()]); $this->error = 1002; return true; } /** * 清空群聊聊天记录 * @param $userId * @param $groupId * @return bool */ public function clear($userId, $groupId) { GroupUserSettingModel::where(['user_id'=> $userId,'group_id'=> $groupId])->update(['clear_time'=> time()]); return true; } /** * 解散群聊 * @param $userId * @param $groupId * @return false */ public function deleteGroup($userId, $groupId) { $info = $this->model->where(['id'=> $groupId,'mark'=>1])->first(); $info = $info? $info->toArray() : []; if(empty($info)){ $this->error = 3410; return false; } $this->model->where(['id'=> $groupId])->update(['mark'=>0,'update_time'=>time()]); MessageService::make()->pushGroupMessage($groupId,'解散群聊', implode('、', ),6); } }