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

Merge branch 'master' of http://182.92.126.35:3000/hrx/mky-vent-base

lxh пре 10 месеци
родитељ
комит
23108bc539

+ 1 - 0
src/enums/cacheEnum.ts

@@ -1,3 +1,4 @@
+export const PWD_KEY = 'PWD__';
 // token key
 export const TOKEN_KEY = 'TOKEN__';
 

+ 42 - 0
src/hooks/vent/useSSO.ts

@@ -0,0 +1,42 @@
+// 本来应该是后端做,出于工期考虑转到前端
+
+import QueryString from 'qs';
+import { useUserStore } from '/@/store/modules/user';
+import { useRoute } from 'vue-router';
+
+/** 单点登录功能的Hook,该Hook是为了部署在同一局域网内的多套系统之间能够无缝切换 */
+export function useSSO() {
+  const userStore = useUserStore();
+  const route = useRoute();
+
+  /** 启用单点登录功能来跳转新的页面 */
+  function open(url: string, target?: string) {
+    const qs = QueryString.stringify({
+      username: userStore.userInfo?.username,
+      // 毫无意义的伪装,但我就是要装一下
+      id: userStore.getPassword,
+    });
+    window.open(`${url}?${qs}`, target);
+  }
+
+  /** 用在跳转到的页面上,执行单点登录的逻辑 */
+  function doSSO() {
+    if (!route.query) return;
+    const { username, id } = route.query;
+    if (!username || !id) return;
+    const realPassword = userStore.decryptPassword(id as string);
+    const params = {
+      username: username as string,
+      password: realPassword,
+      checkKey: new Date().getTime(),
+    };
+    userStore.login(params);
+  }
+
+  return {
+    /** 启用单点登录功能来跳转新的页面,参数与window.open一致,但需要注意url需要指向登录页 */
+    open,
+    /** 用在跳转到的页面上,执行单点登录的逻辑 */
+    doSSO,
+  };
+}

+ 31 - 6
src/store/modules/user.ts

@@ -4,7 +4,16 @@ import { defineStore } from 'pinia';
 import { store } from '/@/store';
 import { RoleEnum } from '/@/enums/roleEnum';
 import { PageEnum } from '/@/enums/pageEnum';
-import { ROLES_KEY, TOKEN_KEY, USER_INFO_KEY, LOGIN_INFO_KEY, DB_DICT_DATA_KEY, TENANT_ID, OAUTH2_THIRD_LOGIN_TENANT_ID } from '/@/enums/cacheEnum';
+import {
+  ROLES_KEY,
+  TOKEN_KEY,
+  USER_INFO_KEY,
+  LOGIN_INFO_KEY,
+  DB_DICT_DATA_KEY,
+  TENANT_ID,
+  OAUTH2_THIRD_LOGIN_TENANT_ID,
+  PWD_KEY,
+} from '/@/enums/cacheEnum';
 import { getAuthCache, setAuthCache, removeAuthCache } from '/@/utils/auth';
 import { GetUserInfoModel, LoginParams, ThirdLoginParams } from '/@/api/sys/model/userModel';
 import { doLogout, getUserInfo, loginApi, phoneLoginApi, thirdLogin } from '/@/api/sys/user';
@@ -20,6 +29,7 @@ import { JDragConfigEnum } from '/@/enums/jeecgEnum';
 import { useSso } from '/@/hooks/web/useSso';
 import { getActions } from '/@/qiankun/state';
 import { useGlobSetting } from '/@/hooks/setting';
