index.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726
  1. <template>
  2. <div :key="viewKey" class="screen-container">
  3. <common-header title="工位任务分布/防静电监控" />
  4. <!-- <div
  5. style="
  6. width: 100vw;
  7. height: 92vh;
  8. display: flex;
  9. justify-content: center;
  10. align-items: center;
  11. position: relative;
  12. "
  13. >
  14. <dv-border-box1
  15. ref="borderRef"
  16. style="width: 66.6%; height: 66.6%; position: absolute"
  17. :style="{ transform: 'scale(' + 1.5 + ')' }"
  18. />
  19. </div> -->
  20. <div class="screen-content">
  21. <!-- <TransitionGroup class="rowbox" name="list1" tag="ul">
  22. <div v-for="(item, index) in showdatas1" :key="item" class="grid-item">
  23. <title-header :title="item.stationName" />
  24. <div class="grid-bottom">
  25. <div class="left-info">
  26. <div
  27. class="box"
  28. style="
  29. display: flex;
  30. flex-direction: column;
  31. justify-content: center;
  32. "
  33. >
  34. <div class="title">{{ item.materialName }}</div>
  35. <div class="code">{{ item.materialModel }}</div>
  36. </div>
  37. <div class="box">
  38. <div style="display: flex; align-items: center">
  39. <dv-digital-flop
  40. :config="completeNumConfigs[index]"
  41. class="flop"
  42. />
  43. <span class="plan-num">/</span>
  44. <dv-digital-flop
  45. :config="taskNumConfigs[index]"
  46. class="flop"
  47. />
  48. </div>
  49. <div class="desc">完成数量 / 计划数量</div>
  50. </div>
  51. </div>
  52. <div class="right-chart">
  53. <dv-water-level-pond
  54. :config="{
  55. data: [setPondNumber(item.rate)],
  56. shape: 'round',
  57. }"
  58. :key="sum1"
  59. style="width: 16vh; height: 16vh"
  60. />
  61. </div>
  62. </div>
  63. </div>
  64. </TransitionGroup> -->
  65. <TransitionGroup class="rowbox itemBackgroud" name="list1" tag="ul">
  66. <title-header :title="'防静电监控'" />
  67. <div class="chartsCarouselBox">
  68. <div class="carouselHeader tableStyle">
  69. <div class="left center1Text">工位名称</div>
  70. <div class="right center1Text">状态</div>
  71. </div>
  72. <div class="carouselBody">
  73. <TransitionGroup name="list" tag="ul">
  74. <li
  75. class="carouselItem tableStyle"
  76. :key="item"
  77. v-for="item in showData1"
  78. >
  79. <div class="left infoBackgroud centerText textComent">
  80. {{ item.stationName }}
  81. </div>
  82. <div
  83. :class="{
  84. outline: item.state === '离线',
  85. error: item.state === '故障',
  86. }"
  87. class="right infoBackgroud centerText textComent"
  88. style="font-weight: bolder"
  89. >
  90. {{ item.state }}
  91. </div>
  92. </li>
  93. </TransitionGroup>
  94. </div>
  95. </div>
  96. </TransitionGroup>
  97. <TransitionGroup class="rowbox" name="list2" tag="ul">
  98. <div v-for="(item, index) in showdatas2" :key="item" class="grid-item">
  99. <title-header :title="item.stationName" />
  100. <div class="grid-bottom">
  101. <div class="left-info">
  102. <div
  103. class="box"
  104. style="
  105. display: flex;
  106. flex-direction: column;
  107. justify-content: center;
  108. "
  109. >
  110. <div class="title">{{ item.materialName }}</div>
  111. <div class="code">{{ item.materialModel }}</div>
  112. </div>
  113. <div class="box">
  114. <div style="display: flex; align-items: center">
  115. <dv-digital-flop
  116. :config="completeNumConfigs[index + 3]"
  117. class="flop"
  118. />
  119. <span class="plan-num">/</span>
  120. <dv-digital-flop
  121. :config="taskNumConfigs[index + 3]"
  122. class="flop"
  123. />
  124. </div>
  125. <div class="desc">完成数量 / 计划数量</div>
  126. </div>
  127. </div>
  128. <div class="right-chart">
  129. <dv-water-level-pond
  130. :config="{
  131. data: [setPondNumber(item.rate)],
  132. shape: 'round',
  133. }"
  134. :key="sum1"
  135. style="width: 16vh; height: 16vh"
  136. />
  137. </div>
  138. </div>
  139. </div>
  140. </TransitionGroup>
  141. <TransitionGroup class="rowbox" name="list3" tag="ul">
  142. <div v-for="(item, index) in showdatas3" :key="item" class="grid-item">
  143. <title-header :title="item.stationName" />
  144. <div class="grid-bottom">
  145. <div class="left-info">
  146. <div
  147. class="box"
  148. style="
  149. display: flex;
  150. flex-direction: column;
  151. justify-content: center;
  152. "
  153. >
  154. <div class="title">{{ item.materialName }}</div>
  155. <div class="code">{{ item.materialModel }}</div>
  156. </div>
  157. <div class="box">
  158. <div style="display: flex; align-items: center">
  159. <dv-digital-flop
  160. :config="completeNumConfigs[index + 3]"
  161. class="flop"
  162. />
  163. <span class="plan-num">/</span>
  164. <dv-digital-flop
  165. :config="taskNumConfigs[index + 3]"
  166. class="flop"
  167. />
  168. </div>
  169. <div class="desc">完成数量 / 计划数量</div>
  170. </div>
  171. </div>
  172. <div class="right-chart">
  173. <dv-water-level-pond
  174. :config="{
  175. data: [setPondNumber(item.rate)],
  176. shape: 'round',
  177. }"
  178. :key="sum1"
  179. style="width: 16vh; height: 16vh"
  180. />
  181. </div>
  182. </div>
  183. </div>
  184. </TransitionGroup>
  185. </div>
  186. </div>
  187. </template>
  188. <script setup>
  189. import CommonHeader from "@/views/report/statistics/screens/common-header.vue";
  190. import TitleHeader from "@/views/report/statistics/screens/titleHeader.vue";
  191. import { getStationTaskInfo, getStationState } from "@/api/bigScreen";
  192. const showData1 = ref([]);
  193. const fontSize = ref(0);
  194. const setPondNumber = (str) => {
  195. const number = Number(str).toFixed(2);
  196. if (number == 1) {
  197. return 100;
  198. } else {
  199. let str = number.toString(); // "0.18"
  200. let truncated = parseInt(
  201. str.substring(str.indexOf(".") + 1, str.indexOf(".") + 3)
  202. );
  203. return truncated;
  204. }
  205. };
  206. const viewKey = ref(false);
  207. const setFontSize = () => {
  208. fontSize.value = (window.innerHeight / 100) * 4;
  209. };
  210. const datas = ref([]);
  211. // const showdatas1 = ref([]);
  212. const showdatas2 = ref([]);
  213. const showdatas3 = ref([]);
  214. const getData = async () => {
  215. const { data } = await getStationTaskInfo();
  216. datas.value = [...data];
  217. // if (datas.value.length < 9) {
  218. // completeNumConfigs.value.splice(0, datas.value.length - 1);
  219. // taskNumConfigs.value.splice(0, datas.value.length - 1);
  220. // }
  221. };
  222. const interval1 = ref(null);
  223. const sum1 = ref(1);
  224. const sum2 = ref(1);
  225. const data1 = ref([]);
  226. const getData1 = async () => {
  227. const { data } = await getStationState();
  228. data1.value = data.stationState;
  229. };
  230. const setShowData1 = (num, time) => {
  231. sum2.value = num;
  232. if (data1.value.length > num) {
  233. const dataA = JSON.parse(JSON.stringify(data1.value));
  234. showData1.value = dataA.splice(0, num);
  235. interval1.value = setInterval(async () => {
  236. await showData1.value.push(data1.value[sum2.value % data1.value.length]);
  237. showData1.value.splice(0, 1);
  238. sum2.value = sum2.value + 1;
  239. }, time);
  240. } else {
  241. showData1.value = data1.value;
  242. }
  243. };
  244. const setShowDatas = async (time) => {
  245. if (datas.value.length > 6) {
  246. // const dataA = JSON.parse(JSON.stringify(datas.value));
  247. const dataB = JSON.parse(JSON.stringify(datas.value));
  248. const dataC = JSON.parse(JSON.stringify(datas.value));
  249. // showdatas1.value = dataA.splice(0, 3);
  250. showdatas2.value = dataB.splice(0, 3);
  251. showdatas3.value = dataC.splice(3, 3);
  252. setNumber(1750);
  253. interval1.value = setInterval(async () => {
  254. // showdatas1.value.push(
  255. // datas.value[(sum1.value + 2) % (datas.value.length - 1)]
  256. // );
  257. showdatas2.value.push(
  258. datas.value[(sum1.value + 2) % (datas.value.length - 1)]
  259. );
  260. showdatas3.value.push(
  261. datas.value[(sum1.value + 5) % (datas.value.length - 1)]
  262. );
  263. // showdatas1.value.splice(0, 1);
  264. showdatas2.value.splice(0, 1);
  265. showdatas3.value.splice(0, 1);
  266. setNumber(0);
  267. sum1.value = sum1.value + 1;
  268. }, time);
  269. } else {
  270. // const dataA = JSON.parse(JSON.stringify(datas.value));
  271. const dataB = JSON.parse(JSON.stringify(datas.value));
  272. const dataC = JSON.parse(JSON.stringify(datas.value));
  273. // showdatas1.value = dataA.splice(0, 3);
  274. showdatas2.value = dataB.splice(0, 3);
  275. showdatas3.value = dataC.splice(3, 3);
  276. setNumber(2000);
  277. }
  278. };
  279. const completeNumConfigs = ref([
  280. {
  281. number: [0],
  282. style: {
  283. fontSize: fontSize,
  284. },
  285. },
  286. {
  287. number: [0],
  288. style: {
  289. fontSize: fontSize,
  290. },
  291. },
  292. {
  293. number: [0],
  294. style: {
  295. fontSize: fontSize,
  296. },
  297. },
  298. {
  299. number: [0],
  300. style: {
  301. fontSize: fontSize,
  302. },
  303. },
  304. {
  305. number: [0],
  306. style: {
  307. fontSize: fontSize,
  308. },
  309. },
  310. {
  311. number: [0],
  312. style: {
  313. fontSize: fontSize,
  314. },
  315. },
  316. {
  317. number: [0],
  318. style: {
  319. fontSize: fontSize,
  320. },
  321. },
  322. {
  323. number: [0],
  324. style: {
  325. fontSize: fontSize,
  326. },
  327. },
  328. {
  329. number: [0],
  330. style: {
  331. fontSize: fontSize,
  332. },
  333. },
  334. ]);
  335. const taskNumConfigs = ref([
  336. {
  337. number: [0],
  338. style: {
  339. fontSize: fontSize,
  340. fill: "#ffffff",
  341. },
  342. },
  343. {
  344. number: [0],
  345. style: {
  346. fontSize: fontSize,
  347. fill: "#ffffff",
  348. },
  349. },
  350. {
  351. number: [0],
  352. style: {
  353. fontSize: fontSize,
  354. fill: "#ffffff",
  355. },
  356. },
  357. {
  358. number: [0],
  359. style: {
  360. fontSize: fontSize,
  361. fill: "#ffffff",
  362. },
  363. },
  364. {
  365. number: [0],
  366. style: {
  367. fontSize: fontSize,
  368. fill: "#ffffff",
  369. },
  370. },
  371. {
  372. number: [0],
  373. style: {
  374. fontSize: fontSize,
  375. fill: "#ffffff",
  376. },
  377. },
  378. {
  379. number: [0],
  380. style: {
  381. fontSize: fontSize,
  382. fill: "#ffffff",
  383. },
  384. },
  385. {
  386. number: [0],
  387. style: {
  388. fontSize: fontSize,
  389. fill: "#ffffff",
  390. },
  391. },
  392. {
  393. number: [0],
  394. style: {
  395. fontSize: fontSize,
  396. fill: "#ffffff",
  397. },
  398. },
  399. ]);
  400. const setTimeOutFnc = (array, num, time) => {
  401. setTimeout(() => {
  402. array.number = [num];
  403. }, time);
  404. };
  405. const setNumber = (time) => {
  406. // if (showdatas1.value.length > 0) {
  407. // showdatas1.value.forEach((item, index) => {
  408. // setTimeOutFnc(completeNumConfigs.value[index], item.completeNum, time);
  409. // setTimeOutFnc(taskNumConfigs.value[index], item.taskNum, time);
  410. // });
  411. // }
  412. if (showdatas2.value.length > 0) {
  413. showdatas2.value.forEach((item, index) => {
  414. setTimeOutFnc(
  415. completeNumConfigs.value[index + 3],
  416. item.completeNum,
  417. time
  418. );
  419. setTimeOutFnc(taskNumConfigs.value[index + 3], item.taskNum, time);
  420. });
  421. }
  422. if (showdatas3.value.length > 0) {
  423. showdatas2.value.forEach((item, index) => {
  424. setTimeOutFnc(
  425. completeNumConfigs.value[index + 3],
  426. item.completeNum,
  427. time
  428. );
  429. setTimeOutFnc(taskNumConfigs.value[index + 3], item.taskNum, time);
  430. });
  431. }
  432. };
  433. onUnmounted(() => {
  434. if (interval1.value) {
  435. clearInterval(interval1.value);
  436. }
  437. });
  438. const checkFullscreen = () => {
  439. viewKey.value = !viewKey.value;
  440. };
  441. onMounted(async () => {
  442. window.addEventListener("resize", checkFullscreen);
  443. setFontSize();
  444. await getData();
  445. await getData1();
  446. setShowData1(17, 2000);
  447. setShowDatas(5000);
  448. });
  449. onUnmounted(() => {
  450. document.removeEventListener("resize", checkFullscreen);
  451. });
  452. </script>
  453. <style lang="scss" scoped>
  454. .outline {
  455. background-color: rgb(80, 83, 90) !important;
  456. }
  457. .error {
  458. background-color: rgb(219, 72, 72) !important;
  459. }
  460. .centerText {
  461. color: rgba(255, 255, 255, 0.8);
  462. font-size: 1.7vh;
  463. display: flex;
  464. align-items: center;
  465. justify-content: center;
  466. padding: 0 0.3vh;
  467. font-weight: 100 !important;
  468. }
  469. .textComent {
  470. white-space: nowrap; /* 不允许换行 */
  471. overflow: hidden; /* 超出长度时隐藏 */
  472. text-overflow: ellipsis; /* 超出部分显示省略号 */
  473. }
  474. .itemBackgroud {
  475. background-color: rgba(0, 0, 0, 0.6);
  476. padding: 2vh;
  477. border-radius: 2vh;
  478. }
  479. .infoBackgroud {
  480. background-color: rgba(255, 255, 255, 0.05);
  481. }
  482. .tableStyle {
  483. display: flex;
  484. justify-content: space-between;
  485. width: 30vw;
  486. .left {
  487. width: 83%;
  488. }
  489. .right {
  490. width: 16%;
  491. }
  492. }
  493. .center1Text {
  494. color: rgba(255, 255, 255, 0.8);
  495. font-size: 1.7vh;
  496. display: flex;
  497. align-items: center;
  498. justify-content: center;
  499. padding: 0 0.3vh;
  500. }
  501. .chartsCarouselBox {
  502. width: 100%;
  503. height: 100%;
  504. display: flex;
  505. flex-direction: column;
  506. position: relative;
  507. .carouselHeader {
  508. height: calc(2vh);
  509. line-height: 2vh;
  510. margin-bottom: 0.5vh;
  511. }
  512. .carouselBody {
  513. flex: 1;
  514. display: flex;
  515. flex-direction: column;
  516. justify-content: space-between;
  517. overflow: hidden;
  518. .carouselItem {
  519. margin-bottom: 0.5vh;
  520. height: 3.9vh;
  521. }
  522. }
  523. }
  524. .infoItemBody {
  525. width: 100%;
  526. height: 60%;
  527. display: flex;
  528. flex-direction: column;
  529. padding: 0.8vw;
  530. .chartsBox {
  531. flex: 1;
  532. position: relative;
  533. }
  534. }
  535. //动画配置
  536. .list-move,
  537. .list-enter-active,
  538. .list-leave-active {
  539. transition: all 1s ease;
  540. }
  541. .list-enter-from,
  542. .list-leave-to {
  543. opacity: 0;
  544. transform: scaleY(0) translateY(-4.6vh);
  545. }
  546. .list-leave-active {
  547. position: absolute;
  548. }
  549. .list1-move,
  550. .list1-enter-active {
  551. transition: all 0.75s ease;
  552. }
  553. .list1-leave-active {
  554. transition: all 2s ease;
  555. }
  556. .list1-enter-from {
  557. transform: translateX(80vw);
  558. }
  559. .list1-leave-to {
  560. opacity: 0;
  561. transform: translateX(-40vw);
  562. }
  563. .list1-leave-active {
  564. position: absolute;
  565. }
  566. .list2-move,
  567. .list2-enter-active {
  568. transition: all 1.25s ease;
  569. }
  570. .list2-leave-active {
  571. transition: all 2s ease;
  572. }
  573. .list2-enter-from {
  574. transform: translateX(60vw);
  575. }
  576. .list2-leave-to {
  577. opacity: 0;
  578. height: 0;
  579. transform: translateY(-40vh);
  580. }
  581. .list2-leave-active {
  582. position: absolute;
  583. }
  584. .list3-move,
  585. .list3-enter-active {
  586. transition: all 1.75s ease;
  587. }
  588. .list3-leave-active {
  589. transition: all 2s ease;
  590. }
  591. .list3-enter-from {
  592. transform: translateX(40vw);
  593. }
  594. .list3-leave-to {
  595. opacity: 0;
  596. height: 0;
  597. transform: translateX(40vw);
  598. }
  599. .list3-leave-active {
  600. position: absolute;
  601. }
  602. //动画配置--
  603. :deep(.dv-water-pond-level) {
  604. text {
  605. font-size: 4vh;
  606. }
  607. }
  608. .screen-container {
  609. width: 100vw;
  610. height: 100vh;
  611. background-image: url("@/assets/images/screen_bg_task.png");
  612. background-size: cover;
  613. background-position: center;
  614. overflow: hidden;
  615. }
  616. .flop {
  617. width: 10vh;
  618. height: 6vh;
  619. display: block;
  620. font-size: 4vh;
  621. }
  622. .screen-content {
  623. height: 84vh;
  624. margin-top: 2vh;
  625. display: flex;
  626. justify-content: space-between;
  627. flex-wrap: wrap;
  628. padding: 0 2vh;
  629. .rowbox {
  630. width: 32vw;
  631. display: flex;
  632. flex-direction: column;
  633. align-items: center;
  634. justify-content: space-between;
  635. }
  636. .grid-item {
  637. height: 100%;
  638. display: flex;
  639. flex-direction: column;
  640. background: rgba(0, 0, 0, 0.5);
  641. border-radius: 2vh;
  642. padding: 2vh 1vh;
  643. width: 31vw;
  644. height: 25vh;
  645. .grid-bottom {
  646. display: flex;
  647. justify-content: space-between;
  648. align-items: center;
  649. flex: 1; //当父组件为flex时候,子组件剩余空间可写100%或者flex:1;
  650. .left-info {
  651. display: flex;
  652. flex-direction: column;
  653. justify-content: space-between;
  654. align-items: start;
  655. padding: 0px 1vh;
  656. height: 100%;
  657. width: 65%;
  658. .box {
  659. height: 50%;
  660. width: 100%;
  661. }
  662. .title {
  663. font-weight: 500;
  664. font-size: 3vh;
  665. color: #ffffff;
  666. line-height: 3vh;
  667. width: 100%;
  668. display: block;
  669. white-space: nowrap; /* 不允许换行 */
  670. overflow: hidden; /* 超出长度时隐藏 */
  671. text-overflow: ellipsis; /* 超出部分显示省略号 */
  672. }
  673. .code {
  674. font-weight: 400;
  675. font-size: 2vh;
  676. color: #fff9;
  677. line-height: 2vh;
  678. margin-top: 1vh;
  679. display: -webkit-box;
  680. -webkit-line-clamp: 2; /* 限制为两行 */
  681. -webkit-box-orient: vertical;
  682. overflow: hidden;
  683. text-overflow: ellipsis;
  684. }
  685. .com-num {
  686. font-weight: 500;
  687. font-size: 2vh;
  688. color: #55d1aa;
  689. }
  690. .plan-num {
  691. font-weight: 500;
  692. font-size: 4vh;
  693. color: #fff;
  694. }
  695. .desc {
  696. font-weight: 400;
  697. font-size: 2vh;
  698. color: #ffffff;
  699. line-height: 2vh;
  700. padding-left: 1.4vh;
  701. }
  702. }
  703. .right-chart {
  704. display: flex;
  705. justify-content: center;
  706. align-items: center;
  707. height: 100%;
  708. width: 35%;
  709. }
  710. }
  711. }
  712. }
  713. </style>