MaintenanceDynamics.vue 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869
  1. <template>
  2. <Layout>
  3. <template #left>
  4. <div class="left-top">
  5. <template
  6. v-for="(item, index) in leftContent.top"
  7. :key="index"
  8. >
  9. <Box
  10. :width="662"
  11. :height="408"
  12. :name="item.name"
  13. style="position: relative;"
  14. >
  15. <SelectDate
  16. v-if="index === 1"
  17. @date-change="selectDatechange"
  18. />
  19. <div
  20. v-if="item.icon"
  21. class="left-top-count"
  22. >
  23. <Icon
  24. :name="item.icon"
  25. :size="81"
  26. style="margin-right: 20px;"
  27. />
  28. <div
  29. v-for="(itm, id) in item.num"
  30. :key="id"
  31. >
  32. {{ itm }}
  33. </div>
  34. <div>辆</div>
  35. </div>
  36. <Echart
  37. v-if="item.option"
  38. :option="item.option"
  39. />
  40. </Box>
  41. </template>
  42. </div>
  43. <Box
  44. :width="1340"
  45. :height="420"
  46. name="维保明细"
  47. class="left-bottom"
  48. >
  49. <n-date-picker
  50. v-model:value="leftContent.bottom.range"
  51. type="daterange"
  52. :bordered="false"
  53. style="width: 260px;"
  54. />
  55. <n-data-table
  56. :columns="leftContent.bottom.head"
  57. :data="tableData"
  58. :bordered="false"
  59. single-column
  60. striped
  61. size="large"
  62. style="height: 300px;"
  63. />
  64. <div class="page">
  65. <n-pagination
  66. v-model:page="leftContent.bottom.page.num"
  67. :page-size="leftContent.bottom.page.size"
  68. :item-count="leftContent.bottom.page.total"
  69. size="large"
  70. />
  71. </div>
  72. </Box>
  73. </template>
  74. <template #right>
  75. <div class="right-top">
  76. <template
  77. v-for="(item, index) in rightContent.top"
  78. :key="index"
  79. >
  80. <Box
  81. :width="438"
  82. :height="408"
  83. :name="item.name"
  84. >
  85. <Echart :option="item.option" />
  86. </Box>
  87. </template>
  88. </div>
  89. <Box
  90. :width="1340"
  91. :height="408"
  92. name="线路运行速度"
  93. class="right-center"
  94. >
  95. <div class="lineSpeed">
  96. <div class="img">
  97. <img
  98. src="../../../../assets/img/1-2.png"
  99. alt="car"
  100. >
  101. </div>
  102. <div class="control">
  103. <n-select
  104. size="large"
  105. :bordered="false"
  106. :options="[{label:'车型',value:1}]"
  107. placeholder="车型选择"
  108. />
  109. <div class="btn">
  110. 一键体检
  111. </div>
  112. </div>
  113. </div>
  114. </Box>
  115. <div class="right-bottom">
  116. <Box
  117. :width="662"
  118. :height="408"
  119. name="体检问题情况"
  120. >
  121. <div class="checkup">
  122. <div class="total">
  123. <div class="num">
  124. {{ checkupProblemTotal }}
  125. </div>
  126. <div style="font-size: 24px;">
  127. 总量
  128. </div>
  129. </div>
  130. <div class="list">
  131. <div
  132. v-for="item,index in checkupProblem"
  133. :key="index"
  134. class="item"
  135. >
  136. <div class="num">
  137. {{ item.number }}
  138. </div>
  139. <div class="label">
  140. {{ item.problemType }}
  141. </div>
  142. </div>
  143. </div>
  144. </div>
  145. </Box>
  146. <Box
  147. :width="662"
  148. :height="408"
  149. :name="rightContent.bottom.name"
  150. >
  151. <Echart :option="rightContent.bottom.option" />
  152. </Box>
  153. </div>
  154. </template>
  155. </Layout>
  156. </template>
  157. <script setup lang='ts'>
  158. import Layout from '@/components/layout.vue'
  159. import Box from '@/components/box.vue'
  160. import SelectDate from '@/components/selectDate.vue'
  161. import {
  162. Ref, computed, onMounted, ref, watch
  163. } from 'vue'
  164. import Echart from '@/components/chart.vue'
  165. import MaintenanceDynamicsService from '../services/maintenanceDynamics.Service'
  166. import { format, subDays } from 'date-fns'
  167. const leftContent:Ref<any> = ref({
  168. top: [
  169. {
  170. name: '车辆总数',
  171. num: '166',
  172. icon: '30'
  173. },
  174. {
  175. name: '维修保养统计',
  176. option: {
  177. grid: {
  178. containLabel: true,
  179. right: 30,
  180. left: 50,
  181. bottom: '25%',
  182. top: '20%'
  183. },
  184. legend: {
  185. show: true,
  186. left: 'center',
  187. bottom: 30,
  188. itemWidth: 15,
  189. itemHeight: 10,
  190. textStyle: {
  191. color: '#646464',
  192. fontSize: 18
  193. }
  194. },
  195. xAxis: {
  196. name: '日期',
  197. nameLocation: 'center',
  198. nameTextStyle: {
  199. fontSize: 16,
  200. color: 'white',
  201. padding: [ 20, 0 ]
  202. },
  203. type: 'category',
  204. axisLine: {
  205. show: false
  206. },
  207. axisLabel: {
  208. color: '#fff',
  209. fontSize: 18
  210. // formatter: (value: number) => format( 1'时')
  211. },
  212. splitLine: {
  213. show: false
  214. },
  215. axisTick: {
  216. show: true,
  217. alignWithLabel: true
  218. },
  219. data: [ '3月26日', '3月27日', '3月28日', '3月29日', '3月30日', '4月1日' ]
  220. },
  221. yAxis: {
  222. name: '维保量/台',
  223. nameLocation: 'center',
  224. nameGap: 50,
  225. nameTextStyle: {
  226. color: '#fff',
  227. fontSize: 18
  228. },
  229. padding: 5,
  230. // max: 1000,
  231. splitLine: {
  232. show: true,
  233. lineStyle: {
  234. color: '#A1A7B3'
  235. // type: 'dashed'
  236. }
  237. },
  238. axisLabel: {
  239. show: true,
  240. margin: 10,
  241. textStyle: {
  242. color: '#fff'
  243. }
  244. }
  245. },
  246. series: {
  247. name: '维保车辆',
  248. type: 'line',
  249. symbolSize: 0,
  250. itemStyle: {
  251. normal: {
  252. // color: '#4293FD',
  253. lineStyle: {
  254. // color: '#4293FD',
  255. width: 2
  256. }
  257. }
  258. },
  259. data: [ 120, 132, 101, 134, 90, 230 ]
  260. },
  261. dataZoom: {
  262. type: 'slider',
  263. height: 20,
  264. bottom: 8,
  265. handleIcon: 'path://M306.1,413c0,2.2-1.8,4-4,4h-59.8c-2.2,0-4-1.8-4-4V200.8c0-2.2,1.8-4,4-4h59.8c2.2,0,4,1.8,4,4V413z',
  266. handleSize: '100%',
  267. handleStyle: {
  268. color: '#409eff'
  269. },
  270. textStyle: {
  271. color: '#666'
  272. },
  273. fillerColor: 'rgba(255,255,255,0.2)',
  274. borderColor: 'rgba(64,158,225,0.3)'
  275. }
  276. }
  277. },
  278. {
  279. name: '车辆运营状态分布',
  280. option: {
  281. title: {
  282. text: '总166', // 图标内容文本
  283. left: 'center', // 图标内容水平居中
  284. top: 'center', // 图标内容垂直居中
  285. // 文本样式
  286. textStyle: {
  287. color: '#fff', // 图标内容文字颜色
  288. fontSize: '18px', // 图标内容文字大小
  289. fontWeight: 'normal'
  290. }
  291. },
  292. grid: {
  293. containLabel: true
  294. },
  295. // 图表图例
  296. legend: {
  297. type: 'scroll',
  298. orient: 'horizontal', // 图例排列方向
  299. icon: 'circle', // 图例样式为圆形
  300. itemWidth: 10, // 图例图形的宽度
  301. itemHeight: 16, // 图例图形的高度
  302. itemGap: 10, // 图例项之间的间隔
  303. left: 'center', // 图例距离容器右侧的距离
  304. bottom: 0, // 图例垂直居中
  305. textStyle: {
  306. color: 'white', // 图例文字颜色
  307. fontSize: 20
  308. }
  309. },
  310. series: [
  311. {
  312. type: 'pie', // 图表类型为饼图
  313. radius: [ '45%', '60%' ], // 控制内外圆环的半径,30%代表内圆,60%代表外圆
  314. avoidLabelOverlap: true, // 是否启用防止标签重叠策略
  315. showEmptyCircle: true, // 是否在无数据的时候显示一个占位圆
  316. label: {
  317. formatter: '{b}\n{d}%',
  318. color: 'white'
  319. },
  320. data: [
  321. { name: '运营中', value: 30619 },
  322. { name: '维保中', value: 5921 },
  323. { name: '报废', value: 1153 }
  324. ]
  325. }
  326. ]
  327. }
  328. },
  329. {
  330. name: '车辆维保状态分别',
  331. option: {
  332. title: {
  333. text: '总166', // 图标内容文本
  334. left: 'center', // 图标内容水平居中
  335. top: 'center', // 图标内容垂直居中
  336. // 文本样式
  337. textStyle: {
  338. color: '#fff', // 图标内容文字颜色
  339. fontSize: '18px', // 图标内容文字大小
  340. fontWeight: 'normal'
  341. }
  342. },
  343. grid: {
  344. containLabel: true
  345. },
  346. // 图表图例
  347. legend: {
  348. type: 'scroll',
  349. orient: 'horizontal', // 图例排列方向
  350. icon: 'circle', // 图例样式为圆形
  351. itemWidth: 10, // 图例图形的宽度
  352. itemHeight: 16, // 图例图形的高度
  353. itemGap: 10, // 图例项之间的间隔
  354. left: 'center', // 图例距离容器右侧的距离
  355. bottom: 0, // 图例垂直居中
  356. textStyle: {
  357. color: 'white', // 图例文字颜色
  358. fontSize: 20
  359. }
  360. },
  361. series: [
  362. {
  363. type: 'pie', // 图表类型为饼图
  364. radius: [ '45%', '60%' ], // 控制内外圆环的半径,30%代表内圆,60%代表外圆
  365. avoidLabelOverlap: true, // 是否启用防止标签重叠策略
  366. showEmptyCircle: true, // 是否在无数据的时候显示一个占位圆
  367. label: {
  368. formatter: '{b}\n{d}%',
  369. color: 'white'
  370. },
  371. data: [
  372. { name: '隔日留交车辆', value: 30619 },
  373. { name: '保养中车辆', value: 5921 },
  374. { name: '维修中车辆', value: 1153 }
  375. ]
  376. }
  377. ]
  378. }
  379. }
  380. ],
  381. bottom: {
  382. head: [
  383. { title: '序号', render: (rowData: object, rowIndex: number) => rowIndex + 1 },
  384. { title: '车辆编号', key: 'code' },
  385. { title: '车牌号', key: 'licensePlate' },
  386. { title: '线路', key: 'line' },
  387. { title: '维修类型', key: 'maintenanceType' },
  388. { title: '故障原因', key: 'faultReason' },
  389. { title: '维修点位', key: 'maintenanceLocation' },
  390. { title: '报修时间', key: 'time' },
  391. { title: '维保结果', key: 'result' }
  392. ],
  393. body: [
  394. {
  395. num: 1, carNum: 1, carNumber: 1, line: '1路', type: '小修', cause: '测试', postion: 'tess', time: '2023-01-01 12:00', result: '已处理'
  396. },
  397. {
  398. num: 1, carNum: 1, carNumber: 1, line: '1路', type: '小修', cause: '测试', postion: 'tess', time: '2023-01-01 12:00', result: '已处理'
  399. },
  400. {
  401. num: 1, carNum: 1, carNumber: 1, line: '1路', type: '小修', cause: '测试', postion: 'tess', time: '2023-01-01 12:00', result: '已处理'
  402. },
  403. {
  404. num: 1, carNum: 1, carNumber: 1, line: '1路', type: '小修', cause: '测试', postion: 'tess', time: '2023-01-01 12:00', result: '已处理'
  405. },
  406. {
  407. num: 1, carNum: 1, carNumber: 1, line: '1路', type: '小修', cause: '测试', postion: 'tess', time: '2023-01-01 12:00', result: '已处理'
  408. }
  409. ],
  410. page: {
  411. size: 5,
  412. total: 10,
  413. num: 1
  414. },
  415. range: [ subDays(Date.now(), 7), Date.now() ]
  416. }
  417. })
  418. const rightContent = ref({
  419. top: [
  420. {
  421. name: '客流线路分布',
  422. option: {
  423. // 图表图例
  424. legend: {
  425. show: true,
  426. type: 'scroll',
  427. orient: 'horizontal', // 图例排列方向
  428. icon: 'circle', // 图例样式为圆形
  429. itemWidth: 10, // 图例图形的宽度
  430. itemHeight: 16, // 图例图形的高度
  431. itemGap: 10, // 图例项之间的间隔
  432. left: 'center', // 图例距离容器右侧的距离
  433. bottom: 50, // 图例垂直居中
  434. textStyle: {
  435. color: 'white', // 图例文字颜色
  436. fontSize: 18
  437. }
  438. },
  439. // color: [ '#6386e0', '#fb9a55', '#6bd98d', '#8dfd15', '#6bd98d', '#fff' ],
  440. series: {
  441. bottom: 50,
  442. type: 'pie', // 图表类型为饼图
  443. radius: '50%', // 控制内外圆环的半径,30%代表内圆,60%代表外圆
  444. avoidLabelOverlap: true, // 是否启用防止标签重叠策略
  445. showEmptyCircle: true, // 是否在无数据的时候显示一个占位圆
  446. label: {
  447. show: true,
  448. fontSize: 16,
  449. formatter: '{b}: {c}个',
  450. color: 'white'
  451. },
  452. data: [
  453. { name: '维保场', value: 10 },
  454. { name: '运维驿站', value: 2 }
  455. ]
  456. }
  457. }
  458. },
  459. {
  460. name: '消费类型',
  461. option: {
  462. // 图表图例
  463. legend: {
  464. show: true,
  465. type: 'scroll',
  466. orient: 'horizontal', // 图例排列方向
  467. icon: 'circle', // 图例样式为圆形
  468. itemWidth: 10, // 图例图形的宽度
  469. itemHeight: 16, // 图例图形的高度
  470. itemGap: 10, // 图例项之间的间隔
  471. left: 'center', // 图例距离容器右侧的距离
  472. bottom: 50, // 图例垂直居中
  473. textStyle: {
  474. color: 'white', // 图例文字颜色
  475. fontSize: 18
  476. }
  477. },
  478. // color: [ '#6386e0', '#fb9a55', '#6bd98d', '#8dfd15', '#6bd98d', '#fff' ],
  479. series: {
  480. bottom: 50,
  481. type: 'pie', // 图表类型为饼图
  482. radius: '50%', // 控制内外圆环的半径,30%代表内圆,60%代表外圆
  483. avoidLabelOverlap: true, // 是否启用防止标签重叠策略
  484. showEmptyCircle: true, // 是否在无数据的时候显示一个占位圆
  485. label: {
  486. show: true,
  487. fontSize: 16,
  488. formatter: '{b}: {c}辆',
  489. color: 'white'
  490. },
  491. data: [
  492. { name: '一保', value: 100 },
  493. { name: '二保', value: 50 },
  494. { name: '三保', value: 16 }
  495. ]
  496. }
  497. }
  498. },
  499. {
  500. name: '乘距分布',
  501. option: {
  502. // 图表图例
  503. legend: {
  504. show: true,
  505. type: 'scroll',
  506. orient: 'horizontal', // 图例排列方向
  507. icon: 'circle', // 图例样式为圆形
  508. itemWidth: 10, // 图例图形的宽度
  509. itemHeight: 16, // 图例图形的高度
  510. itemGap: 10, // 图例项之间的间隔
  511. left: 'center', // 图例距离容器右侧的距离
  512. bottom: 50, // 图例垂直居中
  513. textStyle: {
  514. color: 'white', // 图例文字颜色
  515. fontSize: 18
  516. }
  517. },
  518. // color: [ '#6386e0', '#fb9a55', '#6bd98d', '#8dfd15', '#6bd98d', '#fff' ],
  519. series: {
  520. bottom: 50,
  521. type: 'pie', // 图表类型为饼图
  522. radius: '50%', // 控制内外圆环的半径,30%代表内圆,60%代表外圆
  523. avoidLabelOverlap: true, // 是否启用防止标签重叠策略
  524. showEmptyCircle: true, // 是否在无数据的时候显示一个占位圆
  525. label: {
  526. show: true,
  527. fontSize: 16,
  528. formatter: '{b}: {c}万元',
  529. color: 'white'
  530. },
  531. data: [
  532. { name: '保养', value: 60 },
  533. { name: '维修', value: 100 }
  534. ]
  535. }
  536. }
  537. }
  538. ],
  539. bottom: {
  540. name: '维保执行情况',
  541. option: {
  542. title: {
  543. text: '总报修', // 图标内容文本
  544. subtext: '60',
  545. left: 'center', // 图标内容水平居中
  546. top: 'center', // 图标内容垂直居中
  547. // 文本样式
  548. textStyle: {
  549. color: '#fff', // 图标内容文字颜色
  550. fontSize: '18px', // 图标内容文字大小
  551. fontWeight: 'normal'
  552. },
  553. subtextStyle: {
  554. color: '#fff', // 图标内容文字颜色
  555. fontSize: '18px', // 图标内容文字大小
  556. fontWeight: 'normal'
  557. }
  558. },
  559. grid: {
  560. containLabel: true,
  561. top: 0,
  562. bottom: 0
  563. },
  564. // 图表图例
  565. legend: {
  566. show: true,
  567. type: 'scroll',
  568. orient: 'horizontal', // 图例排列方向
  569. icon: 'circle', // 图例样式为圆形
  570. itemWidth: 10, // 图例图形的宽度
  571. itemHeight: 16, // 图例图形的高度
  572. itemGap: 10, // 图例项之间的间隔
  573. left: 'center', // 图例距离容器右侧的距离
  574. bottom: 0, // 图例垂直居中
  575. textStyle: {
  576. color: 'white', // 图例文字颜色
  577. fontSize: 18
  578. }
  579. },
  580. series: {
  581. type: 'pie', // 图表类型为饼图
  582. radius: [ '45%', '60%' ], // 控制内外圆环的半径,30%代表内圆,60%代表外圆
  583. avoidLabelOverlap: true, // 是否启用防止标签重叠策略
  584. showEmptyCircle: true, // 是否在无数据的时候显示一个占位圆
  585. label: {
  586. show: true,
  587. formatter: '{b}: {d}俩',
  588. color: 'white',
  589. fontSize: 18
  590. },
  591. data: [
  592. { name: '执行', value: 30 },
  593. { name: '竣工', value: 20 },
  594. { name: '在修', value: 10 }
  595. ]
  596. }
  597. }
  598. }
  599. })
  600. const checkupProblem = ref([] as any[])
  601. const checkupProblemTotal = ref(0)
  602. const maintenanceDynamicsService = new MaintenanceDynamicsService()
  603. async function getMaintenanceCarStatus() {
  604. const res = await maintenanceDynamicsService.getMaintenanceCarStatus()
  605. leftContent.value.top[3].option!.series[0].data = res.map((item: any) => ({
  606. name: item.maintenanceStatus, value: item.number
  607. }))
  608. }
  609. getMaintenanceCarStatus()
  610. async function getMaintenanceCarOperate() {
  611. const res = await maintenanceDynamicsService.getMaintenanceCarOperate()
  612. leftContent.value.top[2].option!.series[0].data = res.map((item: any) => ({
  613. name: item.carStatus, value: item.number
  614. }))
  615. }
  616. getMaintenanceCarOperate()
  617. async function getMaintenanceRidingDistance() {
  618. const res = await maintenanceDynamicsService.getMaintenanceRidingDistance()
  619. rightContent.value.top[2].option!.series.data = res.map((item: any) => ({
  620. name: item.distanceType, value: item.number
  621. }))
  622. }
  623. getMaintenanceRidingDistance()
  624. async function getMaintenanceLocationNum() {
  625. const res = await maintenanceDynamicsService.getMaintenanceLocationNum()
  626. rightContent.value.top[0].option!.series.data = res.map((item: any) => ({
  627. name: item.location, value: item.number
  628. }))
  629. }
  630. getMaintenanceLocationNum()
  631. async function getMaintenanceConsumption() {
  632. const res = await maintenanceDynamicsService.getMaintenanceConsumption()
  633. rightContent.value.top[1].option!.series.data = res.map((item: any) => ({
  634. name: item.consumptionType, value: item.number
  635. }))
  636. }
  637. getMaintenanceConsumption()
  638. async function getMaintenanceImplementation() {
  639. const res = await maintenanceDynamicsService.getMaintenanceImplementation()
  640. rightContent.value.bottom.option!.series.data = res.map((item: any) => ({
  641. name: item.executeType, value: item.number
  642. }))
  643. }
  644. getMaintenanceImplementation()
  645. async function getMaintenanceStatistics(type: number) {
  646. const res = await maintenanceDynamicsService.getMaintenanceStatistics(type)
  647. const xData = res.map((item: any) => item.time)
  648. const carNumberData = res.map((item: any) => item.carNumber)
  649. leftContent.value.top[1].option.xAxis!.data = xData
  650. leftContent.value.top[1].option.series.data = carNumberData
  651. }
  652. async function getMaintenanceCheckupProblem() {
  653. const res = await maintenanceDynamicsService.getMaintenanceCheckupProblem()
  654. checkupProblem.value = res
  655. checkupProblemTotal.value = res.reduce((prev: any, item: { number: number }) => {
  656. prev += item.number
  657. return prev
  658. }, 0)
  659. }
  660. getMaintenanceCheckupProblem()
  661. async function getBusLineDetailAll() {
  662. const res = await maintenanceDynamicsService.getBusLineDetailAll()
  663. leftContent.value.top[0].num = `${res.reduce((prev: any, item: { totalCar: number }) => {
  664. prev += item.totalCar
  665. return prev
  666. }, 0)}`
  667. }
  668. getBusLineDetailAll()
  669. const tableData = computed(() => {
  670. const { num, size } = leftContent.value.bottom.page
  671. return leftContent.value.bottom.body.slice((num - 1) * size, num * size)
  672. })
  673. async function getMaintenanceDetail() {
  674. const { range } = leftContent.value.bottom
  675. const params = {
  676. startTime: format(range[0], 'yyyy-MM-dd HH:mm:ss'),
  677. endTime: format(range[1], 'yyyy-MM-dd HH:mm:ss')
  678. }
  679. const res = await maintenanceDynamicsService.getMaintenanceDetail(params)
  680. leftContent.value.bottom.body = res
  681. leftContent.value.bottom.page.total = res.length
  682. }
  683. getMaintenanceDetail()
  684. watch(() => leftContent.value.bottom.range, getMaintenanceDetail)
  685. function selectDatechange(type: any) {
  686. getMaintenanceStatistics(type)
  687. }
  688. onMounted(() => {
  689. selectDatechange(1)
  690. })
  691. </script>
  692. <style lang="scss" scoped>
  693. .left-top {
  694. display: flex;
  695. flex-wrap: wrap;
  696. justify-content: space-between;
  697. &-count {
  698. display: flex;
  699. font-family: 'Impact Normal', 'Impact', sans-serif;
  700. font-weight: 408;
  701. font-style: normal;
  702. text-align: center;
  703. align-items: center;
  704. width: 100%;
  705. height: 100%;
  706. justify-content: center;
  707. &>div:not(:last-child) {
  708. width: 84px;
  709. height: 110px;
  710. background-color: rgba(33, 133, 232, 0.298039215686275);
  711. border: solid 2px rgba(33, 133, 232, 1);
  712. border-radius: 10px;
  713. line-height: 110px;
  714. font-size: 70px;
  715. color: #FFFFFF;
  716. margin-right: 16px;
  717. }
  718. &>div:last-child {
  719. font-size: 24px;
  720. color: #80FFFF;
  721. height: 110px;
  722. line-height: 145px;
  723. }
  724. }
  725. :deep(.selectDate){
  726. top: 50px;
  727. }
  728. }
  729. .left-bottom{
  730. position: relative;
  731. :deep(.n-date-picker){
  732. position: absolute;
  733. right: 230px;
  734. top: 3px;
  735. }
  736. .page{
  737. display: flex;
  738. justify-content: flex-end;
  739. margin-top: 20px;
  740. }
  741. }
  742. .right-bottom,
  743. .right-top {
  744. display: flex;
  745. justify-content: space-between;
  746. }
  747. .right-center{
  748. .lineSpeed{
  749. display: flex;
  750. align-items: center;
  751. height: 100%;
  752. >div{
  753. width: 50%;
  754. }
  755. .img{
  756. text-align: center;
  757. img{
  758. height: 262px;
  759. }
  760. }
  761. .control{
  762. width: 300px;
  763. margin: auto;
  764. display: flex;
  765. flex-wrap: wrap;
  766. justify-content: center;
  767. :deep(.n-select){
  768. .n-base-selection{
  769. border: 1px solid #5689F0;
  770. height: 50px;
  771. .n-base-selection-label{
  772. height: 100%;
  773. background: rgba(86, 137, 240, 0.298);
  774. }
  775. }
  776. }
  777. .btn{
  778. width: 173px;
  779. height: 71px;
  780. line-height: 71px;
  781. border-radius: 5px;
  782. background: rgba(24, 145, 255, 0.298);
  783. border: 1px solid #1891FF;
  784. color: #FFFFFF;
  785. font-size: 24px;
  786. text-align: center;
  787. margin-top: 53px;
  788. }
  789. }
  790. }
  791. }
  792. .right-bottom{
  793. .checkup{
  794. display: flex;
  795. height: 100%;
  796. .total{
  797. width: 30%;
  798. color: #FFFFFF;
  799. text-align: center;
  800. height: fit-content;
  801. margin: auto;
  802. >div{
  803. width: 100%;
  804. }
  805. .num{
  806. font-size: 60px;
  807. text-shadow: 1px 1px 10px rgba(0, 255, 255, 0.698);
  808. }
  809. }
  810. .list{
  811. flex: 1;
  812. display: flex;
  813. align-items: center;
  814. flex-wrap: wrap;
  815. padding-right: 40px;
  816. .item{
  817. width: 50%;
  818. height: 115px;
  819. background: url('../../../../assets/img/1-3.png') no-repeat;
  820. background-size: contain;
  821. text-align: center;
  822. background-position-y: 13px;
  823. .num{
  824. font-size: 50px;
  825. text-shadow: 1px 1px 10px rgba(0, 255, 255, 0.698);
  826. color: #00FFFF;
  827. font-family: Impact Normal;
  828. }
  829. .label{
  830. font-size: 24px;
  831. color: #FFFFFF;
  832. text-shadow: 1px 1px 10px rgba(0, 255, 255, 0.698);
  833. }
  834. }
  835. }
  836. }
  837. }
  838. </style>