Преглед на файлове

app菜单管理,瓦斯监测预警布局修改-提交

lxh преди 5 месеца
родител
ревизия
645861a5ec
променени са 3 файла, в които са добавени 948 реда и са изтрити 413 реда
  1. 122 0
      src/views/system/menuModalApp/menu.api.ts
  2. 416 0
      src/views/system/menuModalApp/menu.data.ts
  3. 410 413
      src/views/vent/monitorManager/alarmMonitor/warn/gasWarn.vue

+ 122 - 0
src/views/system/menuModalApp/menu.api.ts

@@ -0,0 +1,122 @@
+import { defHttp } from '/@/utils/http/axios';
+import { Modal } from 'ant-design-vue';
+
+enum Api {
+  list = '/sys/permissionNew/list',
+  save = '/sys/permissionNew/add',
+  edit = '/sys/permissionNew/edit',
+  delete = '/sys/permissionNew/delete',
+  deleteBatch = '/sys/permissionNew/deleteBatch',
+  ruleList = '/sys/permissionNew/queryPermissionRule',
+  ruleSave = '/sys/permissionNew/addPermissionRule',
+  ruleEdit = '/sys/permissionNew/editPermissionRule',
+  ruleDelete = '/sys/permissionNew/deletePermissionRule',
+  checkPermDuplication = '/sys/permissionNew/checkPermDuplication',
+}
+
+/**
+ * 列表接口
+ * @param params
+ */
+export const list = (params) => {
+  return defHttp.get({ url: Api.list, params });
+};
+
+/**
+ * 删除菜单
+ */
+export const deleteMenu = (params, handleSuccess) => {
+  return defHttp.delete({ url: Api.delete, params }, { joinParamsToUrl: true }).then(() => {
+    handleSuccess();
+  });
+};
+/**
+ * 批量删除菜单
+ * @param params
+ */
+export const batchDeleteMenu = (params, handleSuccess) => {
+  Modal.confirm({
+    title: '确认删除',
+    content: '是否删除选中数据',
+    okText: '确认',
+    cancelText: '取消',
+    onOk: () => {
+      return defHttp.delete({ url: Api.deleteBatch, data: params }, { joinParamsToUrl: true }).then(() => {
+        handleSuccess();
+      });
+    },
+  });
+};
+/**
+ * 保存或者更新菜单
+ * @param params
+ */
+export const saveOrUpdateMenu = (params, isUpdate) => {
+  const url = isUpdate ? Api.edit : Api.save;
+  return defHttp.post({ url: url, params });
+};
+/**
+ * 菜单数据权限列表接口
+ * @param params
+ */
+export const dataRuleList = (params) => defHttp.get({ url: Api.ruleList, params });
+/**
+ * 保存或者更新数据规则
+ * @param params
+ */
+export const saveOrUpdateRule = (params, isUpdate) => {
+  const url = isUpdate ? Api.ruleEdit : Api.ruleSave;
+  return defHttp.post({ url: url, params });
+};
+
+/**
+ * 删除数据权限
+ */
+export const deleteRule = (params, handleSuccess) => {
+  return defHttp.delete({ url: Api.ruleDelete, params }, { joinParamsToUrl: true }).then(() => {
+    handleSuccess();
+  });
+};
+/**
+ * 根据code获取字典数值
+ * @param params
+ */
+export const ajaxGetDictItems = (params) => defHttp.get({ url: `/sys/dict/getDictItems/${params.code}` });
+
+/**
+ * 唯一校验
+ * @param params
+ */
+export const getCheckPermDuplication = (params) => defHttp.get({ url: Api.checkPermDuplication, params }, { isTransformResponse: false });
+
+/**
+ * 校验菜单是否存在
+ * @param model
+ * @param schema
+ * @param required
+ */
+export const checkPermDuplication = (model, schema, required?) => {
+  return [
+    {
+      validator: (_, value) => {
+        if (!value && required) {
+          return Promise.reject(`请输入${schema.label}`);
+        }
+        return new Promise<void>((resolve, reject) => {
+          // getCheckPermDuplication({
+          //   id: model.id,
+          //   url: model.url,
+          //   alwaysShow: model.alwaysShow,
+          // })
+          //   .then((res) => {
+          //     res.success ? resolve() : reject(res.message || '校验失败');
+          //   })
+          //   .catch((err) => {
+          //     reject(err.message || '验证失败');
+          //   });
+          resolve()
+        });
+      },
+    },
+  ];
+};

+ 416 - 0
src/views/system/menuModalApp/menu.data.ts

