OverviewView.vue 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. <template>
  2. <div class="ignition-view overview-view">
  3. <!-- 左:矿井采空区概览 -->
  4. <Module class="overview-module" :x="20" :y="114" :width="393" :height="576" title="矿井采空区概览">
  5. <div class="overview-panel">
  6. <div v-for="item in overview" :key="item.label" class="goaf-item">
  7. <span class="goaf-icon">
  8. <img src="@/assets/images/vent/home/selfIgnition/goaf-icon.svg" alt="" />
  9. </span>
  10. <span class="goaf-label">{{ item.label }}:</span>
  11. <span class="goaf-value">{{ item.value }}</span>
  12. </div>
  13. </div>
  14. </Module>
  15. <!-- 左下:安装设备情况 -->
  16. <Module class="install-module" :x="20" :y="722" :width="393" :height="336" title="安装设备情况">
  17. <div class="install-panel">
  18. <div
  19. v-for="(device, index) in devices"
  20. :key="`${device.name}-${index}`"
  21. class="install-item"
  22. :class="index % 2 === 0 ? 'is-blue' : 'is-green'"
  23. >
  24. <span class="install-icon">
  25. <img v-if="deviceIcon(device.name)" :src="deviceIcon(device.name)" alt="" />
  26. </span>
  27. <span class="install-name">{{ device.name }}</span>
  28. <span class="install-metric"
  29. >安装:<em>{{ device.installed }}</em
  30. >套</span
  31. >
  32. <span class="install-metric"
  33. >运行:<em>{{ device.running }}</em
  34. >套</span
  35. >
  36. </div>
  37. </div>
  38. </Module>
  39. <!-- 右下:分级预警表 -->
  40. <Module class="table-module" :x="433" :y="722" :width="1465" :height="336" title="矿井采空区分级预警">
  41. <div class="warning-table-panel">
  42. <div class="warning-table">
  43. <div class="table-head">
  44. <span class="col-index">序号</span>
  45. <span class="col-name">采空区名称</span>
  46. <span class="col-seam">所属煤层</span>
  47. <span class="col-level">预警等级</span>
  48. <span class="col-safety">安全评价等级</span>
  49. </div>
  50. <div class="table-body">
  51. <div v-for="row in warnings" :key="row.id" class="table-row">
  52. <span class="col-index">{{ row.id }}</span>
  53. <span class="col-name">{{ row.name }}</span>
  54. <span class="col-seam">{{ row.seam }}</span>
  55. <span class="col-level level-cell">
  56. <img v-if="row.level && row.level !== '未预警'" class="level-icon warning-icon" :src="warningLevelIcon" alt="" />
  57. <span :title="row.level">{{ row.level }}</span>
  58. </span>
  59. <span class="col-safety level-cell">
  60. <img v-if="showSafetyIcon(row.safetyLevel || row.level)" class="level-icon safety-icon" :src="safetyLevelIcon" alt="" />
  61. <span :title="row.safetyLevel || row.level">{{ row.safetyLevel || row.level }}</span>
  62. </span>
  63. </div>
  64. <div v-for="n in emptyRowCount" :key="`empty-${n}`" class="table-row table-row-empty"></div>
  65. </div>
  66. </div>
  67. </div>
  68. </Module>
  69. </div>
  70. </template>
  71. <script lang="ts" setup>
  72. import { computed } from 'vue';
  73. import Module from './Module.vue';
  74. import type { DeviceInstallItem, GoafOverviewItem, WarningRow } from '../data';
  75. import bundleMonitorIcon from '@/assets/images/vent/home/selfIgnition/install-bundle-monitor.svg';
  76. import fiberTemperatureIcon from '@/assets/images/vent/home/selfIgnition/install-fiber-temperature.svg';
  77. import sealedMonitorIcon from '@/assets/images/vent/home/selfIgnition/install-sealed-monitor.svg';
  78. import warningLevelIcon from '@/assets/images/vent/home/selfIgnition/level-warning.svg';
  79. import safetyLevelIcon from '@/assets/images/vent/home/selfIgnition/level-safety.svg';
  80. const props = defineProps<{
  81. overview: GoafOverviewItem[];
  82. devices: DeviceInstallItem[];
  83. warnings: WarningRow[];
  84. }>();
  85. const DEVICE_ICONS: Record<string, string> = {
  86. 束管监测: bundleMonitorIcon,
  87. 光纤测温: fiberTemperatureIcon,
  88. 密闭监测: sealedMonitorIcon,
  89. };
  90. function deviceIcon(name: string) {
  91. return DEVICE_ICONS[name] || '';
  92. }
  93. function showSafetyIcon(level: string | undefined) {
  94. return !!level && level !== '安全' && level !== '未评价';
  95. }
  96. // 表体固定 5 行视口,数据不足时用空行补足;超过 5 行时在表体内部滚动
  97. const emptyRowCount = computed(() => Math.max(0, 5 - props.warnings.length));
  98. </script>
  99. <style lang="less" scoped>
  100. @import '/@/views/vent/home/selfIgnition/scrollbar.less';
  101. .overview-view {
  102. position: absolute;
  103. inset: 0;
  104. }
  105. .overview-panel {
  106. display: flex;
  107. flex-direction: column;
  108. justify-content: space-evenly;
  109. gap: 24px;
  110. height: 100%;
  111. padding: 0px 10px 0px 20px;
  112. box-sizing: border-box;
  113. overflow-x: hidden;
  114. overflow-y: auto;
  115. scrollbar-gutter: stable;
  116. .scrollbar-cyan();
  117. }
  118. .goaf-item {
  119. position: relative;
  120. display: flex;
  121. align-items: center;
  122. flex: none;
  123. height: 48px;
  124. padding: 0 14px 0 60px;
  125. box-sizing: border-box;
  126. border: none;
  127. border-radius: 5px;
  128. overflow: hidden;
  129. background-color: #072b49;
  130. background-image: url('@/assets/images/vent/home/selfIgnition/card-bg.png');
  131. background-repeat: no-repeat;
  132. background-size: 100% 100%;
  133. }
  134. .goaf-icon {
  135. position: absolute;
  136. left: 2px;
  137. width: 50px;
  138. height: 50px;
  139. background: url('@/assets/images/vent/home/selfIgnition/list-icon-bg.png') no-repeat center / 100% 100%;
  140. display: flex;
  141. align-items: center;
  142. justify-content: center;
  143. img {
  144. width: 20px;
  145. height: 15px;
  146. }
  147. }
  148. .goaf-label {
  149. flex: 1;
  150. color: #fff;
  151. font-size: 16px;
  152. font-weight: 600;
  153. letter-spacing: 0;
  154. }
  155. .goaf-value {
  156. display: inline-block;
  157. color: #eaffff;
  158. font-family: Arial, sans-serif;
  159. font-size: 19px;
  160. font-weight: 800;
  161. font-style: italic;
  162. line-height: 1;
  163. letter-spacing: 1px;
  164. transform: scaleX(1.2);
  165. transform-origin: right center;
  166. }
  167. .install-panel {
  168. display: flex;
  169. flex-direction: column;
  170. justify-content: space-evenly;
  171. height: 100%;
  172. padding: 8px 0;
  173. box-sizing: border-box;
  174. overflow-x: hidden;
  175. overflow-y: auto;
  176. .scrollbar-cyan();
  177. }
  178. .install-item {
  179. --install-icon-bg: url('@/assets/images/vent/home/selfIgnition/install-icon-blue.png');
  180. --install-name-bg: url('@/assets/images/vent/home/selfIgnition/install-name-blue.png');
  181. --install-metric-bg: url('@/assets/images/vent/home/selfIgnition/install-metric-blue.png');
  182. display: flex;
  183. align-items: center;
  184. flex: none;
  185. height: 69px;
  186. padding: 0 20px 0 12px;
  187. box-sizing: border-box;
  188. &.is-green {
  189. --install-icon-bg: url('@/assets/images/vent/home/selfIgnition/install-icon-green.png');
  190. --install-name-bg: url('@/assets/images/vent/home/selfIgnition/install-name-green.png');
  191. --install-metric-bg: url('@/assets/images/vent/home/selfIgnition/install-metric-green.png');
  192. }
  193. }
  194. .install-icon {
  195. position: relative;
  196. z-index: 4;
  197. display: flex;
  198. align-items: center;
  199. justify-content: center;
  200. flex: 0 0 40px;
  201. width: 40px;
  202. height: 35px;
  203. margin-right: -32px;
  204. background: var(--install-icon-bg) no-repeat center / 100% 100%;
  205. img {
  206. width: 20px;
  207. height: 20px;
  208. }
  209. }
  210. .install-name {
  211. position: relative;
  212. z-index: 3;
  213. display: flex;
  214. align-items: center;
  215. flex: 0 0 124px;
  216. height: 34px;
  217. padding-left: 34px;
  218. box-sizing: border-box;
  219. background: var(--install-name-bg) no-repeat center / 100% 100%;
  220. color: #fff;
  221. font-size: 15px;
  222. font-weight: 600;
  223. letter-spacing: 0;
  224. white-space: nowrap;
  225. }
  226. .install-metric {
  227. position: relative;
  228. z-index: 1;
  229. display: flex;
  230. align-items: center;
  231. flex: 1 1 0;
  232. min-width: 0;
  233. height: 34px;
  234. margin-left: -9px;
  235. padding-left: 16px;
  236. box-sizing: border-box;
  237. background: var(--install-metric-bg) no-repeat center / 100% 100%;
  238. color: #eefcff;
  239. font-size: 15px;
  240. font-weight: 500;
  241. white-space: nowrap;
  242. & + & {
  243. z-index: 2;
  244. }
  245. em {
  246. margin: 0 2px;
  247. color: #3df6ff;
  248. font-family: Arial, sans-serif;
  249. font-style: italic;
  250. font-size: 18px;
  251. font-weight: 700;
  252. line-height: 1;
  253. text-shadow: 0 0 5px rgba(61, 246, 255, 0.45);
  254. }
  255. }
  256. .warning-table-panel {
  257. display: flex;
  258. flex-direction: column;
  259. height: 100%;
  260. padding: 8px 22px 0;
  261. box-sizing: border-box;
  262. }
  263. .warning-table {
  264. flex: 1 1 auto;
  265. height: 100%;
  266. min-height: 0;
  267. box-sizing: border-box;
  268. overflow-y: auto;
  269. border: 1px solid rgba(61, 246, 255, 0.55);
  270. background: rgba(6, 30, 52, 0.2);
  271. .scrollbar-cyan();
  272. }
  273. .table-head,
  274. .table-row {
  275. display: flex;
  276. align-items: center;
  277. text-align: center;
  278. }
  279. .table-head {
  280. position: sticky;
  281. top: 0;
  282. z-index: 1;
  283. height: 39px;
  284. box-sizing: border-box;
  285. color: #3df6ff;
  286. font-size: 15px;
  287. font-weight: 500;
  288. letter-spacing: 1px;
  289. background: #062441;
  290. border-bottom: 1px solid rgba(61, 246, 255, 0.5);
  291. }
  292. .table-row {
  293. height: 42px;
  294. box-sizing: border-box;
  295. color: #fff;
  296. font-size: 15px;
  297. background: #093354;
  298. border-top: 1px solid rgba(61, 246, 255, 0.14);
  299. &:nth-child(even) {
  300. background: #0d4167;
  301. }
  302. }
  303. .table-row-empty {
  304. color: transparent;
  305. }
  306. .col-index {
  307. width: 9%;
  308. }
  309. .col-name {
  310. width: 24%;
  311. }
  312. .col-seam {
  313. width: 18%;
  314. }
  315. .col-level {
  316. width: 24%;
  317. }
  318. .col-safety {
  319. width: 25%;
  320. }
  321. .level-cell {
  322. display: flex;
  323. align-items: center;
  324. justify-content: center;
  325. gap: 7px;
  326. min-width: 0;
  327. > span {
  328. overflow: hidden;
  329. text-overflow: ellipsis;
  330. white-space: nowrap;
  331. }
  332. }
  333. .level-icon {
  334. flex: none;
  335. object-fit: contain;
  336. }
  337. .warning-icon {
  338. width: 14px;
  339. height: 14px;
  340. }
  341. .safety-icon {
  342. width: 12px;
  343. height: 15px;
  344. }
  345. </style>