KTV/app/Http/Controllers/RoomControlController.php
allen.yan 4c8ac6ddab 202508211813
加入與中控資料同步
移除 這首歌與下首歌的 API
2025-08-21 18:16:55 +08:00

246 lines
8.8 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\ReceiveSwitchRequest;
use App\Http\Requests\SessionRequest;
use App\Services\TcpSocketClient;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Auth;
use App\Models\Branch;
use App\Models\Room;
use App\Enums\RoomStatus;
use App\Http\Responses\ApiResponse;
use App\Http\Resources\RoomResource;
use Illuminate\Support\Facades\Log;
/**
* @OA\Tag(
* name="Auth",
* description="包廂控制"
* )
*/
class RoomControlController extends Controller
{
/**
* @OA\Post(
* path="/api/room/session",
* summary="取得包廂狀態",
* description="依據 hostname 與 branch_name 取得或建立房間,並回傳房間資料與最新 session",
* tags={"Room Control"},
* security={{"Authorization":{}}},
* @OA\RequestBody(
* required=true,
* @OA\JsonContent(ref="#/components/schemas/SessionRequest")
* ),
* @OA\Response(
* response=200,
* description="成功取得房間狀態",
* @OA\JsonContent(
* type="object",
* @OA\Property(
* property="room",
* type="object",
* ref="#/components/schemas/Room"
* )
* )
* ),
* @OA\Response(
* response=422,
* description="驗證失敗",
* @OA\JsonContent(
* type="object",
* @OA\Property(property="message", type="string", example="The given data was invalid."),
* @OA\Property(property="errors", type="object")
* )
* )
* )
*/
public function session(SessionRequest $request): JsonResponse
{
$validated = $request->validated();
$roomType = null;
$roomName = null;
$floor = null;
// 從 room_name例如 PC101, SVR01中擷取 type 與 name
if (preg_match('/^([A-Za-z]+)(\d+)$/', $validated['hostname'], $matches)) {
$roomType = strtolower($matches[1]); // 'PC' → 'pc'
$roomName = $matches[2]; // '101'
if($roomType =='svr'){
$floor = '0';
} else{
$floor = (int) substr($roomName, 0, 1);
}
}
$branch=Branch::where('name',$validated['branch_name'])->first();
$room = Room::firstOrNew([
'branch_id' => $branch->id,
'floor' => $floor,
'name' => $roomName,
'type' => $roomType,
]);
$room->internal_ip = $validated['ip'];
$room->port = 1000;
$room->is_online=1;
$room->touch(); // 更新 updated_at
$room->save();
$room->load('latestSession');
if ($room->latestSession) {
$room->latestSession->api_token = !empty($validated['token'])
? $validated['token']
: bin2hex(random_bytes(32));
$room->latestSession->save();
$validated['token']=$room->latestSession->api_token;
}
return ApiResponse::success([
'room' => $room->latestSession,
]);
}
/**
* @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();
$branch = Branch::where('name',$validated['branch_name'])->first();
if (!$branch) {
return ApiResponse::error('分店不存在');
}
if (empty($branch->external_ip) ) {
return ApiResponse::error('分店未設定 外部URL');
}
$roomType = null;
$roomName = null;
// 從 room_name例如 PC101, SVR01中擷取 type 與 name
if (preg_match('/^([A-Za-z]+)(\d+)$/', $validated['room_name'], $matches)) {
$roomType = strtolower($matches[1]); // 'PC' → 'pc'
$roomName = $matches[2]; // '101'
}
$room = Room::where([
'branch_id' => $branch->id,
'name' => $roomName,
'type' => $roomType
])->first();
if (!$room) {
return ApiResponse::error('包廂不存在');
}
$command = $validated['command'];
$room->log_source='api';
$room->log_message='sendSwitch';
$room->update([
'status' => $command,
'started_at' => $validated['started_at'] ?? null,
'ended_at' => $validated['ended_at'] ?? null,
]);
$payload = [
'branch_name' => $validated['branch_name'],
'room_name' => $validated['room_name'],
'command' => $command,
'started_at' => $validated['started_at'] ?? null,
'ended_at' => $validated['ended_at'] ?? null,
];
$token = auth()->user()?->api_plain_token;
$api = new \App\Services\ApiClient($branch->external_ip,$token);
$response = $api->post('/api/room/sendSwitch', $payload);
if (!$response->successful()) {
return ApiResponse::error('指令發送失敗:' . $response->body());
}
return ApiResponse::success("命令已發送:$command");
}
public function receiveSwitch(ReceiveSwitchRequest $request): JsonResponse
{
$validated = $request->validated();
if ($validated['status'] === 'error') {
$validated['started_at'] = null;
$validated['ended_at'] = null;
}
$room = Room::where([
'branch_id' => $validated['branch_id'],
'floor' => $validated['floor'],
'type' => $validated['type'],
'name' => $validated['name'],
])->first();
if ($room) {
// 更新
$room->log_source='api';
$room->log_message='receiveSwitch';
$room->update([
'is_online' => $validated['is_online'],
'status' => $validated['status'],
'started_at' => $validated['started_at'],
'ended_at' => $validated['ended_at'],
]);
//Log::info('Room updated', ['room_id' => $room->id, 'name' => $room->name]);
} else {
// 新增
$room = new Room([
'branch_id' => $validated['branch_id'],
'floor' => $validated['floor'],
'type' => $validated['type'],
'name' => $validated['name'],
'is_online' => $validated['is_online'],
'status' => $validated['status'],
'started_at' => $validated['started_at'],
'ended_at' => $validated['ended_at'],
]);
$room->log_source = 'api';
$room->log_message = 'receiveSwitch';
$room->save();
//Log::info('Room created', ['room_id' => $room->id, 'name' => $room->name]);
}
return ApiResponse::success(new RoomResource($room->refresh()));
}
}