@@ -0,0 +1,416 @@
+import { BasicColumn } from '/@/components/Table';
+import { FormSchema } from '/@/components/Table';
+import { h } from 'vue';
+import { Icon } from '/@/components/Icon';
+import { duplicateCheck } from '../user/user.api';
+import { ajaxGetDictItems, checkPermDuplication } from './menu.api';
+import { render } from '/@/utils/common/renderUtils';
+
+const isDir = (type) => type === 0;
+const isMenu = (type) => type === 1;
+const isButton = (type) => type === 2;
+
+// 定义可选择的组件类型
+export enum ComponentTypes {
+  Default = 'layouts/default/index',
+  // IFrame = 'sys/iframe/FrameBlank',
+  IFrame = 'sys/iframe/index',
+}
+
+export const columns: BasicColumn[] = [
+  {
+    title: '菜单名称',
+    dataIndex: 'name',
+    width: 200,
+    align: 'left',
+  },
+  {
+    title: '菜单类型',
+    dataIndex: 'menuType',
+    width: 150,
+    customRender: ({ text }) => {
+      return render.renderDict(text, 'menu_type');
+    },
+  },
+  {
+    title: '图标',
+    dataIndex: 'icon',
+    width: 50,
+    customRender: ({ record }) => {
+      return h(Icon, { icon: record.icon });
+    },
+  },
+  {
+    title: '组件',
+    dataIndex: 'component',
+    align: 'left',
+    width: 150,
+  },
+  {
+    title: '路径',
+    dataIndex: 'url',
+    align: 'left',
+    width: 150,
+  },
+  {
+    title: '排序',
+    dataIndex: 'sortNo',
+    width: 50,
+  },
+];
+
+export const searchFormSchema: FormSchema[] = [
+  {
+    field: 'name',
+    label: '菜单名称',
+    component: 'Input',
+    colProps: { span: 8 },
+  },
+];
+
+export const formSchema: FormSchema[] = [
+  {
+    label: 'id',
+    field: 'id',
+    component: 'Input',
+    show: false,
+  },
+  {
+    field: 'menuType',
+    label: '菜单类型',
+    component: 'RadioButtonGroup',
+    defaultValue: 0,
+    componentProps: ({ formActionType, formModel }) => {
+      return {
+        options: [
+          { label: '一级菜单', value: 0 },
+          { label: '子菜单', value: 1 },
+          { label: '按钮/权限', value: 2 },
+        ],
+        onChange: (e) => {
+          const { updateSchema, clearValidate } = formActionType;
+          const label = isButton(e) ? '按钮/权限' : '菜单名称';
+          //清除校验
+          clearValidate();
+          updateSchema([
+            {
+              field: 'name',
+              label: label,
+            },
+            {
+              field: 'url',
+              required: !isButton(e),
+            },
+          ]);
+          //update-begin---author:wangshuai ---date:20220729  for:[VUEN-1834]只有一级菜单,才默认值,子菜单的时候,清空------------
+          if (isMenu(e) && !formModel.id && formModel.component == 'layouts/RouteView') {
+            formModel.component = '';
+          }
+          //update-end---author:wangshuai ---date:20220729  for:[VUEN-1834]只有一级菜单,才默认值,子菜单的时候,清空------------
+        },
+      };
+    },
+  },
+  {
+    field: 'name',
+    label: '菜单名称',
+    component: 'Input',
+    required: true,
+  },
+  {
+    field: 'parentId',
+    label: '上级菜单',
+    component: 'TreeSelect',
+    required: true,
+    componentProps: {
+      replaceFields: {
+        title: 'name',
+        key: 'id',
+        value: 'id',
+      },
+      dropdownStyle: {
+        maxHeight: '50vh',
+      },
+      getPopupContainer: (node) => node.parentNode,
+    },
+    ifShow: ({ values }) => !isDir(values.menuType),
+  },
+  {
+    field: 'url',
+    label: '访问路径',
+    component: 'Input',
+    required: true,
+    ifShow: ({ values }) => !(values.component === ComponentTypes.IFrame && values.internalOrExternal) && values.menuType !== 2,
+    //update-begin-author:zyf date:2022-11-02 for: 聚合路由允许路径重复
+     dynamicRules: ({ model, schema }) => {
+       return checkPermDuplication(model, schema, true);
+    },
+    //update-end-author:zyf date:2022-11-02 for: 聚合路由允许路径重复
+  },
+  {
+    field: 'component',
+    label: '前端组件',
+    component: 'Input',
+    componentProps: {
+      placeholder: '请输入前端组件',
+    },
+    defaultValue: 'layouts/RouteView',
+    required: true,
+    ifShow: ({ values }) => !isButton(values.menuType),
+  },
+  {
+    field: 'componentName',
+    label: '组件名称',
+    component: 'Input',
+    componentProps: {
+      placeholder: '请输入组件名称',
+    },
+    helpMessage: [
+      '此处名称应和vue组件的name属性保持一致。',
+      '组件名称不能重复,主要用于路由缓存功能。',
+      '如果组件名称和vue组件的name属性不一致,则会导致路由缓存失效。',
+      '非必填,留空则会根据访问路径自动生成。',
+    ],
+    defaultValue: '',
+    ifShow: ({ values }) => !isButton(values.menuType),
+  },
+  {
+    field: 'frameSrc',
+    label: 'Iframe地址',
+    component: 'Input',
+    rules: [
+      { required: true, message: '请输入Iframe地址' },
+      { type: 'url', message: '请输入正确的url地址' },
+    ],
+    ifShow: ({ values }) => !isButton(values.menuType) && values.component === ComponentTypes.IFrame,
+  },
+  {
+    field: 'redirect',
+    label: '默认跳转地址',
+    component: 'Input',
+    ifShow: ({ values }) => isDir(values.menuType),
+  },
+  {
+    field: 'perms',
+    label: '授权标识',
+    component: 'Input',
+    ifShow: ({ values }) => isButton(values.menuType),
+    dynamicRules: ({ model }) => {
+      return [
+        {
+          required: false,
+          validator: (_, value) => {
+            return new Promise((resolve, reject) => {
+              const params = {
+                tableName: 'sys_permission',
+                fieldName: 'perms',
+                fieldVal: value,
+                dataId: model.id,
+              };
+              duplicateCheck(params)
+                .then((res) => {
+                  res.success ? resolve() : reject(res.message || '校验失败');
+                })
+                .catch((err) => {
+                  reject(err.message || '校验失败');
+                });
+            });
+          },
+        },
+      ];
+    },
+  },
+  {
+    field: 'permsType',
+    label: '授权策略',
+    component: 'RadioGroup',
+    defaultValue: '1',
+    helpMessage: ['可见/可访问(授权后可见/可访问)', '可编辑(未授权时禁用)'],
+    componentProps: {
+      options: [
+        { label: '可见/可访问', value: '1' },
+        { label: '可编辑', value: '2' },
+      ],
+    },
+    ifShow: ({ values }) => isButton(values.menuType),
+  },
+  {
+    field: 'status',
+    label: '状态',
+    component: 'RadioGroup',
+    defaultValue: '1',
+    componentProps: {
+      options: [
+        { label: '有效', value: '1' },
+        { label: '无效', value: '0' },
+      ],
+    },
+    ifShow: ({ values }) => isButton(values.menuType),
+  },
+  {
+    field: 'icon',
+    label: '菜单图标',
+    component: 'IconPicker',
+    ifShow: ({ values }) => !isButton(values.menuType),
+  },
+  {
+    field: 'sortNo',
+    label: '排序',
+    component: 'InputNumber',
+    defaultValue: 1,
+    ifShow: ({ values }) => !isButton(values.menuType),
+  },
+  {
+    field: 'route',
+    label: '是否路由菜单',
+    component: 'Switch',
+    defaultValue: true,
+    componentProps: {
+      checkedChildren: '是',
+      unCheckedChildren: '否',
+    },
+    ifShow: ({ values }) => !isButton(values.menuType),
+  },
+  {
+    field: 'hidden',
+    label: '隐藏路由',
+    component: 'Switch',
+    defaultValue: 0,
+    componentProps: {
+      checkedChildren: '是',
+      unCheckedChildren: '否',
+    },
+    ifShow: ({ values }) => !isButton(values.menuType),
+  },
+  {
+    field: 'hideTab',
+    label: '隐藏Tab',
+    component: 'Switch',
+    defaultValue: 0,
+    componentProps: {
+      checkedChildren: '是',
+      unCheckedChildren: '否',
+    },
+    ifShow: ({ values }) => !isButton(values.menuType),
+  },
+  {
+    field: 'keepAlive',
+    label: '是否缓存路由',
+    component: 'Switch',
+    defaultValue: false,
+    componentProps: {
+      checkedChildren: '是',
+      unCheckedChildren: '否',
+    },
+    ifShow: ({ values }) => !isButton(values.menuType),
+  },
+  {
+    field: 'alwaysShow',
+    label: '聚合路由',
+    component: 'Switch',
+    defaultValue: false,
+    componentProps: {
+      checkedChildren: '是',
+      unCheckedChildren: '否',
+    },
+    ifShow: ({ values }) => !isButton(values.menuType),
+  },
+  {
+    field: 'internalOrExternal',
+    label: '打开方式',
+    component: 'Switch',
+    defaultValue: false,
+    componentProps: {
+      checkedChildren: '外部',
+      unCheckedChildren: '内部',
+    },
+    ifShow: ({ values }) => !isButton(values.menuType),
+  },
+];
+
+export const dataRuleColumns: BasicColumn[] = [
+  {
+    title: '规则名称',
+    dataIndex: 'ruleName',
+    width: 150,
+  },
+  {
+    title: '规则字段',
+    dataIndex: 'ruleColumn',
+    width: 100,
+  },
+  {
+    title: '规则值',
+    dataIndex: 'ruleValue',
+    width: 100,
+  },
+];
+
+export const dataRuleSearchFormSchema: FormSchema[] = [
+  {
+    field: 'ruleName',
+    label: '规则名称',
+    component: 'Input',
+    colProps: { span: 6 },
+  },
+  {
+    field: 'ruleValue',
+    label: '规则值',
+    component: 'Input',
+    colProps: { span: 6 },
+  },
+];
+
+export const dataRuleFormSchema: FormSchema[] = [
+  {
+    label: 'id',
+    field: 'id',
+    component: 'Input',
+    show: false,
+  },
+  {
+    field: 'ruleName',
+    label: '规则名称',
+    component: 'Input',
+    required: true,
+  },
+  {
+    field: 'ruleColumn',
+    label: '规则字段',
+    component: 'Input',
+    ifShow: ({ values }) => {
+      return values.ruleConditions !== 'USE_SQL_RULES';
+    },
+  },
+  {
+    field: 'ruleConditions',
+    label: '条件规则',
+    required: true,
+    component: 'ApiSelect',
+    componentProps: {
+      api: ajaxGetDictItems,
+      params: { code: 'rule_conditions' },
+      labelField: 'text',
+      valueField: 'value',
+      getPopupContainer: (node) => document.body,
+    },
+  },
+  {
+    field: 'ruleValue',
+    label: '规则值',
+    component: 'Input',
+    required: true,
+  },
+  {
+    field: 'status',
+    label: '状态',
+    component: 'RadioButtonGroup',
+    defaultValue: '1',
+    componentProps: {
+      options: [
+        { label: '无效', value: '0' },
+        { label: '有效', value: '1' },
+      ],
+    },
+  },
+];