+import AES from 'crypto-js/aes';
 
 interface UserState {
   userInfo: Nullable<UserInfo>;
@@ -85,8 +95,17 @@ export const useUserStore = defineStore({
     hasShareTenantId(): boolean {
       return this.shareTenantId != null && this.shareTenantId !== '';
     },
+    /** 获取用户加密过的密码 */
+    getPassword() {
+      return getAuthCache<string>(PWD_KEY);
+    },
   },
   actions: {
+    /** 设置用户密码并加密,理论上加密、解密的工作应仅在此模块进行 */
+    setPassword(password: string) {
+      // setAuthCache(PWD_KEY, AES.encrypt(password, PWD_KEY));
+      setAuthCache(PWD_KEY, btoa(password));
+    },
     setToken(info: string | undefined) {
       this.token = info ? info : ''; // for null or undefined value
       setAuthCache(TOKEN_KEY, info);
@@ -141,6 +160,8 @@ export const useUserStore = defineStore({
         // save token
         this.setToken(token);
         this.setTenant(userInfo.loginTenantId);
+        this.setPassword(params.password);
+        // 将用户的用户名与密码存于数据库之中,这是为了
         return this.afterLoginAction(goHome, data);
       } catch (error) {
         return Promise.reject(error);
@@ -362,15 +383,19 @@ export const useUserStore = defineStore({
           password: 'autoAdmin123',
           checkKey: new Date().getTime(),
         };
-        const data = await loginApi(loginParams);
-        const { token } = data;
-        this.setToken(token);
-        const userInfo = data['userInfo'];
-        this.setUserInfo(userInfo);
+        this.login(loginParams);
       } catch (error) {
         return Promise.reject(error);
       }
     },
+    /** 解密用户密码,理论上加密、解密的工作应仅在此模块进行 */
+    decryptPassword(password: string) {
+      // const test1 = AES.encrypt('123123', '321');
+      // const test2 = AES.decrypt(test1, '321');
+      // console.log('debug', AES.decrypt(password, PWD_KEY));
+      return atob(password);
+      // return AES.decrypt(password, PWD_KEY).toString();
+    },
   },
 });
 

+ 0 - 1
src/utils/cache/memory.ts

@@ -96,7 +96,6 @@ export class Memory<T = any, V = any> {
   }
 
   clear() {
-    console.log('------clear------进入clear方法');
     Object.keys(this.cache).forEach((key) => {
       const item = this.cache[key];
       item.timeoutId && clearTimeout(item.timeoutId);

+ 4 - 2
src/utils/cache/persistent.ts

@@ -17,12 +17,14 @@ import {
   TENANT_ID,
   LOGIN_INFO_KEY,
   OAUTH2_THIRD_LOGIN_TENANT_ID,
+  PWD_KEY,
 } from '/@/enums/cacheEnum';
 import { DEFAULT_CACHE_TIME } from '/@/settings/encryptionSetting';
 import { toRaw } from 'vue';
 import { pick, omit } from 'lodash-es';
 
 interface BasicStore {
+  [PWD_KEY]: string | undefined;
   [TOKEN_KEY]: string | number | null | undefined;
   [USER_INFO_KEY]: UserInfo;
   [ROLES_KEY]: string[];
@@ -32,7 +34,7 @@ interface BasicStore {
   [DB_DICT_DATA_KEY]: string;
   [TENANT_ID]: string;
   [LOGIN_INFO_KEY]: LoginInfo;
-  [OAUTH2_THIRD_LOGIN_TENANT_ID]: string
+  [OAUTH2_THIRD_LOGIN_TENANT_ID]: string;
 }
 
 type LocalStore = BasicStore;
@@ -60,7 +62,7 @@ export class Persistent {
   static getLocal<T>(key: LocalKeys) {
     //update-begin---author:scott ---date:2022-10-27  for:token过期退出重新登录,online菜单还是提示token过期----------
     const globalCache = ls.get(APP_LOCAL_CACHE_KEY);
-    if(globalCache){
+    if (globalCache) {
       localMemory.setCache(globalCache);
     }
     //update-end---author:scott ---date::2022-10-27  for:token过期退出重新登录,online菜单还是提示token过期----------

+ 11 - 2
src/views/sys/login/Login.vue

@@ -19,7 +19,7 @@
   <!-- </AdaptiveContainer> -->
 </template>
 <script lang="ts" setup>
-  import { computed, ref } from 'vue';
+  import { computed, onMounted } from 'vue';
   import { AppLogo } from '/@/components/Application';
   import LoginForm from './LoginForm.vue';
   import { useGlobSetting } from '/@/hooks/setting';
@@ -29,6 +29,7 @@
   import { useLoginState } from './useLogin';
 
   import AdaptiveContainer from '/@/components/Container/src/Adaptive.vue';
+  import { useSSO } from '/@/hooks/vent/useSSO';
 
   defineProps({
     sessionTimeout: {
@@ -43,6 +44,12 @@
   const title = computed(() => globSetting?.title ?? '');
   const { handleBackLogin } = useLoginState();
   handleBackLogin();
+
+  const { doSSO } = useSSO();
+
+  onMounted(() => {
+    doSSO();
+  });
 </script>
 <style lang="less" scoped>
   @prefix-cls: ~'@{namespace}-login';
@@ -136,7 +143,9 @@
         color: rgb(224, 224, 224);
         font-size: 30px;
         text-align: center;
-        text-shadow: 1px 1px 1px #fff, -1px -1px 1px #000;
+        text-shadow:
+          1px 1px 1px #fff,
+          -1px -1px 1px #000;
       }
     }
 

+ 3 - 108
src/views/vent/home/billboard/billboard.api.ts

@@ -1,126 +1,21 @@
-import { queryDepartTreeSync } from '/@/api/common/api';
+import { BillboardType } from './billboard.data';
 import { useUserStore } from '/@/store/modules/user';
 import { defHttp } from '/@/utils/http/axios';
 
 const store = useUserStore();
 
 enum Api {
-  getSummary = '/ventanaly-device/monitor/groupCompany/getEachMineInfo',
+  getSummary = '/ventanaly-company/company/index/getEachMinePlateInfo',
 }
 
 /**
  * 获取看板的详细数据
  * @param params
  */
-export const getSummary = () =>
+export const getSummary: () => Promise<BillboardType[]> = () =>
   defHttp.post({
     url: Api.getSummary,
     params: {
       userName: store.userInfo?.username,
     },
   });
-
-// Promise.resolve({
-//   dustInfo: {
-//     //矿井粉尘风险信息
-//     totalNum: 8,
-//     dustTypeList: [
-//       {
-//         deviceType: 'dusting_auto', //设备类型编码
-//         warnLevel: 0, //状态(0或者101:低风险、102:一般风险、103:较大风险、104:重大风险、201:报警、1001:网络断开)
-//         num: 8, //监测数量
-//         typeName: '粉尘传感器', //设备类型名称
-//       },
-//     ],
-//     dustWarnLevel: 0, //矿井粉尘风险性等级
-//   },
-//   fileServerInfo: {
-//     //文件共享中心
-//     totalNum: 29, //文档总数
-//     approvalNum: 0, //待审批文档
-//   },
-//   fireInfo: {
-//     //矿井火灾风险数据
-//     tempMax: 0, //矿井温度传感器最高温度
-//     fireWarnLevel: 0, //矿井火灾风险等级
-//     coSensorInfo: 0, //矿井CO传感器报警等级
-//     bundletubeInfo: 0, //矿井束管监测报警等级
-//     smokeSensorInfo: 0, //矿井烟雾传感器报警等级
-//     fiberInfo: 0, //矿井光纤测温系统报警等级
-//     tempSensorInfo: 0, //矿井温度传感器报警等级
-//   },
-//   gasInfo: {
-//     //瓦斯风险信息
-//     gasWarnLevel: 0, //瓦斯风险等级
-//     gasTypeList: [
-//       {
-//         warnLevel: 0, //当前状态
-//         num: 2, //监测数量
-//         typeName: '瓦斯抽采泵站', //设备类型名称
-//       },
-//       {
-//         warnLevel: 0,
-//         num: 1,
-//         typeName: '瓦斯巡检',
-//       },
-//       {
-//         warnLevel: 0,
-//         num: 2,
-//         typeName: '瓦斯巡检',
-//       },
-//     ],
-//   },
-//   ventInfo: {
-//     //通风系统信息
-//     totallength: 1562.35, //矿井巷道总长度
-//     zonghuifeng: '25881.74', //总回风
-//     fanMainList: [
-//       {
-//         sqzlfb: '31.0%-29.0%-40.0%', //三区阻力分布
-//         strname: '2号回风立井', //风机名称
-//         strinstallpos: '2号回风立井', //安装位置
-//         Fan1m3: '12465.84', //1号风机风量
-//         Fan2m3: '12493.72', //2号风机风量
-//         FanFreqHz: '225', //风机频率
-//       },
-//       {
-//         sqzlfb: '42.0%-37.0%-21.0%',
-//         strname: '1号回风斜井',
-//         strinstallpos: '1号回风斜井',
-//         Fan1m3: '13419.83',
-//         Fan2m3: '13415.9',
-//         FanFreqHz: '225',
-//       },
-//     ],
-//     xufengliang: 15065, //总需风量
-//     zongjinfeng: '24987.25', //总进风
-//   },
-// });
-
-/**
- * 获取矿区列表
- * @param params
- */
-export const getList = () => {
-  return queryDepartTreeSync().then((r) => {
-    return r.map((e) => ({
-      title: e.title,
-      address: `${e.ip}:${e.port}`,
-    }));
-  });
-};
-// Promise.resolve([
-//   { title: '布尔台', address: 'http://10.246.95.4:8092/micro-vent-3dModal/dashboard/analysis' },
-//   { title: '上湾', address: 'http://10.246.167.205:8092/micro-vent-3dModal/dashboard/analysis' },
-//   { title: '大柳塔', address: 'http://10.248.135.10:8092/micro-vent-3dModal/dashboard/analysis' },
-//   { title: '活鸡兔', address: 'http://10.248.135.121:8092/micro-vent-3dModal/dashboard/analysis' },
-//   { title: '锦界', address: 'http://10.248.151.42:8092/micro-vent-3dModal/dashboard/analysis' },
-//   { title: '哈拉沟', address: 'http://10.248.223.12:8092/micro-vent-3dModal/dashboard/analysis' },
-//   { title: '石圪台', address: 'http://10.246.191.13:8092/micro-vent-3dModal/dashboard/analysis' },
-//   { title: '柳塔', address: 'http://10.246.87.121:8092/micro-vent-3dModal/dashboard/analysis' },
-//   { title: '补连塔', address: 'http://10.246.175.16:8092/micro-vent-3dModal/dashboard/analysis' },
-//   { title: '寸草塔矿', address: 'http://10.246.23.171:8092/micro-vent-3dModal/dashboard/analysis' },
-//   { title: '寸草塔二矿', address: 'http://10.246.63.5:8092/micro-vent-3dModal/dashboard/analysis' },
-//   { title: '乌兰木伦', address: 'http://10.246.183.35:8092/micro-vent-3dModal/dashboard/analysis' },
-//   { title: '榆家梁', address: 'http://10.248.143.211:8092/micro-vent-3dModal/dashboard/analysis' },
-// ]);

+ 63 - 2
src/views/vent/home/billboard/billboard.data.ts

@@ -5,6 +5,7 @@ import VentilationStatus from './components/VentilationStatus.vue';
 import GasStatus from './components/GasStatus.vue';
 import leftImg from '/@/assets/images/files/homes/file.svg';
 import rightImg from '/@/assets/images/files/homes/sp.svg';
+import type { Component } from 'vue';
 
 // 基础的表格列配置,针对普通设备
 export const GAS_STATUS_COLUMN = [
@@ -18,7 +19,7 @@ export const GAS_STATUS_COLUMN = [
   },
   {
     name: '当前状态',
-    prop: 'warnLevel',
+    prop: 'warnLevelStr',
   },
 ];
 
@@ -151,10 +152,70 @@ export const GAS_STATUS_HEADER_CONFIG = [
 ];
 
 // 各个监测类型对应的要展示的组件
-export const COMPONENTS_MAP = new Map([
+export const COMPONENTS_MAP = new Map<string, Component>([
   ['dust', DustStatus],
   ['fire', FireStatus],
   ['file', FileOverview],
   ['ventilate', VentilationStatus],
   ['gas', GasStatus],
 ]);
+
+export const DEFAULT_TEST_DATA = {
+  dustInfo: {
+    // 矿井粉尘风险信息
+    totalNum: 0,
+    dustTypeList: [
+      {
+        deviceType: '/',
+        warnLevel: 0,
+        num: 0,
+        typeName: '/',
+      },
+    ],
+    dustWarnLevel: 0, // 矿井粉尘风险性等级
+  },
+  fileServerInfo: {
+    totalNum: 0, // 文档总数
+    approvalNum: 0, // 待审批文档
+  },
+  fireInfo: {
+    tempMax: 0, // 矿井温度传感器最高温度
+    fireWarnLevel: 0, // 矿井火灾风险等级
+    coSensorInfo: 0, // 矿井CO传感器报警等级
+    bundletubeInfo: 0, // 矿井束管监测报警等级
+    smokeSensorInfo: 0, // 矿井烟雾传感器报警等级
+    fiberInfo: 0, // 矿井光纤测温系统报警等级
+    tempSensorInfo: 0, // 矿井温度传感器报警等级
+  },
+  gasInfo: {
+    gasWarnLevel: 0, // 瓦斯风险等级
+    gasTypeList: [
+      {
+        warnLevel: 0,
+        num: 0,
+        typeName: '/',
+      },
+    ],
+  },
+  ventInfo: {
+    //通风系统信息
+    totallength: 0, //矿井巷道总长度
+    zonghuifeng: '0', //总回风
+    fanMainList: [
+      {
+        sqzlfb: '/',
+        strname: '/',
+        strinstallpos: '/',
+        Fan1m3: '/',
+        Fan2m3: '/',
+      },
+    ],
+    xufengliang: 0, //总需风量
+    zongjinfeng: '/', //总进风
+  },
+  orgname: '/',
+  orgcode: '/',
+  ip: 'localhost',
+};
+
+export type BillboardType = typeof DEFAULT_TEST_DATA;

+ 5 - 3
src/views/vent/home/billboard/components/BaseCard.vue

@@ -1,7 +1,7 @@
 <!-- eslint-disable vue/multi-word-component-names -->
 <template>
   <div class="card" :style="{ height: `${height}px` }">
-    <p class="card_title" @click="alert">
+    <p class="card_title" @click="clickHandler">
       <slot name="title">{{ title }}</slot>
     </p>
     <div class="card_content" :style="{ height: `${contentHeight}px` }">
@@ -26,8 +26,10 @@
     }
   );
 
-  function alert() {
-    window.alert('123');
+  const emit = defineEmits(['open']);
+
+  function clickHandler() {
+    emit('open');
   }
 </script>
 <style lang="less" scoped>

+ 18 - 11
src/views/vent/home/billboard/components/DustStatus.vue

@@ -1,20 +1,28 @@
 <!-- eslint-disable vue/multi-word-component-names -->
 <template>
   <CommonTitle class="mb-10px" label="矿井粉尘风险性等级" :value="risk" />
-  <CommonTable :columns="DUST_STATUS_COLUMN" :data="data" />
+  <CommonTable :columns="DUST_STATUS_COLUMN" :data="tableData" />
 </template>
 <script lang="ts" setup>
   import CommonTable from './CommonTable.vue';
   import CommonTitle from './CommonTitle.vue';
-  import { DUST_STATUS_COLUMN } from '../billboard.data';
+  import { BillboardType, DEFAULT_TEST_DATA, DUST_STATUS_COLUMN } from '../billboard.data';
   import { onMounted, ref, shallowRef } from 'vue';
-  import { getSummary } from '../billboard.api';
   // import mapComponent from './3Dmap/index.vue';
 
+  const props = withDefaults(
+    defineProps<{
+      data?: BillboardType;
+    }>(),
+    {
+      data: () => DEFAULT_TEST_DATA,
+    }
+  );
   const risk = ref('低风险');
-  const data = shallowRef<any[]>([]);
+  const tableData = shallowRef<any[]>([]);
 
   function fetchData() {
+    const info = props.data.dustInfo;
     const trans = {
       0: '低风险',
       101: '低风险',
@@ -24,13 +32,12 @@
       201: '报警',
       1001: '网络断开',
     };
-    getSummary().then((r) => {
-      data.value = r.dustInfo.dustTypeList.map((e) => {
-        return {
-          ...e,
-          warnLevelStr: trans[e.warnLevel],
-        };
-      });
+    risk.value = trans[info.dustWarnLevel];
+    tableData.value = info.dustTypeList.map((e) => {
+      return {
+        ...e,
+        warnLevelStr: trans[e.warnLevel],
+      };
     });
   }
 

+ 17 - 11
src/views/vent/home/billboard/components/FileOverview.vue

@@ -1,32 +1,38 @@
 <template>
   <div class="card-b">
-    <div class="box" v-for="item in tabs" :key="item.id" @click="$emit('click', item)">
+    <div class="box" v-for="item in FILE_OVERVIEW_CONFIG" :key="item.id" @click="$emit('click', item)">
       <div class="img"> <img :src="item.src" alt="" /> </div>
       <div class="text">{{ item.text }}</div>
-      <div class="num">{{ data[item.prop] }}</div>
+      <div class="num">{{ fileData[item.prop] }}</div>
     </div>
   </div>
 </template>
 <script lang="ts" setup>
-  import { onMounted, ref, shallowRef } from 'vue';
-  import { FILE_OVERVIEW_CONFIG } from '../billboard.data';
-  import { getSummary } from '../billboard.api';
+  import { onMounted, shallowRef } from 'vue';
+  import { BillboardType, DEFAULT_TEST_DATA, FILE_OVERVIEW_CONFIG } from '../billboard.data';
 
+  const props = withDefaults(
+    defineProps<{
+      data?: BillboardType;
+    }>(),
+    {
+      data: () => DEFAULT_TEST_DATA,
+    }
+  );
   defineEmits(['click']);
 
-  const data = shallowRef<any>({});
+  const fileData = shallowRef<BillboardType['fileServerInfo']>({
+    totalNum: 0,
+    approvalNum: 0,
+  });
 
   function fetchData() {
-    getSummary().then((r) => {
-      data.value = r.fileServerInfo;
-    });
+    fileData.value = props.data.fileServerInfo;
   }
 
   onMounted(() => {
     fetchData();
   });
-
-  let tabs = ref(FILE_OVERVIEW_CONFIG);
 </script>
 
 <style lang="less" scoped>

+ 24 - 7
src/views/vent/home/billboard/components/FireStatus.vue

@@ -6,7 +6,7 @@
     :key="item.icon"
     :icon="item.icon"
     :label="item.label"
-    :value="data[item.prop]"
+    :value="listData[item.prop]"
     :type="i % 2 ? 'green' : 'blue'"
     class="mt-5px"
   />
@@ -15,17 +15,34 @@
   import { onMounted, ref, shallowRef } from 'vue';
   import CommonTitle from './CommonTitle.vue';
   import ListItem from './ListItem.vue';
-  import { FIRE_STATUS_LIST } from '../billboard.data';
-  import { getSummary } from '../billboard.api';
+  import { BillboardType, DEFAULT_TEST_DATA, FIRE_STATUS_LIST } from '../billboard.data';
+
+  const props = withDefaults(
+    defineProps<{
+      data?: BillboardType;
+    }>(),
+    {
+      data: () => DEFAULT_TEST_DATA,
+    }
+  );
 
   const risk = ref('低风险');
 
-  const data = shallowRef<any>({});
+  const listData = shallowRef<any>({});
 
   function fetchData() {
-    getSummary().then((r) => {
-      data.value = r.fireInfo;
-    });
+    const info = props.data.fireInfo;
+    const trans = {
+      0: '低风险',
+      101: '低风险',
+      102: '一般风险',
+      103: '较大风险',
+      104: '重大风险',
+      201: '报警',
+      1001: '网络断开',
+    };
+    risk.value = trans[info.fireWarnLevel];
+    listData.value = info;
   }
 
   onMounted(() => {

+ 30 - 9
src/views/vent/home/billboard/components/GasStatus.vue

@@ -5,27 +5,48 @@
       <LargeBoard :label="item.label" :value="headerData[item.prop]" :type="item.type" />
     </Col>
   </Row>
-  <CommonTable class="mt-10px" :columns="GAS_STATUS_COLUMN" :data="data" />
+  <CommonTable class="mt-10px" :columns="GAS_STATUS_COLUMN" :data="tableData" />
 </template>
 <script lang="ts" setup>
   import { Row, Col } from 'ant-design-vue';
-  import { GAS_STATUS_HEADER_CONFIG, GAS_STATUS_COLUMN } from '../billboard.data';
+  import { GAS_STATUS_HEADER_CONFIG, GAS_STATUS_COLUMN, DEFAULT_TEST_DATA, BillboardType } from '../billboard.data';
   import LargeBoard from './LargeBoard.vue';
   import { onMounted, shallowRef } from 'vue';
   import CommonTable from './CommonTable.vue';
-  import { getSummary } from '../billboard.api';
   // import mapComponent from './components/3Dmap/index.vue';
 
+  const props = withDefaults(
+    defineProps<{
+      data?: BillboardType;
+    }>(),
+    {
+      data: () => DEFAULT_TEST_DATA,
+    }
+  );
+
   const headerData = shallowRef({});
-  const data = shallowRef<any[]>([]);
+  const tableData = shallowRef<BillboardType['gasInfo']['gasTypeList']>([]);
 
   function fetchData() {
-    getSummary().then((r) => {
-      headerData.value = {
-        gasWarnLevel: r.gasInfo.gasWarnLevel,
-        gasJudgeLevel: 0,
+    const info = props.data.gasInfo;
+    const trans = {
+      0: '低风险',
+      101: '低风险',
+      102: '一般风险',
+      103: '较大风险',
+      104: '重大风险',
+      201: '报警',
+      1001: '网络断开',
+    };
+    headerData.value = {
+      gasWarnLevel: trans[info.gasWarnLevel],
+      gasJudgeLevel: '低风险',
+    };
+    tableData.value = info.gasTypeList.map((e) => {
+      return {
+        ...e,
+        warnLevelStr: trans[e.warnLevel],
       };
-      data.value = r.gasInfo.gasTypeList;
     });
   }
 

+ 39 - 28
src/views/vent/home/billboard/components/VentilationStatus.vue

@@ -2,7 +2,7 @@
 <template>
   <Row justify="space-between">
     <Col v-for="(item, i) in VENTILATION_STATUS_HEADER_CONFIG" :key="`svvhbcvs${i}`" :span="12">
-      <MiniBoard :label="item.label" :value="data[item.prop]" :type="item.type" />
+      <MiniBoard :label="item.label" :value="headerData[item.prop]" :type="item.type" />
     </Col>
     <div class="ventilate-status-card">
       <CommonTitle label="通风系统数量" :value="ventilatorCount" />
@@ -14,42 +14,53 @@
   import { Row, Col } from 'ant-design-vue';
   import { BasicTree } from '/@/components/Tree';
   import type { TreeProps } from 'ant-design-vue';
-  import { VENTILATION_STATUS_HEADER_CONFIG, VENTILATION_STATUS_TREE_CONFIG } from '../billboard.data';
+  import { BillboardType, DEFAULT_TEST_DATA, VENTILATION_STATUS_HEADER_CONFIG, VENTILATION_STATUS_TREE_CONFIG } from '../billboard.data';
   import MiniBoard from './MiniBoard.vue';
   import { onMounted, ref, shallowRef } from 'vue';
   import CommonTitle from './CommonTitle.vue';
-  import { getSummary } from '../billboard.api';
+  import _ from 'lodash-es';
   // import mapComponent from './components/3Dmap/index.vue';
 
-  const data = shallowRef({});
+  const props = withDefaults(
+    defineProps<{
+      data?: BillboardType;
+    }>(),
+    {
+      data: () => DEFAULT_TEST_DATA,
+    }
+  );
+
   const ventilatorCount = ref('0');
+  const headerData = shallowRef({});
   const treeData = shallowRef<TreeProps['treeData']>([]);
 
   function fetchData() {
-    getSummary().then((r) => {
-      ventilatorCount.value = r.ventInfo.fanMainList.length.toString();
-      data.value = r.ventInfo;
-      treeData.value = r.ventInfo.fanMainList.map((e, i) => {
-        const { prefix, suffix, prop, children } = VENTILATION_STATUS_TREE_CONFIG;
-        return {
-          title: `${prefix}${e[prop]}${suffix}`,
-          key: i.toString(),
-          children: children.map((child, j) => {
-            // 配置里如果指定了多个prop则进行合并
-            if (Array.isArray(child.prop)) {
-              return {
-                title: `${child.prefix}${child.prop.map((p) => `${e[p]}${suffix}`).join('-')}`,
-                key: `${i}-${j}`,
-              };
-            } else {
-              return {
-                title: `${child.prefix}${e[child.prop]}${child.suffix}`,
-                key: `${i}-${j}`,
-              };
-            }
-          }),
-        };
-      });
+    const info = props.data.ventInfo;
+    const { prefix, suffix, prop, children } = VENTILATION_STATUS_TREE_CONFIG;
+    ventilatorCount.value = info.fanMainList.length.toString();
+    headerData.value = info;
+
+    // 处理树状图的数据
+    treeData.value = info.fanMainList.map((mainfan, i) => {
+      return {
+        title: `${prefix}${mainfan[prop]}${suffix}`,
+        key: i.toString(),
+        children: children.map((child, j) => {
+          // 配置里如果指定了多个prop则进行合并
+          // if (Array.isArray(child.prop)) {
+          //   return {
+          //     title: `${child.prefix}${child.prop.map((p) => `${mainfan[p]}${suffix}`).join('-')}`,
+          //     key: `${i}-${j}`,
+          //   };
+          // }
+
+          // 该部分数据有可能部分为undefined
+          return {
+            title: `${child.prefix}${_.get(mainfan, child.prop, '/')}${child.suffix}`,
+            key: `${i}-${j}`,
+          };
+        }),
+      };
     });
   }
 

+ 13 - 6
src/views/vent/home/billboard/index.vue

@@ -6,8 +6,8 @@
     </div>
     <a-row class="company-content" :gutter="10">
       <a-col v-for="(item, i) in shownBillboards" :key="`svvhbi-${i}`" :span="6">
-        <BaseCard :title="item.title">
-          <component :is="COMPONENTS_MAP.get(billboardType)" />
+        <BaseCard :title="item.orgname" @open="openHandler(item.ip)">
+          <component :is="COMPONENTS_MAP.get(billboardType)" :data="item" />
         </BaseCard>
       </a-col>
     </a-row>
@@ -26,20 +26,22 @@
   import { computed, onMounted, ref } from 'vue';
   import BaseCard from './components/BaseCard.vue';
   import ArrowButton from './components/ArrowButton.vue';
-  import { COMPONENTS_MAP } from './billboard.data';
+  import { BillboardType, COMPONENTS_MAP } from './billboard.data';
   import { useRoute } from 'vue-router';
-  import { getList } from './billboard.api';
+  import { getSummary } from './billboard.api';
+  import { useSSO } from '/@/hooks/vent/useSSO';
   // import mapComponent from './components/3Dmap/index.vue';
 
   const route = useRoute();
+  const { open } = useSSO();
 
   const mainTitle = '煤炭集团';
 
   // 看板相关的基础配置
-  const billboards = ref<{ title: string }[]>([]);
+  const billboards = ref<BillboardType[]>([]);
 
   function fetchBillboards() {
-    getList().then((r) => {
+    getSummary().then((r) => {
       billboards.value = r;
     });
   }
@@ -63,6 +65,11 @@
   const billboardType = ref('dust');
   const showBtn = ref(true);
 
+  // 页面跳转
+  function openHandler(ip: string) {
+    open(`http://${ip}:8092/login`);
+  }
+
   onMounted(() => {
     if (route.query.type) {
       billboardType.value = route.query.type as string;

+ 0 - 1
src/views/vent/home/configurable/components/CostumeHeader.vue

@@ -42,7 +42,6 @@
 
   // 选择了某一项
   function selectHandler({ key, item }) {
-    console.log('debug', key, item);
     selectedKey.value = key;
     selectedLabel.value = item.title;
     emit('change', key);