sale-card.vue 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. <template>
  2. <ele-card
  3. header="订单趋势"
  4. :header-style="{ padding: '0 24px' }"
  5. :body-style="{ padding: 0 }"
  6. >
  7. <template #extra>
  8. <div
  9. class="hidden-xs-only"
  10. style="display: flex; align-items: center; margin: 16px 0"
  11. >
  12. <el-radio-group v-model="saleSearch.dateType" @change="updateDateRange">
  13. <el-radio-button label="2">近7日</el-radio-button>
  14. <el-radio-button label="3">近15日</el-radio-button>
  15. <el-radio-button label="4">近一年</el-radio-button>
  16. </el-radio-group>
  17. <div class="hidden-md-and-down" style="width: 320px; margin-left: 12px">
  18. <el-date-picker
  19. unlink-panels
  20. type="datetimerange"
  21. v-model="saleSearch.datetime"
  22. range-separator="-"
  23. format="YYYY-MM-DD HH:mm"
  24. value-format="YYYY-MM-DD HH:mm"
  25. start-placeholder="开始时间"
  26. end-placeholder="结束时间"
  27. class="ele-fluid"
  28. />
  29. </div>
  30. </div>
  31. </template>
  32. <div class="sale-body">
  33. <v-chart
  34. ref="saleChartRef"
  35. :option="saleChartOption"
  36. style="height: 400px"
  37. />
  38. </div>
  39. </ele-card>
  40. </template>
  41. <script setup>
  42. import { ref, reactive, watch, getCurrentInstance } from 'vue';
  43. import { EleMessage } from 'ele-admin-plus/es';
  44. import { use } from 'echarts/core';
  45. import { CanvasRenderer } from 'echarts/renderers';
  46. import { BarChart } from 'echarts/charts';
  47. import { GridComponent, TooltipComponent } from 'echarts/components';
  48. import VChart from 'vue-echarts';
  49. import { useEcharts } from '@/utils/use-echarts';
  50. import dayjs from 'dayjs';
  51. const { proxy } = getCurrentInstance();
  52. use([CanvasRenderer, BarChart, GridComponent, TooltipComponent]);
  53. const saleChartRef = ref(null);
  54. useEcharts([saleChartRef]);
  55. /** 销售额柱状图配置 */
  56. const saleChartOption = reactive({});
  57. /** 订单数据 */
  58. const orderData = ref([]);
  59. /** 销售量搜索参数 */
  60. const saleSearch = reactive({
  61. dateType: '2',
  62. datetime: []
  63. });
  64. /** 更新时间范围 */
  65. const updateDateRange = (type) => {
  66. console.log(type, 'type');
  67. const now = dayjs();
  68. let start, end;
  69. switch (type) {
  70. case '2': // 近7日
  71. start = now.subtract(6, 'day').startOf('day');
  72. end = now.endOf('day');
  73. break;
  74. case '3': // 近15日
  75. start = now.subtract(14, 'day').startOf('day');
  76. end = now.endOf('day');
  77. break;
  78. case '4': // 近一年
  79. start = now.subtract(1, 'year').startOf('day');
  80. end = now.endOf('day');
  81. break;
  82. }
  83. saleSearch.datetime = [
  84. start.format('YYYY-MM-DD HH:mm'),
  85. end.format('YYYY-MM-DD HH:mm')
  86. ];
  87. };
  88. /** 获取订单数据 */
  89. const getOrderData = async () => {
  90. const [startTime, endTime] = saleSearch.datetime;
  91. proxy.$http
  92. .get('/order/orderstat/orderNumStat', {
  93. params: { startTime, endTime }
  94. })
  95. .then((res) => {
  96. if (res.data.code === 200) {
  97. orderData.value = res.data.data;
  98. updateChartOption();
  99. } else {
  100. EleMessage.error(res.data.msg || '获取订单数据失败');
  101. }
  102. });
  103. };
  104. /** 更新图表配置 */
  105. const updateChartOption = () => {
  106. const dates = orderData.value.map((item) => item.date);
  107. const values = orderData.value.map((item) => item.orderNum);
  108. Object.assign(saleChartOption, {
  109. tooltip: {
  110. trigger: 'axis',
  111. axisPointer: {
  112. type: 'shadow'
  113. }
  114. },
  115. grid: {
  116. left: '3%',
  117. right: '4%',
  118. bottom: '3%',
  119. containLabel: true
  120. },
  121. xAxis: [
  122. {
  123. type: 'category',
  124. data: dates,
  125. axisTick: {
  126. alignWithLabel: true
  127. }
  128. }
  129. ],
  130. yAxis: [
  131. {
  132. type: 'value'
  133. }
  134. ],
  135. series: [
  136. {
  137. name: '订单数量',
  138. type: 'bar',
  139. data: values
  140. }
  141. ]
  142. });
  143. };
  144. // 监听日期范围变化
  145. watch(
  146. () => saleSearch.datetime,
  147. (newDatetime) => {
  148. if (newDatetime && newDatetime.length === 2) {
  149. getOrderData();
  150. }
  151. }
  152. );
  153. // 初始化
  154. updateDateRange('2');
  155. </script>
  156. <style lang="scss" scoped>
  157. .sale-body {
  158. padding: 16px 0 10px 0;
  159. }
  160. .sale-body-title {
  161. padding: 6px 20px;
  162. }
  163. .sale-rank-item {
  164. display: flex;
  165. align-items: center;
  166. padding: 0 20px;
  167. margin-top: 18px;
  168. box-sizing: border-box;
  169. .sale-rank-item-text {
  170. flex: 1;
  171. padding-left: 12px;
  172. }
  173. }
  174. </style>