229 lines
7.6 KiB
PHP
229 lines
7.6 KiB
PHP
<?php
|
||
// +----------------------------------------------------------------------
|
||
// | YwxApp [ WE CAN DO IT JUST THINK ]
|
||
// +----------------------------------------------------------------------
|
||
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
|
||
// +----------------------------------------------------------------------
|
||
// | Author: ywxapp<admin@ywxapp.cn>
|
||
// +----------------------------------------------------------------------
|
||
declare (strict_types = 1);
|
||
|
||
namespace addon\wxchat\controller\member;
|
||
|
||
use addon\wxchat\model\WxchatRoom;
|
||
use addon\wxchat\model\WxchatRoomMember;
|
||
use addon\wxchat\model\WxchatRoomMic;
|
||
use think\facade\Db;
|
||
use think\facade\Request;
|
||
use ywxapp\controller\FrontendBase;
|
||
|
||
/**
|
||
* 语音 / 视频房:创建 / 加入 / 麦位管理 / 弹幕开关
|
||
* 房间公屏聊天复用 group 消息通道(session_id = room_id)
|
||
*/
|
||
class Room extends FrontendBase
|
||
{
|
||
/**
|
||
* 房间列表(直播中按热度)
|
||
*/
|
||
public function lists()
|
||
{
|
||
$type = (int) Request::get('type', 0);
|
||
$query = WxchatRoom::where('status', 1);
|
||
if ($type) {
|
||
$query->where('type', $type);
|
||
}
|
||
$list = $query->order('hot', 'desc')->order('create_at', 'desc')
|
||
->paginate(20, false, ['page' => (int) Request::get('page', 1)]);
|
||
$this->success([
|
||
'list' => $list->items(),
|
||
'total' => $list->total(),
|
||
'pages' => $list->lastPage(),
|
||
]);
|
||
}
|
||
|
||
/**
|
||
* 创建房间(自动初始化麦位 + 房主上 0 号麦)
|
||
*/
|
||
public function create()
|
||
{
|
||
$uid = $this->auth->uid;
|
||
$title = trim((string) Request::post('title', ''));
|
||
$type = (int) Request::post('type', 1);
|
||
$cover = trim((string) Request::post('cover', ''));
|
||
$notice = trim((string) Request::post('notice', ''));
|
||
$micCount = max(2, min(20, (int) Request::post('mic_count', 8)));
|
||
if (! $title) {
|
||
$this->error('请填写房间标题');
|
||
}
|
||
|
||
$room = new WxchatRoom();
|
||
$room->title = $title;
|
||
$room->type = $type;
|
||
$room->owner_uid = $uid;
|
||
$room->cover = $cover;
|
||
$room->notice = $notice;
|
||
$room->mic_count = $micCount;
|
||
$room->danmaku_on = 1;
|
||
$room->status = 1;
|
||
$room->create_at = time();
|
||
$room->save();
|
||
|
||
// 初始化麦位
|
||
$mics = [];
|
||
for ($i = 0; $i < $micCount; $i++) {
|
||
$mics[] = [
|
||
'room_id' => $room->id,
|
||
'mic_index' => $i,
|
||
'uid' => $i == 0 ? $uid : 0,
|
||
'status' => $i == 0 ? 1 : 0,
|
||
'create_at' => time(),
|
||
];
|
||
}
|
||
(new WxchatRoomMic())->saveAll($mics);
|
||
|
||
// 房主进入
|
||
$member = new WxchatRoomMember();
|
||
$member->room_id = $room->id;
|
||
$member->uid = $uid;
|
||
$member->role = 1; // 主播
|
||
$member->join_at = time();
|
||
$member->save();
|
||
|
||
$this->success(['room_id' => $room->id], '开播成功');
|
||
}
|
||
|
||
/**
|
||
* 进入房间(观众)
|
||
*/
|
||
public function join()
|
||
{
|
||
$uid = $this->auth->uid;
|
||
$roomId = (int) Request::post('room_id', 0);
|
||
$room = WxchatRoom::where('id', $roomId)->where('status', 1)->find();
|
||
if (! $room) {
|
||
$this->error('房间不存在或已关闭');
|
||
}
|
||
if (! WxchatRoomMember::where('room_id', $roomId)->where('uid', $uid)->find()) {
|
||
$member = new WxchatRoomMember();
|
||
$member->room_id = $roomId;
|
||
$member->uid = $uid;
|
||
$member->role = 0;
|
||
$member->join_at = time();
|
||
$member->save();
|
||
$room->where('id', $roomId)->inc('hot')->update();
|
||
}
|
||
$mics = WxchatRoomMic::where('room_id', $roomId)->order('mic_index')->select();
|
||
$this->success([
|
||
'room' => $room,
|
||
'mics' => $mics,
|
||
]);
|
||
}
|
||
|
||
/**
|
||
* 离开房间
|
||
*/
|
||
public function leave()
|
||
{
|
||
$uid = $this->auth->uid;
|
||
$roomId = (int) Request::post('room_id', 0);
|
||
WxchatRoomMember::where('room_id', $roomId)->where('uid', $uid)->delete();
|
||
// 释放麦位
|
||
WxchatRoomMic::where('room_id', $roomId)->where('uid', $uid)->update(['uid' => 0, 'status' => 0]);
|
||
$room = WxchatRoom::find($roomId);
|
||
if ($room && $room->owner_uid == $uid) {
|
||
$room->status = 0;
|
||
$room->save();
|
||
}
|
||
$this->success([], '已离开');
|
||
}
|
||
|
||
/**
|
||
* 上麦
|
||
*/
|
||
public function micUp()
|
||
{
|
||
$uid = $this->auth->uid;
|
||
$roomId = (int) Request::post('room_id', 0);
|
||
$micIdx = (int) Request::post('mic_index', 0);
|
||
$mic = WxchatRoomMic::where('room_id', $roomId)->where('mic_index', $micIdx)->find();
|
||
if (! $mic) {
|
||
$this->error('麦位不存在');
|
||
}
|
||
if ($mic->status == 2) {
|
||
$this->error('该麦位已锁定');
|
||
}
|
||
if ($mic->status == 1 && $mic->uid != $uid) {
|
||
$this->error('麦位已被占用');
|
||
}
|
||
$mic->uid = $uid;
|
||
$mic->status = 1;
|
||
$mic->save();
|
||
$this->success([], '上麦成功');
|
||
}
|
||
|
||
/**
|
||
* 下麦
|
||
*/
|
||
public function micDown()
|
||
{
|
||
$uid = $this->auth->uid;
|
||
$roomId = (int) Request::post('room_id', 0);
|
||
$micIdx = (int) Request::post('mic_index', 0);
|
||
$mic = WxchatRoomMic::where('room_id', $roomId)->where('mic_index', $micIdx)->where('uid', $uid)->find();
|
||
if (! $mic) {
|
||
$this->error('你不在该麦位');
|
||
}
|
||
$mic->uid = 0;
|
||
$mic->status = 0;
|
||
$mic->save();
|
||
$this->success([], '下麦成功');
|
||
}
|
||
|
||
/**
|
||
* 锁定 / 解锁 / 禁麦(房主)
|
||
*/
|
||
public function micManage()
|
||
{
|
||
$uid = $this->auth->uid;
|
||
$roomId = (int) Request::post('room_id', 0);
|
||
$micIdx = (int) Request::post('mic_index', 0);
|
||
$op = (int) Request::post('op', 2); // 2锁定 0解锁 3禁麦
|
||
$room = WxchatRoom::find($roomId);
|
||
if (! $room || $room->owner_uid != $uid) {
|
||
$this->error('仅房主可操作');
|
||
}
|
||
WxchatRoomMic::where('room_id', $roomId)->where('mic_index', $micIdx)
|
||
->update(['status' => $op, 'uid' => $op == 0 ? 0 : Db::raw('uid')]);
|
||
$this->success([], '操作成功');
|
||
}
|
||
|
||
/**
|
||
* 弹幕开关(房主房间级 / 或用户快捷关闭)
|
||
*/
|
||
public function danmaku()
|
||
{
|
||
$uid = $this->auth->uid;
|
||
$roomId = (int) Request::post('room_id', 0);
|
||
$on = (int) Request::post('on', 1);
|
||
$room = WxchatRoom::find($roomId);
|
||
if (! $room) {
|
||
$this->error('房间不存在');
|
||
}
|
||
// 房主可切换房间弹幕总开关;普通用户仅对自己快捷关闭(落到个人设置)
|
||
if ($room->owner_uid == $uid) {
|
||
$room->danmaku_on = $on ? 1 : 0;
|
||
$room->save();
|
||
$this->success(['danmaku_on' => $room->danmaku_on], '房间弹幕已' . ($on ? '开启' : '关闭'));
|
||
}
|
||
// 非房主:更新个人弹幕总开关(设置-互动-弹幕管理)
|
||
$pc = \ywxapp\model\MemberProfile::where('uid', $uid)->value('privacy_config');
|
||
$pc = $pc ? json_decode($pc, true) : [];
|
||
$pc = is_array($pc) ? $pc : [];
|
||
$pc['danmaku_global'] = $on ? 1 : 0;
|
||
\ywxapp\model\MemberProfile::where('uid', $uid)
|
||
->update(['privacy_config' => json_encode($pc, JSON_UNESCAPED_UNICODE)]);
|
||
$this->success(['danmaku_global' => $on], '个人弹幕已' . ($on ? '开启' : '关闭'));
|
||
}
|
||
}
|