content.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625
  1. <!-- eslint-disable vue/multi-word-component-names -->
  2. <template>
  3. <!-- 主体内容部分 -->
  4. <div class="content">
  5. <!-- 背景 -->
  6. <img v-if="background.show && background.type === 'image'" class="content__background" :src="background.link" />
  7. <video
  8. v-if="background.show && background.type === 'video' && background.isBoard"
  9. class="content__background"
  10. width="100%"
  11. autoplay
  12. loop
  13. muted
  14. disablepictureinpicture
  15. playsinline
  16. >
  17. <source :src="background.link" />
  18. Not Supportted Link Or Browser
  19. </video>
  20. <video
  21. v-if="background.show && background.type === 'video' && !background.isBoard"
  22. class="content__background_1"
  23. width="100%"
  24. autoplay
  25. loop
  26. muted
  27. disablepictureinpicture
  28. playsinline
  29. >
  30. <source :src="background.link" />
  31. Not Supportted Link Or Browser
  32. </video>
  33. <div class="flex w-full h-full" :style="{ flexDirection: layout.direction }">
  34. <div v-for="config in layoutConfig" :key="config.name" :style="{ flexBasis: config.basis, overflow: config.overflow ? 'auto' : 'none' }">
  35. <!-- 告示板部分 -->
  36. <template v-if="config.name === 'board'">
  37. <div
  38. v-if="config.pageType == 'vent_New'"
  39. style="padding-top: 11%"
  40. class="content__module content__module1 flex flex-justify-around flex-items-center flex-wrap"
  41. >
  42. <MiniBoard
  43. v-for="item in config.items"
  44. :key="item.prop"
  45. :label="item.label"
  46. :value="item.value"
  47. :type="config.type"
  48. :layout="config.layout"
  49. />
  50. </div>
  51. <div v-else-if="config.pageType == 'New_fire'" class="content__module flex flex-justify-around flex-items-center flex-wrap">
  52. <MiniBoardNew
  53. v-for="item in config.items"
  54. :key="item.prop"
  55. :label="item.label"
  56. :value="item.value"
  57. :type="config.type"
  58. :layout="config.layout"
  59. />
  60. </div>
  61. <div v-else class="content__module flex flex-justify-around flex-items-center flex-wrap">
  62. <MiniBoard
  63. v-for="item in config.items"
  64. :key="item.prop"
  65. :label="item.label"
  66. :value="item.value"
  67. :type="config.type"
  68. :layout="config.layout"
  69. />
  70. </div>
  71. </template>
  72. <!-- 图表部分 -->
  73. <template v-if="config.name === 'chart'">
  74. <CustomChart v-if="config.pageType == 'New_dust'" class="content__module_dust" :chart-config="config.config" :chart-data="config.data" />
  75. <CustomChart v-else class="content__module" :chart-config="config.config" :chart-data="config.data" />
  76. </template>
  77. <!-- 通常列表部分 -->
  78. <template v-if="config.name === 'list'">
  79. <template v-if="config.type === 'timeline'">
  80. <TimelineList class="content__module" :list-config="config.items" />
  81. </template>
  82. <template v-else-if="config.type === 'timelineNew'">
  83. <TimelineListNew class="content__module" :list-config="config.items" />
  84. </template>
  85. <template v-else-if="config.pagetype === 'Belt'">
  86. <CustomListBelt class="content__module" :type="config.type" :list-config="config.items" />
  87. </template>
  88. <template v-else>
  89. <CustomList class="content__module" :type="config.type" :list-config="config.items" />
  90. </template>
  91. </template>
  92. <template v-if="config.name === 'fireList'">
  93. <CustomList class="content__module" :type="config.type" :list-config="config.items" />
  94. </template>
  95. <!-- 画廊部分 -->
  96. <template v-if="config.name === 'gallery'">
  97. <CustomGallery class="content__module" :type="config.type" :gallery-config="config.items" />
  98. </template>
  99. <!-- 画廊列表部分 -->
  100. <template v-if="config.name === 'gallery_list'">
  101. <GalleryList class="content__module" :type="config.type" :list-config="config.items" :gallery-config="config.galleryItems" />
  102. </template>
  103. <!-- 复杂列表部分 -->
  104. <template v-if="config.name === 'complex_list'">
  105. <template v-if="config.pagetype === 'Belt'">
  106. <ComplexListBelt class="content__module" :type="config.type" :list-config="config.items" />
  107. </template>
  108. <template v-else-if="config.pagetype === 'complex_list1'">
  109. <ComplexList1Belt class="content__module" :type="config.type" :list-config="config.items" />
  110. </template>
  111. <template v-else>
  112. <ComplexList class="content__module" :type="config.type" :list-config="config.items" />
  113. </template>
  114. </template>
  115. <!-- 表格部分 -->
  116. <template v-if="config.name === 'table'">
  117. <template v-if="config.pagetype === 'Belt'">
  118. <CustomTableBelt
  119. class="content__module text-center overflow-auto"
  120. :type="config.type"
  121. :columns="config.columns"
  122. :auto-scroll="config.autoScroll"
  123. :data="config.data"
  124. />
  125. </template>
  126. <template v-else>
  127. <CustomTable
  128. class="content__module text-center overflow-auto"
  129. :type="config.type"
  130. :columns="config.columns"
  131. :auto-scroll="config.autoScroll"
  132. :data="config.data"
  133. />
  134. </template>
  135. </template>
  136. <template v-if="config.name === 'tabs'">
  137. <CustomTabs class="content__module" :type="config.type" :tab-config="config.items" :overflow="config.overflow" />
  138. </template>
  139. <template v-if="config.name === 'blast_delta'">
  140. <BlastDelta
  141. v-if="config.pageType === 'New_fire'"
  142. class="content__moduleFire"
  143. :pos-monitor="config.data"
  144. :canvasSize="{ width: 250, height: 200 }"
  145. />
  146. <BlastDelta v-else class="content__module" :pos-monitor="config.data" :canvasSize="{ width: 250, height: 200 }" />
  147. </template>
  148. <template v-if="config.name === 'qh_curve'">
  149. <QHCurve class="content__module" :mainfan="config.data" :fan1-prop="config.config.fan1Prop" :fan2-prop="config.config.fan2Prop" />
  150. </template>
  151. <template v-if="config.name === 'ai_chat'">
  152. <AIChat class="content__module" />
  153. </template>
  154. <template v-if="config.name === 'device_alarm'">
  155. <DeviceAlarm class="content__module" :devicedata="config.data" :config="config.config" />
  156. </template>
  157. <!-- lxh -->
  158. <template v-if="config.name === 'select_cs'">
  159. <SelectCs :devicedata="config.data" :config="config.config" />
  160. </template>
  161. <template v-if="config.name === 'measure_detail'">
  162. <MeasureDetail
  163. class="content__module"
  164. :show-title="false"
  165. :composite-data="config.data"
  166. :topconfig="config.config.topconfig"
  167. :btnconfig="config.config.btnconfig"
  168. />
  169. </template>
  170. <template v-if="config.name === 'partition'">
  171. <Partition class="content__module" :type="config.type" :label="config.label" :icon="config.icon" />
  172. </template>
  173. <template v-if="config.name === 'selector_dual_chart'">
  174. <SelectorDualChart :data="config.data" :moduleData="props.moduleData" :config="config" />
  175. </template>
  176. <template v-if="config.name === 'radio_label'">
  177. <RadioLabel class="content__module" :type="config.config.type" :config="config.config" />
  178. </template>
  179. <template v-if="config.name === 'button_list'">
  180. <ButtonList class="content__module" :type="config.config.type" :config="config.config" :buttonList="config.config.buttonList" />
  181. </template>
  182. <template v-if="config.name === 'card_list'">
  183. <cardList class="content__module" :cardData="config.data" />
  184. </template>
  185. <template v-else-if="config.name === 'generalist'">
  186. <generalList class="content__module" :generalData="config.data" />
  187. </template>
  188. <template v-if="config.name === 'nitrogenBtnList'">
  189. <NitrogenBtnList
  190. class="content__module"
  191. :data="config.data"
  192. :type="config.config.type"
  193. :config="config.config"
  194. :buttonList="config.config.buttonList"
  195. />
  196. </template>
  197. <template v-if="config.name === 'gateBoard'">
  198. <GateBoard class="content__module" :config="config.config" :data="config.data" />
  199. </template>
  200. <!-- 3. 火灾监测设备分析 -->
  201. <template v-if="config.name === 'sprayCtrl'">
  202. <SprayControl class="content__module" :config="config.config" :data="data" />
  203. </template>
  204. <template v-if="config.name === 'cameraList'">
  205. <CameraList class="content__module" :config="config.config" :data="config.data" />
  206. </template>
  207. <template v-if="config.name === 'CameraListTest'">
  208. <CameraListTest class="content__module" :config="config.config" :data="config.data" />
  209. </template>
  210. <!-- <template v-if="config.key === 'fire_control'">
  211. <FIreControl class="content__module" />
  212. </template>
  213. <template v-if="config.key === 'fire_warn'">
  214. <FIreWarn class="content__module" />
  215. </template> -->
  216. <!-- ==================== 新增皮带巷火灾监测模块 ==================== -->
  217. <!-- 1. 传感器状态面板 -->
  218. <template v-if="config.name === 'sensor_status'">
  219. <SensorStatusPanel class="content__module" style="height: calc(100% - 30px) !important" :config="config.config" :data="config.data" />
  220. </template>
  221. <!-- 3. 火灾监测设备分析 -->
  222. <template v-if="config.name === 'fire_sensor_analysis'">
  223. <FireSensorAnalysis class="content__module" :config="config.config.config" :data="config.data" />
  224. </template>
  225. <!-- 4. 预警结果列表 -->
  226. <template v-if="config.name === 'warning_result'">
  227. <WarningResultList class="content__module" :config="config.config" :data="config.data" />
  228. </template>
  229. <!-- 5. 车辆定位与 CO 浓度关联分析 -->
  230. <template v-if="config.name === 'vehicle_co_analysis'">
  231. <VehicleCOAnalysis class="content__module" :list="config.config.list" :data="config.data" />
  232. </template>
  233. </div>
  234. </div>
  235. </div>
  236. </template>
  237. <script lang="ts" setup>
  238. import { computed, ref } from 'vue';
  239. import { CommonItem, Config } from '../../../deviceManager/configurationTable/types';
  240. import MiniBoard from './detail/MiniBoard.vue';
  241. import TimelineList from './detail/TimelineList.vue';
  242. import TimelineListNew from './detail/TimelineListNew.vue';
  243. import CustomList from './detail/CustomList.vue';
  244. import CustomGallery from './detail/CustomGallery.vue';
  245. import ComplexList from './detail/ComplexList.vue';
  246. import GalleryList from './detail/GalleryList.vue';
  247. import CustomTable from './detail/CustomTable.vue';
  248. import CustomChart from './detail/CustomChart.vue';
  249. import { clone } from 'lodash-es';
  250. import { getData, getFormattedText } from '../hooks/helper';
  251. import BlastDelta from '../../../monitorManager/deviceMonitor/components/device/modal/blastDelta.vue';
  252. import QHCurve from './preset/QHCurve.vue';
  253. import MeasureDetail from './preset/MeasureDetail.vue';
  254. import CustomTabs from './preset/CustomTabs.vue';
  255. import AIChat from '/@/components/AIChat/MiniChat.vue';
  256. import DeviceAlarm from './preset/DeviceAlarm.vue';
  257. import SelectCs from './preset/SelectCs.vue';
  258. import MiniBoardNew from './detail/MiniBoard-New.vue';
  259. import Partition from './preset/partition.vue';
  260. import SelectorDualChart from './preset/selectorDualChart.vue';
  261. import RadioLabel from './preset/radioLabel.vue';
  262. import ButtonList from './preset/buttonList.vue';
  263. import NitrogenBtnList from './preset/nitrogenBtnList.vue';
  264. import cardList from './preset/cardList.vue';
  265. import generalList from './preset/generalList.vue';
  266. import GateBoard from '../belt/components/detail/gateBoard.vue';
  267. // ==================== 新增皮带巷火灾监测组件 ====================
  268. import SensorStatusPanel from './belt/SensorStatusPanel.vue';
  269. import FireSensorAnalysis from './belt/FireSensorAnalysis.vue';
  270. import WarningResultList from './belt/WarningResultList.vue';
  271. import VehicleCOAnalysis from './belt/VehicleCOAnalysis.vue';
  272. // 首页组件
  273. import CustomListBelt from './belt/CustomListBelt.vue';
  274. import ComplexListBelt from './belt/ComplexListBelt.vue';
  275. import ComplexList1Belt from './belt/ComplexList1Belt.vue';
  276. import CustomTableBelt from './belt/CustomTableBelt.vue';
  277. import SprayControl from './belt/SprayControl.vue';
  278. import CameraList from './belt/CameraList.vue';
  279. import CameraListTest from './belt/CameraListTest.vue';
  280. const props = defineProps<{
  281. data: any;
  282. moduleData: Config['moduleData'];
  283. chartData: any;
  284. }>();
  285. const emit = defineEmits<{
  286. (e: 'start-spray', data: any): void;
  287. (e: 'emergency-action', action: string, data: any): void;
  288. }>();
  289. const { background, layout } = props.moduleData;
  290. // 获取当原始配置带 items 项时的最终 items 配置
  291. function getItems(raw: any, items: CommonItem[]) {
  292. return items.map((i) => {
  293. return {
  294. ...i,
  295. label: getFormattedText(raw, i.label, i.trans),
  296. value: getFormattedText(raw, i.value, i.trans),
  297. };
  298. });
  299. }
  300. // 获取当 List 组件配置带 items 项时的最终 items 配置
  301. function getListItems(raw: any, items: CommonItem[], mapFromData?: boolean) {
  302. if (mapFromData && Array.isArray(raw)) {
  303. return raw.map((data) => {
  304. const item = items[0];
  305. return {
  306. ...item,
  307. label: getFormattedText(data, item.label, item.trans),
  308. value: getFormattedText(data, item.value, item.trans),
  309. };
  310. });
  311. }
  312. return getItems(raw, items);
  313. }
  314. /** 根据配置里的 layout 将配置格式化为带 key 的具体配置 */
  315. const layoutConfig = computed(() => {
  316. const refData = props.data;
  317. const board = clone(props.moduleData.board) || [];
  318. const list = clone(props.moduleData.list) || [];
  319. const gallery = clone(props.moduleData.gallery) || [];
  320. const complex_list = clone(props.moduleData.complex_list) || [];
  321. const gallery_list = clone(props.moduleData.gallery_list) || [];
  322. const tabs = clone(props.moduleData.tabs) || [];
  323. const chart = clone(props.moduleData.chart) || [];
  324. const table = clone(props.moduleData.table) || [];
  325. const preset = clone(props.moduleData.preset) || [];
  326. const partition = clone(props.moduleData.partition) || [];
  327. const mockData = clone(props.chartData) || [];
  328. return layout.items.reduce((arr: any[], item) => {
  329. switch (item.name) {
  330. case 'board': {
  331. const cfg = board.shift();
  332. if (!cfg) break;
  333. const data = getData(refData, cfg.readFrom, cfg.parser);
  334. arr.push({
  335. overflow: true,
  336. ...item,
  337. ...cfg,
  338. items: getItems(data, cfg.items),
  339. });
  340. break;
  341. }
  342. case 'list': {
  343. const cfg = list.shift();
  344. if (!cfg) break;
  345. const data = getData(refData, cfg.readFrom, cfg.parser);
  346. arr.push({
  347. overflow: true,
  348. ...item,
  349. ...cfg,
  350. items: getListItems(data, cfg.items, cfg.mapFromData),
  351. });
  352. break;
  353. }
  354. case 'gallery': {
  355. const cfg = gallery.shift();
  356. if (!cfg) break;
  357. const data = getData(refData, cfg.readFrom, cfg.parser);
  358. arr.push({
  359. overflow: true,
  360. ...item,
  361. ...cfg,
  362. items: getItems(data, cfg.items),
  363. });
  364. break;
  365. }
  366. case 'complex_list': {
  367. const cfg = complex_list.shift();
  368. if (!cfg) break;
  369. const data = getData(refData, cfg.readFrom, cfg.parser);
  370. if (cfg.mapFromData) {
  371. const firstListItem = cfg.items[0];
  372. arr.push({
  373. overflow: true,
  374. ...item,
  375. ...cfg,
  376. items: (data || []).map((d: any) => {
  377. return {
  378. title: getFormattedText(d, firstListItem.title, firstListItem.trans),
  379. contents: firstListItem.contents.map((e: any) => {
  380. return {
  381. ...e,
  382. label: getFormattedText(d, e.label, e.trans),
  383. value: getFormattedText(d, e.value, e.trans),
  384. };
  385. }),
  386. };
  387. }),
  388. });
  389. } else {
  390. arr.push({
  391. overflow: true,
  392. ...item,
  393. ...cfg,
  394. items: cfg.items.map((i: any) => {
  395. return {
  396. title: getFormattedText(data, i.title, i.trans),
  397. contents: i.contents.map((e: any) => {
  398. return {
  399. ...e,
  400. label: getFormattedText(data, e.label, e.trans),
  401. value: getFormattedText(data, e.value, e.trans),
  402. };
  403. }),
  404. };
  405. }),
  406. });
  407. }
  408. break;
  409. }
  410. case 'gallery_list': {
  411. const cfg = gallery_list.shift();
  412. if (!cfg) break;
  413. const data = getData(refData, cfg.readFrom, cfg.parser);
  414. arr.push({
  415. overflow: true,
  416. ...item,
  417. ...cfg,
  418. items: getItems(data, cfg.items),
  419. galleryItems: getItems(data, cfg.galleryItems),
  420. });
  421. break;
  422. }
  423. case 'tabs': {
  424. const cfg = tabs.shift();
  425. if (!cfg) break;
  426. const data = getData(refData, cfg.readFrom, cfg.parser);
  427. if (cfg.mapFromData) {
  428. const firstListItem = cfg.items[0];
  429. arr.push({
  430. overflow: true,
  431. ...item,
  432. ...cfg,
  433. items: (data || []).map((d: any) => {
  434. return {
  435. title: getFormattedText(d, firstListItem.title, firstListItem.trans),
  436. contents: firstListItem.contents.map((e: any) => {
  437. return {
  438. ...e,
  439. label: getFormattedText(d, e.label, e.trans),
  440. value: getFormattedText(d, e.value, e.trans),
  441. };
  442. }),
  443. };
  444. }),
  445. });
  446. } else {
  447. arr.push({
  448. overflow: true,
  449. ...item,
  450. ...cfg,
  451. items: cfg.items.map((i: any) => {
  452. return {
  453. title: getFormattedText(data, i.title, i.trans),
  454. contents: i.contents.map((e: any) => {
  455. return {
  456. ...e,
  457. label: getFormattedText(data, e.label, e.trans),
  458. value: getFormattedText(data, e.value, e.trans),
  459. };
  460. }),
  461. };
  462. }),
  463. });
  464. }
  465. break;
  466. }
  467. case 'chart': {
  468. const cfg = chart.shift();
  469. if (!cfg) break;
  470. const data = cfg?.type == 'scatter' ? getData(mockData, cfg.readFrom, cfg.parser) : getData(refData, cfg.readFrom, cfg.parser);
  471. arr.push({
  472. ...item,
  473. config: cfg,
  474. data,
  475. });
  476. break;
  477. }
  478. case 'table': {
  479. const cfg = table.shift();
  480. if (!cfg) break;
  481. // const data = getData(refData, cfg.readFrom, cfg.parser);
  482. arr.push({
  483. ...cfg,
  484. ...item,
  485. columns: cfg.columns,
  486. data: refData,
  487. });
  488. break;
  489. }
  490. case 'partition': {
  491. const cfg = partition.shift();
  492. if (!cfg) break;
  493. const data = getData(refData, cfg.readFrom, cfg.parser);
  494. arr.push({
  495. overflow: true,
  496. ...item,
  497. data,
  498. ...cfg,
  499. });
  500. break;
  501. }
  502. default: {
  503. const cfg = preset.shift();
  504. if (!cfg) break;
  505. const data = getData(refData, cfg.readFrom, cfg.parser);
  506. arr.push({
  507. ...item,
  508. data,
  509. config: cfg,
  510. });
  511. break;
  512. }
  513. }
  514. return arr;
  515. }, []);
  516. });
  517. </script>
  518. <style lang="less" scoped>
  519. @import '@/design/theme.less';
  520. .content {
  521. height: calc(100% - 30px);
  522. position: relative;
  523. display: flex;
  524. flex-direction: column;
  525. overflow-y: auto;
  526. overflow-x: hidden;
  527. }
  528. .content__background {
  529. width: 100%;
  530. // height: 100%;
  531. height: calc(100% - 65px);
  532. position: absolute;
  533. top: 65px;
  534. left: 0;
  535. z-index: 0;
  536. object-fit: fill;
  537. padding: 5px;
  538. box-sizing: border-box;
  539. }
  540. .content__background_1 {
  541. width: 100%;
  542. height: 100%;
  543. position: absolute;
  544. top: 0px;
  545. left: 0;
  546. z-index: 0;
  547. object-fit: fill;
  548. }
  549. .image__background {
  550. width: 35%;
  551. height: 61%;
  552. left: 30%;
  553. }
  554. .content__module {
  555. width: 100%;
  556. height: 100%;
  557. }
  558. .content__module1 {
  559. background: url('@/assets/images/vent/homeNew/databg/4.png');
  560. background-repeat: no-repeat;
  561. background-size: 100% 100%;
  562. height: 129px;
  563. margin-top: 20%;
  564. }
  565. .content__moduleFire {
  566. width: 100%;
  567. height: 100%;
  568. margin-left: -24% !important;
  569. }
  570. .content__module_dust {
  571. background: url('@/assets/images/vent/homeNew/bottomBg.png');
  572. background-repeat: no-repeat;
  573. background-size: 100% 100%;
  574. width: 100%;
  575. height: 100%;
  576. }
  577. ::-webkit-scrollbar {
  578. width: 5px !important;
  579. }
  580. ::-webkit-scrollbar-thumb {
  581. width: 5px !important;
  582. }
  583. :deep(.zxm-select:not(.zxm-select-customize-input) .zxm-select-selector) {
  584. color: #fff;
  585. }
  586. :deep(.zxm-select-arrow) {
  587. color: #fff;
  588. }
  589. :deep(.zxm-select-selection-item) {
  590. color: #fff !important;
  591. }
  592. :deep(.zxm-select-selection-placeholder) {
  593. color: #fff !important;
  594. }
  595. :deep(.dialog-overlay) {
  596. width: 100%;
  597. height: 100%;
  598. position: unset;
  599. box-shadow: unset;
  600. }
  601. </style>