index.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  1. <template>
  2. <div>
  3. <Middle3D ref="modelRef" />
  4. <div class="screen-container">
  5. <common-headerB title="装调一体式智能生产线仿真大屏" />
  6. <div class="body">
  7. <div class="left block">
  8. <div class="block-header left-block">
  9. <div class="text">工位状态</div>
  10. <div class="english">Station status</div>
  11. </div>
  12. <div class="block-body">
  13. <div class="left-header">
  14. <div class="num-item">
  15. <div class="item-title">总数</div>
  16. <div class="item-num">{{ infoObj.total }}</div>
  17. </div>
  18. <div class="num-item">
  19. <div class="item-title">在线</div>
  20. <div class="item-num">{{ infoObj.online }}</div>
  21. </div>
  22. <div class="num-item">
  23. <div class="item-title">离线</div>
  24. <div class="item-num">{{ infoObj.offline }}</div>
  25. </div>
  26. <div class="num-item">
  27. <div class="item-title">故障</div>
  28. <div class="item-num">{{ infoObj.fault }}</div>
  29. </div>
  30. </div>
  31. <div class="divider"></div>
  32. <ShowScroll
  33. ref="ShowScrollRef1"
  34. :scrollRef="scrollbarRef1"
  35. :innerRef="innerRef1"
  36. >
  37. <el-scrollbar ref="scrollbarRef1" class="left-scrollbar">
  38. <div ref="innerRef1">
  39. <div
  40. class="infoItem"
  41. v-for="(item, index) in taskRateArray"
  42. :key="index"
  43. >
  44. <div class="leftItem textComent itembg">
  45. {{ item.stationName }}
  46. </div>
  47. <div class="rightItem itembg">{{ item.state }}</div>
  48. </div>
  49. </div>
  50. </el-scrollbar>
  51. </ShowScroll>
  52. </div>
  53. </div>
  54. <div class="btn">
  55. <div class="tab">
  56. <div
  57. :class="aotuStatus ? 'tab-list tab-active' : 'tab-list'"
  58. @click="autoView"
  59. >
  60. 自动巡航
  61. </div>
  62. <div
  63. :class="!aotuStatus ? 'tab-list tab-active' : 'tab-list'"
  64. @click="returnView"
  65. >
  66. 恢复视角
  67. </div>
  68. </div>
  69. </div>
  70. <div class="right block">
  71. <div class="block-header right-block">
  72. <div class="text">设备状态</div>
  73. <div class="english">auto-equipment status</div>
  74. </div>
  75. <div class="block-body">
  76. <ShowScroll
  77. ref="ShowScrollRef2"
  78. :scrollRef="scrollbarRef2"
  79. :innerRef="innerRef2"
  80. >
  81. <el-scrollbar ref="scrollbarRef2" class="right-scrollbar">
  82. <div ref="innerRef2">
  83. <div
  84. class="deviceInfo"
  85. v-for="(item, index) in deviceArray"
  86. :key="index"
  87. >
  88. <div class="img">
  89. <el-image
  90. :src="`/images/${item.deviceType}.png`"
  91. class="img"
  92. />
  93. <div
  94. class="imgbg"
  95. :class="{
  96. outlinebg: item.state == '离线',
  97. errorbg: item.state == '故障',
  98. }"
  99. ></div>
  100. </div>
  101. <div class="info">
  102. <div class="info1">{{ item.deviceName }}</div>
  103. <div class="info2">
  104. <div class="text2">
  105. 今日稼动
  106. <span class="nums">{{ item.utilizationRate }}</span>
  107. </div>
  108. |
  109. <div class="text2">
  110. 总稼动
  111. <span class="nums" style="color: white">{{
  112. item.totalRate
  113. }}</span>
  114. </div>
  115. </div>
  116. <div class="info3">
  117. <div class="ip">ID:{{ item.id }}</div>
  118. <div class="ip">位置:{{ item.position }}</div>
  119. <div
  120. class="infoState"
  121. :class="{
  122. red: item.state == '故障',
  123. white: item.state == '离线',
  124. }"
  125. >
  126. {{ item.state }}
  127. </div>
  128. </div>
  129. </div>
  130. </div>
  131. </div>
  132. </el-scrollbar>
  133. </ShowScroll>
  134. </div>
  135. </div>
  136. </div>
  137. </div>
  138. </div>
  139. </template>
  140. <script setup>
  141. import CommonHeaderB from "@/views/report/statistics/screens/common-headerB.vue";
  142. import {
  143. getFaultCount,
  144. getTaskCount,
  145. getTaskRate,
  146. getDeviceList,
  147. getMaterialRate,
  148. getTodayError,
  149. getOnline3DInfo,
  150. } from "@/api/bigScreen";
  151. import Middle3D from "./middle3D.vue";
  152. const aotuStatus = ref(true);
  153. const ShowScrollRef1 = ref(null);
  154. const innerRef1 = ref(null);
  155. const scrollbarRef1 = ref(null);
  156. const ShowScrollRef2 = ref(null);
  157. const innerRef2 = ref(null);
  158. const scrollbarRef2 = ref(null);
  159. const modelRef = ref(null);
  160. const autoView = () => {
  161. aotuStatus.value = true;
  162. modelRef.value.startFnc();
  163. };
  164. const returnView = () => {
  165. aotuStatus.value = false;
  166. modelRef.value.downFnc();
  167. };
  168. const deviceArray = ref([]);
  169. const infoObj = ref({});
  170. const getRateArray = async () => {
  171. const { data } = await getOnline3DInfo();
  172. infoObj.value = data;
  173. taskRateArray.value = data.stationState;
  174. nextTick(() => {
  175. ShowScrollRef1.value.setActive();
  176. });
  177. };
  178. const getDevice = async () => {
  179. const { data } = await getDeviceList({
  180. deviceTypes: ["CCJQR", "DDLSD", "DYJXB", "JDJKQ", "WKDLT", "WSDJKQ"],
  181. });
  182. deviceArray.value = data;
  183. nextTick(() => {
  184. ShowScrollRef2.value.setActive();
  185. });
  186. };
  187. const getRandomLetter = () => {
  188. const letters = ["a", "b", "c", "d"];
  189. const randomIndex = Math.floor(Math.random() * letters.length);
  190. return letters[randomIndex];
  191. };
  192. const taskRateArray = ref([]);
  193. onMounted(() => {
  194. modelRef.value.startFnc();
  195. getDevice();
  196. getRateArray();
  197. });
  198. </script>
  199. <style lang="scss" scoped>
  200. .deviceInfo {
  201. width: 21vw;
  202. height: 10vh;
  203. margin: 1vh 0;
  204. display: flex;
  205. background-color: rgba(255, 255, 255, 0.05);
  206. // clip-path: polygon(0% 0%, 85% 0%, 100% 25%, 100% 100%, 0% 100%);
  207. .img {
  208. height: 10vh;
  209. width: 7vw;
  210. position: relative;
  211. .imgbg {
  212. position: absolute;
  213. height: 10vh;
  214. width: 7vw;
  215. top: 0;
  216. left: 0;
  217. z-index: 2;
  218. background-color: #06ffa520;
  219. border: 0.4vh solid #06ffa5;
  220. }
  221. .outlinebg {
  222. background-color: #ffffff20 !important;
  223. border: 0.4vh solid #fff !important;
  224. }
  225. .errorbg {
  226. background-color: #db484820 !important;
  227. border: 0.4vh solid #db4848 !important;
  228. }
  229. }
  230. .info {
  231. height: 10vh;
  232. width: 100%;
  233. display: flex;
  234. flex-direction: column;
  235. justify-content: space-between;
  236. padding-top: 1vh;
  237. .info1 {
  238. padding-left: 0.5vw;
  239. height: 2vh;
  240. font-size: 2vh;
  241. line-height: 2vh;
  242. font-weight: 600;
  243. color: white;
  244. }
  245. .info2 {
  246. height: 2vh;
  247. padding-left: 0.5vw;
  248. display: flex;
  249. justify-content: space-between;
  250. align-items: center;
  251. color: white;
  252. padding-right: 1vw;
  253. .text2 {
  254. font-size: 1.5vh;
  255. .nums {
  256. color: #0ae0ff;
  257. font-weight: 600;
  258. }
  259. }
  260. }
  261. .info3 {
  262. height: 2vh;
  263. font-size: 2vh;
  264. // background-color: rgba(255, 255, 255, 0.05);
  265. display: flex;
  266. padding-left: 0.5vw;
  267. padding-right: 1vw;
  268. justify-content: space-between;
  269. .ip {
  270. font-size: 1.6vh;
  271. line-height: 2vh;
  272. color: white;
  273. }
  274. .infoState {
  275. font-size: 1.6vh;
  276. line-height: 2vh;
  277. color: #06ffa5;
  278. }
  279. }
  280. }
  281. }
  282. .textComent {
  283. white-space: nowrap; /* 不允许换行 */
  284. overflow: hidden; /* 超出长度时隐藏 */
  285. text-overflow: ellipsis; /* 超出部分显示省略号 */
  286. }
  287. .itembg {
  288. background-color: #46464635;
  289. }
  290. .screen-container {
  291. width: 100vw;
  292. height: 100vh;
  293. position: fixed;
  294. top: 0;
  295. left: 0;
  296. z-index: 20;
  297. .body {
  298. width: 100vw;
  299. height: 92vh;
  300. display: flex;
  301. justify-content: space-between;
  302. .btn {
  303. flex: 1;
  304. height: 10vh;
  305. display: flex;
  306. justify-content: center;
  307. .tab {
  308. display: flex;
  309. align-items: center;
  310. justify-content: center;
  311. .tab-list {
  312. padding: 0.521vw 2.604vw;
  313. letter-spacing: 0.104vw;
  314. color: white;
  315. background-image: url("@/assets/images/environmentTest/tab.png");
  316. background-size: 100% 100%;
  317. font-weight: 700;
  318. font-size: 0.9375vw;
  319. &:nth-of-type(1) {
  320. margin-right: -0.26vw;
  321. }
  322. &:hover {
  323. cursor: pointer;
  324. }
  325. }
  326. .tab-active {
  327. background-image: url("@/assets/images/environmentTest/tab_active.png");
  328. }
  329. }
  330. }
  331. .block {
  332. padding: 2.3vw 2vw;
  333. height: 92vh;
  334. width: 22.292vw;
  335. .block-header {
  336. padding: 0 3vw 0.15vw;
  337. font-weight: 700;
  338. font-style: italic;
  339. letter-spacing: 0.1vw;
  340. .text {
  341. color: white;
  342. font-size: 1.146vw;
  343. }
  344. .english {
  345. font-size: 0.833vw;
  346. color: #318c9f;
  347. }
  348. }
  349. .right-block {
  350. background-image: url("@/assets/images/environmentTest/right-title-bg.png");
  351. background-size: 100% 100%;
  352. }
  353. .left-block {
  354. background-image: url("@/assets/images/environmentTest/left-title-bg.png");
  355. background-size: 100% 100%;
  356. }
  357. .block-body {
  358. display: flex;
  359. flex: 1;
  360. flex-direction: column;
  361. .left-scrollbar {
  362. height: 63vh;
  363. margin: 1vh 0;
  364. }
  365. .right-scrollbar {
  366. width: 26.292vw;
  367. height: 73vh;
  368. margin: 1vh 0;
  369. margin-left: -2vw;
  370. }
  371. .left-header {
  372. height: 10vh;
  373. font-style: italic;
  374. display: flex;
  375. justify-content: space-evenly;
  376. .num-item {
  377. width: 3vw;
  378. height: 10vh;
  379. display: flex;
  380. flex-direction: column;
  381. justify-content: space-evenly;
  382. text-align: center;
  383. color: white;
  384. font-size: 2.5vh;
  385. .item-title {
  386. }
  387. .item-num {
  388. }
  389. }
  390. }
  391. .divider {
  392. height: 0.104vw;
  393. background-image: url("@/assets/images/environmentTest/divider.png");
  394. background-size: 100% 100%;
  395. }
  396. }
  397. }
  398. .left {
  399. background-image: url("@/assets/images/environmentTest/left-bg.png");
  400. background-size: 100% 100%;
  401. }
  402. .right {
  403. background-image: url("@/assets/images/environmentTest/right-bg.png");
  404. background-size: 100% 100%;
  405. }
  406. }
  407. }
  408. .infoItem {
  409. height: 4vh;
  410. margin-bottom: 0.4vh;
  411. display: flex;
  412. .leftItem {
  413. flex: 1;
  414. height: 4vh;
  415. font-size: 1.8vh;
  416. line-height: 4vh;
  417. color: white;
  418. text-align: center;
  419. }
  420. .rightItem {
  421. width: 25%;
  422. height: 4vh;
  423. line-height: 4vh;
  424. margin-left: 0.3vw;
  425. font-size: 1.8vh;
  426. color: white;
  427. text-align: center;
  428. }
  429. .leftItem1 {
  430. flex: 1;
  431. height: 4vh;
  432. font-size: 1.8vh;
  433. line-height: 4vh;
  434. color: white;
  435. text-align: center;
  436. }
  437. .midItem1 {
  438. width: 25%;
  439. height: 4vh;
  440. line-height: 4vh;
  441. margin-left: 0.3vw;
  442. font-size: 1.8vh;
  443. color: white;
  444. text-align: center;
  445. }
  446. .rightItem1 {
  447. width: 20%;
  448. height: 4vh;
  449. line-height: 4vh;
  450. margin-left: 0.3vw;
  451. font-size: 1.8vh;
  452. color: white;
  453. text-align: center;
  454. }
  455. }
  456. </style>