SystemLoad.vue 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. <template>
  2. <Box title="系统实时负载">
  3. <div class="l-flex__fill l-flex--col c-load">
  4. <div class="l-flex c-duration u-bold">
  5. 系统运行时长<span class="c-duration__num">{{ diffDay }}</span>天
  6. </div>
  7. <div class="l-flex__none l-flex--row c-load__header">
  8. <div class="l-flex__fill">服务器</div>
  9. <div class="l-flex__fill">CPU使用率</div>
  10. <div class="l-flex__fill">内存使用率</div>
  11. <div class="l-flex__fill">磁盘空间使用率</div>
  12. <div class="l-flex__fill col__net">网络</div>
  13. <div class="l-flex__fill">状态</div>
  14. </div>
  15. <status-wrapper v-if="!tableData.length" />
  16. <template v-else>
  17. <div class="l-flex__fill u-relative">
  18. <div class="c-load__list">
  19. <vue-seamless-scroll
  20. :data="tableData"
  21. :class-option="classOption"
  22. >
  23. <div
  24. v-for="item in tableData"
  25. :key="item.id"
  26. class="l-flex--row c-load__item"
  27. >
  28. <div class="l-flex__fill">
  29. <auto-text
  30. class="u-text--center"
  31. :text="item.ip"
  32. />
  33. </div>
  34. <div class="l-flex__fill item__chart l-flex--col">
  35. <LineChart
  36. class="l-flex__fill"
  37. :list="item.cpu"
  38. :color-type="0"
  39. />
  40. </div>
  41. <div class="l-flex__fill item__chart l-flex--col">
  42. <LineChart
  43. class="l-flex__fill"
  44. :list="item.memory"
  45. :color-type="1"
  46. />
  47. </div>
  48. <div class="l-flex__fill item__chart l-flex--col">
  49. <LineChart
  50. class="l-flex__fill"
  51. :list="item.disk"
  52. :color-type="2"
  53. />
  54. </div>
  55. <div class="l-flex__fill item__chart l-flex--col col__net">
  56. <LineChart
  57. class="l-flex__fill"
  58. :list="item.net"
  59. :color-type="3"
  60. unit="Kbps"
  61. />
  62. </div>
  63. <div class="l-flex__fill">
  64. <auto-text
  65. class="u-text--center"
  66. :text="item.status === 1 ? '正常' : '离线'"
  67. :style="{
  68. color: item.status === 1 ? '#04FF98' : '#F40645',
  69. }"
  70. />
  71. </div>
  72. </div>
  73. </vue-seamless-scroll>
  74. </div>
  75. </div>
  76. </template>
  77. </div>
  78. </Box>
  79. </template>
  80. <script>
  81. import Box from './Box'
  82. import LineChart from './LineChart'
  83. import VueSeamlessScroll from 'vue-seamless-scroll'
  84. export default {
  85. name: 'SystemLoad',
  86. components: {
  87. Box,
  88. VueSeamlessScroll,
  89. LineChart
  90. },
  91. props: {
  92. deviceList: {
  93. type: Array,
  94. default: () => []
  95. }
  96. },
  97. data () {
  98. this.$count = 0
  99. return {
  100. loaded: false,
  101. error: false,
  102. classOption: {
  103. step: 0.5,
  104. hoverStop: false
  105. },
  106. initDay: '2022-1-1',
  107. tableData: []
  108. }
  109. },
  110. computed: {
  111. diffDay () {
  112. return Math.floor(
  113. (Date.parse(new Date()) - Date.parse(this.initDay)) / (1000 * 3600 * 24)
  114. )
  115. }
  116. },
  117. created () {
  118. this.initData()
  119. },
  120. methods: {
  121. getRandomData (value = Math.floor(50 + Math.random() * 10), limit = true) {
  122. let gap = Math.floor(Math.random() * 20 - 10)
  123. if (!limit) {
  124. gap *= 3
  125. }
  126. value += gap
  127. if (limit) {
  128. if (value < 0) {
  129. value = 10
  130. }
  131. if (value > 100) {
  132. value = 90
  133. }
  134. } else if (value < 0) {
  135. value = 10
  136. }
  137. this.$count++
  138. return [this.$count, value]
  139. },
  140. getChartData (num, limit) {
  141. const arr = [this.getRandomData(num, limit)]
  142. for (let index = 0; index < 30; index++) {
  143. arr.push(this.getRandomData(arr[index][1], limit))
  144. }
  145. return arr
  146. },
  147. initData () {
  148. this.loaded = true
  149. this.tableData = Array.from({ length: 2 }, (i, index) => {
  150. return {
  151. ip: ['主服务器', '副服务器'][index],
  152. cpu: this.getChartData(),
  153. memory: this.getChartData(),
  154. disk: this.getChartData(),
  155. net: this.getChartData(700, false),
  156. status: 1,
  157. id: index
  158. }
  159. })
  160. this.updateValue()
  161. },
  162. updateValue () {
  163. const map = ['cpu', 'memory', 'disk', 'net']
  164. setTimeout(() => {
  165. this.tableData = this.tableData.map(i => {
  166. for (const key of map) {
  167. i[key].shift()
  168. i[key].push(
  169. this.getRandomData(i[key][i[key].length - 1][1], key !== 'net')
  170. )
  171. }
  172. return i
  173. })
  174. this.updateValue()
  175. }, 1000)
  176. }
  177. }
  178. }
  179. </script>
  180. <style lang="scss" scoped>
  181. .c-load {
  182. &__header {
  183. color: #9ea9cd;
  184. background-color: #313a5a;
  185. }
  186. .c-duration {
  187. font-size: 24px;
  188. color: #ffffff;
  189. justify-content: center;
  190. align-items: flex-end;
  191. margin: 5px 0 50px;
  192. &__num {
  193. margin-left: 60px;
  194. margin-right: 15px;
  195. transform: translateY(14px);
  196. font-size: 72px;
  197. color: #00d1ff;
  198. }
  199. }
  200. &__list {
  201. position: absolute;
  202. top: 0;
  203. left: 0;
  204. width: 100%;
  205. height: 100%;
  206. overflow: hidden;
  207. }
  208. &__header,
  209. &__item {
  210. font-size: 18px;
  211. line-height: 60px;
  212. height: 60px;
  213. text-align: center;
  214. }
  215. &__item {
  216. color: #ffffff;
  217. border-bottom: 1px solid #313a5a;
  218. height: 72px;
  219. line-height: 72px;
  220. }
  221. .item__chart {
  222. height: 100%;
  223. }
  224. .col__net {
  225. flex: 1 1 50px;
  226. }
  227. }
  228. </style>