|
|
@@ -7,9 +7,48 @@
|
|
|
:tools="false"
|
|
|
>
|
|
|
<template #toolbar>
|
|
|
+ <!-- 添加日期选择器 -->
|
|
|
+ <div class="date-selector-container">
|
|
|
+ <div class="date-period-selector">
|
|
|
+ <el-button
|
|
|
+ :class="{ active: activePeriod === 'yesterday' }"
|
|
|
+ @click="changePeriod('yesterday')"
|
|
|
+ >昨日</el-button>
|
|
|
+ <el-button
|
|
|
+ :class="{ active: activePeriod === '7d' }"
|
|
|
+ @click="changePeriod('7d')"
|
|
|
+ >7日</el-button>
|
|
|
+ <el-button
|
|
|
+ :class="{ active: activePeriod === '15d' }"
|
|
|
+ @click="changePeriod('15d')"
|
|
|
+ >15日</el-button>
|
|
|
+ <el-button
|
|
|
+ :class="{ active: activePeriod === '30d' }"
|
|
|
+ @click="changePeriod('30d')"
|
|
|
+ >30日</el-button>
|
|
|
+
|
|
|
+ <el-date-picker
|
|
|
+ v-model="dateRange"
|
|
|
+ type="datetimerange"
|
|
|
+ range-separator="至"
|
|
|
+ start-placeholder="开始日期时间"
|
|
|
+ end-placeholder="结束日期时间"
|
|
|
+ format="YYYY-MM-DD HH:mm:ss"
|
|
|
+ value-format="YYYY-MM-DD HH:mm:ss"
|
|
|
+ :clearable="false"
|
|
|
+ :disabled-date="(date) => false"
|
|
|
+ @change="handleDateRangeChange"
|
|
|
+ />
|
|
|
+ <div class="date-action-buttons">
|
|
|
+ <el-button type="primary" @click="fetchData">搜索</el-button>
|
|
|
+ <el-button @click="resetFilters">重置</el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
<div class="flex mb-6">
|
|
|
- <pieChart class="flex-1"></pieChart>
|
|
|
- <rank-list></rank-list>
|
|
|
+ <pieChart ref="pieChartRef" class="flex-1"></pieChart>
|
|
|
+ <rank-list ref="rankListRef"></rank-list>
|
|
|
</div>
|
|
|
</template>
|
|
|
</common-table>
|
|
|
@@ -17,34 +56,189 @@
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
- import { ref, reactive } from 'vue';
|
|
|
+ import { ref, reactive, onMounted, computed } from 'vue';
|
|
|
import CommonTable from '@/components/CommonPage/CommonTable.vue';
|
|
|
import pieChart from '@/views/optimization/orderAnalysis/components/pie-chart.vue';
|
|
|
import rankList from '@/views/optimization/orderAnalysis/components/rank-list.vue';
|
|
|
import { useDictData } from '@/utils/use-dict-data';
|
|
|
+ import dayjs from 'dayjs';
|
|
|
+ import request from '@/utils/request';
|
|
|
+ import { ElMessage } from 'element-plus';
|
|
|
|
|
|
defineOptions({ name: 'orderCancelAnalysis' });
|
|
|
|
|
|
+ // 状态变量
|
|
|
+ const activePeriod = ref('');
|
|
|
+ const isCustomDateRange = ref(false);
|
|
|
+ const dateRange = ref([
|
|
|
+ dayjs().startOf('day').format('YYYY-MM-DD HH:mm:ss'),
|
|
|
+ dayjs().endOf('day').format('YYYY-MM-DD HH:mm:ss')
|
|
|
+ ]);
|
|
|
+
|
|
|
+ // 图表组件实例
|
|
|
+ const pieChartRef = ref(null);
|
|
|
+ const rankListRef = ref(null);
|
|
|
+
|
|
|
/** 表格列配置 */
|
|
|
const columns = ref([
|
|
|
- { label: '订单编号', prop: 'orderCode', align: 'center' },
|
|
|
- { label: '用户UID', prop: 'uid', align: 'center' },
|
|
|
- { label: '取消原因', prop: 'cancelReason', align: 'center', minWidth: 200 },
|
|
|
- { label: '取消时间', prop: 'createTime', align: 'center' }
|
|
|
+ { label: '订单编号', prop: 'orderId', align: 'center' },
|
|
|
+ { label: '用户UID', prop: 'userId', align: 'center' },
|
|
|
+ { label: '用户昵称', prop: 'nickName', align: 'center' },
|
|
|
+ { label: '取消原因', prop: 'reason', align: 'center', minWidth: 200 },
|
|
|
+ { label: '取消时间', prop: 'cancelTime', align: 'center' }
|
|
|
]);
|
|
|
|
|
|
/** 页面组件实例 */
|
|
|
const pageRef = ref(null);
|
|
|
|
|
|
const pageConfig = reactive({
|
|
|
- pageUrl: '/baseinfo/godown/pagelist',
|
|
|
- exportUrl: '/baseinfo/godown/export',
|
|
|
+ pageUrl: '/order/recycleOrderStatistic/cancel/list',
|
|
|
fileName: '订单取消分析',
|
|
|
cacheKey: 'orderCancelAnalysisTable'
|
|
|
});
|
|
|
|
|
|
+ // 根据时间段更新日期范围的方法
|
|
|
+ const updateDateRangeByPeriod = (period) => {
|
|
|
+ isCustomDateRange.value = false;
|
|
|
+
|
|
|
+ switch (period) {
|
|
|
+ case 'yesterday':
|
|
|
+ dateRange.value = [
|
|
|
+ dayjs().subtract(1, 'day').startOf('day').format('YYYY-MM-DD HH:mm:ss'),
|
|
|
+ dayjs().subtract(1, 'day').endOf('day').format('YYYY-MM-DD 23:59:59')
|
|
|
+ ];
|
|
|
+ break;
|
|
|
+ case '7d':
|
|
|
+ dateRange.value = [
|
|
|
+ dayjs().subtract(7, 'day').startOf('day').format('YYYY-MM-DD 00:00:00'),
|
|
|
+ dayjs().endOf('day').format('YYYY-MM-DD 23:59:59')
|
|
|
+ ];
|
|
|
+ break;
|
|
|
+ case '15d':
|
|
|
+ dateRange.value = [
|
|
|
+ dayjs().subtract(15, 'day').startOf('day').format('YYYY-MM-DD 00:00:00'),
|
|
|
+ dayjs().endOf('day').format('YYYY-MM-DD 23:59:59')
|
|
|
+ ];
|
|
|
+ break;
|
|
|
+ case '30d':
|
|
|
+ dateRange.value = [
|
|
|
+ dayjs().subtract(30, 'day').startOf('day').format('YYYY-MM-DD 00:00:00'),
|
|
|
+ dayjs().endOf('day').format('YYYY-MM-DD 23:59:59')
|
|
|
+ ];
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ dateRange.value = [
|
|
|
+ dayjs().startOf('day').format('YYYY-MM-DD 00:00:00'),
|
|
|
+ dayjs().endOf('day').format('YYYY-MM-DD 23:59:59')
|
|
|
+ ];
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ // 处理时间段变更按钮点击的方法
|
|
|
+ const changePeriod = (period) => {
|
|
|
+ activePeriod.value = period;
|
|
|
+ updateDateRangeByPeriod(period);
|
|
|
+ fetchData();
|
|
|
+ };
|
|
|
+
|
|
|
+ // 处理日期选择器变更
|
|
|
+ const handleDateRangeChange = () => {
|
|
|
+ isCustomDateRange.value = true;
|
|
|
+ activePeriod.value = '';
|
|
|
+ };
|
|
|
+
|
|
|
+ const getDateRangeForAPI = () => {
|
|
|
+ let startDate, endDate;
|
|
|
+
|
|
|
+ if (Array.isArray(dateRange.value) && dateRange.value.length === 2) {
|
|
|
+ startDate = dateRange.value[0];
|
|
|
+ endDate = dateRange.value[1];
|
|
|
+ } else {
|
|
|
+ // 如果dateRange不是数组,使用当天作为默认值
|
|
|
+ startDate = dayjs().startOf('day').format('YYYY-MM-DD 00:00:00');
|
|
|
+ endDate = dayjs().endOf('day').format('YYYY-MM-DD 23:59:59');
|
|
|
+ }
|
|
|
+
|
|
|
+ return { startDate, endDate };
|
|
|
+ };
|
|
|
+
|
|
|
+ const fetchData = async () => {
|
|
|
+ const { startDate, endDate } = getDateRangeForAPI();
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 统计数据
|
|
|
+ const { data } = await request.get('/order/recycleOrderStatistic/cancel/sum', {
|
|
|
+ params: {
|
|
|
+ startDate,
|
|
|
+ endDate
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ // 更新饼图和排行榜数据
|
|
|
+ if (data && data.data) {
|
|
|
+ pieChartRef.value?.updateChartData(data.data);
|
|
|
+ rankListRef.value?.updateRankData(data.data);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 刷新表格
|
|
|
+ reload({
|
|
|
+ startDate,
|
|
|
+ endDate
|
|
|
+ });
|
|
|
+ } catch (error) {
|
|
|
+ ElMessage.error('获取数据失败');
|
|
|
+ console.error('Failed to fetch statistic data:', error);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const resetFilters = () => {
|
|
|
+ isCustomDateRange.value = false;
|
|
|
+ activePeriod.value = '';
|
|
|
+ // 重置为今日
|
|
|
+ dateRange.value = [
|
|
|
+ dayjs().startOf('day').format('YYYY-MM-DD 00:00:00'),
|
|
|
+ dayjs().endOf('day').format('YYYY-MM-DD 23:59:59')
|
|
|
+ ];
|
|
|
+ fetchData();
|
|
|
+ };
|
|
|
+
|
|
|
//刷新表格
|
|
|
function reload(where) {
|
|
|
pageRef.value?.reload(where);
|
|
|
}
|
|
|
+
|
|
|
+ onMounted(() => {
|
|
|
+ // 默认加载今日数据
|
|
|
+ fetchData();
|
|
|
+ });
|
|
|
</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+ .date-selector-container {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ margin-bottom: 20px;
|
|
|
+ border-bottom: 1px solid #ebeef5;
|
|
|
+ padding-bottom: 16px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .date-period-selector {
|
|
|
+ display: flex;
|
|
|
+ gap: 10px;
|
|
|
+
|
|
|
+ .el-button {
|
|
|
+ border-radius: 4px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .active {
|
|
|
+ color: #409eff;
|
|
|
+ border-color: #409eff;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .date-action-buttons {
|
|
|
+ display: flex;
|
|
|
+ gap: 8px;
|
|
|
+ }
|
|
|
+</style>
|