productionSchedule.vue 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799
  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. </div>
  13. <div class="title"> 生产进度看板 </div>
  14. <div class="time">
  15. <span
  16. style="color: #7fa7ce; margin: 5px 10px 15px 0; cursor: pointer"
  17. @click.passive="onFullscreen"
  18. >
  19. <i
  20. v-if="isFullscreen"
  21. title="取消全屏"
  22. class="el-icon-_screen-restore"
  23. ></i>
  24. <i v-else title="全屏" class="el-icon-_screen-full"></i>
  25. </span>
  26. <div style="margin-right: 10px">
  27. <span style="color: #7fa7ce">{{ date }}</span>
  28. <span style="color: rgb(210 215 221); padding: 0 5px">{{
  29. time
  30. }}</span>
  31. <span style="color: #7fa7ce">{{ week }} </span>
  32. </div>
  33. </div>
  34. </div>
  35. <div class="box-middle">
  36. <template v-for="item in borderData">
  37. <div class="box-middle-content">
  38. <dvBorderContent :objD="item"></dvBorderContent>
  39. </div>
  40. </template>
  41. </div>
  42. <div class="box-footer">
  43. <div class="box-footer-left">
  44. <div class="box-echarts">
  45. <div class="box-echarts-top">
  46. <span class="box-top-name">合格数统计</span>
  47. <!-- <span class="box-top-unit">(万元)</span> -->
  48. </div>
  49. <div class="monthly_sales_volume">
  50. <div
  51. v-if="isFlag"
  52. id="monthly_sales_volume"
  53. ref="monthly_sales_volume"
  54. ></div>
  55. </div>
  56. </div>
  57. <div class="box-echarts">
  58. <div class="box-echarts-top">
  59. <span class="box-top-name">月度产量统计</span>
  60. <span class="box-top-unit">(KG)</span>
  61. </div>
  62. <div class="monthly_output">
  63. <div v-if="isFlag" id="monthly_output" ref="monthly_output"></div>
  64. </div>
  65. </div>
  66. </div>
  67. <div class="box-footer-right">
  68. <div class="box-echarts-top">
  69. <span class="box-top-name">生产工单进度看板</span>
  70. </div>
  71. <dv-scroll-board
  72. v-if="isFlag"
  73. :config="config"
  74. style="width: 90%; height: 87%; transform: translate(5%, 1%)"
  75. />
  76. </div>
  77. </div>
  78. </div>
  79. </vue-fullscreen>
  80. </template>
  81. <script>
  82. import dvBorderContent from './dv-border-content.vue';
  83. import * as echarts from 'echarts';
  84. import { component } from 'vue-fullscreen';
  85. import { isFullscreen } from 'ele-admin';
  86. import { count, getSalesFinishListAPI, completionCount } from '@/api/mes/productionSchedule'
  87. export default {
  88. name: 'index',
  89. components: {
  90. dvBorderContent,
  91. VueFullscreen: component
  92. },
  93. computed: {
  94. contentWidth() {
  95. return this.$store.state.theme.contentWidth;
  96. }
  97. },
  98. watch: {
  99. isFullscreen: {
  100. handler() {
  101. this.isFlag = false;
  102. this.$nextTick(() => {
  103. let { clientWidth: deviceWidth, clientHeight: deviceHeight } =
  104. document.documentElement;
  105. let eleAdminHeaderHeight =
  106. (!this.isFullscreen &&
  107. document.getElementsByClassName('ele-admin-header')[0]
  108. ?.offsetHeight) ||
  109. 0;
  110. let eleAdminSidebarWidth =
  111. (!this.isFullscreen &&
  112. document.getElementsByClassName('ele-admin-sidebar')[0]
  113. ?.offsetWidth) ||
  114. 0;
  115. let eleAdminTabsWidth =
  116. (!this.isFullscreen &&
  117. document.getElementsByClassName('ele-admin-tabs')[0]
  118. ?.offsetHeight) ||
  119. 0;
  120. const setContainerSize = (item) => {
  121. item.style.height =
  122. deviceHeight - eleAdminHeaderHeight - eleAdminTabsWidth + 'px';
  123. item.style.width = deviceWidth - eleAdminSidebarWidth + 'px';
  124. };
  125. let boxContainer = [
  126. ...document.getElementsByClassName('box-container')
  127. ];
  128. boxContainer.forEach(setContainerSize);
  129. document.documentElement.style.fontSize = this.isFullscreen
  130. ? '24px'
  131. : '16px';
  132. this.isFlag = true;
  133. this.$nextTick(() => {
  134. let chartDom = this.$refs.monthly_sales_volume;
  135. this.salesChart = echarts.init(chartDom);
  136. let chartDom2 = this.$refs.monthly_output;
  137. this.outputChart = echarts.init(chartDom2);
  138. this.getMonthlySalesStatistic();
  139. this.getMonthlyProduceStatistic();
  140. });
  141. });
  142. },
  143. immediate: true
  144. },
  145. contentWidth: {
  146. handler() {
  147. this.isFlag = false;
  148. this.$nextTick(() => {
  149. let { clientWidth: deviceWidth, clientHeight: deviceHeight } =
  150. document.documentElement;
  151. let eleAdminHeaderHeight =
  152. (!this.isFullscreen &&
  153. document.getElementsByClassName('ele-admin-header')[0]
  154. ?.offsetHeight) ||
  155. 0;
  156. let eleAdminSidebarWidth =
  157. (!this.isFullscreen &&
  158. document.getElementsByClassName('ele-admin-sidebar')[0]
  159. ?.offsetWidth) ||
  160. 0;
  161. let eleAdminTabsWidth =
  162. (!this.isFullscreen &&
  163. document.getElementsByClassName('ele-admin-tabs')[0]
  164. ?.offsetHeight) ||
  165. 0;
  166. const setContainerSize = (item) => {
  167. item.style.height =
  168. deviceHeight - eleAdminHeaderHeight - eleAdminTabsWidth + 'px';
  169. item.style.width = deviceWidth - eleAdminSidebarWidth + 'px';
  170. };
  171. let boxContainer = [
  172. ...document.getElementsByClassName('box-container')
  173. ];
  174. boxContainer.forEach(setContainerSize);
  175. document.documentElement.style.fontSize = this.isFullscreen
  176. ? '24px'
  177. : '16px';
  178. this.isFlag = true;
  179. this.$nextTick(() => {
  180. let chartDom = this.$refs.monthly_sales_volume;
  181. this.salesChart = echarts.init(chartDom);
  182. let chartDom2 = this.$refs.monthly_output;
  183. this.outputChart = echarts.init(chartDom2);
  184. this.getMonthlySalesStatistic();
  185. this.getMonthlyProduceStatistic();
  186. });
  187. });
  188. },
  189. immediate: true
  190. }
  191. },
  192. deactivated() {
  193. clearInterval(this.updateTimer);
  194. },
  195. data() {
  196. return {
  197. isFullscreen: false, // 是否是全屏
  198. isFlag: false, // 是否展示图表
  199. date: '',
  200. time: '',
  201. week: '',
  202. signedTotal: 0,
  203. deliveryTotal: 0,
  204. salesTotal: 0,
  205. WeightGainTotal: 0,
  206. WeightStorageTotal: 0,
  207. salesChart: null,
  208. outputChart: null,
  209. borderData: [
  210. {
  211. titleName: '工单数量',
  212. titleUnit: '',
  213. value: '0',
  214. },
  215. {
  216. titleName: '待生产数量',
  217. titleUnit: '',
  218. value: '0',
  219. },
  220. {
  221. titleName: '已完成数量',
  222. titleUnit: '',
  223. value: '0',
  224. },
  225. // {
  226. // titleName: '工时统计',
  227. // titleUnit: '',
  228. // value: '0',
  229. // fun: () => getIncreaseWeightAPI()
  230. // },
  231. {
  232. titleName: '合格率',
  233. titleUnit: '',
  234. value: '0%',
  235. }
  236. ],
  237. monthlySalesVolumeOption: {
  238. legend: {
  239. left: 'center',
  240. selectedMode: false,
  241. itemGap: 30,
  242. textStyle: {
  243. fontSize: '0.7rem',
  244. color: '#fff',
  245. lineHeight: 0,
  246. padding: [10, 0, 0, 0]
  247. }
  248. },
  249. grid: {
  250. bottom: '5%', // 组件离容器底部的距离
  251. containLabel: true // 包含坐标轴的标签
  252. },
  253. xAxis: {
  254. type: 'category',
  255. data: [],
  256. axisLabel: {
  257. interval: 0,
  258. formatter: function (value, index) {
  259. let month = value.split('-');
  260. return month[1] + '月';
  261. },
  262. textStyle: {
  263. color: '#fff', // 修改字体颜色为红色
  264. fontSize: '0.7rem',
  265. fontFamily: 'AlibabaPuHuiTi' // 修改字体为Arial
  266. }
  267. }
  268. },
  269. yAxis: {
  270. type: 'value',
  271. axisLabel: {
  272. textStyle: {
  273. color: '#fff', // 修改字体颜色为红色
  274. fontSize: '0.7rem',
  275. fontFamily: 'AlibabaPuHuiTi' // 修改字体为Arial
  276. }
  277. }
  278. },
  279. series: []
  280. },
  281. monthlyOutputOption: {
  282. legend: {
  283. left: 'center',
  284. selectedMode: false,
  285. itemGap: 40,
  286. textStyle: {
  287. color: '#fff',
  288. lineHeight: 0,
  289. fontSize: '0.7rem',
  290. padding: [10, 0, 0, 0]
  291. }
  292. },
  293. grid: {
  294. bottom: '5%', // 组件离容器底部的距离
  295. containLabel: true // 包含坐标轴的标签
  296. },
  297. xAxis: {
  298. type: 'category',
  299. data: [],
  300. axisLabel: {
  301. interval: 0,
  302. formatter: function (value, index) {
  303. let month = value.split('-');
  304. return month[1] + '月';
  305. },
  306. textStyle: {
  307. color: '#fff', // 修改字体颜色为红色
  308. fontSize: '0.7rem',
  309. fontFamily: 'AlibabaPuHuiTi' // 修改字体为Arial
  310. }
  311. }
  312. },
  313. yAxis: {
  314. type: 'value',
  315. axisLabel: {
  316. textStyle: {
  317. color: '#fff', // 修改字体颜色为红色
  318. fontSize: '0.7rem',
  319. fontFamily: 'AlibabaPuHuiTi' // 修改字体为Arial
  320. }
  321. }
  322. },
  323. series: []
  324. },
  325. tableHeader: [
  326. '客户代号',
  327. '生产工单号',
  328. '编码',
  329. '名称',
  330. '当前工序',
  331. '交付状态'
  332. ],
  333. config: {
  334. header: [],
  335. data: [],
  336. align: ['center', 'center', 'center', 'center', 'center', 'center'],
  337. headerBGC: '#031d42',
  338. columnWidth: [110, 200],
  339. headerHeight: 20,
  340. oddRowBGC: '#031d42',
  341. evenRowBGC: '#031d42',
  342. waitTime: 5000,
  343. rowNum: 12
  344. },
  345. // 1未交付2提前3按时4延期
  346. deliveryStatusList: [
  347. {
  348. dictKey: 1,
  349. dictValue: '未交付'
  350. },
  351. {
  352. dictKey: 2,
  353. dictValue: '提前'
  354. },
  355. {
  356. dictKey: 3,
  357. dictValue: '按时'
  358. },
  359. {
  360. dictKey: 4,
  361. dictValue: '延期'
  362. }
  363. ],
  364. //1未生产2已生产3已完成
  365. produceStatusList: [
  366. {
  367. dictKey: 1,
  368. dictValue: '未生产'
  369. },
  370. {
  371. dictKey: 2,
  372. dictValue: '已生产'
  373. },
  374. {
  375. dictKey: 3,
  376. dictValue: '已完成'
  377. }
  378. ],
  379. //1未采购2已采购3已入库
  380. purchaseStatusList: [
  381. {
  382. dictKey: 1,
  383. dictValue: '未采购'
  384. },
  385. {
  386. dictKey: 2,
  387. dictValue: '已采购'
  388. },
  389. {
  390. dictKey: 3,
  391. dictValue: '已入库'
  392. }
  393. ],
  394. //scheduleStatus 排产状态 1待排产2已排产 integer(int32)*/
  395. scheduleStatusList: [
  396. {
  397. dictKey: 1,
  398. dictValue: '待排产'
  399. },
  400. {
  401. dictKey: 2,
  402. dictValue: '已排产'
  403. }
  404. ]
  405. };
  406. },
  407. created() {
  408. this.updateTimer = setInterval(this.updateTime, 1000);
  409. },
  410. mounted() {
  411. this.getAllAmount();
  412. this.getSalesFinishList();
  413. setInterval(() => {
  414. this.getSalesFinishList();
  415. }, 3600000);
  416. },
  417. methods: {
  418. /* 全屏切换 */
  419. onFullscreen() {
  420. this.isFullscreen = !this.isFullscreen;
  421. },
  422. //获取头部统计
  423. async getAllAmount() {
  424. let rest = await count({factoriesId: 0});
  425. this.borderData.forEach(async (item) => {
  426. if (item.titleName === '工单数量') {
  427. item.value = rest.inProductCount;
  428. } else if (item.titleName === '待生产数量') {
  429. item.value = rest.planCount;
  430. } else if (item.titleName === '已完成数量') {
  431. item.value = rest.formedWeight;
  432. } else if (item.titleName === '合格率') {
  433. item.value = rest.qualifiedRate + '%';
  434. }
  435. });
  436. console.log(rest, 'rest');
  437. },
  438. //获取成品发货统计
  439. async getMonthlySalesStatistic() {
  440. let params = {
  441. startDate: new Date().getFullYear() + '-01-01',
  442. endDate: new Date().getFullYear() + '-12-31',
  443. factoriesId: 0
  444. }
  445. let data = await completionCount(params);
  446. let series = [
  447. {
  448. field: 'qualified',
  449. name: '合格数量',
  450. data: [],
  451. type: 'bar',
  452. itemStyle: {
  453. color: '#03c391'
  454. }
  455. },
  456. {
  457. field: 'noQualifiedSum',
  458. name: '不合格数量',
  459. data: [],
  460. type: 'bar',
  461. itemStyle: {
  462. color: '#ea5082'
  463. }
  464. },
  465. ];
  466. this.monthlySalesVolumeOption.xAxis.data = data.map(
  467. (item) => item.inProductDate
  468. );
  469. series.forEach((item) => {
  470. item.data = data.map((i) => i[item.field]);
  471. });
  472. this.monthlySalesVolumeOption.series = series;
  473. this.salesChart.setOption(this.monthlySalesVolumeOption);
  474. },
  475. //获取月度产量统计
  476. async getMonthlyProduceStatistic() {
  477. let params = {
  478. startDate: new Date().getFullYear() + '-01-01',
  479. endDate: new Date().getFullYear() + '-12-31',
  480. factoriesId: 0
  481. }
  482. let data = await completionCount(params);
  483. let series = [
  484. {
  485. field: 'inWarehouseCount',
  486. name: '成品入库数量',
  487. data: [],
  488. type: 'bar',
  489. itemStyle: {
  490. color: '#e9ac80'
  491. }
  492. },
  493. {
  494. field: 'packingWeightSum',
  495. name: '成品入库重量',
  496. data: [],
  497. type: 'bar',
  498. itemStyle: {
  499. color: '#03c391'
  500. }
  501. }
  502. ];
  503. this.monthlyOutputOption.xAxis.data = data.map((item) => item.inProductDate);
  504. series.forEach((item) => {
  505. item.data = data.map((i) => i[item.field]);
  506. });
  507. this.monthlyOutputOption.series = series;
  508. this.outputChart.setOption(this.monthlyOutputOption);
  509. },
  510. //生产工单
  511. async getSalesFinishList() {
  512. /*serialNo 客户代号 string
  513. days 交付状态 N剩余N天 0已完成 -1延期 integer(int32)
  514. productName 名称 integer(int32)
  515. productCode 设备编码 1未采购2已采购3已入库 integer(int32)
  516. code 工单号 string
  517. taskName 当前工序 */
  518. let data = await getSalesFinishListAPI({factoriesId: 0});
  519. this.config = {
  520. header: this.tableHeader.map(
  521. (item) =>
  522. `<div style="color: #f4d29c;font-size: 0.9rem;font-weight: bold">${item}</div>`
  523. ),
  524. data:
  525. data.map((item) => {
  526. let list = [];
  527. for (let i in item) {
  528. let div = '';
  529. if (i === 'serialNo') {
  530. div = `<div class="white" style="font-size: 0.8rem;">${item[i]}</div>`;
  531. list[0] = div;
  532. }
  533. if (i === 'code') {
  534. div = `<div class="white" style="font-size: 0.8rem;">${item[i]}</div>`;
  535. list[1] = div;
  536. }
  537. if (i === 'productCode') {
  538. div = `<div class="yellow" style="font-size: 0.8rem;">${item[i]}</div>`;
  539. list[2] = div;
  540. }
  541. if (i === 'productName') {
  542. div = `<div class="white" style="font-size: 0.8rem;">${item[i]}</div>`;
  543. list[3] = div;
  544. }
  545. if (i === 'taskName') {
  546. div = `<div class="yellow" style="font-size: 0.8rem;">${item[i]}</div>`;
  547. list[4] = div;
  548. }
  549. if (i === 'days') {
  550. //1未交付2提前3按时4延期
  551. if (item[i] == '-1') {
  552. div = `<div class="white" style="font-size: 0.8rem;color:red">已延期</div>`;
  553. list[5] = div;
  554. }
  555. if (item[i] == '0') {
  556. div = `<div class="green" style="font-size: 0.8rem;">已完成</div>`;
  557. list[5] = div;
  558. }
  559. if (item[i] > 0) {
  560. div = `<div class="yellow" style="font-size: 0.8rem;">剩余${item[i]}天</div>`;
  561. list[5] = div;
  562. }
  563. }
  564. }
  565. return list;
  566. }) ?? [],
  567. align: ['center', 'center', 'center', 'center', 'center', 'center'],
  568. headerBGC: '#031d42',
  569. columnWidth: [110, 200],
  570. headerHeight: 30,
  571. oddRowBGC: '#031d42',
  572. evenRowBGC: '#031d42',
  573. waitTime: 5000,
  574. rowNum: 10
  575. };
  576. },
  577. //实时更新日期
  578. updateTime() {
  579. let now = new Date();
  580. let hours = now.getHours();
  581. let minutes = now.getMinutes();
  582. let seconds = now.getSeconds();
  583. this.time =
  584. hours.toString().padStart(2, '0') +
  585. ':' +
  586. minutes.toString().padStart(2, '0') +
  587. ':' +
  588. seconds.toString().padStart(2, '0');
  589. let year = now.getFullYear();
  590. let month = now.getMonth() + 1;
  591. let day = now.getDate();
  592. this.date = year + '年' + month + '月' + day + '日';
  593. let weekInfo = {
  594. 1: '一',
  595. 2: '二',
  596. 3: '三',
  597. 4: '四',
  598. 5: '五',
  599. 6: '六',
  600. 0: '日'
  601. };
  602. this.week = '星期' + weekInfo[now.getDay()];
  603. }
  604. }
  605. };
  606. </script>
  607. <style lang="scss" scoped>
  608. .box-container {
  609. font-size: 16px;
  610. font-family: 'AlibabaPuHuiTi';
  611. background: #011635;
  612. display: flex;
  613. flex-direction: column;
  614. .box-header {
  615. background-image: url('@/assets/border2.png');
  616. background-repeat: no-repeat;
  617. background-size: 100% 100%;
  618. display: flex;
  619. width: 100% !important;
  620. height: 10%;
  621. justify-content: space-between;
  622. .title {
  623. font-family: '优设标题黑';
  624. font-size: 2.75rem;
  625. flex: 1;
  626. display: flex;
  627. justify-content: center;
  628. align-items: center;
  629. color: #fff;
  630. transform: translateY(-10%);
  631. letter-spacing: 0.4rem;
  632. }
  633. .logo {
  634. display: inline-block;
  635. width: 20%;
  636. }
  637. .time {
  638. width: 20%;
  639. display: flex;
  640. align-items: center;
  641. justify-content: space-around;
  642. flex-direction: column;
  643. align-items: flex-end;
  644. justify-content: flex-start;
  645. font-size: 0.8rem;
  646. }
  647. }
  648. .box-middle {
  649. width: 100% !important;
  650. height: 10% !important;
  651. display: flex;
  652. justify-content: space-evenly;
  653. margin: 5px 0 10px 0;
  654. .box-middle-content {
  655. width: 15%;
  656. height: 100%;
  657. background-image: url('@/assets/border1.png');
  658. background-repeat: no-repeat;
  659. background-size: 100% 100%;
  660. margin: 0px 28px 10px 0px;
  661. }
  662. .border-box-content {
  663. }
  664. }
  665. .box-footer {
  666. flex: 1;
  667. display: flex;
  668. justify-content: space-around;
  669. .box-footer-left {
  670. width: 50%;
  671. height: 100%;
  672. .box-echarts {
  673. width: 100%;
  674. height: 50%;
  675. display: flex;
  676. flex-direction: column;
  677. background-image: url('@/assets/border3.png');
  678. background-repeat: no-repeat;
  679. background-size: 100% 100%;
  680. .box-echarts-top {
  681. height: 20%;
  682. width: 100%;
  683. display: flex;
  684. align-items: center;
  685. /* justify-content: space-around; */
  686. transform: translateX(6%);
  687. color: #fff;
  688. .box-top-name {
  689. display: inline-block;
  690. font-size: 1.3rem;
  691. font-weight: bold;
  692. }
  693. .box-top-unit {
  694. display: inline-block;
  695. font-size: 0.75rem;
  696. transform: translate(0px, 20%);
  697. letter-spacing: 1px;
  698. font-weight: bold;
  699. }
  700. }
  701. .monthly_sales_volume {
  702. transform: translateX(-7%);
  703. flex: 1;
  704. //width: 100%;
  705. //height: 100%;
  706. #monthly_sales_volume {
  707. width: 113%;
  708. height: 100%;
  709. }
  710. }
  711. .monthly_output {
  712. transform: translateX(-7%);
  713. flex: 1;
  714. #monthly_output {
  715. width: 113%;
  716. height: 100%;
  717. //width: 100%;
  718. //height: 100%;
  719. }
  720. }
  721. }
  722. }
  723. .box-footer-right {
  724. width: 50%;
  725. height: 100%;
  726. background-image: url('@/assets/border4.png');
  727. background-repeat: no-repeat;
  728. background-size: 100% 100%;
  729. .box-echarts-top {
  730. height: 10.5%;
  731. width: 100%;
  732. display: flex;
  733. align-items: center;
  734. /* justify-content: space-around; */
  735. transform: translateX(8%);
  736. color: #fff;
  737. font-size: 1.1rem;
  738. letter-spacing: 2px;
  739. .box-top-name {
  740. display: inline-block;
  741. font-size: 1.3rem;
  742. font-weight: bold;
  743. }
  744. }
  745. }
  746. }
  747. }
  748. [v-cloak] {
  749. display: none;
  750. }
  751. </style>
  752. <style>
  753. .white {
  754. color: #ffffff;
  755. }
  756. .yellow {
  757. color: #ffd16c;
  758. }
  759. .green {
  760. color: green;
  761. }
  762. .red {
  763. color: red;
  764. }
  765. </style>