Files

229 lines
7.6 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?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 ? '开启' : '关闭'));
}
}