+ 410 - 413
src/views/vent/monitorManager/alarmMonitor/warn/gasWarn.vue

@@ -1,23 +1,18 @@
 <template>
   <customHeader :options="options" @change="getSelectRow" :optionValue="optionValue"> 瓦斯监测预警 </customHeader>
   <div class="gasWarn">
-    <a-button
-      v-if="!hasPermission('gasWarn:return')"
-      preIcon="ant-design:rollback-outlined"
-      type="text"
-      size="small"
-      style="position: absolute; left: 15px; top: 15px; color: #fff"
-      @click="getBack"
-      >返回</a-button
-    >
+    <a-button v-if="!hasPermission('gasWarn:return')" preIcon="ant-design:rollback-outlined" type="text" size="small"
+      style="position: absolute; left: 15px; top: 15px; color: #fff" @click="getBack">返回</a-button>
     <div class="alarm-menu">
       <div class="type-btn">
-        <div :class="activeIndex == index ? 'btn1' : 'btn'" v-for="(item, index) in typeMenuListGas" :key="index" @click="btnClick(index)">
+        <div :class="activeIndex == index ? 'btn1' : 'btn'" v-for="(item, index) in typeMenuListGas" :key="index"
+          @click="btnClick(index)">
           {{ item.name }}
         </div>
       </div>
       <div class="card-btn">
