StatisticText.vue 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. <!--
  2. * @Author: fxs bjnsfxs@163.com
  3. * @Date: 2024-08-26 13:57:37
  4. * @LastEditors: fxs bjnsfxs@163.com
  5. * @LastEditTime: 2024-10-10 09:04:54
  6. * @FilePath: \Game-Backstage-Management-System\src\components\dataAnalysis\StatisticText.vue
  7. * @Description: 用于展示统计数据,如总览页面上方的总览数据
  8. *
  9. -->
  10. <script setup lang="ts">
  11. import type { StaticDataInfo, StaticField } from '@/types/dataAnalysis'
  12. import { decimalToPercentage } from '@/utils/common'
  13. import { onMounted, reactive, ref, watch } from 'vue'
  14. import axiosInstance from '@/utils/axios/axiosInstance'
  15. const props = defineProps<StaticDataInfo>()
  16. const dataList = reactive<Array<StaticField>>([])
  17. const dataState = ref(false) // 数据是否加载成功
  18. /**
  19. * @description: 用于获取数据
  20. * @tip 这里暂时只请求当日的数据,没有比较
  21. * @return {*}
  22. */
  23. const getData = () => {
  24. try {
  25. if (props.requestConfig) {
  26. axiosInstance
  27. .post(props.requestConfig.url, props.requestConfig.otherOptions)
  28. .then((info) => {
  29. dataList.splice(0, dataList.length) // 清空一下
  30. let data = info.data
  31. props.fieldsInfo.map((item) => {
  32. dataList.push({
  33. name: item.name,
  34. cnName: item.cnName,
  35. value: data[item.name]
  36. })
  37. })
  38. dataState.value = true
  39. })
  40. .catch(() => {
  41. dataState.value = false
  42. })
  43. } else {
  44. let hasNull = props.fieldsInfo.every((item) => item.value !== '')
  45. if (hasNull) {
  46. dataList.splice(0, dataList.length) // 清空一下
  47. props.fieldsInfo.map((item) => {
  48. dataList.push({
  49. name: item.name,
  50. cnName: item.cnName,
  51. value: item.value
  52. })
  53. })
  54. dataState.value = true
  55. } else {
  56. dataState.value = false
  57. }
  58. }
  59. } catch (err) {
  60. console.log(err)
  61. throw new Error('数据获取失败')
  62. }
  63. }
  64. /**
  65. * @description: 监听requesconfig的变化,一旦变化就重新请求
  66. * @return {*}
  67. */
  68. watch(
  69. () => [
  70. props.requestConfig?.otherOptions.gid,
  71. props.requestConfig?.otherOptions.pf,
  72. props.fieldsInfo
  73. ],
  74. () => {
  75. getData()
  76. }
  77. )
  78. onMounted(() => {
  79. getData()
  80. })
  81. defineExpose({})
  82. </script>
  83. <template>
  84. <div class="dataBox">
  85. <div class="dataBody" v-if="dataState">
  86. <div class="dataItem" v-for="item in dataList">
  87. <div class="header">
  88. <span :class="titleClass ? titleClass : 'dataTitle'">{{ item.cnName }}</span>
  89. </div>
  90. <div class="body">
  91. <span :class="valueClass ? valueClass : 'value'">{{ item.value }}</span>
  92. <span class="compare" v-if="item.compareVal">
  93. <span>
  94. {{ decimalToPercentage((item.value - item.compareVal) / item.compareVal) }}
  95. <el-icon v-if="(item.value - item.compareVal) / item.compareVal >= 0" color="#5fbb5d">
  96. <CaretTop />
  97. </el-icon>
  98. <el-icon v-else color="#ed4014">
  99. <CaretBottom />
  100. </el-icon>
  101. </span>
  102. </span>
  103. </div>
  104. </div>
  105. </div>
  106. <div v-else>
  107. <span>加载失败</span>
  108. </div>
  109. </div>
  110. </template>
  111. <style scoped>
  112. .dataBox {
  113. width: 100%;
  114. padding: 20px 24px;
  115. box-sizing: border-box;
  116. }
  117. .dataBody {
  118. display: flex;
  119. width: 100%;
  120. box-shadow:
  121. 0 4px 8px 0 rgba(0, 0, 0, 0.02),
  122. 0 1px 3px 0 rgba(0, 0, 0, 0.02);
  123. }
  124. .dataItem {
  125. margin-right: 32px;
  126. }
  127. .dataTitle {
  128. min-width: 48px;
  129. font-size: 12px;
  130. color: #657180;
  131. line-height: 16px;
  132. }
  133. .value {
  134. font-size: 28px;
  135. padding-right: 12px;
  136. line-height: 48px;
  137. }
  138. .chartStaticValue {
  139. font-size: 24px;
  140. color: #1c2438;
  141. font-weight: 500;
  142. }
  143. .compare {
  144. font-size: 12px;
  145. box-sizing: border-box;
  146. margin-left: 8px;
  147. }
  148. </style>