PanelGroup.vue 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. <script setup lang="ts">
  2. import { ElRow, ElCol, ElCard, ElSkeleton } from 'element-plus'
  3. import { CountTo } from '@/components/CountTo'
  4. import { useDesign } from '@/hooks/web/useDesign'
  5. import { useI18n } from '@/hooks/web/useI18n'
  6. import { ref, reactive } from 'vue'
  7. import { getCountApi } from '@/api/dashboard/analysis'
  8. import type { AnalysisTotalTypes } from '@/api/dashboard/analysis/types'
  9. const { t } = useI18n()
  10. const { getPrefixCls } = useDesign()
  11. const prefixCls = getPrefixCls('panel')
  12. const loading = ref(true)
  13. let totalState = reactive<AnalysisTotalTypes>({
  14. users: 0,
  15. messages: 0,
  16. moneys: 0,
  17. shoppings: 0
  18. })
  19. const getCount = async () => {
  20. const res = await getCountApi()
  21. .catch(() => {})
  22. .finally(() => {
  23. loading.value = false
  24. })
  25. totalState = Object.assign(totalState, res?.data || {})
  26. }
  27. getCount()
  28. </script>
  29. <template>
  30. <ElRow :gutter="20" justify="space-between" :class="prefixCls">
  31. <ElCol :xl="6" :lg="6" :md="12" :sm="12" :xs="24">
  32. <ElCard shadow="hover" class="mb-20px">
  33. <ElSkeleton :loading="loading" animated :rows="2">
  34. <template #default>
  35. <div :class="`${prefixCls}__item flex justify-between`">
  36. <div>
  37. <div
  38. :class="`${prefixCls}__item--icon ${prefixCls}__item--peoples p-16px inline-block rounded-6px`"
  39. >
  40. <Icon icon="svg-icon:peoples" :size="40" />
  41. </div>
  42. </div>
  43. <div class="flex flex-col justify-between">
  44. <div :class="`${prefixCls}__item--text text-16px text-gray-500 text-right`">{{
  45. t('analysis.newUser')
  46. }}</div>
  47. <CountTo
  48. class="text-20px font-700 text-right"
  49. :start-val="0"
  50. :end-val="102400"
  51. :duration="2600"
  52. />
  53. </div>
  54. </div>
  55. </template>
  56. </ElSkeleton>
  57. </ElCard>
  58. </ElCol>
  59. <ElCol :xl="6" :lg="6" :md="12" :sm="12" :xs="24">
  60. <ElCard shadow="hover" class="mb-20px">
  61. <ElSkeleton :loading="loading" animated :rows="2">
  62. <template #default>
  63. <div :class="`${prefixCls}__item flex justify-between`">
  64. <div>
  65. <div
  66. :class="`${prefixCls}__item--icon ${prefixCls}__item--message p-16px inline-block rounded-6px`"
  67. >
  68. <Icon icon="svg-icon:message" :size="40" />
  69. </div>
  70. </div>
  71. <div class="flex flex-col justify-between">
  72. <div :class="`${prefixCls}__item--text text-16px text-gray-500 text-right`">{{
  73. t('analysis.unreadInformation')
  74. }}</div>
  75. <CountTo
  76. class="text-20px font-700 text-right"
  77. :start-val="0"
  78. :end-val="81212"
  79. :duration="2600"
  80. />
  81. </div>
  82. </div>
  83. </template>
  84. </ElSkeleton>
  85. </ElCard>
  86. </ElCol>
  87. <ElCol :xl="6" :lg="6" :md="12" :sm="12" :xs="24">
  88. <ElCard shadow="hover" class="mb-20px">
  89. <ElSkeleton :loading="loading" animated :rows="2">
  90. <template #default>
  91. <div :class="`${prefixCls}__item flex justify-between`">
  92. <div>
  93. <div
  94. :class="`${prefixCls}__item--icon ${prefixCls}__item--money p-16px inline-block rounded-6px`"
  95. >
  96. <Icon icon="svg-icon:money" :size="40" />
  97. </div>
  98. </div>
  99. <div class="flex flex-col justify-between">
  100. <div :class="`${prefixCls}__item--text text-16px text-gray-500 text-right`">{{
  101. t('analysis.transactionAmount')
  102. }}</div>
  103. <CountTo
  104. class="text-20px font-700 text-right"
  105. :start-val="0"
  106. :end-val="9280"
  107. :duration="2600"
  108. />
  109. </div>
  110. </div>
  111. </template>
  112. </ElSkeleton>
  113. </ElCard>
  114. </ElCol>
  115. <ElCol :xl="6" :lg="6" :md="12" :sm="12" :xs="24">
  116. <ElCard shadow="hover" class="mb-20px">
  117. <ElSkeleton :loading="loading" animated :rows="2">
  118. <template #default>
  119. <div :class="`${prefixCls}__item flex justify-between`">
  120. <div>
  121. <div
  122. :class="`${prefixCls}__item--icon ${prefixCls}__item--shopping p-16px inline-block rounded-6px`"
  123. >
  124. <Icon icon="svg-icon:shopping" :size="40" />
  125. </div>
  126. </div>
  127. <div class="flex flex-col justify-between">
  128. <div :class="`${prefixCls}__item--text text-16px text-gray-500 text-right`">{{
  129. t('analysis.totalShopping')
  130. }}</div>
  131. <CountTo
  132. class="text-20px font-700 text-right"
  133. :start-val="0"
  134. :end-val="13600"
  135. :duration="2600"
  136. />
  137. </div>
  138. </div>
  139. </template>
  140. </ElSkeleton>
  141. </ElCard>
  142. </ElCol>
  143. </ElRow>
  144. </template>
  145. <style lang="less" scoped>
  146. @prefix-cls: ~'@{adminNamespace}-panel';
  147. .@{prefix-cls} {
  148. &__item {
  149. &--peoples {
  150. color: #40c9c6;
  151. }
  152. &--message {
  153. color: #36a3f7;
  154. }
  155. &--money {
  156. color: #f4516c;
  157. }
  158. &--shopping {
  159. color: #34bfa3;
  160. }
  161. &:hover {
  162. :deep(.@{adminNamespace}-icon) {
  163. color: #fff !important;
  164. }
  165. .@{prefix-cls}__item--icon {
  166. transition: all 0.38s ease-out;
  167. }
  168. .@{prefix-cls}__item--peoples {
  169. background: #40c9c6;
  170. }
  171. .@{prefix-cls}__item--message {
  172. background: #36a3f7;
  173. }
  174. .@{prefix-cls}__item--money {
  175. background: #f4516c;
  176. }
  177. .@{prefix-cls}__item--shopping {
  178. background: #34bfa3;
  179. }
  180. }
  181. }
  182. }
  183. </style>