KTV/app/Http/Controllers/RoomControlController.php
allen.yan 3bbb1a5cc0 Room 加入 is_online 來區別再不再線上
調整 FavoriteSongs 資料塞值改用seeder
加入 user_song table
/api/room/receiveRegister 調整邏輯
room介面 開關包帳功能調整
寫入心跳封包
20250522
2025-05-22 10:08:34 +08:00

223 lines
7.5 KiB
PHP
Raw 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
namespace App\Http\Controllers;
use App\Http\Requests\SendRoomSwitchCommandRequest;
use App\Http\Requests\ReceiveRoomRegisterRequest;
use App\Http\Requests\ReceiveRoomStatusRequest;
use App\Services\TcpSocketClient;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Auth;
use App\Models\Room;
use App\Enums\RoomStatus;
use App\Http\Responses\ApiResponse;
/**
* @OA\Tag(
* name="Auth",
* description="包廂控制"
* )
*/
class RoomControlController extends Controller
{
/**
* @OA\Post(
* path="/api/room/receiveRegister",
* summary="包廂註冊控制指令",
* description="依據傳入的 branch_id 與 room_name知道過來的設備來之於那個IP設備。",
* operationId="registerRoomCommand",
* tags={"Room Control"},
* @OA\RequestBody(
* required=true,
* @OA\JsonContent(ref="#/components/schemas/ReceiveRoomRegisterRequest")
* ),
* @OA\Response(
* response=200,
* description="成功傳送指令並回傳 TCP 回應",
* @OA\JsonContent(
* allOf={
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
* @OA\Schema(
* @OA\Property(property="data", ref="#/components/schemas/Room")
* )
* }
* )
* ),
* @OA\Response(
* response=401,
* description="Unauthorized",
* @OA\JsonContent(
* allOf={
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
* @OA\Schema(
* @OA\Property(property="code", type="string", example="UNAUTHORIZED"),
* @OA\Property(property="message", type="string", example="Unauthorized"),
* @OA\Property(property="data", type="null")
* )
* }
* )
* ),
* @OA\Parameter(
* name="Accept",
* in="header",
* required=true,
* @OA\Schema(type="string", default="application/json")
* )
* )
*/
public function receiveRegister(ReceiveRoomRegisterRequest $request): JsonResponse
{
// 1. 驗證帳密(登入用)
$credentials = $request->only('email', 'password');
if (!Auth::attempt($credentials)) {
return ApiResponse::unauthorized();
}
// 2. 取得登入使用者
$user = Auth::user();
// 3. 產生或取得 Token
if (empty($user->api_plain_token)) {
$token = $user->createToken('pc-heartbeat')->plainTextToken;
$user->api_plain_token = $token;
$user->save();
} else {
$token = $user->api_plain_token;
}
// 4. 驗證其他註冊欄位
$validated = $request->validated(); // branch_id, room_name, room_ip
// 5. 找出對應包廂
$room = Room::where('branch_id', $validated['branch_id'])
->where('name', $validated['room_name'])
->first();
if (!$room) {
return ApiResponse::error('找不到對應包廂');
}
// 6. 更新包廂資訊
$room->internal_ip = $request->ip();
$room->port = 1000; // 預設值
$room->is_online =1;
$room->status = RoomStatus::Closed;
$room->touch(); // 更新 updated_at
$room->save();
// 7. 回傳 token 與包廂資料
return ApiResponse::success([
'token' => $token,
'room' => $room,
]);
}
public function StatusReport(ReceiveRoomStatusRequest $request)
{
$data = $request->validate([
'hostname' => 'required|string',
'ip' => 'required|string',
'cpu' => 'nullable|numeric',
'memory' => 'nullable|numeric',
'disk' => 'nullable|numeric',
'status' => 'required|string',
]);
}
/**
* @OA\Post(
* path="/api/room/sendSwitch",
* summary="送出包廂控制指令",
* description="依據傳入的 room_id 與 command透過 TCP 傳送對應指令給包廂電腦。",
* operationId="sendRoomSwitchCommand",
* tags={"Room Control"},
* security={{"Authorization":{}}},
* @OA\RequestBody(
* required=true,
* @OA\JsonContent(ref="#/components/schemas/SendRoomSwitchCommandRequest")
* ),
* @OA\Response(
* response=200,
* description="成功傳送指令並回傳 TCP 回應",
* @OA\JsonContent(
* allOf={
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
* @OA\Schema(
* @OA\Property(property="data", ref="#/components/schemas/Room")
* )
* }
* )
* ),
* @OA\Response(
* response=401,
* description="Unauthorized",
* @OA\JsonContent(
* allOf={
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
* @OA\Schema(
* @OA\Property(property="code", type="string", example="UNAUTHORIZED"),
* @OA\Property(property="message", type="string", example="Unauthorized"),
* @OA\Property(property="data", type="null")
* )
* }
* )
* ),
* @OA\Parameter(
* name="Accept",
* in="header",
* required=true,
* @OA\Schema(type="string", default="application/json")
* )
* )
*/
public function sendSwitch(SendRoomSwitchCommandRequest $request): JsonResponse
{
$validated = $request->validated();
$room = Room::where([
['branch_id', $validated['branch_id']],
['name', $validated['room_name']],
])->first();
if (!$room) {
return ApiResponse::error('房間不存在');
}
// 檢查必要欄位是否缺失或狀態為錯誤
if (empty($room->internal_ip) || empty($room->port)) {
return ApiResponse::error('房間未設定 IP 或 Port');
}
if ($room->status === RoomStatus::Error) {
return ApiResponse::error('房間目前處於錯誤狀態,無法操作');
}
$suffix = substr($room->name, -3) ?: $room->name;
$signal = match ($validated['command']) {
'active' => 'O',
'closed' => 'X',
'fire' => 'F',
default => 'X', // fallback 保險起見
};
$data = $suffix . "," . $signal;
//dd($data);
$client = new TcpSocketClient($room->internal_ip, $room->port);
try {
$response = $client->send($data);
$room->status=$validated['command'];
$room->started_at=$validated['started_at'];
$room->ended_at=$validated['ended_at'];
$room->save();
return ApiResponse::success($room);
} catch (\Throwable $e) {
$room->status=RoomStatus::Error;
$room->started_at=null;
$room->ended_at=null;
$room->save();
return ApiResponse::error($e->getMessage());
}
}
}