where('room_no', $value); } public function searchUserIdAttribute($query, $value, array $params): mixed { if (empty($value)) { return $query; } return $query->where('user_id', $value); } /** * 创建直播间 * @param array $user auth_user * @param string $room_name 直播间名称 * @return bool */ public function createRoom(array $user,string $room_name = '', string $image = ''): bool { $this->setIsStatusSearchValue(0); if (!$room = $this->getDetail(params: ['user_id' => $user['id']])) { // 没有直播间 创建一个 $room_no = (rand(10, 99) . (sprintf("%06d", $user['id']))); $room_session = $room_no . "_" . date('YmdHis'); $insert = [ 'user_id' => $user['id'], 'name' => $room_name, 'logo' => $user['avatar'], 'image' => !empty($image) ? $image : $user['avatar'], 'room_no' => $room_no, 'session' => $room_session, 'status' => 1, 'create_time' => time(), ]; if (!$room_id = $this->query()->insertGetId($insert)) { return $this->error('创建失败'); } } else { // 有直播间 更新直播状态 if ($room['status'] == 2) { return $this->error('直播被封禁!'); } // 已经开播了 if ($room['status'] == 1) { $update = [ 'name' => $room_name, 'logo' => $user['avatar'], 'image' => !empty($image) ? $image : $user['avatar'], 'update_time' => time() ]; if (!$this->query()->where('user_id', $user['id'])->update($update)) { return $this->error('开播失败'); } return $this->success('开播成功', [ 'room_no' => $room['room_no'], 'room_name' => $room['name'], 'talk_status' => $room['talk_status'], 'status' => 1, ]); } $room_no = $room['room_no']; $room_session = $room_no . "_" . date('YmdHis'); $room_id = $room['id']; $room_name = !empty($room_name) ? $room_name : $room['name']; $update = [ 'name' => $room_name, 'logo' => $user['avatar'], 'image' => !empty($image) ? $image : $user['avatar'], 'session' => $room_session, 'status' => 1, 'update_time' => time() ]; if (!$this->query()->where('user_id', $user['id'])->update($update)) { return $this->error('开播失败'); } } $log = [ 'user_id' => $user['id'], 'room_id' => $room_id, 'room_no' => $room_no, 'session' => $room_session, 'open_time' => time(), ]; if (!(new LiveRoomLogModel())->query()->insertGetId($log)) { return $this->error('开播失败'); } return $this->success('开播成功', [ 'room_no' => $room_no, 'room_name' => $room_name, 'talk_status' => $room['talk_status'] ?? 1, ]); } /** * 关闭房间 * @param $room_id * @return bool */ public function closeRoom($room_id) { if (!$room = $this->getDetail(params: ['id' => $room_id])) { return $this->success('关闭成功'); } if (!$this->where('id', $room_id)->update(['status' => 0])) { return $this->error('关闭失败'); } $time = time(); $logUp = [ 'duration' => Db::raw("{$time} - open_time"), 'close_time' => $time, ]; if (!(new LiveRoomLogModel())->where('session',$room['session'])->update($logUp)) { return $this->error('开播失败'); } // 解散直播间移除观众 RedisUtil::getInstance(RedisKeyEnum::ROOM_USER_LIST,$room['room_no'])->del(); return $this->success('关播成功'); } /** * 禁言 * @param int $user_id 主播ID * @param string $room_no 房间号 * @param int $admin_id 观众ID * @return bool */ public function shut_up(int $user_id, string $room_no, int $audience_id, int $time = 86400) { if (!$room = $this->getDetail(params: ['room_no' => $room_no])) { return $this->error('直播间已关闭'); } if ($room['user_id'] != $user_id) { $model = new LiveRoomAdminModel(); if (!$model->getAdmin($user_id, $room_no)) { return $this->error('未拥有此权限'); } } RedisUtil::getInstance(RedisKeyEnum::ROOM_SHUT_UP,$room_no,im_prefix($audience_id))->setex(1,$time+1); // 腾讯直播创建房间 && 创建群组 $im = new TencentIm(); if (!$im->forbid_send_msg($room_no, im_prefix($audience_id), $time)) { return $this->error($im->getMessage() ?? '操作失败'); } return $this->success('成功'); } /** * 封禁 黑名单 * @param int $user_id 主播ID * @param string $room_no 房间号 * @param int $admin_id 观众ID * @return bool */ public function black_add(int $user_id, string $room_no, int $audience_id, int $time = 86400) { if (!$room = $this->getDetail(params: ['room_no' => $room_no])) { return $this->error('直播间已关闭'); } if ($room['user_id'] != $user_id) { $model = new LiveRoomAdminModel(); if (!$model->getAdmin($user_id, $room_no)) { return $this->error('未拥有此权限'); } } Db::beginTransaction(); if (!$info = LiveRoomBlackModel::query()->where(['user_id'=>$audience_id,'room_id'=>$room['id'],'room_no'=>$room_no])->first()){ $log = [ 'user_id' => $audience_id, 'room_id' => $room['id'], 'room_no' => $room_no, 'status' => 1, 'create_time' => time(), 'end_time' => time() + $time, ]; if (!LiveRoomBlackModel::query()->insertGetId($log)) { Db::rollBack(); return $this->error('拉黑失败'); } }else{ if ($info->status == 1 && $info->end_time > time()){ Db::rollBack(); return $this->error('已拉黑过了'); } if (!LiveRoomBlackModel::query()->where('id',$info->id)->update(['status'=>1,'end_time'=>time() + $time,'create_time'=>time()])){ Db::rollBack(); return $this->error('拉黑失败了'); } } RedisUtil::getInstance(RedisKeyEnum::ROOM_BLACK,$room_no,im_prefix($audience_id))->setex(1,$time); // 腾讯直播创建房间 && 创建群组 $im = new TencentIm(); // if (!$im->ban_group_member($room_no, im_prefix($audience_id), $time)) { // return $this->error($im->getMessage() ?? '操作失败'); // } if (!$im->delete_group_member($room_no, im_prefix($audience_id))) { Db::rollBack(); return $this->error($im->getMessage() ?? '操作失败'); } Db::commit(); return $this->success('成功'); } /** * 移除 封禁 黑名单 * @param int $user_id 主播ID * @param string $room_no 房间号 * @param int $admin_id 观众ID * @return bool */ public function black_remove(int $user_id, string $room_no, int $audience_id) { if (!$room = $this->getDetail(params: ['room_no' => $room_no])) { return $this->error('直播间已关闭'); } if ($room['user_id'] != $user_id) { $model = new LiveRoomAdminModel(); if (!$model->getAdmin($user_id, $room_no)) { return $this->error('未拥有此权限'); } } if (!$info = LiveRoomBlackModel::query()->where(['user_id'=>$user_id,'room_id'=>$room['id'],'room_no'=>$room_no])->first()){ return $this->error('您未拉黑过'); }else{ if ($info->status != 1){ return $this->error('已取消拉黑'); } if (!LiveRoomBlackModel::query()->where('id',$info->id)->update(['status'=>0])){ return $this->error('操作失败'); } } RedisUtil::getInstance(RedisKeyEnum::ROOM_BLACK,$room_no,im_prefix($audience_id))->del(); // 腾讯直播创建房间 && 创建群组 // $im = new TencentIm(); // if (!$im->unban_group_member($room_no, im_prefix($audience_id))) { // return $this->error($im->getMessage() ?? '操作失败'); // } return $this->success('成功'); } /** * 采集器 * @param $value * @param $data * @return mixed */ public function dataLogoAttribute($value,$data) { return cdn_url($value); } public function dataImageAttribute($value,$data) { return cdn_url($value); } // 开播日志 public function log() { return $this->hasOne(LiveRoomLogModel::class, 'session', 'session'); } // 主播信息 public function user() { return $this->hasOne(UserModel::class, 'id', 'user_id'); } }