moldPressingWorkshop.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654
  1. <template>
  2. <vue-fullscreen
  3. class="box-container"
  4. v-model="isFullscreen"
  5. fullscreenClass="box-container"
  6. :exit-on-click-wrapper="false"
  7. v-cloak
  8. >
  9. <div class="box-container">
  10. <div class="box-header">
  11. <div class="logo">
  12. <!-- <img src="../../../assets/logo_1.png" alt="" />
  13. <span>株硬集团型材分公司</span> -->
  14. </div>
  15. <div class="title"> 模压车间设备运维看板 </div>
  16. <div class="time">
  17. <span
  18. style="color: #7fa7ce; margin: 5px 10px 15px 0; cursor: pointer"
  19. @click.passive="onFullscreen"
  20. >
  21. <i
  22. v-if="isFullscreen"
  23. title="取消全屏"
  24. class="el-icon-_screen-restore"
  25. ></i>
  26. <i v-else title="全屏" class="el-icon-_screen-full"></i>
  27. </span>
  28. <div style="margin-right: 10px">
  29. <span style="color: #7fa7ce">{{ date }}</span>
  30. <span style="color: rgb(210 215 221); padding: 0 5px">{{
  31. time
  32. }}</span>
  33. <span style="color: #7fa7ce">{{ week }} </span>
  34. </div>
  35. </div>
  36. </div>
  37. <div class="list_item margin-bt20">
  38. <div ref="pie" class="table_bar"></div>
  39. <div class="table_bar">
  40. <div class="title">
  41. <div>
  42. <span>选点检:</span>
  43. <span class="blue">25</span>
  44. </div>
  45. </div>
  46. <div class="table"> </div>
  47. <dv-scroll-board
  48. v-if="isFlag"
  49. :config="config"
  50. style="width: 90%; height: 87%; transform: translate(5%, 1%)"
  51. />
  52. </div>
  53. </div>
  54. <div class="list_item">
  55. <div class="table_bar">
  56. <div class="title">
  57. <div>
  58. <span>保养:</span>
  59. <span class="blue">25</span>
  60. </div>
  61. </div>
  62. <div class="table"> </div>
  63. <dv-scroll-board
  64. v-if="isFlag"
  65. :config="config"
  66. style="width: 90%; height: 87%; transform: translate(5%, 1%)"
  67. />
  68. </div>
  69. <div class="table_bar">
  70. <div class="title">
  71. <div>
  72. <span>维修:</span>
  73. <span class="blue">25</span>
  74. </div>
  75. </div>
  76. <div class="table"> </div>
  77. <dv-scroll-board
  78. v-if="isFlag"
  79. :config="config"
  80. style="width: 90%; height: 87%; transform: translate(5%, 1%)"
  81. />
  82. </div>
  83. </div>
  84. </div>
  85. <!-- <button type="button" @click="toggle">{{ fullscreen?"退出":"进入" }}全屏</button>-->
  86. </vue-fullscreen>
  87. </template>
  88. <script>
  89. import dvBorderContent from './dv-border-content.vue';
  90. import * as echarts from 'echarts';
  91. import { component } from 'vue-fullscreen';
  92. import { getRepairWorkList, statisticsDeviceStatus } from '@/api/equipment';
  93. export default {
  94. name: 'index',
  95. components: {
  96. dvBorderContent,
  97. VueFullscreen: component
  98. },
  99. computed: {
  100. contentWidth() {
  101. return this.$store.state.theme.contentWidth;
  102. }
  103. },
  104. watch: {
  105. isFullscreen: {
  106. handler() {
  107. this.isFlag = false;
  108. this.$nextTick(() => {
  109. let { clientWidth: deviceWidth, clientHeight: deviceHeight } =
  110. document.documentElement;
  111. let eleAdminHeaderHeight =
  112. (!this.isFullscreen &&
  113. document.getElementsByClassName('ele-admin-header')[0]
  114. ?.offsetHeight) ||
  115. 0;
  116. let eleAdminSidebarWidth =
  117. (!this.isFullscreen &&
  118. document.getElementsByClassName('ele-admin-sidebar')[0]
  119. ?.offsetWidth) ||
  120. 0;
  121. let eleAdminTabsWidth =
  122. (!this.isFullscreen &&
  123. document.getElementsByClassName('ele-admin-tabs')[0]
  124. ?.offsetHeight) ||
  125. 0;
  126. const setContainerSize = (item) => {
  127. item.style.height =
  128. deviceHeight - eleAdminHeaderHeight - eleAdminTabsWidth + 'px';
  129. item.style.width = deviceWidth - eleAdminSidebarWidth + 'px';
  130. };
  131. let boxContainer = [
  132. ...document.getElementsByClassName('box-container')
  133. ];
  134. boxContainer.forEach(setContainerSize);
  135. document.documentElement.style.fontSize = this.isFullscreen
  136. ? '18px'
  137. : '16px';
  138. this.isFlag = true;
  139. this.$nextTick(() => {
  140. statisticsDeviceStatus().then((data) => {
  141. this.totalData = data;
  142. });
  143. });
  144. });
  145. },
  146. immediate: true
  147. },
  148. contentWidth: {
  149. handler() {
  150. this.isFlag = false;
  151. this.$nextTick(() => {
  152. let { clientWidth: deviceWidth, clientHeight: deviceHeight } =
  153. document.documentElement;
  154. let eleAdminHeaderHeight =
  155. (!this.isFullscreen &&
  156. document.getElementsByClassName('ele-admin-header')[0]
  157. ?.offsetHeight) ||
  158. 0;
  159. let eleAdminSidebarWidth =
  160. (!this.isFullscreen &&
  161. document.getElementsByClassName('ele-admin-sidebar')[0]
  162. ?.offsetWidth) ||
  163. 0;
  164. let eleAdminTabsWidth =
  165. (!this.isFullscreen &&
  166. document.getElementsByClassName('ele-admin-tabs')[0]
  167. ?.offsetHeight) ||
  168. 0;
  169. const setContainerSize = (item) => {
  170. item.style.height =
  171. deviceHeight - eleAdminHeaderHeight - eleAdminTabsWidth + 'px';
  172. item.style.width = deviceWidth - eleAdminSidebarWidth + 'px';
  173. };
  174. let boxContainer = [
  175. ...document.getElementsByClassName('box-container')
  176. ];
  177. boxContainer.forEach(setContainerSize);
  178. document.documentElement.style.fontSize = this.isFullscreen
  179. ? '18px'
  180. : '16px';
  181. this.isFlag = true;
  182. this.$nextTick(() => {
  183. statisticsDeviceStatus().then((data) => {
  184. this.totalData = data;
  185. });
  186. });
  187. });
  188. },
  189. immediate: true
  190. }
  191. },
  192. deactivated() {
  193. clearInterval(this.updateTimer);
  194. },
  195. data() {
  196. return {
  197. totalData: {},
  198. isFullscreen: false, // 是否是全屏
  199. isFlag: false, // 是否展示图表
  200. date: '',
  201. time: '',
  202. week: '',
  203. signedTotal: 0,
  204. deliveryTotal: 0,
  205. salesTotal: 0,
  206. WeightGainTotal: 0,
  207. WeightStorageTotal: 0,
  208. salesChart: null,
  209. outputChart: null,
  210. orderStatusOptions: {
  211. 0: '待接收',
  212. 1: '已接收',
  213. 2: '执行中',
  214. 3: '待验收',
  215. 4: '已完成'
  216. },
  217. tableHeader: ['工单号', '负责人', '状态', '响应时间'],
  218. config: {
  219. header: [],
  220. data: [],
  221. align: ['center', 'center', 'center', 'center'],
  222. headerBGC: '#031d42',
  223. columnWidth: [110, 120],
  224. headerHeight: 20,
  225. oddRowBGC: '#031d42',
  226. evenRowBGC: '#031d42',
  227. waitTime: 5000,
  228. rowNum: 12
  229. },
  230. optionData: [
  231. {
  232. code: '3',
  233. name: '运行数量',
  234. cws: 80,
  235. zcs: 20,
  236. zcl: '25%',
  237. value: 80,
  238. startRatio: 0,
  239. endRatio: 0.34782608695652173,
  240. itemStyle: {
  241. color: '#5089F2',
  242. opacity: 1
  243. }
  244. },
  245. {
  246. code: '1',
  247. name: '故障检修数量',
  248. cws: 40,
  249. zcs: 30,
  250. zcl: '75%',
  251. value: 40,
  252. startRatio: 0.8260869565217391,
  253. endRatio: 1,
  254. itemStyle: {
  255. color: '#FF736A',
  256. opacity: 1
  257. }
  258. }
  259. ]
  260. };
  261. },
  262. created() {
  263. // window.isFullscreen = false
  264. this.updateTimer = setInterval(this.updateTime, 1000);
  265. },
  266. mounted() {
  267. this.getSalesFinishList();
  268. setInterval(() => {
  269. this.getSalesFinishList();
  270. }, 3600000);
  271. statisticsDeviceStatus().then((data) => {
  272. this.totalData = data;
  273. this.initCircle(this.$refs.pie);
  274. });
  275. },
  276. methods: {
  277. initCircle(ref) {
  278. let rightChart2 = echarts.init(ref);
  279. let option = {
  280. tooltip: {
  281. trigger: 'item'
  282. },
  283. graphic: {
  284. //图形中间图片
  285. elements: [
  286. {
  287. type: 'image',
  288. style: {
  289. image: require('../../../assets/circle_bg.png'), //你的图片地址
  290. width: 200,
  291. height: 200
  292. },
  293. left: '13%',
  294. top: '23%'
  295. },
  296. {
  297. type: 'text', //通过不同top值可以设置上下显示
  298. left: '21.5%',
  299. top: '44%',
  300. style: {
  301. text: '100',
  302. fill: '#fff', //文字的颜色
  303. width: 30,
  304. height: 30,
  305. fontSize: 30,
  306. color: '#fff',
  307. fontFamily: 'Microsoft YaHei'
  308. }
  309. },
  310. {
  311. type: 'text', //通过不同top值可以设置上下显示
  312. left: '21%',
  313. top: '53%',
  314. style: {
  315. text: '总数(台)',
  316. fill: '#fff', //文字的颜色
  317. width: 30,
  318. height: 30,
  319. fontSize: 18,
  320. color: '#fff',
  321. fontFamily: 'Microsoft YaHei'
  322. }
  323. }
  324. ]
  325. },
  326. legend: {
  327. top: 'center',
  328. right: '25%',
  329. type: 'scroll',
  330. orient: 'vertical',
  331. itemGap: 30,
  332. textStyle: {
  333. rich: {
  334. // 通过富文本rich给每个项设置样式,下面的oneone、twotwo、threethree可以理解为"每一列"的样式
  335. oneone: {
  336. // 设置文字、数学、英语这一列的样式
  337. width: 70,
  338. color: '#fff',
  339. fontSize: 18,
  340. fontWeight: 'bolder'
  341. },
  342. twotwo: {
  343. // 设置10分、20分、30分这一列的样式
  344. width: 35,
  345. color: '#0577F9',
  346. fontSize: 18
  347. },
  348. threethree: {
  349. // 设置百分比这一列的样式
  350. width: 20,
  351. color: '#EE6666',
  352. fontSize: 18
  353. }
  354. }
  355. },
  356. formatter: (name) => {
  357. return `{oneone|${name}} {twotwo|40} {threethree|40%}`;
  358. }
  359. },
  360. series: [
  361. {
  362. name: '工单',
  363. type: 'pie',
  364. radius: ['60%', '70%'],
  365. center: ['25%', '50%'], //图的位置,距离左跟上的位置
  366. avoidLabelOverlap: false,
  367. padAngle: 5,
  368. itemStyle: {
  369. borderRadius: 5
  370. },
  371. label: {
  372. show: false,
  373. position: 'center'
  374. },
  375. emphasis: {
  376. label: {
  377. show: false,
  378. fontSize: 40,
  379. fontWeight: 'bold'
  380. }
  381. },
  382. labelLine: {
  383. show: false
  384. },
  385. data: [
  386. { value: 12, name: '已报工' },
  387. { value: 33, name: '已指派' },
  388. { value: 44, name: '处理中' },
  389. { value: 22, name: '待接单' }
  390. ]
  391. }
  392. ]
  393. };
  394. rightChart2.setOption(option);
  395. },
  396. fomatFloat(num, n) {
  397. var f = parseFloat(num);
  398. if (isNaN(f)) {
  399. return false;
  400. }
  401. f = Math.round(num * Math.pow(10, n)) / Math.pow(10, n); // n 幂
  402. var s = f.toString();
  403. var rs = s.indexOf('.');
  404. //判定如果是整数,增加小数点再补0
  405. if (rs < 0) {
  406. rs = s.length;
  407. s += '.';
  408. }
  409. while (s.length <= rs + n) {
  410. s += '0';
  411. }
  412. return s;
  413. },
  414. /* 全屏切换 */
  415. onFullscreen() {
  416. this.isFullscreen = !this.isFullscreen;
  417. },
  418. //
  419. async getSalesFinishList() {
  420. /*customerMark 客户代号 string
  421. deliveryStatus 交付状态 1未交付2提前3按时4延期 integer(int32)
  422. produceStatus 生产状态 1未生产2已生产3已完成 integer(int32)
  423. purchaseStatus 采购状态 1未采购2已采购3已入库 integer(int32)
  424. saleOrderCode 销售订单号 string
  425. scheduleStatus 排产状态 1待排产2已排产 integer(int32)*/
  426. let HeaderFiled = [
  427. 'customerMark',
  428. 'saleOrderCode',
  429. 'purchaseStatus',
  430. 'scheduleStatus',
  431. 'produceStatus',
  432. 'deliveryStatus'
  433. ];
  434. let data = await getRepairWorkList();
  435. console.log(data);
  436. this.config = {
  437. header: this.tableHeader.map(
  438. (item) =>
  439. `<div style="color: #0577FF;font-size: 1.3rem;font-weight: bold">${item}</div>`
  440. ),
  441. data:
  442. data.map((item) => {
  443. let list = [];
  444. for (let i in item) {
  445. let div = '';
  446. if (i === 'executeGroupName') {
  447. div = `<div class="white" style="font-size: 1.3rem;">${item[i]}</div>`;
  448. list[0] = div;
  449. }
  450. if (i === 'executeUserName') {
  451. div = `<div class="white" style="font-size: 1.3rem;">${item[i]}</div>`;
  452. list[1] = div;
  453. }
  454. if (i === 'orderStatus') {
  455. if (item[i] > -1) {
  456. switch (item[i]) {
  457. case '0':
  458. div = `<div class="white" style="font-size: 1.3rem;">${
  459. this.orderStatusOptions[item[i]]
  460. }</div>`;
  461. break;
  462. case '1':
  463. div = `<div class="yellow" style="font-size: 1.3rem;">${
  464. this.orderStatusOptions[item[i]]
  465. }</div>`;
  466. break;
  467. case '2':
  468. div = `<div class="green" style="font-size: 1.3rem;">${
  469. this.orderStatusOptions[item[i]]
  470. }</div>`;
  471. break;
  472. default:
  473. div = `<div class="red" style="font-size: 1.3rem;">${
  474. this.orderStatusOptions[item[i]]
  475. }</div>`;
  476. break;
  477. }
  478. list[2] = div;
  479. } else {
  480. div = `<div class="white" style="font-size: 1.3rem;"></div>`;
  481. list[2] = div;
  482. }
  483. }
  484. }
  485. return list;
  486. }) ?? [],
  487. align: ['center', 'center', 'center', 'center', 'center', 'center'],
  488. headerBGC: '#031d42',
  489. columnWidth: [140, 250, 170, 150],
  490. headerHeight: 30,
  491. oddRowBGC: '#031d42',
  492. evenRowBGC: '#031d42',
  493. waitTime: 5000,
  494. rowNum: 8
  495. };
  496. },
  497. //实时更新日期
  498. updateTime() {
  499. let now = new Date();
  500. let hours = now.getHours();
  501. let minutes = now.getMinutes();
  502. let seconds = now.getSeconds();
  503. this.time =
  504. hours.toString().padStart(2, '0') +
  505. ':' +
  506. minutes.toString().padStart(2, '0') +
  507. ':' +
  508. seconds.toString().padStart(2, '0');
  509. let year = now.getFullYear();
  510. let month = now.getMonth() + 1;
  511. let day = now.getDate();
  512. this.date = year + '年' + month + '月' + day + '日';
  513. let weekInfo = {
  514. 1: '一',
  515. 2: '二',
  516. 3: '三',
  517. 4: '四',
  518. 5: '五',
  519. 6: '六',
  520. 0: '日'
  521. };
  522. this.week = '星期' + weekInfo[now.getDay()];
  523. }
  524. }
  525. };
  526. </script>
  527. <style lang="scss" scoped>
  528. .box-container {
  529. font-size: 16px;
  530. font-family: 'AlibabaPuHuiTi';
  531. background: #031d42;
  532. display: flex;
  533. flex-direction: column;
  534. .box-header {
  535. background-image: url('@/assets/border2.png');
  536. background-repeat: no-repeat;
  537. background-size: 100% 100%;
  538. display: flex;
  539. width: 100% !important;
  540. height: 10%;
  541. justify-content: space-between;
  542. .title {
  543. font-family: '优设标题黑';
  544. font-size: 2.75rem;
  545. flex: 1;
  546. display: flex;
  547. justify-content: center;
  548. align-items: center;
  549. color: #fff;
  550. transform: translateY(-10%);
  551. letter-spacing: 0.4rem;
  552. }
  553. .logo {
  554. display: inline-block;
  555. width: 20%;
  556. display: flex;
  557. align-items: center;
  558. > img {
  559. width: 6.48rem;
  560. height: 3rem;
  561. }
  562. > span {
  563. color: #fff;
  564. font-size: 1rem;
  565. font-weight: bold;
  566. }
  567. }
  568. .time {
  569. width: 20%;
  570. display: flex;
  571. align-items: center;
  572. justify-content: space-around;
  573. flex-direction: column;
  574. align-items: flex-end;
  575. justify-content: flex-start;
  576. font-size: 0.8rem;
  577. }
  578. }
  579. .list_item {
  580. flex: 1;
  581. display: flex;
  582. .table_bar {
  583. flex: 1;
  584. display: flex;
  585. flex-direction: column;
  586. overflow: hidden;
  587. .title {
  588. background: linear-gradient(90deg, #1f385e 0%, #021f4b 55%);
  589. height: 2.2rem;
  590. > div {
  591. height: 2.2rem;
  592. line-height: 2.2rem;
  593. width: 17.3125rem;
  594. padding-left: 2.8rem;
  595. background-image: url('@/assets/title_bg.png');
  596. background-repeat: no-repeat;
  597. background-size: 100% 100%;
  598. > span {
  599. font-size: 1.3rem;
  600. font-weight: bold;
  601. color: #fff;
  602. }
  603. }
  604. }
  605. .table {
  606. flex: 1;
  607. }
  608. }
  609. }
  610. .margin-bt20 {
  611. margin-bottom: 1rem;
  612. }
  613. }
  614. [v-cloak] {
  615. display: none;
  616. }
  617. </style>
  618. <style>
  619. .white {
  620. color: #ffffff;
  621. }
  622. .yellow {
  623. color: #ffd16c;
  624. }
  625. .green {
  626. color: green;
  627. }
  628. .red {
  629. color: red;
  630. }
  631. .blue {
  632. color: #0577ff !important;
  633. }
  634. .row-item {
  635. margin-bottom: 0.3rem;
  636. }
  637. </style>