belt-new.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449
  1. <!-- belt-new.vue -->
  2. <template>
  3. <div class="company-home">
  4. <!-- 顶部标题栏 + 下拉选择 -->
  5. <customHeader> 皮带巷智能管控 </customHeader>
  6. <div class="modal-box" id="modalBox" v-if="pageType !== 'history'">
  7. <Three3D ref="three3D" :modalName="'pidai'" class="modal-3d" @success="initModalAnimate" />
  8. <div class="modal-css3d" id="css3dContainer"> </div>
  9. </div>
  10. <div class="top-bg">
  11. <BeltNav @change-page="changePage" :pageType="pageType" />
  12. </div>
  13. <!-- 主体区域 -->
  14. <div class="border">
  15. <!-- 配置模块区 -->
  16. <template v-if="pageType == 'fireMonitor'">
  17. <ModuleCommon
  18. v-for="cfg in configs"
  19. :key="cfg.deviceType"
  20. :show-style="cfg.showStyle"
  21. :module-data="cfg.moduleData"
  22. :module-name="cfg.moduleName"
  23. :device-type="cfg.deviceType"
  24. :page-type="cfg.pageType"
  25. :data="data"
  26. :visible="true"
  27. />
  28. </template>
  29. <template v-if="pageType == 'emergencyControl'">
  30. <ModuleCommon
  31. v-for="cfg in configs"
  32. :key="cfg.deviceType"
  33. :show-style="cfg.showStyle"
  34. :module-data="cfg.moduleData"
  35. :module-name="cfg.moduleName"
  36. :device-type="cfg.deviceType"
  37. :page-type="cfg.pageType"
  38. :data="data"
  39. :visible="true"
  40. />
  41. </template>
  42. <template v-if="pageType == 'sprayControl'">
  43. <ModuleCommon
  44. v-for="cfg in configs"
  45. :key="cfg.deviceType"
  46. :show-style="cfg.showStyle"
  47. :module-data="cfg.moduleData"
  48. :module-name="cfg.moduleName"
  49. :device-type="cfg.deviceType"
  50. :page-type="cfg.pageType"
  51. :data="data"
  52. :visible="true"
  53. />
  54. </template>
  55. <template v-if="pageType == 'history'">
  56. <History />
  57. </template>
  58. </div>
  59. </div>
  60. </template>
  61. <script setup lang="ts">
  62. import { onMounted, ref, watch, computed } from 'vue';
  63. import customHeader from './components/customHeader-belt.vue';
  64. import { useInitConfigs, useInitPage } from '../hooks/useInit';
  65. import { testBeltNew, testYjkf, testSpary } from './configurable.data';
  66. import ModuleCommon from './components/ModuleCommon.vue';
  67. import Three3D from '/@/views/vent/home/configurable/components/three3D.vue';
  68. import BeltNav from './components/BeltNav.vue';
  69. import { useRouter, useRoute } from 'vue-router';
  70. import { getSystem } from './configurable.api';
  71. import { modalAnimate } from './threejs/belt.threejs';
  72. import History from './components/detail/history.vue';
  73. // 初始化配置
  74. const { configs, fetchConfigs } = useInitConfigs();
  75. const { updateEnhancedConfigs, updateData, data } = useInitPage('皮带巷智能管控');
  76. // const pageType = computed(() => {
  77. // const currentType = route.params.type as string;
  78. // return currentType;
  79. // });
  80. const pageType = ref('');
  81. const route = useRoute();
  82. // 下拉框选项
  83. const beltOptions = [
  84. { id: '1', beltName: '主运巷皮带 1' },
  85. { id: '2', beltName: '主运巷皮带 2' },
  86. ];
  87. const selectedBeltId = ref('1');
  88. // 模拟数据
  89. const readData = {
  90. fmhjcInfo: [
  91. {
  92. beltName: '主运巷皮带1',
  93. wz: { strtype: 'wz', avg: '111', max: '222', min: '333', alarm: false, pos: 'AAAA', maxTime: '2013-05-24 15:52:42' },
  94. hcl: { strtype: 'HCl', avg: 'XXX', max: 'XXX', min: 'XXX', alarm: false, pos: 'AAAA', maxTime: '2013-05-24 15:52:42' },
  95. gx: { strtype: 'gx', avg: 'XXX', max: 'XXX', min: 'XXX', alarm: false, pos: 'AAAA', maxTime: '2013-05-24 15:52:42' },
  96. co: { strtype: 'CO', avg: 'XXX', max: 'XXX', min: 'XXX', alarm: true, pos: 'AAAA', maxTime: '2013-05-24 15:52:42' },
  97. wd: { strtype: 'wd', avg: 'XXX', max: 'XXX', min: 'XXX', alarm: false, pos: 'AAAA', maxTime: '2013-05-24 15:52:42' },
  98. },
  99. ],
  100. pdhzfxInfo: [
  101. {
  102. beltName: '主运巷皮带1',
  103. warningLevel: '一般风险',
  104. sysList: [
  105. {
  106. time: '2026-03-21 13:23:34',
  107. area: '3#皮带区域',
  108. type: 'CO浓度异常',
  109. status: '三级预警',
  110. advice: '立即检查该区域设备,启动应急预案',
  111. action: '启动喷淋',
  112. },
  113. {
  114. time: '2026-03-21 13:23:34',
  115. area: '3#皮带区域',
  116. type: 'CO浓度异常',
  117. status: '三级预警',
  118. advice: '立即检查该区域设备,启动应急预案',
  119. action: '启动喷淋',
  120. },
  121. {
  122. time: '2026-03-21 13:23:34',
  123. area: '3#皮带区域',
  124. type: 'CO浓度异常',
  125. status: '三级预警',
  126. advice: '立即检查该区域设备,启动应急预案',
  127. action: '启动喷淋',
  128. },
  129. {
  130. time: '2026-03-21 13:23:34',
  131. area: '3#皮带区域',
  132. type: 'CO浓度异常',
  133. status: '三级预警',
  134. advice: '立即检查该区域设备,启动应急预案',
  135. action: '启动喷淋',
  136. },
  137. ],
  138. },
  139. ],
  140. sensorAnalysis: {
  141. hy: { name: '火焰传感器', alarm: false, maxTime: '2013-05-24 15:52:42', pos: '' },
  142. wd: { name: '温度传感器', alarm: false, maxTime: '2013-05-24 15:52:42', pos: '' },
  143. yw: { name: '烟雾传感器', alarm: false, maxTime: '2013-05-24 15:52:42', pos: '' },
  144. },
  145. vehicleCOAnalysis: {
  146. isRisk: true,
  147. activityList: [
  148. {
  149. pos: '1#皮带区域',
  150. vehicle: '车辆23425',
  151. status: '0',
  152. // vehicle2: '车辆53456',
  153. // vehicle3: '未通过车辆',
  154. // coReason1: 'CO浓度异常升高,已确认为车辆干扰',
  155. // coReason3: 'CO浓度异常升高,已确认非车辆干扰',
  156. // possibleCause: '皮带摩擦过热或电器设备故障',
  157. // recommendation: '立即检查3#皮带区域设备',
  158. },
  159. {
  160. pos: '2#皮带区域',
  161. vehicle: '车辆53456',
  162. status: '1',
  163. },
  164. {
  165. pos: '3#皮带区域',
  166. vehicle: '未通过车辆',
  167. status: '0',
  168. },
  169. ],
  170. analysisList: [
  171. {
  172. pos: '1#皮带区域',
  173. analysisText: 'CO浓度异常升高,已确认为车辆干扰',
  174. },
  175. {
  176. pos: '1#皮带区域',
  177. analysisText: 'CO浓度异常升高,已确认为车辆干扰',
  178. },
  179. ],
  180. possibleCause: '皮带摩擦过热或电器设备故障',
  181. recommendation: '立即检查3#皮带区域设备',
  182. },
  183. sprayData: [
  184. {
  185. beltArea: '1#皮带区域',
  186. devicePosition: '1#皮带-50m处',
  187. netStatus: '0', // 网络状态:0=断开,1=连接
  188. runStatus: '1', // 运行状态:0=异常,1=正常
  189. waterVolume: 86,
  190. waterPressure: 1.4,
  191. },
  192. {
  193. beltArea: '2#皮带区域',
  194. devicePosition: '2#皮带-120m处',
  195. netStatus: '1',
  196. runStatus: '1',
  197. waterVolume: 72,
  198. waterPressure: 0.8,
  199. },
  200. {
  201. beltArea: '3#皮带区域',
  202. devicePosition: '3#皮带-200m处',
  203. netStatus: '1',
  204. runStatus: '0',
  205. waterVolume: 45,
  206. waterPressure: 1.6,
  207. },
  208. ],
  209. };
  210. // 下拉框切换处理
  211. function handleBeltChange(id: string) {
  212. selectedBeltId.value = id;
  213. refresh();
  214. }
  215. // 风险等级样式映射
  216. function getLevelClass(level: string) {
  217. switch (level) {
  218. case '重大风险':
  219. return 'level-critical';
  220. case '高风险':
  221. return 'level-high';
  222. case '一般风险':
  223. return 'level-normal';
  224. default:
  225. return '';
  226. }
  227. }
  228. // 刷新数据
  229. function refresh() {
  230. fetchConfigs('belt').then(() => {
  231. if (pageType.value == 'fireMonitor') {
  232. configs.value = testBeltNew;
  233. Promise.resolve(readData).then(updateData);
  234. } else if (pageType.value == 'emergencyControl') {
  235. const params = {
  236. devicetype: 'sys',
  237. systemID: '1637983899775242242',
  238. type: 'ventS',
  239. };
  240. Promise.resolve(getSystem(params)).then(updateData);
  241. configs.value = testYjkf;
  242. } else if (pageType.value == 'sprayControl') {
  243. configs.value = testSpary;
  244. Promise.resolve(readData).then(updateData);
  245. } else {
  246. configs.value = testBeltNew;
  247. }
  248. updateEnhancedConfigs(configs.value);
  249. });
  250. }
  251. // // 定时刷新
  252. // function initInterval() {
  253. // setInterval(() => {
  254. // refresh();
  255. // }, 60000);
  256. // }
  257. async function changePage(pageTypeStr: string) {
  258. const finalPageType = pageTypeStr || (route.query.pageType as string) || '';
  259. pageType.value = finalPageType;
  260. await refresh();
  261. }
  262. // watch(
  263. // // 监听动态路由参数 :type
  264. // () => route.params.type,
  265. // (newVal) => {
  266. // if (newVal) {
  267. // console.log('切换页面类型:', newVal);
  268. // refresh(); // 切换路由自动刷新
  269. // }
  270. // }
  271. // );
  272. function initModalAnimate(modal) {
  273. console.log('初始化模型', modal);
  274. modal.isRender = true;
  275. modalAnimate(modal);
  276. }
  277. watch(
  278. () => route.query.pageType,
  279. (newQueryType) => {
  280. if (newQueryType) {
  281. changePage(newQueryType as string);
  282. }
  283. },
  284. { immediate: true } // 初始化立刻执行
  285. );
  286. onMounted(() => {
  287. refresh();
  288. // initInterval();
  289. });
  290. </script>
  291. <style lang="less" scoped>
  292. .company-home {
  293. background: url('/@/assets/images/beltFire/baseMap.png') no-repeat center;
  294. width: 100%;
  295. height: 100%;
  296. color: @white;
  297. position: relative;
  298. font-family: 'Microsoft YaHei', sans-serif;
  299. .top-bg {
  300. width: 100%;
  301. height: 56px;
  302. position: absolute;
  303. margin-top: 10px;
  304. z-index: 1;
  305. }
  306. .header-container {
  307. position: absolute;
  308. top: 20px;
  309. left: 20px;
  310. z-index: 10;
  311. }
  312. .border {
  313. width: 100%;
  314. height: 94%;
  315. background: url('/@/assets/images/beltFire/mainbj.png') no-repeat;
  316. background-size: 100% 100%;
  317. position: relative;
  318. overflow: hidden;
  319. margin-top: 50px;
  320. .box-container {
  321. position: relative;
  322. width: 100%;
  323. height: 100%;
  324. }
  325. }
  326. // 中间预警结果区
  327. .center-warning-container {
  328. position: absolute;
  329. left: 50%;
  330. transform: translateX(-50%);
  331. top: 50%;
  332. width: 600px;
  333. height: 200px;
  334. background-color: rgba(0, 0, 0, 0.7);
  335. border-radius: 10px;
  336. padding: 15px;
  337. box-shadow: 0 0 20px rgba(0, 255, 255, 0.3);
  338. z-index: 5;
  339. color: #fff;
  340. .warning-header {
  341. font-size: 18px;
  342. font-weight: bold;
  343. margin-bottom: 10px;
  344. color: #ff6b6b;
  345. }
  346. .warning-list {
  347. width: 100%;
  348. height: 100%;
  349. overflow-y: auto;
  350. display: flex;
  351. flex-direction: column;
  352. gap: 8px;
  353. }
  354. .warning-item {
  355. display: flex;
  356. justify-content: space-between;
  357. align-items: center;
  358. padding: 8px;
  359. background-color: rgba(0, 0, 0, 0.5);
  360. border-radius: 5px;
  361. border-left: 4px solid #ff6b6b;
  362. .warning-time {
  363. font-size: 14px;
  364. color: #ccc;
  365. }
  366. .warning-level {
  367. font-size: 14px;
  368. font-weight: bold;
  369. padding: 4px 8px;
  370. border-radius: 4px;
  371. &.level-critical {
  372. background-color: #ff6b6b;
  373. color: white;
  374. }
  375. &.level-high {
  376. background-color: #ffcc00;
  377. color: black;
  378. }
  379. &.level-normal {
  380. background-color: #66cc66;
  381. color: white;
  382. }
  383. }
  384. .warning-action {
  385. .btn-start-spray {
  386. background-color: #00e1ff;
  387. color: #000;
  388. border: none;
  389. padding: 4px 10px;
  390. border-radius: 4px;
  391. cursor: pointer;
  392. font-size: 12px;
  393. transition: all 0.3s;
  394. &:hover {
  395. background-color: #00c3e6;
  396. }
  397. }
  398. }
  399. }
  400. }
  401. // 巷道示意图
  402. .belt-diagram {
  403. position: absolute;
  404. left: 50%;
  405. transform: translateX(-50%);
  406. bottom: 50px;
  407. width: 800px;
  408. height: 100px;
  409. display: flex;
  410. justify-content: center;
  411. align-items: center;
  412. img {
  413. width: 100%;
  414. height: 100%;
  415. object-fit: contain;
  416. }
  417. }
  418. }
  419. .modal-box {
  420. width: 100%;
  421. height: 100%;
  422. position: absolute;
  423. z-index: 1;
  424. }
  425. </style>