調整 FavoriteSongs 資料塞值改用seeder 加入 user_song table /api/room/receiveRegister 調整邏輯 room介面 開關包帳功能調整 寫入心跳封包 20250522
223 lines
7.5 KiB
PHP
223 lines
7.5 KiB
PHP
<?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());
|
||
}
|
||
}
|
||
}
|