UsageRing.vue 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. <template>
  2. <div class="usage-ring" :class="{ 'is-template': isTemplate }">
  3. <div class="dashboard-card-wrap">
  4. <div class="dashboard-card-header">
  5. <div class="dashboard-card-header-left">{{title}}<a-icon class="ml-2" type="loading" v-if="loading" /></div>
  6. </div>
  7. <div class="dashboard-card-body align-items-center">
  8. <a-progress type="circle" :percent="percent" :strokeWidth="12" :status="status" :strokeColor="percentColor">
  9. <template v-slot:format><span class="percent-tips" :style="{ color: percentColor }">{{ percentTips }}</span></template>
  10. </a-progress>
  11. <div class="flex-fill ml-4">
  12. <div class="d-flex">
  13. <div class="flex-shrink-0 flex-grow-0">{{ useLabel }}</div>
  14. <div class="ml-2 flex-fill text-right">{{ use }}</div>
  15. </div>
  16. <div class="d-flex">
  17. <div class="flex-shrink-0 flex-grow-0">
  18. {{ unuseLabel }}
  19. </div>
  20. <div class="ml-2 flex-fill text-right">{{ unuse }}</div>
  21. </div>
  22. <div class="d-flex">
  23. <div class="flex-shrink-0 flex-grow-0">
  24. {{ sumLabel }}
  25. </div>
  26. <div class="ml-2 flex-fill text-right">{{ sum }}</div>
  27. </div>
  28. </div>
  29. </div>
  30. </div>
  31. </div>
  32. </template>
  33. <script>
  34. import COLORS from '@/constants/color'
  35. export default {
  36. name: 'UsageRing',
  37. props: {
  38. title: {
  39. type: String,
  40. },
  41. field: {
  42. type: String,
  43. },
  44. options: {
  45. type: Object,
  46. default: () => {},
  47. },
  48. isTemplate: {
  49. type: Boolean,
  50. default: false,
  51. },
  52. },
  53. data () {
  54. return {
  55. sumLabel: this.options?.label?.sum,
  56. sum: this.options?.value?.sum,
  57. useLabel: this.options?.label?.use,
  58. use: this.options?.value?.use,
  59. unuseLabel: this.options?.label?.unuse,
  60. unuse: this.options?.value?.unuse,
  61. }
  62. },
  63. computed: {
  64. percent () {
  65. if (this.use && this.sum) {
  66. return parseInt((this.use / this.sum) * 100)
  67. }
  68. return 0
  69. },
  70. percentTips () {
  71. return `${this.percent} %`
  72. },
  73. percentColor () {
  74. const isReverse = COLORS.COLORS_SCHEME_REVERSE_FIELDS.find(v => this.field.endsWith(v))
  75. if (isReverse) {
  76. if (this.percent < 60) {
  77. return COLORS.COLORS_SCHEME.REVERSE.PERCENT_60
  78. } else if (this.percent < 80) {
  79. return COLORS.COLORS_SCHEME.REVERSE.PERCENT_80
  80. } else {
  81. return COLORS.COLORS_SCHEME.REVERSE.PERCENT_100
  82. }
  83. } else {
  84. if (this.percent < 60) {
  85. return COLORS.COLORS_SCHEME.DEFAULT.PERCENT_60
  86. } else if (this.percent < 80) {
  87. return COLORS.COLORS_SCHEME.DEFAULT.PERCENT_80
  88. } else {
  89. return COLORS.COLORS_SCHEME.DEFAULT.PERCENT_100
  90. }
  91. }
  92. },
  93. status () {
  94. let ret = 'normal'
  95. if (this.percent > 100) {
  96. ret = 'exception'
  97. }
  98. return ret
  99. },
  100. },
  101. }
  102. </script>
  103. <style lang="scss" scoped>
  104. .usage-ring {
  105. width: 100%;
  106. height:197px;
  107. margin-bottom: 16px;
  108. box-sizing: border-box;
  109. box-shadow: 1px 1px 10px rgba(0, 0, 0, 0.1);
  110. &.is-template {
  111. box-shadow: none;
  112. border: 1px solid #e5e6eb;
  113. }
  114. }
  115. </style>