KTV/app/Http/Controllers/RoomControlController.php

246 lines
8.8 KiB
PHP
Raw Normal View History

<?php
namespace App\Http\Controllers;
use App\Http\Requests\SendRoomSwitchCommandRequest;
2025-06-05 21:49:55 +08:00
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;
2025-06-27 13:41:36 +08:00
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");
}
2025-06-05 21:49:55 +08:00
public function receiveSwitch(ReceiveSwitchRequest $request): JsonResponse
{
$validated = $request->validated();
2025-06-05 21:49:55 +08:00
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'],
]);
2025-07-17 17:33:30 +08:00
//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'],
2025-06-05 21:49:55 +08:00
'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();
2025-07-17 17:33:30 +08:00
//Log::info('Room created', ['room_id' => $room->id, 'name' => $room->name]);
}
2025-06-27 13:41:36 +08:00
return ApiResponse::success(new RoomResource($room->refresh()));
}
}