index.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642
  1. <template>
  2. <div class="table-box">
  3. <div class="card container-box">
  4. <div style="display: flex;justify-content: space-between">站台概况
  5. <div class="header-button-ri">
  6. <slot name="toolButton">
  7. <img class="setting" src="@/assets/images/setting.png" @click="handleSetting"/>
  8. </slot>
  9. </div>
  10. </div>
  11. <div class="container-main mt15">
  12. <div class="container-item container__label">站号:
  13. <SelectItem :select-data="selectedData" :select-list="platformList" :is-checkbox="true" @update:selectedItems="selectedItems" style="width: 200px"> </SelectItem>
  14. </div>
  15. <div class="container-item container__label">名称:{{selectedItem.as_name?selectedItem.as_name:'--'}}</div>
  16. <div class="container-item container__label">观测时间:{{processTableFrom.data_time?processTableFrom.data_time:'--'}}</div>
  17. <div class="container-item container__label">自动站状态:
  18. <!-- <el-tag type="danger" size="default" hit>离线</el-tag>-->
  19. <!-- <el-tag type="success" size="default" hit>在线</el-tag>-->
  20. --
  21. </div>
  22. <div class="container-item container__label">站址:{{addressLabel(selectedItem)}}</div>
  23. </div>
  24. <!-- <div class="container-main mt15">-->
  25. <!-- <div class="container-item container__label">自动站状态:<el-tag type="danger" size="default" hit>故障</el-tag></div>-->
  26. <!-- <div class="container-item container__label">站址:未命名29号</div>-->
  27. <!-- <div class="container-item container__label"></div>-->
  28. <!-- <div class="container-item container__label"></div>-->
  29. <!-- </div>-->
  30. </div>
  31. <div class="card table-main">
  32. <div>站台状况</div>
  33. <div v-if="customizeColumns&&customizeColumns.length>0" class="container-device-main mt15">
  34. <template v-for="item in customizeColumns">
  35. <div class="container-device-item" @click="handlePlatform(item)">
  36. <div class="container-text-box">
  37. <div class="container-title">{{item.se_name}}</div>
  38. <div class="container-name mt15 mb15">传感器状态:
  39. <el-button v-if="getProcessValue(item.se_type)==='正常'" color="#009100" plain>{{getProcessValue(item.se_type)}}</el-button>
  40. <el-button v-if="getProcessValue(item.se_type)==='未连接'" color="#636363" plain>{{getProcessValue(item.se_type)}}</el-button>
  41. <el-button v-if="getProcessValue(item.se_type)==='告警'" color="#ff7700" plain>{{getProcessValue(item.se_type)}}</el-button>
  42. <el-button v-if="getProcessValue(item.se_type)==='故障'" color="#910000" plain>{{getProcessValue(item.se_type)}}</el-button>
  43. <el-button v-if="getProcessValue(item.se_type)==='不确定'" color="#777700" plain>{{getProcessValue(item.se_type)}}</el-button>
  44. <el-button v-if="getProcessValue(item.se_type)==='未启用'" color="#9e6b85" plain>{{getProcessValue(item.se_type)}}</el-button>
  45. <template v-if="getProcessValue(item.se_type)==='--'">
  46. {{getProcessValue(item.se_type)}}
  47. </template>
  48. </div>
  49. <div class="container-name">证书剩余时间:{{findRemainingDays(item.se_type)}}</div>
  50. </div>
  51. <div class="device-img">
  52. <img :src="getCustomImg(item.se_type)" class="device-img">
  53. </div>
  54. </div>
  55. </template>
  56. </div>
  57. <div v-else class="no-data">
  58. <img src="/src/assets/images/notData.png" alt="notData">
  59. <div class="no-data-title">暂无数据</div>
  60. </div>
  61. </div>
  62. <!-- 添加或修改对话框 -->
  63. <el-dialog :title="dialog.title" v-model="dialog.visible" width="1200px" append-to-body>
  64. <div style="height: 500px;display: flex">
  65. <el-tabs tab-position="left" class="demo-tabs" style="height: 100%;flex-grow: 1">
  66. <el-tab-pane label="组件">
  67. <div class="container-tag">
  68. <template v-for="item in sensorList" :key="item.se_type" >
  69. <div v-if="item.se_state===0" :class="item.isSelected?'item-tag-active':'item-tag'" @click="toggleSelection(item)" >{{item.se_name}}</div>
  70. </template>
  71. </div>
  72. </el-tab-pane>
  73. <el-tab-pane label="自动">
  74. <div class="container-tag">
  75. <template v-for="item in sensorList" :key="item.se_type" >
  76. <div v-if="item.se_state===1" :class="item.isSelected?'item-tag-active':'item-tag'" @click="toggleSelection(item)" >{{item.se_name}}</div>
  77. </template>
  78. </div>
  79. </el-tab-pane>
  80. <el-tab-pane label="人工">
  81. <div class="container-tag">
  82. <template v-for="item in sensorList" :key="item.se_type" >
  83. <div v-if="item.se_state===2" :class="item.isSelected?'item-tag-active':'item-tag'" @click="toggleSelection(item)" >{{item.se_name}}</div>
  84. </template>
  85. </div>
  86. </el-tab-pane>
  87. </el-tabs>
  88. <div class="selected-list-box">
  89. <div class="disposition-title" style="margin-top: 0px">已选设备</div>
  90. <div class="selected-list-c">
  91. <template v-for="(item,index) in copiedCustomizeColumns" :key="item.se_type">
  92. <div :class="selectedItemIndex===index?'selected-item-tag-active':'selected-item-tag'" @click="changeSelected(index)"
  93. draggable="true"
  94. @dragstart="dragStart($event, index)"
  95. @dragover.prevent
  96. @drop="drop($event, index)"
  97. >{{item.se_name}}</div>
  98. </template>
  99. </div>
  100. <div class="button-container">
  101. <el-button type="primary" plain class="top-left" @click="changeMoveUp">上移</el-button>
  102. <el-button type="primary" plain class="top-right" @click="changeMoveDown">下移</el-button>
  103. <el-button type="primary" plain class="bottom-left" @click="changeRemove">移除</el-button>
  104. <el-button type="primary" plain class="bottom-right" @click="changeCleared">清空</el-button>
  105. </div>
  106. </div>
  107. </div>
  108. <template #footer>
  109. <div class="dialog-footer">
  110. <el-button @click="cancel">取 消</el-button>
  111. <el-button type="primary" @click="submitForm">确 定</el-button>
  112. </div>
  113. </template>
  114. </el-dialog>
  115. <!-- 添加或修改对话框 -->
  116. <el-dialog :title="dialog2.title" v-model="dialog2.visible" width="900px" append-to-body>
  117. <div style="height: 400px;display: flex">
  118. <div style="width: 25%;display: flex;justify-content: center;align-items: center">
  119. <div class="device-img">
  120. <img :src="getCustomImg(itemData.se_type)" class="device-img">
  121. </div>
  122. </div>
  123. <div style="width: 75%;">
  124. <el-radio-group v-model="radio1">
  125. <el-radio-button label="传感器" value="1" plain/>
  126. <el-radio-button label="状态组" value="2" plain/>
  127. </el-radio-group>
  128. <div style="height: 300px;margin-top:20px;">
  129. <div v-if="radio1==='1'" class="item-system" >
  130. <div>传感器类型:{{itemData.se_name}}</div>
  131. <div style="margin-top: 10px">传感器状态:
  132. <el-button v-if="getProcessValue(itemData.se_type)==='正常'" color="#009100" plain>{{getProcessValue(itemData.se_type)}}</el-button>
  133. <el-button v-if="getProcessValue(itemData.se_type)==='未连接'" color="#636363" plain>{{getProcessValue(itemData.se_type)}}</el-button>
  134. <el-button v-if="getProcessValue(itemData.se_type)==='告警'" color="#ff7700" plain>{{getProcessValue(itemData.se_type)}}</el-button>
  135. <el-button v-if="getProcessValue(itemData.se_type)==='故障'" color="#910000" plain>{{getProcessValue(itemData.se_type)}}</el-button>
  136. <el-button v-if="getProcessValue(itemData.se_type)==='不确定'" color="#777700" plain>{{getProcessValue(itemData.se_type)}}</el-button>
  137. <el-button v-if="getProcessValue(itemData.se_type)==='未启用'" color="#9e6b85" plain>{{getProcessValue(itemData.se_type)}}</el-button>
  138. <template v-if="getProcessValue(itemData.se_type)==='--'">
  139. {{getProcessValue(itemData.se_type)}}
  140. </template>
  141. </div>
  142. <div style="margin-top: 10px">证书剩余时间:{{findRemainingDays(itemData.se_type)}}</div>
  143. </div>
  144. <div v-if="radio1==='2'" class="table-box" style="margin-top: 10px;" >
  145. <!-- 表格主体 -->
  146. <el-table stripe ref="tableRef" :border="true" :data="processTableData2" size="small">
  147. <el-table-column align="left" label="序号" width="80px" :show-overflow-tooltip="true">
  148. <template #default="scope">
  149. {{scope.$index + 1 }}
  150. </template>
  151. </el-table-column>
  152. <template v-for="item in columns" :key="item">
  153. <el-table-column v-bind="item" :align="item.align ?? 'left'" :reserve-selection="item.type == 'selection'" :show-overflow-tooltip="true">
  154. </el-table-column>
  155. </template>
  156. <!-- 无数据 -->
  157. <template #empty>
  158. <div class="table-empty">
  159. <slot name="empty">
  160. <img src="@/assets/images/notData.png" alt="notData" />
  161. <div>暂无数据</div>
  162. </slot>
  163. </div>
  164. </template>
  165. </el-table>
  166. </div>
  167. </div>
  168. </div>
  169. </div>
  170. <template #footer>
  171. <div class="dialog-footer">
  172. <el-button @click="cancel2">取 消</el-button>
  173. </div>
  174. </template>
  175. </el-dialog>
  176. </div>
  177. </template>
  178. <script setup lang="ts">
  179. import SelectItem from "@/components/SelectItem/index.vue";
  180. import img0 from "@/assets/images/single/0.png"
  181. import img100 from "@/assets/images/single/100.png"
  182. import img200 from "@/assets/images/single/200.png"
  183. import img300 from "@/assets/images/single/300.png"
  184. import img400 from "@/assets/images/single/400.png"
  185. import img500 from "@/assets/images/single/500.png"
  186. import img600 from "@/assets/images/single/600.png"
  187. import img700 from "@/assets/images/single/700.png"
  188. import img800 from "@/assets/images/single/800.png"
  189. import img900 from "@/assets/images/single/900.png"
  190. import img1000 from "@/assets/images/single/1000.png"
  191. import img1100 from "@/assets/images/single/1100.png"
  192. import img1200 from "@/assets/images/single/1200.png"
  193. import img1300 from "@/assets/images/single/1300.png"
  194. import img1400 from "@/assets/images/single/1400.png"
  195. import img1500 from "@/assets/images/single/1500.png"
  196. import img1600 from "@/assets/images/single/1600.png"
  197. import img1700 from "@/assets/images/single/1700.png"
  198. import {getPlatformList, getQuerCertList, getStaitemList, getYallSensorList} from "@/api/modules/allData";
  199. import {computed, onActivated, onDeactivated, onMounted, reactive, ref} from "vue";
  200. import {Platform} from "@/api/interface";
  201. import {ColumnProps} from "@/components/ProTable/interface";
  202. import {useUserStore} from "@/stores/modules/user";
  203. const radio1 =ref('1');
  204. const getCustomImg = (iconName: string) => {
  205. const icons = {
  206. 0: img0,
  207. 100: img100,
  208. 200: img200,
  209. 300: img300,
  210. 400: img400,
  211. 500: img500,
  212. 600: img600,
  213. 700: img700,
  214. 800: img800,
  215. 900: img900,
  216. 1000: img1000,
  217. 1100: img1100,
  218. 1200: img1200,
  219. 1300: img1300,
  220. 1400: img1400,
  221. 1500: img1500,
  222. 1600: img1600,
  223. 1700: img1700,
  224. };
  225. return icons[iconName] || null;
  226. };
  227. // 表格配置项
  228. const columns = reactive<ColumnProps[]>([
  229. { prop: "sta_name", label: "状态"},
  230. { prop: "sta_value", label: "状态值"},
  231. { prop: "sta_remark", label: "备注" },
  232. ]);
  233. const dragStart = (event, index) => {
  234. event.dataTransfer.effectAllowed = 'move';
  235. // 保存当前拖动的元素索引
  236. event.dataTransfer.setData('text/plain', index.toString());
  237. };
  238. const drop = (event, index) => {
  239. const draggedIndex = parseInt(event.dataTransfer.getData('text/plain'));
  240. // 移动数组中的元素来更新顺序
  241. const draggedItem = copiedCustomizeColumns.value.splice(draggedIndex, 1)[0];
  242. copiedCustomizeColumns.value.splice(index, 0, draggedItem);
  243. };
  244. const handlePlatform = (item) => {
  245. if (!item || typeof item !== 'object') {
  246. console.error('Invalid item provided');
  247. return;
  248. }
  249. radio1.value = '1';
  250. itemData.value = item;
  251. dialog2.visible = true;
  252. dialog2.title = '传感器信息';
  253. processTableData2.value = [];
  254. const { se_type } = item;
  255. if (se_type === undefined || se_type === null) {
  256. console.error('Invalid se_type in item');
  257. return;
  258. }
  259. switch (se_type) {
  260. case 0:
  261. processTableData2.value = processTableFrom.value?.sta_yclq || [];
  262. break;
  263. case 1:
  264. processTableData2.value = processTableFrom.value?.sta_txmk || [];
  265. break;
  266. default:
  267. const result = processTableFrom.value?.sta_list?.find(obj => obj.id === se_type.toString());
  268. if (result) {
  269. processTableData2.value = result.item || [];
  270. } else {
  271. console.warn(`No matching entry found for se_type: ${se_type}`);
  272. }
  273. break;
  274. }
  275. };
  276. const itemData= ref({})
  277. const pageable = ref<any>({
  278. data_type: true,
  279. time_order: undefined,
  280. time_space: 1,
  281. as_code_list:[],
  282. state_list: [
  283. 0,
  284. 1,
  285. 2
  286. ],
  287. pageNum: 1,
  288. pageSize: 1000,
  289. total: 0
  290. });
  291. const processTableData = ref([]);
  292. const processTableData2 = ref([]);
  293. const processTableFrom = ref({});
  294. const certData = ref([]);
  295. const findRemainingDays = (inputSeType) => {
  296. if(!certData.value){
  297. return '--'
  298. }
  299. const selectedCert = certData.value.find(cert => cert.se_type === parseInt(inputSeType));
  300. if (selectedCert) {
  301. // 将 cal_date_i 转换为毫秒
  302. const startTime = selectedCert.cal_date_i * 1000;
  303. // 创建 Date 对象
  304. const startDate = new Date(startTime);
  305. // 计算结束日期
  306. const endDate = new Date(startDate);
  307. endDate.setMonth(endDate.getMonth() + selectedCert.cal_period);
  308. // 获取当前时间
  309. const currentDate = new Date();
  310. // 计算剩余天数
  311. const timeDifference = endDate - currentDate;
  312. const daysRemaining = Math.ceil(timeDifference / (1000 * 60 * 60 * 24))+'天';
  313. return daysRemaining;
  314. } else {
  315. return '--'
  316. }
  317. };
  318. const getProcessValue=(param)=>{
  319. if (!processTableFrom.value) {
  320. console.error('processTableFrom is null or undefined');
  321. return '';
  322. }
  323. const valve = processTableFrom.value[param] !== undefined ? processTableFrom.value[param] : null;
  324. return getLabelByValue(valve);
  325. }
  326. const sensorList =ref<any>([])
  327. // 被选中当条数据下标
  328. const selectedItemIndex = ref(0)
  329. let customizeColumns= ref<any>([])
  330. const changeMoveUp = () =>{
  331. //上移
  332. if (selectedItemIndex.value > 0) {
  333. const temp = copiedCustomizeColumns.value[selectedItemIndex.value - 1]
  334. copiedCustomizeColumns.value[selectedItemIndex.value - 1] = copiedCustomizeColumns.value[selectedItemIndex.value]
  335. copiedCustomizeColumns.value[selectedItemIndex.value] = temp
  336. selectedItemIndex.value--
  337. }
  338. }
  339. const changeMoveDown = ()=>{
  340. //下移
  341. if (selectedItemIndex.value < copiedCustomizeColumns.value.length - 1) {
  342. const temp = copiedCustomizeColumns.value[selectedItemIndex.value + 1]
  343. copiedCustomizeColumns.value[selectedItemIndex.value + 1] = copiedCustomizeColumns.value[selectedItemIndex.value]
  344. copiedCustomizeColumns.value[selectedItemIndex.value] = temp
  345. selectedItemIndex.value++
  346. }
  347. }
  348. const changeRemove= ()=>{
  349. //删除数据
  350. if (copiedCustomizeColumns.value.length > 0) {
  351. const custom= copiedCustomizeColumns.value[selectedItemIndex.value];
  352. const se_type = custom.se_type
  353. for (let i = 0; i < sensorList.value.length; i++) {
  354. if (sensorList.value[i].se_type === se_type) {
  355. sensorList.value[i].isSelected = false;
  356. }
  357. }
  358. copiedCustomizeColumns.value.splice(selectedItemIndex.value, 1)
  359. if (selectedItemIndex.value === copiedCustomizeColumns.value.length) {
  360. selectedItemIndex.value--
  361. }
  362. }
  363. }
  364. const changeCleared=()=>{
  365. //清空所有数据
  366. selectedItemIndex.value = 0
  367. copiedCustomizeColumns.value = []
  368. for (let i = 0; i < sensorList.value.length; i++) {
  369. sensorList.value[i].isSelected = false;
  370. }
  371. }
  372. const changeSelected = (index) =>{
  373. selectedItemIndex.value = index
  374. }
  375. //操作 自定义部分表头
  376. const copiedCustomizeColumns = ref<any>([...customizeColumns.value]);
  377. // 要素的选中和取消
  378. const toggleSelection=(item)=> {
  379. item.isSelected=!item.isSelected
  380. if(item.isSelected){
  381. //添加
  382. copiedCustomizeColumns.value.push(item)
  383. }else {
  384. //删除
  385. copiedCustomizeColumns.value= copiedCustomizeColumns.value.filter(column => column.se_type !== item.se_type);
  386. }
  387. }
  388. const dialog = reactive<any>({
  389. visible: false,
  390. title: ''
  391. });
  392. const dialog2 = reactive<any>({
  393. visible: false,
  394. title: ''
  395. });
  396. const handleSetting = () => {
  397. copiedCustomizeColumns.value = [...customizeColumns.value]
  398. sensorList.value.forEach(element => {
  399. const column = copiedCustomizeColumns.value.find(col => col.se_type === element.se_type);
  400. if (column) {
  401. element.isSelected = true;
  402. } else {
  403. element.isSelected = false;
  404. }
  405. });
  406. dialog.title = "列表字段设置"
  407. dialog.visible = true;
  408. }
  409. const queryParams = ref({
  410. name: "1"
  411. });
  412. const getSensorList = async () => {
  413. const { data } = await getYallSensorList();
  414. sensorList.value = data.list
  415. };
  416. const querCert = ref<any>({
  417. pageSize: 1000,
  418. pageNum: 1,
  419. asCode: undefined
  420. })
  421. const getCertList= async ()=>{
  422. const { data } = await getQuerCertList(querCert.value);
  423. certData.value = data.list
  424. }
  425. const getLabelByValue = (value) => {
  426. const item = deviceType.find(device => device.value === value);
  427. return item ? item.label : '--';
  428. };
  429. const deviceType= [
  430. {
  431. value: 0,
  432. label: '正常',
  433. },
  434. {
  435. value: 1,
  436. label: '未连接',
  437. },
  438. {
  439. value: 2,
  440. label: '告警',
  441. },
  442. {
  443. value: 3,
  444. label: '故障',
  445. },
  446. {
  447. value: 4,
  448. label: '不确定',
  449. },
  450. {
  451. value: 5,
  452. label: '未启用',
  453. }
  454. ]
  455. const submitForm = () => {
  456. dialog.visible = false;
  457. customizeColumns.value = [...copiedCustomizeColumns.value]
  458. updateColumns()
  459. saveCustomizeColumns()
  460. }
  461. const updateColumns = () => {
  462. // pageable.value.data_items = [...customizeColumns.value];
  463. if(pageable.value.as_code_list&&pageable.value.as_code_list.length>0){
  464. getList()
  465. }
  466. }
  467. const as_code_list = ref('')
  468. const selectedItem =ref({})
  469. //搜索站号
  470. const selectedData= ref([])
  471. const selectedItems =(data)=>{
  472. if(data.length>0){
  473. pageable.value.as_code_list = data
  474. const firstCode = data[0] ?? null;
  475. selectedItem.value = platformList.value.find(item => item.as_code === firstCode);
  476. querCert.value.asCode = firstCode
  477. }else {
  478. const firstCode = platformList.value[0]?.as_code ?? null;
  479. pageable.value.as_code_list = firstCode ? [firstCode] : [];
  480. selectedItem.value = platformList.value.find(item => item.as_code === firstCode);
  481. querCert.value.asCode = firstCode
  482. selectedData.value = [firstCode]
  483. }
  484. getList()
  485. getCertList()
  486. };
  487. const cancel = () => {
  488. dialog.visible = false;
  489. }
  490. const cancel2 = () => {
  491. dialog2.visible = false;
  492. }
  493. onMounted(() => {
  494. loadCustomizeColumns()
  495. // updateColumns()
  496. getPlatforms()
  497. getSensorList()
  498. })
  499. // 保存customizeColumns数组到localStorage
  500. function saveCustomizeColumns() {
  501. const jsonString = JSON.stringify(customizeColumns.value);
  502. localStorage.setItem('singleDevice', jsonString);
  503. }
  504. // 从localStorage中获取customizeColumns数组
  505. function loadCustomizeColumns() {
  506. const jsonString = localStorage.getItem('singleDevice');
  507. if (jsonString) {
  508. customizeColumns.value = JSON.parse(jsonString);
  509. }
  510. }
  511. const userStore = useUserStore();
  512. const platformList =ref<any>(computed(() => userStore.stations))
  513. const getPlatforms = async () => {
  514. if (platformList.value .length > 0) {
  515. const firstCode = platformList.value[0]?.as_code ?? null;
  516. pageable.value.as_code_list = firstCode ? [firstCode] : [];
  517. selectedItem.value = platformList.value.find(item => item.as_code === firstCode);
  518. as_code_list.value = firstCode;
  519. querCert.value.asCode = firstCode
  520. selectedData.value = [firstCode]
  521. await getList()
  522. await getCertList()
  523. }
  524. };
  525. const getList = async () => {
  526. const { data } = await getStaitemList(pageable.value);
  527. processTableData.value = data.list
  528. if (Array.isArray(processTableData.value) && processTableData.value.length > 0) {
  529. processTableFrom.value = processTableData.value[0];
  530. } else {
  531. processTableFrom.value = {}
  532. }
  533. pageable.value.total = data.total
  534. };
  535. function addressLabel(item) {
  536. const { as_province, as_city, as_area, as_address } = item;
  537. if (as_province===undefined&&as_province===undefined&&as_area===undefined&&as_address===undefined) {
  538. return '--';
  539. } else {
  540. return `${as_province}${as_city}${as_area}${as_address}`;
  541. }
  542. }
  543. let intervalId;
  544. onActivated(() => {
  545. intervalId = setInterval(() => {
  546. getList()
  547. getCertList()
  548. }, 30 * 1000);
  549. });
  550. onDeactivated(() => {
  551. clearInterval(intervalId);
  552. });
  553. </script>
  554. <style scoped>
  555. .no-data{
  556. display: flex;
  557. flex-direction: column;
  558. justify-content: center;
  559. align-items: center;
  560. margin-top: 200px
  561. }
  562. .no-data-title{
  563. margin-top: 12px;
  564. color: var(--el-text-color-secondary);
  565. font-size: 12px;
  566. }
  567. .item-system{
  568. border: 1px solid var(--el-color-primary-light-5);
  569. border-radius: 10px;
  570. padding: 30px;
  571. height: 230px;
  572. font-size: 16px
  573. }
  574. </style>