-        <div :class="activeIndex1 == ind ? 'btn1' : 'btn'" v-for="(item, ind) in menuList" :key="ind" @click="cardClick(ind, item)">
+        <div :class="activeIndex1 == ind ? 'btn1' : 'btn'" v-for="(item, ind) in menuList" :key="ind"
+          @click="cardClick(ind, item)">
           <div class="text">{{ item.name }}</div>
           <div class="warn">{{ item.warn }}</div>
         </div>
@@ -35,33 +30,30 @@
               <div class="box-values">
                 <div class="value-b" v-for="(items, ind) in item.list" :key="ind">
                   <span>{{ `${items.name} : ` }}</span>
-                  <span
-                    :class="{
-                      'box-value': items.val == 0 && items.name == '报警状态',
-                      'box-value1': items.val == 101 && items.name == '报警状态',
-                      'box-value2': items.val == 102 && items.name == '报警状态',
-                      'box-value3': items.val == 103 && items.name == '报警状态',
-                      'box-value4': items.val == 104 && items.name == '报警状态',
-                      'box-value5': (items.val == 201 || item.val == 1001) && items.name == '报警状态',
-                    }"
-                    >{{
-                      items.val == 0 && items.name == '报警状态'
-                        ? '正常'
-                        : items.val == 101 && items.name == '报警状态'
+                  <span :class="{
+                    'box-value': items.val == 0 && items.name == '报警状态',
+                    'box-value1': items.val == 101 && items.name == '报警状态',
+                    'box-value2': items.val == 102 && items.name == '报警状态',
+                    'box-value3': items.val == 103 && items.name == '报警状态',
+                    'box-value4': items.val == 104 && items.name == '报警状态',
+                    'box-value5': (items.val == 201 || item.val == 1001) && items.name == '报警状态',
+                  }">{{
+                    items.val == 0 && items.name == '报警状态'
+                      ? '正常'
+                      : items.val == 101 && items.name == '报警状态'
                         ? '较低风险'
                         : items.val == 102 && items.name == '报警状态'
-                        ? '低风险'
-                        : items.val == 103 && items.name == '报警状态'
-                        ? '中风险'
-                        : items.val == 104 && items.name == '报警状态'
-                        ? '高风险'
-                        : items.val == 201 && items.name == '报警状态'
-                        ? '报警'
-                        : items.val == 1001 && items.name == '报警状态'
-                        ? '网络断开'
-                        : items.val
-                    }}</span
-                  >
+                          ? '低风险'
+                          : items.val == 103 && items.name == '报警状态'
+                            ? '中风险'
+                            : items.val == 104 && items.name == '报警状态'
+                              ? '高风险'
+                              : items.val == 201 && items.name == '报警状态'
+                                ? '报警'
+                                : items.val == 1001 && items.name == '报警状态'
+                                  ? '网络断开'
+                                  : items.val
+                  }}</span>
                 </div>
               </div>
             </div>
@@ -73,21 +65,20 @@
             <div class="text-b">安全监控测点信息</div>
           </div>
           <div class="content-b">
-            <div class="card-b" v-for="(item, index) in cardListWs" :key="index">
-              <div class="item-l">
-                <div class="label-l">{{ item.label }}</div>
-                <div class="value-l">{{ `${item.value}%` }}</div>
-              </div>
-              <div class="item-r">
-                <div class="content-r" v-for="(items, ind) in item.listR" :key="ind">
-                  <span>{{ `${items.label} : ` }}</span>
-                  <span
-                    :class="{
+            <div class="content-b-item">
+              <div class="card-b" v-for="(item, index) in cardListWs" :key="index">
+                <div class="item-l">
+                  <div class="label-l">{{ item.label }}</div>
+                  <div class="value-l">{{ `${item.value}%` }}</div>
+                </div>
+                <div class="item-r">
+                  <div class="content-r" v-for="(items, ind) in item.listR" :key="ind">
+                    <span>{{ `${items.label} : ` }}</span>
+                    <span :class="{
                       'status-f': items.value == 1,
                       'status-l': items.value == 0,
-                    }"
-                    >{{ items.value == 1 ? '异常' : items.value == 0 ? '正常' : items.value }}</span
-                  >
+                    }">{{ items.value == 1 ? '异常' : items.value == 0 ? '正常' : items.value }}</span>
+                  </div>
                 </div>
               </div>
             </div>
@@ -105,420 +96,422 @@
 </template>
 
 <script setup lang="ts">
