index.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754
  1. <template>
  2. <div class="system-user-container">
  3. <div class="flex-row gap-3">
  4. <el-col :xs="24" :sm="12" :md="8" class="marg-b-15">
  5. <el-card class="box-card-meter">
  6. <div class="el-table--enable-row-hover el-table--medium">
  7. <el-row :gutter="30">
  8. <el-col :xs="24" :sm="24" :md="12">
  9. <table cellspacing="0" style="width: 100%">
  10. <tbody>
  11. <tr>
  12. <td>
  13. <div class="cell-card">CPU数: </div>
  14. </td>
  15. <td>
  16. <div class="cell-card">{{ sysInfo.cpuNum }}</div>
  17. </td>
  18. </tr>
  19. <tr>
  20. <td>
  21. <div class="cell-card">核心数: </div>
  22. </td>
  23. <td>
  24. <div class="cell-card">{{ sysInfo.cpuCores }}</div>
  25. </td>
  26. </tr>
  27. <tr>
  28. <td>
  29. <div class="cell-card">使用率:</div>
  30. </td>
  31. <td>
  32. <div class="cell-card">{{ sysInfo.cpuUsed }}%</div>
  33. </td>
  34. </tr>
  35. <tr>
  36. <td>
  37. <div class="cell-card">LA5:</div>
  38. </td>
  39. <td>
  40. <div class="cell-card">{{ sysInfo.cpuAvg5 }}%</div>
  41. </td>
  42. </tr>
  43. <tr>
  44. <td>
  45. <div class="cell-card">LA15:</div>
  46. </td>
  47. <td>
  48. <div class="cell-card">{{ sysInfo.cpuAvg15 }}%</div>
  49. </td>
  50. </tr>
  51. </tbody>
  52. </table>
  53. </el-col>
  54. <el-col :xs="24" :sm="24" :md="12">
  55. <div style="min-height: 180px" ref="chartsWarningRef1"></div>
  56. </el-col>
  57. </el-row>
  58. </div>
  59. </el-card>
  60. </el-col>
  61. <el-col :xs="24" :sm="12" :md="8" class="marg-b-15">
  62. <el-card class="box-card-meter">
  63. <div class="el-table--enable-row-hover el-table--medium">
  64. <el-row :gutter="30">
  65. <el-col :xs="24" :sm="24" :md="12">
  66. <table cellspacing="0" style="width: 100%">
  67. <tbody>
  68. <tr>
  69. <td>
  70. <div class="cell-card">内存总数:</div>
  71. </td>
  72. <td>
  73. <div class="cell-card">{{ memorySizeFormat(sysInfo.memTotal) }}</div>
  74. </td>
  75. </tr>
  76. <tr>
  77. <td>
  78. <div class="cell-card">已使用:</div>
  79. </td>
  80. <td>
  81. <div class="cell-card">{{ memorySizeFormat(sysInfo.memUsed) }}</div>
  82. </td>
  83. </tr>
  84. <tr>
  85. <td>
  86. <div class="cell-card">剩余:</div>
  87. </td>
  88. <td>
  89. <div class="cell-card">{{ memorySizeFormat(sysInfo.memFree) }}</div>
  90. </td>
  91. </tr>
  92. <tr>
  93. <td>
  94. <div class="cell-card">系统使用:</div>
  95. </td>
  96. <td>
  97. <div class="cell-card">{{ memorySizeFormat(sysInfo.goUsed) }}</div>
  98. </td>
  99. </tr>
  100. <tr>
  101. <td>
  102. <div class="cell-card">使用率:</div>
  103. </td>
  104. <td>
  105. <div class="cell-card">{{ sysInfo.memUsage }}%</div>
  106. </td>
  107. </tr>
  108. </tbody>
  109. </table>
  110. </el-col>
  111. <el-col :xs="24" :sm="24" :md="12">
  112. <div style="min-height: 180px" ref="chartsWarningRef2"></div>
  113. </el-col>
  114. </el-row>
  115. </div>
  116. </el-card>
  117. </el-col>
  118. <el-col :xs="24" :sm="12" :md="8" class="marg-b-15">
  119. <el-card class="box-card-meter">
  120. <div class="el-table--enable-row-hover el-table--medium">
  121. <el-row :gutter="30">
  122. <el-col :xs="24" :sm="24" :md="12">
  123. <table cellspacing="0" style="width: 100%">
  124. <tbody>
  125. <tr>
  126. <td>
  127. <div class="cell-card">磁盘容量:</div>
  128. </td>
  129. <td>
  130. <div class="cell-card">{{ memorySizeFormat(sysInfo.diskTotal) }}</div>
  131. </td>
  132. </tr>
  133. <tr>
  134. <td>
  135. <div class="cell-card">已使用:</div>
  136. </td>
  137. <td>
  138. <div class="cell-card">{{ memorySizeFormat(sysInfo.diskUsed) }}</div>
  139. </td>
  140. </tr>
  141. <tr>
  142. <td>
  143. <div class="cell-card">使用率:</div>
  144. </td>
  145. <td>
  146. <div class="cell-card">{{ sysInfo.diskUsedPercent }}%</div>
  147. </td>
  148. </tr>
  149. </tbody>
  150. </table>
  151. </el-col>
  152. <el-col :xs="24" :sm="24" :md="12">
  153. <div style="min-height: 180px" ref="chartsWarningRef3"></div>
  154. </el-col>
  155. </el-row>
  156. </div>
  157. </el-card>
  158. </el-col>
  159. </div>
  160. <div class="flex-row gap-3">
  161. <el-col :xs="24" :sm="12" :md="8" class="marg-b-15">
  162. <el-card class="box-card-height" style="height:auto">
  163. <template #header>
  164. <div class="card-header">
  165. <span>CPU运行情况</span>
  166. </div>
  167. </template>
  168. <div style="height: 250px" ref="chartsWarningRef4"></div>
  169. </el-card>
  170. </el-col>
  171. <el-col :xs="24" :sm="12" :md="8" class="marg-b-15">
  172. <el-card class="box-card-height" style="height:auto">
  173. <template #header>
  174. <div class="card-header">
  175. <span>内存运行情况</span>
  176. </div>
  177. </template>
  178. <div style="height: 250px" ref="chartsWarningRef5"></div>
  179. </el-card>
  180. </el-col>
  181. <el-col :xs="24" :sm="12" :md="8" class="marg-b-15">
  182. <el-card class="box-card-height" style="height:auto">
  183. <template #header>
  184. <div class="card-header">
  185. <span>磁盘使用情况</span>
  186. </div>
  187. </template>
  188. <div style="height: 250px" ref="chartsWarningRef6"></div>
  189. </el-card>
  190. </el-col>
  191. </div>
  192. <div class="flex-row gap-3">
  193. <el-col :xs="24" :sm="24" :md="24" class="marg-b-15">
  194. <el-card class="box-card-height" style="height:auto">
  195. <template #header>
  196. <div class="card-header">
  197. <span>运行环境信息</span>
  198. </div>
  199. </template>
  200. <div class="flex-row">
  201. <el-form label-position="right" label-width="100px" class="flex1" style="max-width: 460px">
  202. <el-form-item label="操作系统">{{goInfoData.os}}</el-form-item>
  203. <el-form-item label="启动时间">{{goInfoData.startTime}}</el-form-item>
  204. <el-form-item label="运行时长">{{timeFormat(goInfoData.runTime)}}</el-form-item>
  205. <el-form-item label="运行内存">{{goInfoData.goMem}}</el-form-item>
  206. </el-form>
  207. <el-form label-position="right" label-width="100px" class="flex1" style="max-width: 460px">
  208. <el-form-item label="系统架构">{{goInfoData.kernelArch}}</el-form-item>
  209. <el-form-item label="语言环境">{{goInfoData.goName}}</el-form-item>
  210. <el-form-item label="磁盘占用">{{goInfoData.goSize}}</el-form-item>
  211. <el-form-item label="项目地址">{{goInfoData.pwd}}</el-form-item>
  212. </el-form>
  213. <el-form label-position="right" label-width="100px" class="flex1" style="max-width: 460px">
  214. <el-form-item label="架构版本">{{goInfoData.kernelVersion}}</el-form-item>
  215. <el-form-item label="GO 版本">{{goInfoData.goVersion}}</el-form-item>
  216. <el-form-item label="协程数量">{{goInfoData.goroutine}}</el-form-item>
  217. <el-form-item label="服务器IP">{{goInfoData.intranet_ip}}</el-form-item>
  218. </el-form>
  219. </div>
  220. </el-card>
  221. </el-col>
  222. </div>
  223. </div>
  224. </template>
  225. <script lang="ts">
  226. import { toRefs, reactive, onMounted, getCurrentInstance, defineComponent } from 'vue';
  227. import * as echarts from 'echarts';
  228. import 'echarts-wordcloud';
  229. import dayjs from 'dayjs';
  230. import getOrigin from '/@/utils/origin'
  231. let interval: any = null;
  232. export default defineComponent({
  233. name: 'monitor',
  234. components: {},
  235. setup() {
  236. const { proxy } = getCurrentInstance() as any;
  237. const state: any = reactive({
  238. myCharts: [],
  239. sysInfo: {},
  240. });
  241. let myChart1: any;
  242. let myChart2: any;
  243. let myChart3: any;
  244. let myChart4: any;
  245. let myChart5: any;
  246. let myChart6: any;
  247. const goInfoData = reactive({
  248. "os":"-","kernelArch":"-","kernelVersion":"-","goMem": "-", "goName": "-", "goSize": "-", "goVersion": "-", "goroutine": '-', "pwd": "-", "rootPath": "-",
  249. "runTime": '', "startTime": "-","intranet_ip":"-"
  250. });
  251. function goInfo(event: { data: any; }) {
  252. const data = JSON.parse(event.data);
  253. Object.assign(goInfoData, data);
  254. }
  255. const myChart4Data: any = {
  256. name: [],
  257. value: [],
  258. }
  259. const myChart5Data: any = {
  260. name: [],
  261. value: [],
  262. }
  263. const myChart6Data: any = {
  264. name: [],
  265. value: [],
  266. }
  267. const moveOption = {
  268. tooltip: {
  269. trigger: 'axis',
  270. },
  271. grid: {
  272. top: 10,
  273. bottom: 20,
  274. left: 10,
  275. right: 10,
  276. containLabel: true
  277. },
  278. xAxis: {
  279. type: 'category',
  280. splitLine: {
  281. show: false
  282. }
  283. },
  284. yAxis: {
  285. type: 'value',
  286. boundaryGap: [0, '100%'],
  287. splitLine: {
  288. show: false
  289. }
  290. },
  291. series: [
  292. {
  293. name: '使用率',
  294. type: 'line',
  295. showSymbol: false,
  296. data: []
  297. }
  298. ]
  299. };
  300. function setOptChart1(value: number) {
  301. myChart1.setOption({
  302. series: [
  303. {
  304. data: [
  305. {
  306. value: value,
  307. name: '',//cpu
  308. },
  309. ],
  310. },
  311. ],
  312. });
  313. }
  314. function setOptChart2(value: number) {
  315. myChart2.setOption({
  316. series: [
  317. {
  318. data: [
  319. {
  320. value: value,
  321. name: '',//内存
  322. },
  323. ],
  324. },
  325. ],
  326. });
  327. }
  328. function setOptChart3(value: number) {
  329. myChart3.setOption({
  330. series: [
  331. {
  332. data: [
  333. {
  334. value: value,
  335. name: '',//磁盘
  336. },
  337. ],
  338. },
  339. ],
  340. });
  341. }
  342. function setOptChart(myChart: any, myChartData: any, value: number) {
  343. myChartData.name.push(dayjs().format('HH:mm:ss'));
  344. myChartData.value.push(value);
  345. myChart.setOption({
  346. xAxis: {
  347. data: myChartData.name
  348. },
  349. series: [
  350. {
  351. data: myChartData.value
  352. },
  353. ],
  354. });
  355. }
  356. //CPU
  357. const initChartCPU = () => {
  358. myChart1 = echarts.init(proxy.$refs.chartsWarningRef1);
  359. const option = {
  360. tooltip: {
  361. formatter: '{a} <br/>{b} : {c}%',
  362. },
  363. series: [
  364. {
  365. type: 'gauge',
  366. name: 'CPU',
  367. radius: '90%', //修改表盘大小
  368. title: {
  369. show: true, //控制表盘title(今日预计用电量)字体是否显示
  370. fontSize: 12, //控制表盘title(今日预计用电量)字体大小
  371. 'color': 'green', //控制表盘title(今日预计用电量)字体颜色
  372. offsetCenter: [-2, '30%'], //设置表盘title(今日预计用电量)位置
  373. },
  374. axisLine: {
  375. show: true,
  376. lineStyle: {
  377. // 属性lineStyle控制线条样式
  378. color: [
  379. [0.3, '#4dabf7'],
  380. [0.6, '#69db7c'],
  381. [0.8, '#ffa94d'],
  382. [1, '#ff6b6b'],
  383. ],
  384. },
  385. },
  386. splitNumber: 5, //分割线之间的刻度
  387. detail: {
  388. valueAnimation: true,
  389. formatter: '{value}%',
  390. textStyle: {
  391. fontSize: 20,
  392. color: 'red',
  393. },
  394. offsetCenter: ['0', '80%'], //表盘数据(30%)位置
  395. },
  396. // data: [
  397. // {
  398. // value: 15,
  399. // name: 'CPU使用率',
  400. // },
  401. // ],
  402. },
  403. ],
  404. };
  405. myChart1.setOption(option);
  406. state.myCharts.push(myChart1);
  407. };
  408. //内存
  409. const initChartRAM = () => {
  410. myChart2 = echarts.init(proxy.$refs.chartsWarningRef2);
  411. const option = {
  412. tooltip: {
  413. formatter: '{a} <br/>{b} : {c}%',
  414. },
  415. series: [
  416. {
  417. type: 'gauge',
  418. name: '内存',
  419. radius: '90%', //修改表盘大小
  420. title: {
  421. show: true, //控制表盘title(今日预计用电量)字体是否显示
  422. fontSize: 12, //控制表盘title(今日预计用电量)字体大小
  423. 'color': 'green', //控制表盘title(今日预计用电量)字体颜色
  424. offsetCenter: [-2, '30%'], //设置表盘title(今日预计用电量)位置
  425. },
  426. axisLine: {
  427. show: true,
  428. lineStyle: {
  429. // 属性lineStyle控制线条样式
  430. color: [
  431. [0.3, '#4dabf7'],
  432. [0.6, '#69db7c'],
  433. [0.8, '#ffa94d'],
  434. [1, '#ff6b6b'],
  435. ],
  436. },
  437. },
  438. splitNumber: 5, //分割线之间的刻度
  439. detail: {
  440. valueAnimation: true,
  441. formatter: '{value}%',
  442. textStyle: {
  443. fontSize: 20,
  444. color: 'red',
  445. },
  446. offsetCenter: ['0', '80%'], //表盘数据(30%)位置
  447. },
  448. // data: [
  449. // {
  450. // value: 30,
  451. // name: '内存使用率',
  452. // },
  453. // ],
  454. },
  455. ],
  456. };
  457. myChart2.setOption(option);
  458. state.myCharts.push(myChart2);
  459. };
  460. //磁盘
  461. const initChartDISK = () => {
  462. myChart3 = echarts.init(proxy.$refs.chartsWarningRef3);
  463. const option = {
  464. tooltip: {
  465. formatter: '{a} <br/>{b} : {c}%',
  466. },
  467. series: [
  468. {
  469. type: 'gauge',
  470. name: '磁盘',
  471. radius: '90%', //修改表盘大小
  472. title: {
  473. show: true, //控制表盘title(今日预计用电量)字体是否显示
  474. fontSize: 12, //控制表盘title(今日预计用电量)字体大小
  475. 'color': 'green', //控制表盘title(今日预计用电量)字体颜色
  476. offsetCenter: [-2, '30%'], //设置表盘title(今日预计用电量)位置
  477. },
  478. axisLine: {
  479. show: true,
  480. lineStyle: {
  481. // 属性lineStyle控制线条样式
  482. color: [
  483. [0.3, '#4dabf7'],
  484. [0.6, '#69db7c'],
  485. [0.8, '#ffa94d'],
  486. [1, '#ff6b6b'],
  487. ],
  488. },
  489. },
  490. splitNumber: 5, //分割线之间的刻度
  491. detail: {
  492. valueAnimation: true,
  493. formatter: '{value}%',
  494. textStyle: {
  495. fontSize: 20,
  496. color: 'red',
  497. },
  498. offsetCenter: ['0', '80%'], //表盘数据(30%)位置
  499. },
  500. // data: [
  501. // {
  502. // value: 30,
  503. // name: '内存使用率',
  504. // },
  505. // ],
  506. },
  507. ],
  508. };
  509. myChart3.setOption(option);
  510. state.myCharts.push(myChart3);
  511. };
  512. //cpu运行状态
  513. const initChartCPURun = () => {
  514. myChart4 = echarts.init(proxy.$refs.chartsWarningRef4);
  515. myChart4.setOption({ ...moveOption });
  516. state.myCharts.push(myChart4);
  517. };
  518. //内存运行状态
  519. const initChartRAMRun = () => {
  520. myChart5 = echarts.init(proxy.$refs.chartsWarningRef5);
  521. myChart5.setOption({ ...moveOption });
  522. state.myCharts.push(myChart5);
  523. };
  524. //磁盘运行状态
  525. const initChartDISKRun = () => {
  526. myChart6 = echarts.init(proxy.$refs.chartsWarningRef6);
  527. myChart6.setOption({ ...moveOption });
  528. state.myCharts.push(myChart6);
  529. };
  530. // 页面加载时
  531. onMounted(() => {
  532. initChartCPU();
  533. initChartRAM();
  534. initChartDISK();
  535. initChartCPURun();
  536. initChartRAMRun();
  537. initChartDISKRun();
  538. });
  539. function startWs() {
  540. // ws = null;
  541. // ws = new WebSocket(import.meta.env.VITE_WS_URL + '/monitorServer/ws');
  542. // ws.onopen = () => {};
  543. // ws.onmessage = ({ data: dataStr }) => {
  544. // const data = JSON.parse(dataStr);
  545. // state.sysInfo = data;
  546. // setOptChart1(data.cpuUsed);
  547. // setOptChart2(data.memUsage);
  548. // setOptChart3(data.diskUsedPercent);
  549. // };
  550. const es = new EventSource(getOrigin(import.meta.env.VITE_SERVER_URL + "/subscribe/sysenv"));
  551. es.addEventListener("host", displayHost);
  552. es.addEventListener("mem", displayMem);
  553. es.addEventListener("cpu", displayCpu);
  554. es.addEventListener("sysLoad", displaySysLoad);
  555. es.addEventListener("disk", displayDisk);
  556. es.addEventListener("go", goInfo);
  557. }
  558. startWs();
  559. function displayHost(event: { data: any; }) {
  560. const data = JSON.parse(event.data);
  561. state.sysInfo.os = data.os
  562. state.sysInfo.kernelArch = data.kernelArch
  563. state.sysInfo.sysComputerName = data.hostname
  564. state.sysInfo.goStartTime = data.bootTime
  565. state.sysInfo.goRunTime = data.uptime
  566. }
  567. function displayMem(event: { data: any; }) {
  568. const data = JSON.parse(event.data);
  569. setOptChart2(data.usedPercent.toFixed(2));
  570. state.sysInfo.memTotal = data.total
  571. state.sysInfo.memUsed = data.used
  572. state.sysInfo.memFree = data.free
  573. state.sysInfo.goUsed = data.goUsed
  574. state.sysInfo.memUsage = data.usedPercent.toFixed(2)
  575. // console.log(state.sysInfo.memUsage)
  576. setOptChart(myChart5, myChart5Data, state.sysInfo.memUsage);
  577. }
  578. function displayCpu(event: { data: any; }) {
  579. const data = JSON.parse(event.data);
  580. state.sysInfo.cpuNum = data.Number
  581. state.sysInfo.cpuCores = data.Cores
  582. state.sysInfo.cpuUsed = data.UsedPercent[0].toFixed(2)
  583. setOptChart1(data.UsedPercent[0].toFixed(2));
  584. setOptChart(myChart4, myChart4Data, state.sysInfo.cpuUsed);
  585. };
  586. function displaySysLoad(event: { data: any; }) {
  587. const data = JSON.parse(event.data)
  588. state.sysInfo.cpuAvg5 = data.load5.toFixed(2)
  589. state.sysInfo.cpuAvg15 = data.load15.toFixed(2)
  590. };
  591. function displayDisk(event: { data: any; }) {
  592. const data = JSON.parse(event.data)
  593. state.sysInfo.diskTotal = data.total
  594. state.sysInfo.diskUsed = data.used
  595. state.sysInfo.diskUsedPercent = data.usedPercent.toFixed(2)
  596. setOptChart3(data.usedPercent.toFixed(2));
  597. setOptChart(myChart6, myChart6Data, state.sysInfo.diskUsedPercent);
  598. };
  599. // function getSystemInfo() {
  600. // api.getSysInfo().then((res: any) => {
  601. // state.sysInfo = res;
  602. // setOptChart1(res.cpuUsed);
  603. // setOptChart2(res.memUsage);
  604. // setOptChart3(res.diskUsedPercent);
  605. //
  606. // });
  607. // }
  608. return {
  609. ...toRefs(state),
  610. goInfoData,
  611. setOptChart1,
  612. setOptChart2,
  613. setOptChart3,
  614. // ws,
  615. };
  616. },
  617. created() {
  618. // this.getSystemInfo();
  619. // if (interval === null) {
  620. // interval = setInterval(() => {
  621. // this.getSystemInfo();
  622. // }, 5000);
  623. // }
  624. },
  625. unmounted() {
  626. // if (this.ws) {
  627. // (this.ws as WebSocket).close();
  628. // }
  629. if (interval) {
  630. clearInterval(interval);
  631. interval = null;
  632. }
  633. },
  634. data() {
  635. return {};
  636. },
  637. methods: {
  638. memorySizeFormat(size: any) {
  639. size = parseFloat(size);
  640. let rank = 0;
  641. let rankchar = 'Bytes';
  642. while (size > 1024 && rankchar != 'TB') {
  643. size = size / 1024;
  644. rank++;
  645. if (rank == 1) {
  646. rankchar = 'KB';
  647. } else if (rank == 2) {
  648. rankchar = 'MB';
  649. } else if (rank == 3) {
  650. rankchar = 'GB';
  651. } else if (rank == 4) {
  652. rankchar = 'TB';
  653. }
  654. }
  655. return size.toFixed(2) + ' ' + rankchar;
  656. },
  657. timeFormat(second: any) {
  658. if (!second) return '-'
  659. second = parseFloat(second);
  660. let rank = 0;
  661. let rankchar = '秒';
  662. while ((second > 60 && rankchar != '小时' && rankchar != '天') || (second > 24 && rankchar == '小时')) {
  663. if (rankchar == '小时') {
  664. second = second / 24;
  665. } else {
  666. second = second / 60;
  667. }
  668. rank++;
  669. if (rank == 1) {
  670. rankchar = '分';
  671. } else if (rank == 2) {
  672. rankchar = '小时';
  673. } else if (rank == 3) {
  674. rankchar = '天';
  675. }
  676. }
  677. return second.toFixed(2) + ' ' + rankchar;
  678. },
  679. },
  680. });
  681. </script>
  682. <style scoped lang="scss">
  683. .el-card {
  684. height: 300px;
  685. overflow-y: auto;
  686. }
  687. .marg-b-15 {
  688. margin-bottom: 15px;
  689. }
  690. .cell {
  691. box-sizing: border-box;
  692. overflow: hidden;
  693. text-overflow: ellipsis;
  694. white-space: normal;
  695. word-break: break-all;
  696. line-height: 36px;
  697. padding-left: 10px;
  698. padding-right: 10px;
  699. }
  700. .cell-card {
  701. box-sizing: border-box;
  702. overflow: hidden;
  703. text-overflow: ellipsis;
  704. white-space: normal;
  705. word-break: break-all;
  706. line-height: 36px;
  707. }
  708. .box-card {
  709. min-height: 380px;
  710. }
  711. .box-card-meter {
  712. height: 230px;
  713. min-height: 180px;
  714. }
  715. </style>