[FEAT] 重構機台日誌 UI 與增加多語系支援,並整合 IoT API 核心架構
- 機台日誌:對齊 Luxury UI 規範,實作整合式佈局與分頁組件。 - 多語系:完成機台日誌繁、英、日三語系翻譯與動態處理。 - UI 規範:更新 SKILL.md 定義「標準列表 Bible」。 - 後端:完善 TenantScoped 隔離邏輯,修復儀表板死循環與 User Model 缺失。 - IoT:擴展機台、會員 Model 並建立交易、商品、狀態等核心表結構。 - 基礎設施:設置台北時區與 Docker 環境變數同步。
This commit is contained in:
@@ -4,42 +4,69 @@ namespace App\Services\Machine;
|
||||
|
||||
use App\Models\Machine\Machine;
|
||||
use App\Models\Machine\MachineLog;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Carbon\Carbon;
|
||||
|
||||
class MachineService
|
||||
{
|
||||
/**
|
||||
* 處理機台日誌寫入與狀態更新
|
||||
* Update machine heartbeat and status.
|
||||
*
|
||||
* @param string $serialNo
|
||||
* @param array $data
|
||||
* @return Machine
|
||||
*/
|
||||
public function updateHeartbeat(string $serialNo, array $data): Machine
|
||||
{
|
||||
return DB::transaction(function () use ($serialNo, $data) {
|
||||
$machine = Machine::where('serial_no', $serialNo)->firstOrFail();
|
||||
|
||||
$updateData = [
|
||||
'status' => 'online',
|
||||
'temperature' => $data['temperature'] ?? $machine->temperature,
|
||||
'current_page' => $data['current_page'] ?? $machine->current_page,
|
||||
'door_status' => $data['door_status'] ?? $machine->door_status,
|
||||
'firmware_version' => $data['firmware_version'] ?? $machine->firmware_version,
|
||||
'last_heartbeat_at' => now(),
|
||||
];
|
||||
|
||||
$machine->update($updateData);
|
||||
|
||||
// Record log if provided
|
||||
if (!empty($data['log'])) {
|
||||
$machine->logs()->create([
|
||||
'level' => $data['log_level'] ?? 'info',
|
||||
'message' => $data['log'],
|
||||
'payload' => $data['log_payload'] ?? null,
|
||||
]);
|
||||
}
|
||||
|
||||
return $machine;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Update machine slot stock.
|
||||
*/
|
||||
public function updateSlotStock(Machine $machine, int $slotNo, int $stock): void
|
||||
{
|
||||
$machine->slots()->where('slot_no', $slotNo)->update([
|
||||
'stock' => $stock,
|
||||
'last_restocked_at' => now(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legacy support for recordLog (Existing code).
|
||||
*/
|
||||
public function recordLog(int $machineId, array $data): MachineLog
|
||||
{
|
||||
$machine = Machine::findOrFail($machineId);
|
||||
|
||||
// 建立日誌紀錄
|
||||
$log = $machine->logs()->create([
|
||||
return $machine->logs()->create([
|
||||
'level' => $data['level'] ?? 'info',
|
||||
'message' => $data['message'],
|
||||
'context' => $data['context'] ?? null,
|
||||
'payload' => $data['context'] ?? null,
|
||||
]);
|
||||
|
||||
// 同步更新機台最後活耀時間與狀態
|
||||
$machine->update([
|
||||
'last_heartbeat_at' => now(),
|
||||
'status' => $this->resolveStatus($data),
|
||||
]);
|
||||
|
||||
return $log;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根據日誌內容判斷機台是否應標記成錯誤
|
||||
*/
|
||||
protected function resolveStatus(array $data): string
|
||||
{
|
||||
if (isset($data['level']) && $data['level'] === 'error') {
|
||||
return 'error';
|
||||
}
|
||||
|
||||
return 'online';
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user