| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- <template>
- <ele-card
- header="订单趋势"
- :header-style="{ padding: '0 24px' }"
- :body-style="{ padding: 0 }"
- >
- <template #extra>
- <div
- class="hidden-xs-only"
- style="display: flex; align-items: center; margin: 16px 0"
- >
- <el-radio-group v-model="saleSearch.dateType" @change="updateDateRange">
- <el-radio-button label="2">近7日</el-radio-button>
- <el-radio-button label="3">近15日</el-radio-button>
- <el-radio-button label="4">近一年</el-radio-button>
- </el-radio-group>
- <div class="hidden-md-and-down" style="width: 320px; margin-left: 12px">
- <el-date-picker
- unlink-panels
- type="datetimerange"
- v-model="saleSearch.datetime"
- range-separator="-"
- format="YYYY-MM-DD HH:mm"
- value-format="YYYY-MM-DD HH:mm"
- start-placeholder="开始时间"
- end-placeholder="结束时间"
- class="ele-fluid"
- />
- </div>
- </div>
- </template>
- <div class="sale-body">
- <v-chart
- ref="saleChartRef"
- :option="saleChartOption"
- style="height: 400px"
- />
- </div>
- </ele-card>
- </template>
- <script setup>
- import { ref, reactive, watch, getCurrentInstance } from 'vue';
- import { EleMessage } from 'ele-admin-plus/es';
- import { use } from 'echarts/core';
- import { CanvasRenderer } from 'echarts/renderers';
- import { BarChart } from 'echarts/charts';
- import { GridComponent, TooltipComponent } from 'echarts/components';
- import VChart from 'vue-echarts';
- import { useEcharts } from '@/utils/use-echarts';
- import dayjs from 'dayjs';
- const { proxy } = getCurrentInstance();
- use([CanvasRenderer, BarChart, GridComponent, TooltipComponent]);
- const saleChartRef = ref(null);
- useEcharts([saleChartRef]);
- /** 销售额柱状图配置 */
- const saleChartOption = reactive({});
- /** 订单数据 */
- const orderData = ref([]);
- /** 销售量搜索参数 */
- const saleSearch = reactive({
- dateType: '2',
- datetime: []
- });
- /** 更新时间范围 */
- const updateDateRange = (type) => {
- console.log(type, 'type');
- const now = dayjs();
- let start, end;
- switch (type) {
- case '2': // 近7日
- start = now.subtract(6, 'day').startOf('day');
- end = now.endOf('day');
- break;
- case '3': // 近15日
- start = now.subtract(14, 'day').startOf('day');
- end = now.endOf('day');
- break;
- case '4': // 近一年
- start = now.subtract(1, 'year').startOf('day');
- end = now.endOf('day');
- break;
- }
- saleSearch.datetime = [
- start.format('YYYY-MM-DD HH:mm'),
- end.format('YYYY-MM-DD HH:mm')
- ];
- };
- /** 获取订单数据 */
- const getOrderData = async () => {
- const [startTime, endTime] = saleSearch.datetime;
- proxy.$http
- .get('/order/orderstat/orderNumStat', {
- params: { startTime, endTime }
- })
- .then((res) => {
- if (res.data.code === 200) {
- orderData.value = res.data.data;
- updateChartOption();
- } else {
- EleMessage.error(res.data.msg || '获取订单数据失败');
- }
- });
- };
- /** 更新图表配置 */
- const updateChartOption = () => {
- const dates = orderData.value.map((item) => item.date);
- const values = orderData.value.map((item) => item.orderNum);
- Object.assign(saleChartOption, {
- tooltip: {
- trigger: 'axis',
- axisPointer: {
- type: 'shadow'
- }
- },
- grid: {
- left: '3%',
- right: '4%',
- bottom: '3%',
- containLabel: true
- },
- xAxis: [
- {
- type: 'category',
- data: dates,
- axisTick: {
- alignWithLabel: true
- }
- }
- ],
- yAxis: [
- {
- type: 'value'
- }
- ],
- series: [
- {
- name: '订单数量',
- type: 'bar',
- data: values
- }
- ]
- });
- };
- // 监听日期范围变化
- watch(
- () => saleSearch.datetime,
- (newDatetime) => {
- if (newDatetime && newDatetime.length === 2) {
- getOrderData();
- }
- }
- );
- // 初始化
- updateDateRange('2');
- </script>
- <style lang="scss" scoped>
- .sale-body {
- padding: 16px 0 10px 0;
- }
- .sale-body-title {
- padding: 6px 20px;
- }
- .sale-rank-item {
- display: flex;
- align-items: center;
- padding: 0 20px;
- margin-top: 18px;
- box-sizing: border-box;
- .sale-rank-item-text {
- flex: 1;
- padding-left: 12px;
- }
- }
- </style>
|