index.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. <template>
  2. <ele-page flex-table v-loading="loading">
  3. <ele-card flex-table>
  4. <date-search class="mb-4" v-model="mapDateRange" @search="fetchProvinceData" position="left" />
  5. <map-card class="flex-1" :province-data="provinceData" />
  6. <div class="flex gap-10">
  7. <div class="flex-1 stat-card">
  8. <el-statistic title="总扫描次数" :value="realTimeData.scanTimesTotal" value-style="font-size:30px;color:#409eef" />
  9. </div>
  10. <div class="flex-1 stat-card">
  11. <el-statistic title="总审核单量" :value="realTimeData.auditNumTotal" value-style="font-size:30px;color:#409eef" />
  12. </div>
  13. <div class="flex-1 stat-card">
  14. <el-statistic title="总审核本数" :value="realTimeData.auditBookNumTotal" value-style="font-size:30px;color:#409eef" />
  15. </div>
  16. <div class="flex-1 stat-card">
  17. <el-statistic title="总审核金额" :value="realTimeData.auditMoneyTotal" value-style="font-size:30px;color:#409eef" :precision="2" />
  18. </div>
  19. <div class="flex-1 stat-card">
  20. <el-statistic title="总用户人数" :value="realTimeData.userNumTotal" value-style="font-size:30px;color:#409eef" />
  21. </div>
  22. </div>
  23. <el-divider></el-divider>
  24. <div class="flex justify-end mb-2" @click="fetchRealTimeData">
  25. <div class="flex items-center gap-2 cursor-pointer">
  26. <el-icon><Refresh /></el-icon>
  27. <span>更新时间:{{ nowTime }}</span>
  28. </div>
  29. </div>
  30. <div class="flex gap-4">
  31. <div class="flex-1 stat-card">
  32. <stat-card title="回收订单数" :value="realTimeData.orderNum" :data="realTimeData.orderNumTodayCharts" :yesterday-data="realTimeData.orderNumYestodayCharts" :chatAxis="realTimeData.chatAxis"></stat-card>
  33. </div>
  34. <div class="flex-1 stat-card">
  35. <stat-card title="回收数量(本)" :value="realTimeData.bookNum" :data="realTimeData.bookNumTodayCharts" :yesterday-data="realTimeData.bookNumYestodayCharts" :chatAxis="realTimeData.chatAxis"></stat-card>
  36. </div>
  37. <div class="flex-1 stat-card">
  38. <stat-card title="回收单本均价" :precision="2" :value="realTimeData.recycleAveragePrice" :data="realTimeData.recycleAveragePriceTodayCharts" :yesterday-data="realTimeData.recycleAveragePriceYestodayCharts" :chatAxis="realTimeData.chatAxis"></stat-card>
  39. </div>
  40. <div class="flex-1 stat-card">
  41. <stat-card title="待审核订单数" :value="realTimeData.waitAuditOrderNum" :data="realTimeData.waitAuditOrderNumTodayCharts" :yesterday-data="realTimeData.waitAuditOrderNumYestodayCharts" :chatAxis="realTimeData.chatAxis"></stat-card>
  42. </div>
  43. <div class="flex-1 stat-card">
  44. <stat-card title="待签收订单数" :value="realTimeData.waitSignOrderNum" :data="realTimeData.waitSignOrderNumTodayCharts" :yesterday-data="realTimeData.waitSignOrderNumYestodayCharts" :chatAxis="realTimeData.chatAxis"></stat-card>
  45. </div>
  46. </div>
  47. <div class="flex gap-4 mt-4">
  48. <div class="flex-1 stat-card">
  49. <stat-card title="今日扫描次数" :value="realTimeData.scanTimes" :data="realTimeData.scanTimesTodayCharts" :yesterday-data="realTimeData.scanTimesYestodayCharts" :chatAxis="realTimeData.chatAxis"></stat-card>
  50. </div>
  51. <div class="flex-1 stat-card">
  52. <stat-card title="今日扫描人数" :value="realTimeData.scanUserNum" :data="realTimeData.scanUserNumTodayCharts" :yesterday-data="realTimeData.scanUserNumYestodayCharts" :chatAxis="realTimeData.chatAxis"></stat-card>
  53. </div>
  54. <div class="flex-1 stat-card">
  55. <stat-card title="用户增长数" :value="realTimeData.userRegNum" :data="realTimeData.userRegNumTodayCharts" :yesterday-data="realTimeData.userRegNumYestodayCharts" :chatAxis="realTimeData.chatAxis"></stat-card>
  56. </div>
  57. <div class="flex-1 stat-card">
  58. <stat-card title="待审核金额" :precision="2" :value="realTimeData.waitAuditMoney" :data="realTimeData.waitAuditMoneyTodayCharts" :yesterday-data="realTimeData.waitAuditMoneyYestodayCharts" :chatAxis="realTimeData.chatAxis"></stat-card>
  59. </div>
  60. <div class="flex-1 stat-card">
  61. <stat-card title="待打款金额" :precision="2" :value="realTimeData.waitPayoutMoney" :data="realTimeData.waitPayoutMoneyTodayCharts" :yesterday-data="realTimeData.waitPayoutMoneyYestodayCharts" :chatAxis="realTimeData.chatAxis"></stat-card>
  62. </div>
  63. </div>
  64. <el-divider></el-divider>
  65. <div class="flex-col">
  66. <date-search class="mb-4" v-model="dateRange" @search="fetchHistoryData" />
  67. <div class="gap-4 flex">
  68. <div style="flex: 4" class="flex flex-col">
  69. <div class="flex gap-4">
  70. <div class="flex-1 stat-card">
  71. <stat-card title="回收订单数" :data="historyData.orderNumCharts" :chatAxis="historyData.chatAxis" :value="historyData.orderNum"></stat-card>
  72. </div>
  73. <div class="flex-1 stat-card">
  74. <stat-card title="回收数量(本)" :value="historyData.bookNum" :data="historyData.bookNumCharts" :chatAxis="historyData.chatAxis"></stat-card>
  75. </div>
  76. <div class="flex-1 stat-card">
  77. <stat-card title="回收单本均价" :value="historyData.recycleAveragePrice" :data="historyData.recycleAveragePriceCharts" :chatAxis="historyData.chatAxis" :precision="2"></stat-card>
  78. </div>
  79. <div class="flex-1 stat-card">
  80. <stat-card title="审核订单数" :value="historyData.auditNum" :data="historyData.auditNumCharts" :chatAxis="historyData.chatAxis"></stat-card>
  81. </div>
  82. </div>
  83. <div class="flex gap-4 mt-4">
  84. <div class="flex-1 stat-card">
  85. <stat-card title="签收订单数" :value="historyData.signOrderNum" :data="historyData.signOrderNumCharts" :chatAxis="historyData.chatAxis"></stat-card>
  86. </div>
  87. <div class="flex-1 stat-card">
  88. <stat-card title="扫描次数" :value="historyData.scanTimes" :data="historyData.scanTimesCharts" :chatAxis="historyData.chatAxis"></stat-card>
  89. </div>
  90. <div class="flex-1 stat-card">
  91. <stat-card title="扫描人数" :value="historyData.scanUserNum" :data="historyData.scanUserNumCharts" :chatAxis="historyData.chatAxis"></stat-card>
  92. </div>
  93. <div class="flex-1 stat-card">
  94. <stat-card title="用户增长数" :value="historyData.userRegNum" :data="historyData.userRegNumCharts" :chatAxis="historyData.chatAxis"></stat-card>
  95. </div>
  96. </div>
  97. </div>
  98. <div class="flex-1 flex flex-col stat-card">
  99. <pie-chart title="回收折扣占比" :data="recycleDiscountData" />
  100. <pie-chart title="审核品相比例分析" :data="auditRatioData" />
  101. </div>
  102. </div>
  103. </div>
  104. </ele-card>
  105. </ele-page>
  106. </template>
  107. <script setup>
  108. import mapCard from "@/views/statistic/overview/components/map-card.vue";
  109. import statCard from "@/views/statistic/overview/components/stat-card.vue";
  110. import pieChart from "@/views/statistic/overview/components/pie-chart.vue";
  111. import DateSearch from "@/components/DateSearch/index.vue";
  112. import { Refresh } from "@element-plus/icons-vue";
  113. import dayjs from "dayjs";
  114. import request from "@/utils/request";
  115. import { onMounted, ref } from "vue";
  116. const provinceData = ref([]);
  117. const dateRange = ref([
  118. dayjs().subtract(7, "day").format("YYYY-MM-DD"),
  119. dayjs().subtract(1, "day").format("YYYY-MM-DD"),
  120. ]);
  121. // 地图数据时间范围
  122. const mapDateRange = ref([
  123. dayjs().subtract(7, "day").format("YYYY-MM-DD"),
  124. dayjs().subtract(1, "day").format("YYYY-MM-DD"),
  125. ]);
  126. // 组织回收折扣比例数据
  127. const recycleDiscountData = ref([
  128. { value: 0, name: "≥2折", key: "discount2" },
  129. { value: 0, name: "2<至≥1", key: "discount12" },
  130. { value: 0, name: "1<至≥0.5", key: "discount051" },
  131. { value: 0, name: "≤0.5", key: "discount05" },
  132. ]);
  133. // 组织审核品相比例分析数据
  134. const auditRatioData = ref([
  135. { value: 0, name: "良好", key: "auditGoodNum" },
  136. { value: 0, name: "一般", key: "auditGeneralNum" },
  137. { value: 0, name: "较差", key: "auditBadNum" },
  138. ]);
  139. //获取历史数据汇总
  140. const historyData = ref({
  141. orderNumCharts: [],
  142. chatAxis: [],
  143. });
  144. const fetchHistoryData = async () => {
  145. let params = {
  146. statisticDateStart: dateRange.value[0],
  147. statisticDateEnd: dateRange.value[1],
  148. };
  149. request.get("/order/recycleStatisticOverview/history", { params })
  150. .then((res) => {
  151. if (res.data.code === 200) {
  152. recycleDiscountData.value.forEach((item) => {
  153. item.value = res.data.data[item.key] || 0;
  154. });
  155. auditRatioData.value.forEach((item) => {
  156. item.value = res.data.data[item.key] || 0;
  157. });
  158. historyData.value = res.data.data;
  159. }
  160. });
  161. };
  162. // 获取省份排名数据 //传入的时间是近7天,结束时间就是今天,使用 dayjs
  163. const fetchProvinceData = async () => {
  164. const params = {
  165. statisticDateStart: mapDateRange.value[0],
  166. statisticDateEnd: mapDateRange.value[1],
  167. };
  168. request.get("/order/recycleStatisticOverview/provinceRankList", {
  169. params,
  170. }).then((res) => {
  171. if (res.data.code === 200) {
  172. provinceData.value = res.data.data;
  173. }
  174. });
  175. };
  176. // 获取实时数据
  177. const realTimeData = ref({});
  178. const loading = ref(false);
  179. const nowTime = ref('');
  180. const fetchRealTimeData = async () => {
  181. loading.value = true;
  182. request.get("/order/recycleStatisticOverview/realtime").then((res) => {
  183. if (res.data.code === 200) {
  184. loading.value = false;
  185. realTimeData.value = res.data.data;
  186. nowTime.value = res.data.data.nowTime || dayjs().format('YYYY-MM-DD HH:mm:ss');
  187. }
  188. }).finally(() => {
  189. loading.value = false;
  190. });
  191. };
  192. onMounted(() => {
  193. fetchProvinceData();
  194. fetchHistoryData();
  195. fetchRealTimeData();
  196. });
  197. </script>
  198. <style lang="scss">
  199. .stat-card {
  200. border-radius: 10px;
  201. background: #f8f7f6;
  202. padding: 20px;
  203. display: flex;
  204. flex-direction: column;
  205. justify-content: center;
  206. align-items: center;
  207. .el-statistic__head {
  208. text-align: center;
  209. }
  210. }
  211. </style>