-  import { ref, reactive, onMounted, onUnmounted } from 'vue';
-  import { sysTypeWarnList, sysWarn } from '../common.api';
-  import { useSystemSelect } from '/@/hooks/vent/useSystemSelect';
-  import { useRouter } from 'vue-router';
-  import CustomHeader from '/@/components/vent/customHeader.vue';
-  import warnTargetGas from '../common/warnTargetGas.vue';
-  import gasParamter from '../common/gasParamter.vue';
-  import { typeMenuListGas } from '../common.data';
-  import { usePermission } from '/@/hooks/web/usePermission';
-
-  const { hasPermission } = usePermission();
-  const { options, optionValue, getSelectRow, getSysDataSource } = useSystemSelect('sys_surface_caimei'); // 参数为场景类型(设备类型管理中可以查询到)
-  //当前左侧激活菜单的索引
-  let activeIndex1 = ref(0);
-  //左侧数据列表
-  let menuList = reactive<any[]>([]);
-  //瓦斯顶部区域数据
-  let topAreaListWs = reactive<any[]>([]);
-  //瓦斯监控列表数据
-  let cardListWs = reactive<any[]>([]);
-  let router = useRouter();
-  //监测/指标激活索引
-  let activeIndex = ref(0);
-  let isShow = ref('yjjc');
-
-  // https获取监测数据
-  let timer: null | NodeJS.Timeout = null;
-  function getMonitor(deviceID, flag?) {
-    timer = setTimeout(
-      async () => {
-        await getSysWarnList(deviceID, 'gas');
-        if (timer) {
-          timer = null;
-        }
-        getMonitor(deviceID);
-      },
-      flag ? 0 : 1000
-    );
-  }
-
-  //返回首页
-  function getBack() {
-    router.push('/monitorChannel/monitor-alarm-home');
-  }
-
-  //获取预警详情弹窗右侧数据
-  function getSysWarnList(id, type) {
-    sysWarn({ sysid: id, type: type }).then((res) => {
-      // listData.common = res;
-      topAreaListWs.length = 0;
-      cardListWs.length = 0;
-      if (JSON.stringify(res) != '{}') {
-        res.pump.forEach((v) => {
-          topAreaListWs.push({
-            label: v.strinstallpos || '--',
-            list: [
-              // { name: '抽采泵流量', val: v.readData.FlowSensor_InputFlux || 0 },
-              { name: '报警状态', val: v.warnLevel || 0 },
-              { name: '输入管道内一氧化碳(ppm)', val: v.readData.coVal && v.readData.coVal != '0' ? v.readData.coVal : '-' },
-              { name: '管路出口处瓦斯(%CH4)', val: v.readData.gas1 && v.readData.gas1 != '0' ? v.readData.gas1 : '-' }, //v.readData.gas1
-              { name: '泵站内瓦斯(%CH4)', val: v.readData.gas2 && v.readData.gas2 != '0' ? v.readData.gas2 : '-' }, //v.readData.gas2
-              { name: '输入管道内瓦斯(%CH4)', val: v.readData.gas3 && v.readData.gas3 != '0' ? v.readData.gas3 : '-' }, //v.readData.gas3
-              { name: '管道输出瓦斯(%CH4)', val: v.readData.gas4 && v.readData.gas4 != '0' ? v.readData.gas4 : '-' }, //v.readData.gas4
-              { name: '输入管道内工混流量(m³/min)', val: v.readData.mixedTraffic && v.readData.mixedTraffic != '0' ? v.readData.mixedTraffic : '-' }, //v.readData.mixedTraffic
-              {
-                name: '输入管道内标况流量(m³/min)',
-                val: v.readData.standardTraffic && v.readData.standardTraffic != '0' ? v.readData.standardTraffic : '-',
-              }, //v.readData.standardTraffic
-              { name: '瓦斯抽放量(m³)', val: v.readData.totalGasDrainage && v.readData.totalGasDrainage != '0' ? v.readData.totalGasDrainage : '-' },
-            ],
-          });
-        });
-
-        res.gas.forEach((el) => {
-          el.strinstallpos = el.strinstallpos.indexOf('&') == -1 ? el.strinstallpos : el.strinstallpos.substring(0, el.strinstallpos.indexOf('&'));
-          cardListWs.push({
-            label: '甲烷',
-            value: el.readData.gasC || '--',
-            // value: 0,
-            listR: [
-              { id: 0, label: '测点类型', value: '瓦斯' },
-              { id: 1, label: '测点位置', value: el.strinstallpos || '--' },
-              // { id: 2, label: '数据时间', value: el.readData.datetime || '--' },
-              { id: 2, label: '数据时间', value: el.readTime || '--' },
-              { id: 3, label: '测点状态', value: el.warnFlag },
-            ],
-          });
-        });
+import { ref, reactive, onMounted, onUnmounted } from 'vue';
+import { sysTypeWarnList, sysWarn } from '../common.api';
+import { useSystemSelect } from '/@/hooks/vent/useSystemSelect';
+import { useRouter } from 'vue-router';
+import CustomHeader from '/@/components/vent/customHeader.vue';
+import warnTargetGas from '../common/warnTargetGas.vue';
+import gasParamter from '../common/gasParamter.vue';
+import { typeMenuListGas } from '../common.data';
+import { usePermission } from '/@/hooks/web/usePermission';
+
+const { hasPermission } = usePermission();
+const { options, optionValue, getSelectRow, getSysDataSource } = useSystemSelect('sys_surface_caimei'); // 参数为场景类型(设备类型管理中可以查询到)
+//当前左侧激活菜单的索引
+let activeIndex1 = ref(0);
+//左侧数据列表
+let menuList = reactive<any[]>([]);
+//瓦斯顶部区域数据
+let topAreaListWs = reactive<any[]>([]);
+//瓦斯监控列表数据
+let cardListWs = reactive<any[]>([]);
+let router = useRouter();
+//监测/指标激活索引
+let activeIndex = ref(0);
+let isShow = ref('yjjc');
+
+// https获取监测数据
+let timer: null | NodeJS.Timeout = null;
+function getMonitor(deviceID, flag?) {
+  timer = setTimeout(
+    async () => {
+      await getSysWarnList(deviceID, 'gas');
+      if (timer) {
+        timer = null;
       }
-    });
-  }
+      getMonitor(deviceID);
+    },
+    flag ? 0 : 1000
+  );
+}
+
+//返回首页
+function getBack() {
+  router.push('/monitorChannel/monitor-alarm-home');
+}
+
+//获取预警详情弹窗右侧数据
+function getSysWarnList(id, type) {
+  sysWarn({ sysid: id, type: type }).then((res) => {
+    // listData.common = res;
+    topAreaListWs.length = 0;
+    cardListWs.length = 0;
+    if (JSON.stringify(res) != '{}') {
+      res.pump.forEach((v) => {
+        topAreaListWs.push({
+          label: v.strinstallpos || '--',
+          list: [
+            // { name: '抽采泵流量', val: v.readData.FlowSensor_InputFlux || 0 },
+            { name: '报警状态', val: v.warnLevel || 0 },
+            { name: '输入管道内一氧化碳(ppm)', val: v.readData.coVal && v.readData.coVal != '0' ? v.readData.coVal : '-' },
+            { name: '管路出口处瓦斯(%CH4)', val: v.readData.gas1 && v.readData.gas1 != '0' ? v.readData.gas1 : '-' }, //v.readData.gas1
+            { name: '泵站内瓦斯(%CH4)', val: v.readData.gas2 && v.readData.gas2 != '0' ? v.readData.gas2 : '-' }, //v.readData.gas2
+            { name: '输入管道内瓦斯(%CH4)', val: v.readData.gas3 && v.readData.gas3 != '0' ? v.readData.gas3 : '-' }, //v.readData.gas3
+            { name: '管道输出瓦斯(%CH4)', val: v.readData.gas4 && v.readData.gas4 != '0' ? v.readData.gas4 : '-' }, //v.readData.gas4
+            { name: '输入管道内工混流量(m³/min)', val: v.readData.mixedTraffic && v.readData.mixedTraffic != '0' ? v.readData.mixedTraffic : '-' }, //v.readData.mixedTraffic
+            {
+              name: '输入管道内标况流量(m³/min)',
+              val: v.readData.standardTraffic && v.readData.standardTraffic != '0' ? v.readData.standardTraffic : '-',
+            }, //v.readData.standardTraffic
+            { name: '瓦斯抽放量(m³)', val: v.readData.totalGasDrainage && v.readData.totalGasDrainage != '0' ? v.readData.totalGasDrainage : '-' },
+          ],
+        });
+      });
 
-  //获取左侧菜单列表
-  async function getMenuList() {
-    let res = await sysTypeWarnList({ type: 'gas' });
-    if (res.length != 0) {
-      menuList.length = 0;
-      res.forEach((el) => {
-        menuList.push({
-          name: el.systemname,
-          warn: '低风险',
-          deviceID: el.id,
-          strtype: el.strtype,
+      res.gas.forEach((el) => {
+        el.strinstallpos = el.strinstallpos.indexOf('&') == -1 ? el.strinstallpos : el.strinstallpos.substring(0, el.strinstallpos.indexOf('&'));
+        cardListWs.push({
+          label: '甲烷',
+          value: el.readData.gasC || '--',
+          // value: 0,
+          listR: [
+            { id: 0, label: '测点类型', value: '瓦斯' },
+            { id: 1, label: '测点位置', value: el.strinstallpos || '--' },
+            // { id: 2, label: '数据时间', value: el.readData.datetime || '--' },
+            { id: 2, label: '数据时间', value: el.readTime || '--' },
+            { id: 3, label: '测点状态', value: el.warnFlag },
+          ],
         });
       });
-      getMonitor(menuList[0].deviceID, true);
     }
+  });
+}
+
+//获取左侧菜单列表
+async function getMenuList() {
+  let res = await sysTypeWarnList({ type: 'gas' });
+  if (res.length != 0) {
+    menuList.length = 0;
+    res.forEach((el) => {
+      menuList.push({
+        name: el.systemname,
+        warn: '低风险',
+        deviceID: el.id,
+        strtype: el.strtype,
+      });
+    });
+    getMonitor(menuList[0].deviceID, true);
   }
-
-  //监测/预警指标选项切换
-  function btnClick(ind) {
-    activeIndex.value = ind;
-    clearTimeout(timer);
-    switch (ind) {
-      case 0:
-        activeIndex1.value = 0;
-        isShow.value = 'yjjc';
-        break;
-      case 1:
-        activeIndex1.value = 0;
-        isShow.value = 'yjzb';
-        break;
-      case 2:
-        activeIndex1.value = 0;
-        isShow.value = 'wscs';
-        break;
-    }
+}
+
+//监测/预警指标选项切换
+function btnClick(ind) {
+  activeIndex.value = ind;
+  clearTimeout(timer);
+  switch (ind) {
+    case 0:
+      activeIndex1.value = 0;
+      isShow.value = 'yjjc';
+      break;
+    case 1:
+      activeIndex1.value = 0;
+      isShow.value = 'yjzb';
+      break;
+    case 2:
+      activeIndex1.value = 0;
+      isShow.value = 'wscs';
+      break;
   }
-
-  //菜单选项切换
-  function cardClick(ind, item) {
-    activeIndex1.value = ind;
+}
+
+//菜单选项切换
+function cardClick(ind, item) {
+  activeIndex1.value = ind;
+  clearTimeout(timer);
+  getMonitor(item.deviceID, true);
+}
+
+onMounted(() => {
+  getMenuList();
+});
+onUnmounted(() => {
+  if (timer) {
     clearTimeout(timer);
-    getMonitor(item.deviceID, true);
+    timer = undefined;
   }
-
-  onMounted(() => {
-    getMenuList();
-  });
-  onUnmounted(() => {
-    if (timer) {
-      clearTimeout(timer);
-      timer = undefined;
-    }
-  });
+});
 </script>
 
 <style lang="less" scoped>
-  .gasWarn {
-    width: 100%;
+.gasWarn {
+  width: 100%;
+  height: 100%;
+  padding: 80px 10px 15px 10px;
+  box-sizing: border-box;
+  display: flex;
+  justify-content: space-between;
+
+  .alarm-menu {
     height: 100%;
-    padding: 80px 10px 15px 10px;
-    box-sizing: border-box;
-    display: flex;
-    justify-content: space-between;
+    width: 15%;
+
+    .type-btn {
+      width: 100%;
+      height: 28px;
+      line-height: 28px;
+      border: 1px solid #0058ee;
+      margin-bottom: 20px;
+      border-radius: 5px;
+      box-sizing: border-box;
+      display: flex;
+      justify-content: space-between;
 
-    .alarm-menu {
-      height: 100%;
-      width: 15%;
+      .btn {
+        width: 33.33%;
+        height: 100%;
+        font-size: 14px;
+        text-align: center;
+        color: #fff;
+        cursor: pointer;
+      }
 
-      .type-btn {
-        width: 100%;
-        height: 28px;
-        line-height: 28px;
-        border: 1px solid #0058ee;
-        margin-bottom: 20px;
-        border-radius: 5px;
-        box-sizing: border-box;
-        display: flex;
-        justify-content: space-between;
+      .btn1 {
+        width: 33.33%;
+        height: 100%;
+        font-size: 14px;
+        color: #fff;
+        text-align: center;
+        border-radius: 2px;
+        background: #0058ee;
+        cursor: pointer;
+      }
+    }
 
-        .btn {
-          width: 33.33%;
-          height: 100%;
-          font-size: 14px;
+    .card-btn {
+      width: 100%;
+      height: calc(100% - 48px);
+      overflow-y: auto;
+
+      .btn {
+        position: relative;
+        width: 81%;
+        height: 14%;
+        margin-bottom: 10%;
+        font-family: 'douyuFont';
+        background: url('../../../../../assets/images/fire/no-choice.png') no-repeat;
+        background-size: 100% 100%;
+        cursor: pointer;
+
+        .text {
+          width: 80%;
+          position: absolute;
+          left: 50%;
+          top: 28px;
+          font-size: 16px;
+          color: #01fefc;
           text-align: center;
-          color: #fff;
-          cursor: pointer;
+          transform: translate(-50%, 0);
         }
 
-        .btn1 {
-          width: 33.33%;
-          height: 100%;
+        .warn {
+          width: 100%;
+          position: absolute;
+          left: 50%;
+          bottom: 14px;
           font-size: 14px;
           color: #fff;
           text-align: center;
-          border-radius: 2px;
-          background: #0058ee;
-          cursor: pointer;
+          transform: translate(-50%, 0);
         }
       }
 
-      .card-btn {
+      .btn1 {
+        position: relative;
         width: 100%;
-        height: calc(100% - 48px);
-        overflow-y: auto;
-
-        .btn {
-          position: relative;
-          width: 81%;
-          height: 14%;
-          margin-bottom: 10%;
-          font-family: 'douyuFont';
-          background: url('../../../../../assets/images/fire/no-choice.png') no-repeat;
-          background-size: 100% 100%;
-          cursor: pointer;
-
-          .text {
-            width: 80%;
-            position: absolute;
-            left: 50%;
-            top: 28px;
-            font-size: 16px;
-            color: #01fefc;
-            text-align: center;
-            transform: translate(-50%, 0);
-          }
-
-          .warn {
-            width: 100%;
-            position: absolute;
-            left: 50%;
-            bottom: 14px;
-            font-size: 14px;
-            color: #fff;
-            text-align: center;
-            transform: translate(-50%, 0);
-          }
+        height: 14%;
+        margin-bottom: 10%;
+        font-family: 'douyuFont';
+        background: url('../../../../../assets/images/fire/choice.png') no-repeat;
+        background-size: 100% 100%;
+        cursor: pointer;
+
+        .text {
+          width: 80%;
+          position: absolute;
+          left: 50%;
+          top: 28px;
+          font-size: 16px;
+          color: #01fefc;
+          text-align: center;
+          transform: translate(-62%, 0);
         }
 
-        .btn1 {
-          position: relative;
+        .warn {
           width: 100%;
-          height: 14%;
-          margin-bottom: 10%;
-          font-family: 'douyuFont';
-          background: url('../../../../../assets/images/fire/choice.png') no-repeat;
-          background-size: 100% 100%;
-          cursor: pointer;
-
-          .text {
-            width: 80%;
-            position: absolute;
-            left: 50%;
-            top: 28px;
-            font-size: 16px;
-            color: #01fefc;
-            text-align: center;
-            transform: translate(-62%, 0);
-          }
-
-          .warn {
-            width: 100%;
-            position: absolute;
-            left: 50%;
-            bottom: 14px;
-            font-size: 14px;
-            color: #fff;
-            text-align: center;
-            transform: translate(-60%, 0);
-          }
+          position: absolute;
+          left: 50%;
+          bottom: 14px;
+          font-size: 14px;
+          color: #fff;
+          text-align: center;
+          transform: translate(-60%, 0);
         }
       }
     }
+  }
 
-    .gas-content {
-      position: relative;
-      width: calc(85% - 10px);
-      height: 100%;
-      margin-left: 10px;
-      padding: 15px;
-      background: url('../../../../../assets/images/fire/border.png') no-repeat;
+  .gas-content {
+    position: relative;
+    width: calc(85% - 10px);
+    height: 100%;
+    margin-left: 10px;
+    padding: 15px;
+    background: url('../../../../../assets/images/fire/border.png') no-repeat;
+    background-size: 100% 100%;
+    box-sizing: border-box;
+
+    .top-area {
+      height: 356px;
+      margin-bottom: 10px;
+      padding: 10px;
+      background: url('../../../../../assets/images/fire/bj1.png') no-repeat center;
       background-size: 100% 100%;
       box-sizing: border-box;
 
-      .top-area {
-        height: 356px;
+      .title-t {
+        height: 30px;
         margin-bottom: 10px;
-        padding: 10px;
-        background: url('../../../../../assets/images/fire/bj1.png') no-repeat center;
-        background-size: 100% 100%;
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+
+        .text-t {
+          font-family: 'douyuFont';
+          font-size: 14px;
+          color: #fff;
+        }
+      }
+
+      .content-t {
+        width: 100%;
+        height: 276px;
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        padding: 0px 10px;
         box-sizing: border-box;
 
-        .title-t {
-          height: 30px;
-          margin-bottom: 10px;
-          display: flex;
-          justify-content: space-between;
-          align-items: center;
+        .top-box {
+          position: relative;
+          width: 724px;
+          height: 100%;
+          background: url('../../../../../assets/images/fire/top-area.png') no-repeat center;
+          background-size: 100% 100%;
 
-          .text-t {
+          .box-label {
+            position: absolute;
+            left: 50%;
+            top: 198px;
+            transform: translate(-50%, 0);
+            width: 80%;
             font-family: 'douyuFont';
-            font-size: 14px;
+            font-size: 16px;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            word-wrap: break-word;
             color: #fff;
           }
-        }
-
-        .content-t {
-          width: 100%;
-          height: 276px;
-          display: flex;
-          justify-content: space-between;
-          align-items: center;
-          padding: 0px 10px;
-          box-sizing: border-box;
-
-          .top-box {
-            position: relative;
-            width: 724px;
-            height: 100%;
-            background: url('../../../../../assets/images/fire/top-area.png') no-repeat center;
-            background-size: 100% 100%;
-
-            .box-label {
-              position: absolute;
-              left: 50%;
-              top: 198px;
-              transform: translate(-50%, 0);
-              width: 80%;
-              font-family: 'douyuFont';
-              font-size: 16px;
-              display: flex;
-              justify-content: center;
-              align-items: center;
-              word-wrap: break-word;
-              color: #fff;
-            }
 
-            .box-values {
-              position: absolute;
-              left: 50%;
-              top: 26px;
-              transform: translate(-50%, 0);
-              width: 84%;
+          .box-values {
+            position: absolute;
+            left: 50%;
+            top: 26px;
+            transform: translate(-50%, 0);
+            width: 84%;
+            display: flex;
+            justify-content: space-between;
+            align-items: center;
+            flex-wrap: wrap;
+
+            .value-b {
+              width: calc(50% - 10px);
+              height: 25px;
               display: flex;
               justify-content: space-between;
               align-items: center;
-              flex-wrap: wrap;
+              color: #fff;
+              font-size: 14px;
 
-              .value-b {
-                width: calc(50% - 10px);
-                height: 25px;
-                display: flex;
-                justify-content: space-between;
-                align-items: center;
-                color: #fff;
+              span {
                 font-size: 14px;
 
-                span {
-                  font-size: 14px;
-
-                  &:last-child {
-                    font-family: 'douyuFont';
-                    color: rgb(0, 242, 255);
-                  }
+                &:last-child {
+                  font-family: 'douyuFont';
+                  color: rgb(0, 242, 255);
                 }
+              }
 
-                .box-value {
-                  color: rgb(145, 230, 9) !important;
-                }
+              .box-value {
+                color: rgb(145, 230, 9) !important;
+              }
 
-                .box-value1 {
-                  color: rgb(0, 242, 255) !important;
-                }
+              .box-value1 {
+                color: rgb(0, 242, 255) !important;
+              }
 
-                .box-value2 {
-                  color: #ffff35 !important;
-                }
+              .box-value2 {
+                color: #ffff35 !important;
+              }
 
-                .box-value3 {
-                  color: #ffbe69 !important;
-                }
+              .box-value3 {
+                color: #ffbe69 !important;
+              }
 
-                .box-value4 {
-                  color: #ff6f00 !important;
-                }
+              .box-value4 {
+                color: #ff6f00 !important;
+              }
 
-                .box-value5 {
-                  color: #ff0000 !important;
-                }
+              .box-value5 {
+                color: #ff0000 !important;
               }
             }
           }
         }
       }
+    }
 
-      .bot-area {
-        height: calc(100% - 356px);
-        padding: 10px;
-        background: url('../../../../../assets/images/fire/bj1.png') no-repeat center;
-        background-size: 100% 100%;
-        box-sizing: border-box;
+    .bot-area {
+      height: calc(100% - 356px);
+      padding: 10px;
+      background: url('../../../../../assets/images/fire/bj1.png') no-repeat center;
+      background-size: 100% 100%;
+      box-sizing: border-box;
 
-        .title-b {
-          height: 30px;
-          margin-bottom: 10px;
-          display: flex;
-          justify-content: space-between;
-          align-items: center;
+      .title-b {
+        height: 30px;
+        margin-bottom: 10px;
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
 
-          .text-b {
-            font-family: 'douyuFont';
-            font-size: 14px;
-            color: #fff;
-          }
+        .text-b {
+          font-family: 'douyuFont';
+          font-size: 14px;
+          color: #fff;
         }
+      }
+
+      .content-b {
+        height: calc(100% - 40px);
+        overflow-y: auto;
 
-        .content-b {
-          height: calc(100% - 40px);
+        .content-b-item {
           display: flex;
           justify-content: flex-start;
           align-items: flex-start;
           flex-wrap: wrap;
-          overflow-y: auto;
 
           .card-b {
             position: relative;
@@ -599,36 +592,39 @@
           }
         }
       }
+    }
 
-      .bot-area1 {
-        height: 100%;
-        padding: 10px 15px 0px 15px;
-        background: url('../../../../../assets/images/fire/bj1.png') no-repeat center;
-        background-size: 100% 100%;
-        box-sizing: border-box;
+    .bot-area1 {
+      height: 100%;
+      padding: 10px 15px 0px 15px;
+      background: url('../../../../../assets/images/fire/bj1.png') no-repeat center;
+      background-size: 100% 100%;
+      box-sizing: border-box;
 
-        .title-b {
-          height: 30px;
-          margin-bottom: 10px;
-          display: flex;
-          justify-content: space-between;
-          align-items: center;
+      .title-b {
+        height: 30px;
+        margin-bottom: 10px;
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
 
-          .text-b {
-            font-family: 'douyuFont';
-            font-size: 14px;
-            color: #fff;
-          }
+        .text-b {
+          font-family: 'douyuFont';
+          font-size: 14px;
+          color: #fff;
         }
+      }
 
-        .content-b {
-          width: 100%;
-          height: calc(100% - 40px);
+      .content-b {
+        width: 100%;
+        height: calc(100% - 40px);
+        overflow-y: auto;
+
+        .content-b-item {
           display: flex;
           justify-content: flex-start;
           align-items: flex-start;
           flex-wrap: wrap;
-          overflow-y: auto;
 
           .card-b {
             position: relative;
@@ -711,4 +707,5 @@
       }
     }
   }
+}
 </style>