// +---------------------------------------------------------------------- declare(strict_types=1); namespace addon\iot\controller\backend; use think\facade\Db; use think\facade\View; use ywxapp\controller\BackendBase; use addon\iot\service\SceneService; /** * 场景联动控制器(智慧生活自动化:设备状态/定时/手动 → 动作组) */ class Scenes extends BackendBase { /** * 场景列表页(场景与设备数据以 JSON 注入,前端 layui.table 本地渲染) */ public function scene() { $list = SceneService::list(0); $devs = Db::name('iot_device') ->field('uuid,title,model')->order('id', 'desc')->select()->toArray(); // 与 ota() 同理:JSON_HEX_* 转义防模板 htmlentities 二次转义破坏 JS 字面量 $flags = JSON_UNESCAPED_UNICODE | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT; View::assign('scenesJson', (string) json_encode($list, $flags)); View::assign('devicesJson', (string) json_encode($devs, $flags)); return View::fetch('admin/scene'); } /** * 场景详情(JSON,含 triggers/actions,供编辑弹层初始化) */ public function sceneDetail() { $id = (int) input('get.id', 0); $row = SceneService::findScene($id); if (!$row) { $this->result->error('场景不存在'); } $this->result->success($row); } public function saveScene() { try { $data = $this->request->post(); $data['member_id'] = 0; // 后台全局场景 // 前端将 triggers/actions 以 JSON 字符串提交,Service 按数组遍历 foreach (['triggers', 'actions'] as $k) { if (isset($data[$k]) && is_string($data[$k]) && $data[$k] !== '') { $decoded = json_decode($data[$k], true); $data[$k] = is_array($decoded) ? $decoded : []; } elseif (!isset($data[$k])) { $data[$k] = []; } } SceneService::save($data); } catch (\Throwable $e) { $this->result->error('保存失败:' . $e->getMessage()); } $this->result->success('保存成功(约 30s 内在 Broker 生效)'); } public function deleteScene() { $id = (int) input('post.id', 0); SceneService::remove($id, 0); $this->result->success('已删除'); } public function toggleScene() { $id = (int) input('post.id', 0); $enabled = (int) input('post.enabled', 0); SceneService::toggle($id, $enabled, 0); $this->result->success('已更新'); } public function runScene() { $id = (int) input('post.id', 0); SceneService::runScene($id, 'manual', '后台手动执行'); $this->result->success('已触发执行'); } public function sceneLogs() { $id = (int) input('get.id', 0); $page = max(1, (int) input('get.page', 1)); $data = SceneService::logs($id, $page, 20); $this->result->success($data); } }