Преглед изворни кода

解决权限问题,完成算法盒子和物联感知。

wukai пре 4 месеци
родитељ
комит
0d658d028a

+ 44 - 0
src/api/biz/algo.js

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询算法盒子配置列表
+export function listAlgo(query) {
+    return request({
+        url: '/biz/algo/list',
+        method: 'get',
+        params: query
+    })
+}
+
+// 查询算法盒子配置详细
+export function getAlgo(algoId) {
+    return request({
+        url: '/biz/algo/' + algoId,
+        method: 'get'
+    })
+}
+
+// 新增算法盒子配置
+export function addAlgo(data) {
+    return request({
+        url: '/biz/algo',
+        method: 'post',
+        data: data
+    })
+}
+
+// 修改算法盒子配置
+export function updateAlgo(data) {
+    return request({
+        url: '/biz/algo',
+        method: 'put',
+        data: data
+    })
+}
+
+// 删除算法盒子配置
+export function delAlgo(algoId) {
+    return request({
+        url: '/biz/algo/' + algoId,
+        method: 'delete'
+    })
+}

+ 7 - 0
src/api/biz/sensorConfig.js

@@ -9,6 +9,13 @@ export function listSensorConfig(query) {
     })
 }
 
+export function listRecord(sensorId) {
+    return request({
+        url: '/biz/sensorRecord/list/' + sensorId,
+        method: 'get',
+    })
+}
+
 // 查询传感器网关配置详细
 export function getSensorConfig(sensorId) {
     return request({

+ 15 - 15
src/layout/components/Sidebar/SidebarItem.vue

@@ -10,22 +10,22 @@
       </app-link>
     </template>
 
-    <el-sub-menu v-else ref="subMenu" :index="resolvePath(item.path)" teleported>
-      <template v-if="item.meta" #title>
-        <svg-icon v-if="item.meta!=null && item.meta.icon!=null" :icon-class="item.meta && item.meta.icon" />
-        <img v-else :src="getImageSrc(item.meta.png)" />
-        <span class="menu-title" :title="hasTitle(item.meta.title)">{{ item.meta.title }}</span>
-      </template>
+<!--    <el-sub-menu v-else ref="subMenu" :index="resolvePath(item.path)" teleported>-->
+<!--      <template v-if="item.meta" #title>-->
+<!--        <svg-icon v-if="item.meta!=null && item.meta.icon!=null" :icon-class="item.meta && item.meta.icon" />-->
+<!--        <img v-else :src="getImageSrc(item.meta.png)" />-->
+<!--        <span class="menu-title" :title="hasTitle(item.meta.title)">{{ item.meta.title }}</span>-->
+<!--      </template>-->
 
-      <sidebar-item
-        v-for="(child, index) in item.children"
-        :key="child.path + index"
-        :is-nest="true"
-        :item="child"
-        :base-path="resolvePath(child.path)"
-        class="nest-menu"
-      />
-    </el-sub-menu>
+<!--      <sidebar-item-->
+<!--        v-for="(child, index) in item.children"-->
+<!--        :key="child.path + index"-->
+<!--        :is-nest="true"-->
+<!--        :item="child"-->
+<!--        :base-path="resolvePath(child.path)"-->
+<!--        class="nest-menu"-->
+<!--      />-->
+<!--    </el-sub-menu>-->
   </div>
 </template>
 

+ 7 - 5
src/router/index.js

@@ -89,8 +89,8 @@ export const constantRoutes = [
     redirect: '/device',
     children: [
       {
-        path: '/biz/sensorConfig',
-        component: () => import('@/views/biz/sensorRecord/index'),
+        path: '/device',
+        component: () => import('@/views/biz/sensorConfig/index'),
         name: 'device',
         meta: { title: '感知', png: 'ico_device.png', affix: true }
       }
@@ -103,8 +103,8 @@ export const constantRoutes = [
     children: [
       {
         path: '/ai',
-        component: () => import('@/views/ai/index'),
-        name: 'device',
+        component: () => import('@/views/biz/algo/index'),
+        name: 'ai',
         meta: { title: 'AI', png: 'ico_ai.png', affix: true }
       }
     ]
@@ -116,8 +116,10 @@ export const constantRoutes = [
     children: [
       {
         path: '/alarm',
-        component: () => import('@/views/alarm/index'),
         name: 'alarm',
+        beforeEnter() {
+          window.open('https://smp.quanmate.com.cn/admin/yet_another_workflow/flows?page=1&per_page=24&status=active', '_blank');
+        },
         meta: { title: '事件', png: 'ico_alarm.png', affix: true }
       }
     ]

+ 317 - 0
src/views/biz/algo/index.vue

@@ -0,0 +1,317 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="98px">
+      <el-form-item label="仓库名称" prop="houseName">
+        <el-input
+            v-model="queryParams.houseName"
+            placeholder="请输入仓库名称"
+            clearable
+            @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="算法盒子名称" prop="algoName">
+        <el-input
+            v-model="queryParams.algoName"
+            placeholder="请输入算法盒子名称"
+            clearable
+            @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
+        <el-button icon="Refresh" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+            type="primary"
+            plain
+            icon="Plus"
+            @click="handleAdd"
+        >新增
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+            type="success"
+            plain
+            icon="Edit"
+            :disabled="single"
+            @click="handleUpdate"
+        >修改
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+            type="danger"
+            plain
+            icon="Delete"
+            :disabled="multiple"
+            @click="handleDelete"
+        >删除
+        </el-button>
+      </el-col>
+<!--      <el-col :span="1.5">-->
+<!--        <el-button-->
+<!--            type="warning"-->
+<!--            plain-->
+<!--            icon="Download"-->
+<!--            @click="handleExport"-->
+<!--            v-hasPermi="['biz:algo:export']"-->
+<!--        >导出-->
+<!--        </el-button>-->
+<!--      </el-col>-->
+      <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="algoList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center"/>
+<!--      <el-table-column label="算法盒子ID" align="center" prop="algoId"/>-->
+      <el-table-column label="仓库名称" align="center" prop="houseName"/>
+      <el-table-column label="算法盒子名称" align="center" prop="algoName">
+        <template #default="scope">
+          <a :href="scope.row.algoAddr" target="_blank" rel="noopener noreferrer" class="link-style">{{ scope.row.algoName }}</a>
+        </template>
+      </el-table-column>
+<!--      <el-table-column label="跳转地址" align="center" prop="algoAddr"/>-->
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template #default="scope">
+          <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)">
+            修改
+          </el-button>
+          <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)"
+                    >删除
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+        v-show="total>0"
+        :total="total"
+        v-model:page="queryParams.pageNum"
+        v-model:limit="queryParams.pageSize"
+        @pagination="getList"
+    />
+
+    <!-- 添加或修改算法盒子配置对话框 -->
+    <el-dialog :title="title" v-model="open" width="500px" append-to-body>
+      <el-form ref="algoRef" :model="form" :rules="rules" label-width="100px">
+        <el-form-item label="仓库名称" prop="houseName">
+          <el-select v-model="form.houseName" placeholder="请选择仓库名称" clearable filterable
+                     @change="handleHouseChange">
+            <el-option
+                v-for="item in houseConfigList"
+                :key="item.houseName"
+                :label="item.houseName"
+                :value="item.houseId"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="算法盒子名称" prop="algoName">
+          <el-input v-model="form.algoName" placeholder="请输入算法盒子名称"/>
+        </el-form-item>
+        <el-form-item label="跳转地址" prop="algoAddr">
+          <el-input v-model="form.algoAddr" placeholder="请输入跳转地址"/>
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitForm">确 定</el-button>
+          <el-button @click="cancel">取 消</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+<style scoped>
+.link-style {
+  text-decoration: underline;
+  color: #409eff; /* 可选:设置链接颜色 */
+}
+</style>
+<script setup name="Algo">
+import {addAlgo, delAlgo, getAlgo, listAlgo, updateAlgo} from "@/api/biz/algo";
+import {listHouseConfig} from "@/api/biz/houseConfig";
+const {proxy} = getCurrentInstance();
+
+const algoList = ref([]);
+const open = ref(false);
+const loading = ref(true);
+const showSearch = ref(true);
+const ids = ref([]);
+const single = ref(true);
+const multiple = ref(true);
+const total = ref(0);
+const title = ref("");
+const houseConfigList = ref(undefined);
+const data = reactive({
+  form: {},
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    houseId: null,
+    houseName: null,
+    houseCode: null,
+    algoName: null,
+  },
+  rules: {}
+});
+
+const {queryParams, form, rules} = toRefs(data);
+/** 查询仓库配置列表 */
+function getHouseList() {
+  listHouseConfig().then(response => {
+    houseConfigList.value = response.rows;
+  });
+}
+
+function handleHouseChange(value) {
+  console.log(value)
+  if (value) {
+    // 查找选中的部门信息
+    const selectedDept = findDeptById(houseConfigList.value, value);
+    console.log(selectedDept)
+    if (selectedDept) {
+      form.value.houseId = selectedDept.houseId;
+      form.value.houseName = selectedDept.houseName;
+      form.value.houseCode = selectedDept.houseCode;
+    }
+
+  } else {
+    form.value.houseId = '';
+  }
+}
+
+/** 根据ID查找部门信息 */
+function findDeptById(deptList, id) {
+  if (!deptList || !id) return null;
+
+  for (let i = 0; i < deptList.length; i++) {
+    const dept = deptList[i];
+    if (dept.houseId === id) {
+      return dept;
+    }
+    if (dept.children && dept.children.length) {
+      const found = findDeptById(dept.children, id);
+      if (found) return found;
+    }
+  }
+  return null;
+}
+/** 查询算法盒子配置列表 */
+function getList() {
+  loading.value = true;
+  listAlgo(queryParams.value).then(response => {
+    algoList.value = response.rows;
+    total.value = response.total;
+    loading.value = false;
+  });
+}
+
+// 取消按钮
+function cancel() {
+  open.value = false;
+  reset();
+}
+
+// 表单重置
+function reset() {
+  form.value = {
+    algoId: null,
+    houseId: null,
+    houseName: null,
+    houseCode: null,
+    algoName: null,
+    algoAddr: null,
+    createBy: null,
+    createTime: null,
+    updateBy: null,
+    updateTime: null,
+    remark: null
+  };
+  proxy.resetForm("algoRef");
+}
+
+/** 搜索按钮操作 */
+function handleQuery() {
+  queryParams.value.pageNum = 1;
+  getList();
+}
+
+/** 重置按钮操作 */
+function resetQuery() {
+  proxy.resetForm("queryRef");
+  handleQuery();
+}
+
+// 多选框选中数据
+function handleSelectionChange(selection) {
+  ids.value = selection.map(item => item.algoId);
+  single.value = selection.length != 1;
+  multiple.value = !selection.length;
+}
+
+/** 新增按钮操作 */
+function handleAdd() {
+  reset();
+  open.value = true;
+  title.value = "添加算法盒子配置";
+}
+
+/** 修改按钮操作 */
+function handleUpdate(row) {
+  reset();
+  const _algoId = row.algoId || ids.value
+  getAlgo(_algoId).then(response => {
+    form.value = response.data;
+    open.value = true;
+    title.value = "修改算法盒子配置";
+  });
+}
+
+/** 提交按钮 */
+function submitForm() {
+  proxy.$refs["algoRef"].validate(valid => {
+    if (valid) {
+      if (form.value.algoId != null) {
+        updateAlgo(form.value).then(response => {
+          proxy.$modal.msgSuccess("修改成功");
+          open.value = false;
+          getList();
+        });
+      } else {
+        addAlgo(form.value).then(response => {
+          proxy.$modal.msgSuccess("新增成功");
+          open.value = false;
+          getList();
+        });
+      }
+    }
+  });
+}
+
+/** 删除按钮操作 */
+function handleDelete(row) {
+  const _algoIds = row.algoId || ids.value;
+  proxy.$modal.confirm('是否确认删除算法盒子配置编号为"' + _algoIds + '"的数据项?').then(function () {
+    return delAlgo(_algoIds);
+  }).then(() => {
+    getList();
+    proxy.$modal.msgSuccess("删除成功");
+  }).catch(() => {
+  });
+}
+
+/** 导出按钮操作 */
+function handleExport() {
+  proxy.download('biz/algo/export', {
+    ...queryParams.value
+  }, `algo_${new Date().getTime()}.xlsx`)
+}
+getHouseList()
+getList();
+</script>

+ 293 - 156
src/views/biz/houseConfig/index.vue

@@ -1,160 +1,205 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
-      <el-form-item label="仓库名称" prop="houseName">
-        <el-input
-          v-model="queryParams.houseName"
-          placeholder="请输入仓库名称"
-          clearable
-          @keyup.enter="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="仓库编号" prop="houseNum">
-        <el-input
-          v-model="queryParams.houseNum"
-          placeholder="请输入仓库编号"
-          clearable
-          @keyup.enter="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="仓库简称" prop="simpleName">
-        <el-input
-          v-model="queryParams.simpleName"
-          placeholder="请输入仓库简称"
-          clearable
-          @keyup.enter="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="仓库编码" prop="houseCode">
-        <el-input
-          v-model="queryParams.houseCode"
-          placeholder="请输入仓库编码"
-          clearable
-          @keyup.enter="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="所属部门" prop="deptId">
-        <el-input
-          v-model="queryParams.deptId"
-          placeholder="请输入所属部门"
-          clearable
-          @keyup.enter="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="部门名称" prop="deptName">
-        <el-input
-          v-model="queryParams.deptName"
-          placeholder="请输入部门名称"
-          clearable
-          @keyup.enter="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item>
-        <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
-        <el-button icon="Refresh" @click="resetQuery">重置</el-button>
-      </el-form-item>
-    </el-form>
+    <el-row :gutter="20">
+      <splitpanes class="default-theme">
+        <!--部门数据-->
+        <pane size="16">
+          <el-col>
+            <div class="head-container">
+              <el-input v-model="deptName" placeholder="请输入部门名称" clearable prefix-icon="Search"
+                        style="margin-bottom: 20px"/>
+            </div>
+            <div class="head-container">
+              <el-tree :data="deptOptions" :props="{ label: 'label', children: 'children' }"
+                       :expand-on-click-node="false" :filter-node-method="filterNode" ref="deptTreeRef" node-key="id"
+                       highlight-current default-expand-all @node-click="handleNodeClick"/>
+            </div>
+          </el-col>
+        </pane>
+        <!--用户数据-->
+        <pane size="84">
+          <el-col>
+            <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
+              <el-form-item label="仓库名称" prop="houseName">
+                <el-input
+                    v-model="queryParams.houseName"
+                    placeholder="请输入仓库名称"
+                    clearable
+                    @keyup.enter="handleQuery"
+                />
+              </el-form-item>
+              <el-form-item label="仓库编号" prop="houseNum">
+                <el-input
+                    v-model="queryParams.houseNum"
+                    placeholder="请输入仓库编号"
+                    clearable
+                    @keyup.enter="handleQuery"
+                />
+              </el-form-item>
+<!--              <el-form-item label="仓库简称" prop="simpleName">-->
+<!--                <el-input-->
+<!--                    v-model="queryParams.simpleName"-->
+<!--                    placeholder="请输入仓库简称"-->
+<!--                    clearable-->
+<!--                    @keyup.enter="handleQuery"-->
+<!--                />-->
+<!--              </el-form-item>-->
+              <el-form-item label="仓库编码" prop="houseCode">
+                <el-input
+                    v-model="queryParams.houseCode"
+                    placeholder="请输入仓库编码"
+                    clearable
+                    @keyup.enter="handleQuery"
+                />
+              </el-form-item>
+<!--              <el-form-item label="所属部门" prop="deptId">-->
+<!--                <el-input-->
+<!--                    v-model="queryParams.deptId"-->
+<!--                    placeholder="请输入所属部门"-->
+<!--                    clearable-->
+<!--                    @keyup.enter="handleQuery"-->
+<!--                />-->
+<!--              </el-form-item>-->
+<!--              <el-form-item label="部门名称" prop="deptName">-->
+<!--                <el-input-->
+<!--                    v-model="queryParams.deptName"-->
+<!--                    placeholder="请输入部门名称"-->
+<!--                    clearable-->
+<!--                    @keyup.enter="handleQuery"-->
+<!--                />-->
+<!--              </el-form-item>-->
+              <el-form-item>
+                <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
+                <el-button icon="Refresh" @click="resetQuery">重置</el-button>
+              </el-form-item>
+            </el-form>
 
-    <el-row :gutter="10" class="mb8">
-      <el-col :span="1.5">
-        <el-button
-          type="primary"
-          plain
-          icon="Plus"
-          @click="handleAdd"
-          v-hasPermi="['biz:houseConfig:add']"
-        >新增</el-button>
-      </el-col>
-      <el-col :span="1.5">
-        <el-button
-          type="success"
-          plain
-          icon="Edit"
-          :disabled="single"
-          @click="handleUpdate"
-          v-hasPermi="['biz:houseConfig:edit']"
-        >修改</el-button>
-      </el-col>
-      <el-col :span="1.5">
-        <el-button
-          type="danger"
-          plain
-          icon="Delete"
-          :disabled="multiple"
-          @click="handleDelete"
-          v-hasPermi="['biz:houseConfig:remove']"
-        >删除</el-button>
-      </el-col>
-      <el-col :span="1.5">
-        <el-button
-          type="warning"
-          plain
-          icon="Download"
-          @click="handleExport"
-          v-hasPermi="['biz:houseConfig:export']"
-        >导出</el-button>
-      </el-col>
-      <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
-    </el-row>
+            <el-row :gutter="10" class="mb8">
+              <el-col :span="1.5">
+                <el-button
+                    type="primary"
+                    plain
+                    icon="Plus"
+                    @click="handleAdd"
+                    v-hasPermi="['biz:houseConfig:add']"
+                >新增
+                </el-button>
+              </el-col>
+              <el-col :span="1.5">
+                <el-button
+                    type="success"
+                    plain
+                    icon="Edit"
+                    :disabled="single"
+                    @click="handleUpdate"
+                    v-hasPermi="['biz:houseConfig:edit']"
+                >修改
+                </el-button>
+              </el-col>
+              <el-col :span="1.5">
+                <el-button
+                    type="danger"
+                    plain
+                    icon="Delete"
+                    :disabled="multiple"
+                    @click="handleDelete"
+                    v-hasPermi="['biz:houseConfig:remove']"
+                >删除
+                </el-button>
+              </el-col>
+<!--              <el-col :span="1.5">-->
+<!--                <el-button-->
+<!--                    type="warning"-->
+<!--                    plain-->
+<!--                    icon="Download"-->
+<!--                    @click="handleExport"-->
+<!--                    v-hasPermi="['biz:houseConfig:export']"-->
+<!--                >导出-->
+<!--                </el-button>-->
+<!--              </el-col>-->
+              <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+            </el-row>
 
-    <el-table v-loading="loading" :data="houseConfigList" @selection-change="handleSelectionChange">
-      <el-table-column type="selection" width="55" align="center" />
-      <el-table-column label="仓库ID" align="center" prop="houseId" />
-      <el-table-column label="仓库名称" align="center" prop="houseName" />
-      <el-table-column label="仓库编号" align="center" prop="houseNum" />
-      <el-table-column label="仓库简称" align="center" prop="simpleName" />
-      <el-table-column label="仓库编码" align="center" prop="houseCode" />
-      <el-table-column label="仓库地址" align="center" prop="houseAddr" />
-      <el-table-column label="经度" align="center" prop="lon" />
-      <el-table-column label="纬度" align="center" prop="lat" />
-      <el-table-column label="所属部门" align="center" prop="deptId" />
-      <el-table-column label="部门名称" align="center" prop="deptName" />
-      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
-        <template #default="scope">
-          <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['biz:houseConfig:edit']">修改</el-button>
-          <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['biz:houseConfig:remove']">删除</el-button>
-        </template>
-      </el-table-column>
-    </el-table>
-    
-    <pagination
-      v-show="total>0"
-      :total="total"
-      v-model:page="queryParams.pageNum"
-      v-model:limit="queryParams.pageSize"
-      @pagination="getList"
-    />
+            <el-table v-loading="loading" :data="houseConfigList" @selection-change="handleSelectionChange">
+              <el-table-column type="selection" width="55" align="center"/>
+<!--              <el-table-column label="仓库ID" align="center" prop="houseId"/>-->
+              <el-table-column label="仓库名称" align="center" prop="houseName"/>
+              <el-table-column label="仓库编号" align="center" prop="houseNum"/>
+              <el-table-column label="仓库简称" align="center" prop="simpleName"/>
+              <el-table-column label="仓库编码" align="center" prop="houseCode"/>
+              <el-table-column label="仓库地址" align="center" prop="houseAddr"/>
+              <el-table-column label="经度" align="center" prop="lon"/>
+              <el-table-column label="纬度" align="center" prop="lat"/>
+<!--              <el-table-column label="所属部门" align="center" prop="deptId"/>-->
+              <el-table-column label="部门名称" align="center" prop="deptName"/>
+              <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+                <template #default="scope">
+                  <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)"
+                             v-hasPermi="['biz:houseConfig:edit']">修改
+                  </el-button>
+                  <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)"
+                             v-hasPermi="['biz:houseConfig:remove']">删除
+                  </el-button>
+                </template>
+              </el-table-column>
+            </el-table>
 
+            <pagination
+                v-show="total>0"
+                :total="total"
+                v-model:page="queryParams.pageNum"
+                v-model:limit="queryParams.pageSize"
+                @pagination="getList"
+            />
+          </el-col>
+        </pane>
+      </splitpanes>
+    </el-row>
     <!-- 添加或修改仓库配置对话框 -->
     <el-dialog :title="title" v-model="open" width="500px" append-to-body>
       <el-form ref="houseConfigRef" :model="form" :rules="rules" label-width="80px">
-        <el-form-item label="仓库名称" prop="houseName">
-          <el-input v-model="form.houseName" placeholder="请输入仓库名称" />
-        </el-form-item>
-        <el-form-item label="仓库编号" prop="houseNum">
-          <el-input v-model="form.houseNum" placeholder="请输入仓库编号" />
-        </el-form-item>
-        <el-form-item label="仓库简称" prop="simpleName">
-          <el-input v-model="form.simpleName" placeholder="请输入仓库简称" />
-        </el-form-item>
-        <el-form-item label="仓库编码" prop="houseCode">
-          <el-input v-model="form.houseCode" placeholder="请输入仓库编码" />
-        </el-form-item>
-        <el-form-item label="仓库地址" prop="houseAddr">
-          <el-input v-model="form.houseAddr" placeholder="请输入仓库地址" />
-        </el-form-item>
-        <el-form-item label="经度" prop="lon">
-          <el-input v-model="form.lon" placeholder="请输入经度" />
-        </el-form-item>
-        <el-form-item label="纬度" prop="lat">
-          <el-input v-model="form.lat" placeholder="请输入纬度" />
-        </el-form-item>
-        <el-form-item label="所属部门" prop="deptId">
-          <el-input v-model="form.deptId" placeholder="请输入所属部门" />
-        </el-form-item>
-        <el-form-item label="部门名称" prop="deptName">
-          <el-input v-model="form.deptName" placeholder="请输入部门名称" />
-        </el-form-item>
+            <el-form-item label="仓库名称" prop="houseName">
+              <el-input v-model="form.houseName" placeholder="请输入仓库名称"/>
+            </el-form-item>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="仓库编码" prop="houseCode">
+              <el-input v-model="form.houseCode" placeholder="请输入仓库编码"/>
+            </el-form-item>
+            <el-form-item label="仓库简称" prop="simpleName">
+              <el-input v-model="form.simpleName" placeholder="请输入仓库简称"/>
+            </el-form-item>
+            <el-form-item label="仓库编号" prop="houseNum">
+              <el-input v-model="form.houseNum" placeholder="请输入仓库编号"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+
+            <el-form-item label="所属部门" prop="deptId">
+              <el-tree-select
+                v-model="form.deptId"
+                :data="enabledDeptOptions"
+                :props="{ value: 'id', label: 'label', children: 'children' }"
+                value-key="id"
+                placeholder="请选择归属部门"
+                check-strictly
+                @change="handleDeptChange"
+              />
+            </el-form-item>
+<!--            <el-form-item label="部门名称" prop="deptName">-->
+<!--              <el-input v-model="form.deptName" placeholder="请输入部门名称" readonly />-->
+<!--            </el-form-item>-->
+            <el-form-item label="经度" prop="lon">
+              <el-input v-model="form.lon" placeholder="请输入经度"/>
+            </el-form-item>
+            <el-form-item label="纬度" prop="lat">
+              <el-input v-model="form.lat" placeholder="请输入纬度"/>
+            </el-form-item>
+          </el-col>
+        </el-row>
+          <el-form-item label="仓库地址" prop="houseAddr">
+            <el-input v-model="form.houseAddr" placeholder="请输入仓库地址" type="textarea" :rows="3"/>
+          </el-form-item>
       </el-form>
       <template #footer>
         <div class="dialog-footer">
@@ -167,9 +212,18 @@
 </template>
 
 <script setup name="HouseConfig">
-import { listHouseConfig, getHouseConfig, delHouseConfig, addHouseConfig, updateHouseConfig } from "@/api/biz/houseConfig";
+import {
+  addHouseConfig,
+  delHouseConfig,
+  getHouseConfig,
+  listHouseConfig,
+  updateHouseConfig
+} from "@/api/biz/houseConfig";
+import {Pane, Splitpanes} from "splitpanes"
+import "splitpanes/dist/splitpanes.css"
+import {deptTreeSelect} from "@/api/system/user";
 
-const { proxy } = getCurrentInstance();
+const {proxy} = getCurrentInstance();
 
 const houseConfigList = ref([]);
 const open = ref(false);
@@ -180,7 +234,8 @@ const single = ref(true);
 const multiple = ref(true);
 const total = ref(0);
 const title = ref("");
-
+const deptOptions = ref(undefined);
+const enabledDeptOptions = ref(undefined);
 const data = reactive({
   form: {},
   queryParams: {
@@ -194,10 +249,37 @@ const data = reactive({
     deptName: null,
   },
   rules: {
+    houseName: [
+      {required: true, message: "仓库名称不能为空", trigger: "blur"}
+    ],
+    houseNum: [
+      {required: true, message: "仓库编号不能为空", trigger: "blur"}
+    ],
+    simpleName: [
+      {required: true, message: "仓库简称不能为空", trigger: "blur"}
+    ],
+    houseCode: [
+      {required: true, message: "仓库编码不能为空", trigger: "blur"}
+    ],
+    houseAddr: [
+      {required: true, message: "仓库地址不能为空", trigger: "blur"}
+    ],
+    // lon: [
+    //   {required: true, message: "经度不能为空", trigger: "blur"}
+    // ],
+    // lat: [
+    //   {required: true, message: "纬度不能为空", trigger: "blur"}
+    // ],
+    deptId: [
+      {required: true, message: "所属部门不能为空", trigger: "blur"}
+    ],
+    // deptName: [
+    //   {required: true, message: "部门名称不能为空", trigger: "blur"}
+    // ],
   }
 });
 
-const { queryParams, form, rules } = toRefs(data);
+const {queryParams, form, rules} = toRefs(data);
 
 /** 查询仓库配置列表 */
 function getList() {
@@ -214,7 +296,11 @@ function cancel() {
   open.value = false;
   reset();
 }
-
+/** 节点单击事件 */
+function handleNodeClick(data) {
+  queryParams.value.deptId = data.id;
+  handleQuery();
+};
 // 表单重置
 function reset() {
   form.value = {
@@ -237,6 +323,27 @@ function reset() {
   proxy.resetForm("houseConfigRef");
 }
 
+/** 查询部门下拉树结构 */
+function getDeptTree() {
+  deptTreeSelect().then(response => {
+    deptOptions.value = response.data;
+    enabledDeptOptions.value = filterDisabledDept(JSON.parse(JSON.stringify(response.data)));
+  });
+};
+
+/** 过滤禁用的部门 */
+function filterDisabledDept(deptList) {
+  return deptList.filter(dept => {
+    if (dept.disabled) {
+      return false;
+    }
+    if (dept.children && dept.children.length) {
+      dept.children = filterDisabledDept(dept.children);
+    }
+    return true;
+  });
+};
+
 /** 搜索按钮操作 */
 function handleQuery() {
   queryParams.value.pageNum = 1;
@@ -298,12 +405,13 @@ function submitForm() {
 /** 删除按钮操作 */
 function handleDelete(row) {
   const _houseIds = row.houseId || ids.value;
-  proxy.$modal.confirm('是否确认删除仓库配置编号为"' + _houseIds + '"的数据项?').then(function() {
+  proxy.$modal.confirm('是否确认删除仓库配置编号为"' + _houseIds + '"的数据项?').then(function () {
     return delHouseConfig(_houseIds);
   }).then(() => {
     getList();
     proxy.$modal.msgSuccess("删除成功");
-  }).catch(() => {});
+  }).catch(() => {
+  });
 }
 
 /** 导出按钮操作 */
@@ -312,6 +420,35 @@ function handleExport() {
     ...queryParams.value
   }, `houseConfig_${new Date().getTime()}.xlsx`)
 }
+/** 部门选择变更事件 */
+function handleDeptChange(value) {
+  if (value) {
+    // 查找选中的部门信息
+    const selectedDept = findDeptById(deptOptions.value, value);
+    if (selectedDept) {
+      form.value.deptName = selectedDept.label;
+    }
+  } else {
+    form.value.deptName = '';
+  }
+}
 
+/** 根据ID查找部门信息 */
+function findDeptById(deptList, id) {
+  if (!deptList || !id) return null;
+
+  for (let i = 0; i < deptList.length; i++) {
+    const dept = deptList[i];
+    if (dept.id === id) {
+      return dept;
+    }
+    if (dept.children && dept.children.length) {
+      const found = findDeptById(dept.children, id);
+      if (found) return found;
+    }
+  }
+  return null;
+}
+getDeptTree();
 getList();
 </script>

+ 320 - 103
src/views/biz/sensorConfig/index.vue

@@ -3,26 +3,26 @@
     <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
       <el-form-item label="仓库名称" prop="houseName">
         <el-input
-          v-model="queryParams.houseName"
-          placeholder="请输入仓库名称"
-          clearable
-          @keyup.enter="handleQuery"
+            v-model="queryParams.houseName"
+            placeholder="请输入仓库名称"
+            clearable
+            @keyup.enter="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="仓库编码" prop="houseCode">
+      <!--      <el-form-item label="仓库编码" prop="houseCode">-->
+      <!--        <el-input-->
+      <!--          v-model="queryParams.houseCode"-->
+      <!--          placeholder="请输入仓库编码"-->
+      <!--          clearable-->
+      <!--          @keyup.enter="handleQuery"-->
+      <!--        />-->
+      <!--      </el-form-item>-->
+      <el-form-item label="网关名称" prop="sensorName">
         <el-input
-          v-model="queryParams.houseCode"
-          placeholder="请输入仓库编码"
-          clearable
-          @keyup.enter="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="传感器名称" prop="sensorName">
-        <el-input
-          v-model="queryParams.sensorName"
-          placeholder="请输入传感器名称"
-          clearable
-          @keyup.enter="handleQuery"
+            v-model="queryParams.sensorName"
+            placeholder="请输入传感器网关名称"
+            clearable
+            @keyup.enter="handleQuery"
         />
       </el-form-item>
       <el-form-item>
@@ -34,109 +34,134 @@
     <el-row :gutter="10" class="mb8">
       <el-col :span="1.5">
         <el-button
-          type="primary"
-          plain
-          icon="Plus"
-          @click="handleAdd"
-          v-hasPermi="['biz:sensorConfig:add']"
-        >新增</el-button>
+            type="primary"
+            plain
+            icon="Plus"
+            @click="handleAdd"
+        >新增
+        </el-button>
       </el-col>
       <el-col :span="1.5">
         <el-button
-          type="success"
-          plain
-          icon="Edit"
-          :disabled="single"
-          @click="handleUpdate"
-          v-hasPermi="['biz:sensorConfig:edit']"
-        >修改</el-button>
+            type="success"
+            plain
+            icon="Edit"
+            :disabled="single"
+            @click="handleUpdate"
+        >修改
+        </el-button>
       </el-col>
       <el-col :span="1.5">
         <el-button
-          type="danger"
-          plain
-          icon="Delete"
-          :disabled="multiple"
-          @click="handleDelete"
-          v-hasPermi="['biz:sensorConfig:remove']"
-        >删除</el-button>
-      </el-col>
-      <el-col :span="1.5">
-        <el-button
-          type="warning"
-          plain
-          icon="Download"
-          @click="handleExport"
-          v-hasPermi="['biz:sensorConfig:export']"
-        >导出</el-button>
+            type="danger"
+            plain
+            icon="Delete"
+            :disabled="multiple"
+            @click="handleDelete"
+        >删除
+        </el-button>
       </el-col>
+      <!--      <el-col :span="1.5">-->
+      <!--        <el-button-->
+      <!--          type="warning"-->
+      <!--          plain-->
+      <!--          icon="Download"-->
+      <!--          @click="handleExport"-->
+      <!--          v-hasPermi="['biz:sensorConfig:export']"-->
+      <!--        >导出</el-button>-->
+      <!--      </el-col>-->
       <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
     </el-row>
 
     <el-table v-loading="loading" :data="sensorConfigList" @selection-change="handleSelectionChange">
-      <el-table-column type="selection" width="55" align="center" />
-      <el-table-column label="传感器ID" align="center" prop="sensorId" />
-      <el-table-column label="仓库ID" align="center" prop="houseId" />
-      <el-table-column label="仓库名称" align="center" prop="houseName" />
-      <el-table-column label="仓库编码" align="center" prop="houseCode" />
-      <el-table-column label="传感器名称" align="center" prop="sensorName" />
-      <el-table-column label="订阅地址" align="center" prop="subscribAddr" />
-      <el-table-column label="订阅主题" align="center" prop="topic" />
-      <el-table-column label="烟雾阈值" align="center" prop="smokeThreshold" />
-      <el-table-column label="温度阈值" align="center" prop="tmpThreshold" />
-      <el-table-column label="温度阈值" align="center" prop="rhThreshold" />
-      <el-table-column label="发布流程间隔时间" align="center" prop="alarmTime" />
-      <el-table-column label="上次发布流程时间" align="center" prop="lastTime" width="180">
+      <el-table-column type="selection" width="55" align="center"/>
+      <!--      <el-table-column label="传感器ID" align="center" prop="sensorId" />-->
+      <!--      <el-table-column label="仓库ID" align="center" prop="houseId" />-->
+      <el-table-column label="仓库名称" align="center" prop="houseName" width="250px"/>
+      <!--      <el-table-column label="仓库编码" align="center" prop="houseCode" />-->
+      <el-table-column label="网关名称" align="center" prop="sensorName"/>
+      <el-table-column label="订阅地址" align="center" prop="subscribAddr"/>
+      <el-table-column label="订阅主题" align="center" prop="topic"/>
+      <el-table-column label="烟雾阈值" align="center" prop="smokeThreshold" width="80px"/>
+      <el-table-column label="温度阈值" align="center" prop="tmpThreshold" width="80px"/>
+      <el-table-column label="湿度阈值" align="center" prop="rhThreshold" width="80px"/>
+      <el-table-column label="告警间隔分钟" align="center" prop="alarmTime" width="80px"/>
+      <el-table-column label="上次告警时间" align="center" prop="lastTime" width="180">
         <template #default="scope">
-          <span>{{ parseTime(scope.row.lastTime, '{y}-{m}-{d}') }}</span>
+          <span>{{ parseTime(scope.row.lastTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
         </template>
       </el-table-column>
       <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
         <template #default="scope">
-          <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['biz:sensorConfig:edit']">修改</el-button>
-          <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['biz:sensorConfig:remove']">删除</el-button>
+          <el-button link type="primary" icon="List" @click="handleList(scope.row)"
+          >历史数据
+          </el-button>
+          <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)"
+                     >修改
+          </el-button>
+          <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)"
+                     >删除
+          </el-button>
         </template>
       </el-table-column>
     </el-table>
-    
+
     <pagination
-      v-show="total>0"
-      :total="total"
-      v-model:page="queryParams.pageNum"
-      v-model:limit="queryParams.pageSize"
-      @pagination="getList"
+        v-show="total>0"
+        :total="total"
+        v-model:page="queryParams.pageNum"
+        v-model:limit="queryParams.pageSize"
+        @pagination="getList"
     />
 
     <!-- 添加或修改传感器网关配置对话框 -->
     <el-dialog :title="title" v-model="open" width="500px" append-to-body>
-      <el-form ref="sensorConfigRef" :model="form" :rules="rules" label-width="80px">
+      <el-form ref="sensorConfigRef" :model="form" :rules="rules" label-width="120px">
         <el-form-item label="仓库名称" prop="houseName">
-          <el-input v-model="form.houseName" placeholder="请输入仓库名称" />
+          <el-select v-model="form.houseName" placeholder="请选择仓库名称" clearable filterable
+                     @change="handleHouseChange">
+            <el-option
+                v-for="item in houseConfigList"
+                :key="item.houseName"
+                :label="item.houseName"
+                :value="item.houseId"
+            >
+            </el-option>
+          </el-select>
         </el-form-item>
-        <el-form-item label="仓库编码" prop="houseCode">
-          <el-input v-model="form.houseCode" placeholder="请输入仓库编码" />
-        </el-form-item>
-        <el-form-item label="传感器名称" prop="sensorName">
-          <el-input v-model="form.sensorName" placeholder="请输入传感器名称" />
+        <el-form-item label="网关名称" prop="sensorName">
+          <el-input v-model="form.sensorName" placeholder="请输入传感器网关名称"/>
         </el-form-item>
         <el-form-item label="订阅地址" prop="subscribAddr">
-          <el-input v-model="form.subscribAddr" placeholder="请输入订阅地址" />
+          <el-input v-model="form.subscribAddr" placeholder="请输入订阅地址"/>
         </el-form-item>
         <el-form-item label="订阅主题" prop="topic">
-          <el-input v-model="form.topic" placeholder="请输入订阅主题" />
-        </el-form-item>
-        <el-form-item label="烟雾阈值" prop="smokeThreshold">
-          <el-input v-model="form.smokeThreshold" placeholder="请输入烟雾阈值" />
-        </el-form-item>
-        <el-form-item label="温度阈值" prop="tmpThreshold">
-          <el-input v-model="form.tmpThreshold" placeholder="请输入温度阈值" />
-        </el-form-item>
-        <el-form-item label="温度阈值" prop="rhThreshold">
-          <el-input v-model="form.rhThreshold" placeholder="请输入温度阈值" />
-        </el-form-item>
-        <el-form-item label="发布流程间隔时间" prop="alarmTime">
-          <el-input v-model="form.alarmTime" placeholder="请输入发布流程间隔时间" />
+          <el-input v-model="form.topic" placeholder="请输入订阅主题"/>
         </el-form-item>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="告警间隔分钟" prop="alarmTime">
+              <el-input-number v-model="form.alarmTime" placeholder="告警间隔分钟" :min="10" controls-position="right"
+                               style="width: 100%"/>
+            </el-form-item>
+            <el-form-item label="烟雾阈值" prop="smokeThreshold">
+              <el-input-number v-model="form.smokeThreshold" placeholder="请输入烟雾阈值" :min="1"
+                               controls-position="right"
+                               style="width: 100%"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+
+            <el-form-item label="温度阈值" prop="tmpThreshold">
+              <el-input-number v-model="form.tmpThreshold" placeholder="请输入温度阈值" :precision="1" :step="0.1"
+                               controls-position="right" style="width: 100%"/>
+            </el-form-item>
+            <el-form-item label="湿度阈值" prop="rhThreshold">
+              <el-input-number v-model="form.rhThreshold" placeholder="请输入湿度阈值" :precision="1" :step="0.1"
+                               controls-position="right" style="width: 100%"/>
+            </el-form-item>
+          </el-col>
+        </el-row>
       </el-form>
       <template #footer>
         <div class="dialog-footer">
@@ -145,13 +170,32 @@
         </div>
       </template>
     </el-dialog>
+
+    <!-- 历史数据图表对话框 -->
+    <el-dialog :title="chartTitle" v-model="chartOpen" width="800px" append-to-body>
+      <div ref="chartRef" style="width: 100%; height: 400px;"></div>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="chartOpen = false">关闭</el-button>
+        </div>
+      </template>
+    </el-dialog>
   </div>
 </template>
 
 <script setup name="SensorConfig">
-import { listSensorConfig, getSensorConfig, delSensorConfig, addSensorConfig, updateSensorConfig } from "@/api/biz/sensorConfig";
+import {
+  addSensorConfig,
+  delSensorConfig,
+  getSensorConfig,
+  listSensorConfig,
+  updateSensorConfig,
+  listRecord
+} from "@/api/biz/sensorConfig";
+import {listHouseConfig} from "@/api/biz/houseConfig";
+import * as echarts from 'echarts';
 
-const { proxy } = getCurrentInstance();
+const {proxy} = getCurrentInstance();
 
 const sensorConfigList = ref([]);
 const open = ref(false);
@@ -162,45 +206,92 @@ const single = ref(true);
 const multiple = ref(true);
 const total = ref(0);
 const title = ref("");
-
+const chartTitle = ref("");
+const houseConfigList = ref(undefined);
+const chartOpen = ref(false); // 控制图表对话框显示
+const chartRef = ref(null); // 图表容器引用
 const data = reactive({
   form: {},
   queryParams: {
     pageNum: 1,
     pageSize: 10,
+    houseId: null,
     houseName: null,
     houseCode: null,
     sensorName: null,
   },
   rules: {
+    houseName: [
+      {required: true, message: "仓库名称不能为空", trigger: "blur"}
+    ],
     sensorName: [
-      { required: true, message: "传感器名称不能为空", trigger: "blur" }
+      {required: true, message: "传感器名称不能为空", trigger: "blur"}
     ],
     subscribAddr: [
-      { required: true, message: "订阅地址不能为空", trigger: "blur" }
+      {required: true, message: "订阅地址不能为空", trigger: "blur"}
     ],
     topic: [
-      { required: true, message: "订阅主题不能为空", trigger: "blur" }
+      {required: true, message: "订阅主题不能为空", trigger: "blur"}
     ],
     smokeThreshold: [
-      { required: true, message: "烟雾阈值不能为空", trigger: "blur" }
+      {required: true, message: "烟雾阈值不能为空", trigger: "blur"}
     ],
     tmpThreshold: [
-      { required: true, message: "温度阈值不能为空", trigger: "blur" }
+      {required: true, message: "温度阈值不能为空", trigger: "blur"}
     ],
     rhThreshold: [
-      { required: true, message: "温度阈值不能为空", trigger: "blur" }
+      {required: true, message: "温度阈值不能为空", trigger: "blur"}
     ],
     alarmTime: [
-      { required: true, message: "发布流程间隔时间不能为空", trigger: "blur" }
+      {required: true, message: "发布流程间隔时间不能为空", trigger: "blur"}
     ],
     lastTime: [
-      { required: true, message: "上次发布流程时间不能为空", trigger: "blur" }
+      {required: true, message: "上次发布流程时间不能为空", trigger: "blur"}
     ],
   }
 });
 
-const { queryParams, form, rules } = toRefs(data);
+const {queryParams, form, rules} = toRefs(data);
+
+/** 查询仓库配置列表 */
+function getHouseList() {
+  listHouseConfig().then(response => {
+    houseConfigList.value = response.rows;
+  });
+}
+
+function handleHouseChange(value) {
+  if (value) {
+    // 查找选中的部门信息
+    const selectedDept = findDeptById(houseConfigList.value, value);
+    console.log(selectedDept)
+    if (selectedDept) {
+      form.value.houseId = selectedDept.houseId;
+      form.value.houseName = selectedDept.houseName;
+      form.value.houseCode = selectedDept.houseCode;
+    }
+
+  } else {
+    form.value.houseId = '';
+  }
+}
+
+/** 根据ID查找部门信息 */
+function findDeptById(deptList, id) {
+  if (!deptList || !id) return null;
+
+  for (let i = 0; i < deptList.length; i++) {
+    const dept = deptList[i];
+    if (dept.houseId === id) {
+      return dept;
+    }
+    if (dept.children && dept.children.length) {
+      const found = findDeptById(dept.children, id);
+      if (found) return found;
+    }
+  }
+  return null;
+}
 
 /** 查询传感器网关配置列表 */
 function getList() {
@@ -212,6 +303,130 @@ function getList() {
   });
 }
 
+// 显示历史数据图表
+function handleList(row) {
+  chartOpen.value = true;
+  chartTitle.value=row.sensorName+"-历史数据"
+  nextTick(() => {
+    listRecord(row.sensorId).then(response => {
+      initChart(row, response);
+    });
+  });
+}
+
+// 初始化图表
+function initChart(row,list) {
+  if (!chartRef.value) return;
+
+  const chart = echarts.init(chartRef.value);
+
+  // 模拟数据
+  const xAxisData = [];
+  const smokeData = [];
+  const temperatureData = [];
+  const humidityData = [];
+  for (let i = 0; i < list.length; i++) {
+    const item = list[i];
+    xAxisData.push(item.createTime);
+    smokeData.push(item.smoke);
+    temperatureData.push(item.tmp);
+    humidityData.push(item.rh);
+  }
+  for (let i = 0; i < 24; i++) {
+    xAxisData.push(`${i}:00`);
+    // 烟雾值只有0和1
+    smokeData.push(Math.random() > 0.9 ? 1 : 0);
+    temperatureData.push(Math.floor(Math.random() * 40));
+    humidityData.push(Math.floor(Math.random() * 100));
+  }
+
+  const option = {
+    // title: {
+    //   text: `${row.sensorName}`
+    // },
+    tooltip: {
+      trigger: 'axis'
+    },
+    legend: {
+      data: ['烟雾', '温度(℃)', '湿度(%)']
+    },
+    dataZoom: [
+      {
+        type: 'inside',
+        start: 98,
+        end: 100
+      },
+      {
+        start: 98,
+        end: 100
+      }
+    ],
+    grid: {
+      left: '3%',
+      right: '4%',
+      bottom: '3%',
+      containLabel: true
+    },
+    xAxis: {
+      type: 'category',
+      boundaryGap: false,
+      data: xAxisData
+    },
+    yAxis: [
+      {
+        type: 'value',
+        name: '烟雾',
+        position: 'left',
+        min: 0,
+        max: 1,
+        interval: 1
+      },
+      {
+        type: 'value',
+        name: '温度(℃)/湿度(%)',
+        position: 'right'
+      }
+    ],
+    series: [
+      {
+        name: '烟雾',
+        type: 'line',
+        yAxisIndex: 0,
+        step: 'end',
+        data: smokeData,
+        areaStyle: {
+          color: '#8a5b3c',
+          opacity: 0.3
+        },
+        color: '#ff0000'
+      },
+      {
+        name: '温度(℃)',
+        type: 'line',
+        yAxisIndex: 1,
+        data: temperatureData,
+        smooth: true,
+        color: '#0946dc'
+      },
+      {
+        name: '湿度(%)',
+        type: 'line',
+        yAxisIndex: 1,
+        data: humidityData,
+        smooth: true,
+        color: '#abff5c'
+      }
+    ]
+  };
+
+  chart.setOption(option);
+
+  // 监听窗口大小变化,自动调整图表大小
+  window.addEventListener('resize', () => {
+    chart.resize();
+  });
+}
+
 // 取消按钮
 function cancel() {
   open.value = false;
@@ -304,12 +519,13 @@ function submitForm() {
 /** 删除按钮操作 */
 function handleDelete(row) {
   const _sensorIds = row.sensorId || ids.value;
-  proxy.$modal.confirm('是否确认删除传感器网关配置编号为"' + _sensorIds + '"的数据项?').then(function() {
+  proxy.$modal.confirm('是否确认删除传感器网关配置编号为"' + _sensorIds + '"的数据项?').then(function () {
     return delSensorConfig(_sensorIds);
   }).then(() => {
     getList();
     proxy.$modal.msgSuccess("删除成功");
-  }).catch(() => {});
+  }).catch(() => {
+  });
 }
 
 /** 导出按钮操作 */
@@ -319,5 +535,6 @@ function handleExport() {
   }, `sensorConfig_${new Date().getTime()}.xlsx`)
 }
 
+getHouseList()
 getList();
 </script>