|
@@ -4,45 +4,55 @@
|
|
|
<div class="filter-form">
|
|
|
<el-form :model="filterForm" label-width="80px" inline>
|
|
|
<!-- 时间范围 -->
|
|
|
- <el-form-item label="时间范围">
|
|
|
- <el-date-picker v-model="filterForm.dateRange" type="daterange" range-separator="至" start-placeholder="开始日期"
|
|
|
- end-placeholder="结束日期" format="YYYY-MM-DD" value-format="YYYY-MM-DD" size="default" clearable />
|
|
|
+ <el-form-item :label="t('dataReport.timeRange')">
|
|
|
+ <el-date-picker v-model="filterForm.dateRange" type="daterange" range-separator="至"
|
|
|
+ :start-placeholder="t('dataReport.startDate')" :end-placeholder="t('dataReport.endDate')"
|
|
|
+ format="YYYY-MM-DD" value-format="YYYY-MM-DD" size="default" clearable />
|
|
|
</el-form-item>
|
|
|
|
|
|
<!-- 时间区间 -->
|
|
|
- <el-form-item label="时间区间">
|
|
|
- <el-select v-model="filterForm.timeInterval" placeholder="选择时间区间" size="default" clearable>
|
|
|
- <el-option label="最近7天" :value="7" />
|
|
|
- <el-option label="最近30天" :value="30" />
|
|
|
- <el-option label="最近90天" :value="90" />
|
|
|
+ <el-form-item :label="t('dataReport.timeInterval')">
|
|
|
+ <el-select v-model="filterForm.timeInterval" :placeholder="t('dataReport.selectTimeInterval')" size="default"
|
|
|
+ clearable>
|
|
|
+ <el-option :label="t('dataReport.yesterday')" :value="1" />
|
|
|
+ <el-option :label="t('dataReport.past7Days')" :value="7" />
|
|
|
+ <el-option :label="t('dataReport.past14Days')" :value="14" />
|
|
|
+ <el-option :label="t('dataReport.past30Days')" :value="30" />
|
|
|
+ <el-option :label="t('dataReport.past60Days')" :value="60" />
|
|
|
+ <el-option :label="t('dataReport.past90Days')" :value="90" />
|
|
|
+ <el-option :label="t('dataReport.past180Days')" :value="180" />
|
|
|
+ <el-option :label="t('dataReport.past360Days')" :value="360" />
|
|
|
</el-select>
|
|
|
</el-form-item>
|
|
|
|
|
|
<!-- 汇总周期 -->
|
|
|
- <el-form-item label="汇总周期">
|
|
|
- <el-select v-model="filterForm.summaryPeriod" placeholder="选择汇总周期" size="default" clearable>
|
|
|
- <el-option label="按日" :value="1" />
|
|
|
- <el-option label="按周" :value="2" />
|
|
|
- <el-option label="按月" :value="3" />
|
|
|
+ <el-form-item :label="t('dataReport.summaryPeriod')">
|
|
|
+ <el-select v-model="filterForm.summaryPeriod" :placeholder="t('dataReport.selectSummaryPeriod')"
|
|
|
+ size="default" clearable>
|
|
|
+ <el-option :label="t('dataReport.byDay')" :value="1" />
|
|
|
+ <el-option :label="t('dataReport.byWeek')" :value="2" />
|
|
|
+ <el-option :label="t('dataReport.byMonth')" :value="3" />
|
|
|
+ <el-option :label="t('dataReport.byYear')" :value="4" />
|
|
|
</el-select>
|
|
|
</el-form-item>
|
|
|
|
|
|
<!-- 颗粒度 -->
|
|
|
- <el-form-item label="颗粒度">
|
|
|
- <el-select v-model="filterForm.granularity" placeholder="选择颗粒度" size="default" clearable>
|
|
|
- <el-option label="应用级" :value="2" />
|
|
|
- <el-option label="页面级" :value="1" />
|
|
|
- <el-option label="组件级" :value="3" />
|
|
|
+ <el-form-item :label="t('dataReport.granularity')">
|
|
|
+ <el-select v-model="filterForm.granularity" :placeholder="t('dataReport.selectGranularity')" size="default"
|
|
|
+ clearable>
|
|
|
+ <el-option :label="t('dataReport.applicationLevel')" :value="2" />
|
|
|
+ <el-option :label="t('dataReport.pageLevel')" :value="1" />
|
|
|
+ <el-option :label="t('dataReport.componentLevel')" :value="3" />
|
|
|
</el-select>
|
|
|
</el-form-item>
|
|
|
|
|
|
<!-- 操作按钮 -->
|
|
|
<el-form-item>
|
|
|
<el-button type="primary" @click="handleSearch" :loading="chartLoading">
|
|
|
- 查询
|
|
|
+ {{ t('dataReport.query') }}
|
|
|
</el-button>
|
|
|
<el-button @click="handleReset">
|
|
|
- 重置
|
|
|
+ {{ t('common.reset') }}
|
|
|
</el-button>
|
|
|
</el-form-item>
|
|
|
</el-form>
|
|
@@ -61,8 +71,13 @@
|
|
|
<script setup>
|
|
|
import { ref, computed, watch, onMounted } from 'vue';
|
|
|
import { ElMessage } from 'element-plus';
|
|
|
+import { useI18n } from 'vue-i18n';
|
|
|
import { api } from '../../data.service.js';
|
|
|
import ReportChart from './report-chart.vue';
|
|
|
+import dsDetailData from '../dsDetail.json'
|
|
|
+
|
|
|
+// 使用国际化
|
|
|
+const { t } = useI18n();
|
|
|
|
|
|
const props = defineProps({
|
|
|
modal: {
|
|
@@ -76,8 +91,8 @@ const emit = defineEmits(['confirm', 'cancel']);
|
|
|
// 筛选表单数据
|
|
|
const filterForm = ref({
|
|
|
dateRange: null, // 时间范围,默认为null
|
|
|
- timeInterval: null, // 时间区间,默认为null
|
|
|
- summaryPeriod: null, // 汇总周期,默认为null
|
|
|
+ timeInterval: 7, // 时间区间,默认过去7天
|
|
|
+ summaryPeriod: 1, // 汇总周期,默认按日
|
|
|
granularity: null // 颗粒度,默认为null
|
|
|
});
|
|
|
|
|
@@ -88,7 +103,7 @@ const chartData = ref([]);
|
|
|
|
|
|
// 计算属性
|
|
|
const dialogTitle = computed(() => {
|
|
|
- return dimensionData.value?.name || '数据详情';
|
|
|
+ return dimensionData.value?.name || t('dataReport.dataDetail');
|
|
|
});
|
|
|
|
|
|
const iconComponent = computed(() => {
|
|
@@ -96,7 +111,7 @@ const iconComponent = computed(() => {
|
|
|
});
|
|
|
|
|
|
const chartTitle = computed(() => {
|
|
|
- return dimensionData.value?.name || '数据分析';
|
|
|
+ return dimensionData.value?.name || t('dataReport.dataAnalysis');
|
|
|
});
|
|
|
|
|
|
|
|
@@ -109,8 +124,8 @@ const handleSearch = () => {
|
|
|
const handleReset = () => {
|
|
|
filterForm.value = {
|
|
|
dateRange: null,
|
|
|
- timeInterval: null,
|
|
|
- summaryPeriod: null,
|
|
|
+ timeInterval: 7, // 默认过去7天
|
|
|
+ summaryPeriod: 1, // 默认按日
|
|
|
granularity: null
|
|
|
};
|
|
|
loadDimensionDetail();
|
|
@@ -120,7 +135,7 @@ const handleReset = () => {
|
|
|
const handleChartTypeChange = async (newType) => {
|
|
|
const dimensionId = props.modal.params.id;
|
|
|
if (!dimensionId) {
|
|
|
- ElMessage.error('缺少维度ID');
|
|
|
+ ElMessage.error(t('dataReport.missingDimensionId'));
|
|
|
return;
|
|
|
}
|
|
|
|
|
@@ -131,10 +146,10 @@ const handleChartTypeChange = async (newType) => {
|
|
|
});
|
|
|
|
|
|
chartType.value = newType;
|
|
|
- ElMessage.success('图表类型更新成功');
|
|
|
+ ElMessage.success(t('dataReport.chartTypeUpdateSuccess'));
|
|
|
} catch (error) {
|
|
|
console.error('更新图表类型失败:', error);
|
|
|
- ElMessage.error('更新图表类型失败');
|
|
|
+ ElMessage.error(t('dataReport.updateChartTypeFailed'));
|
|
|
}
|
|
|
};
|
|
|
|
|
@@ -146,7 +161,7 @@ const loadData = () => {
|
|
|
const loadDimensionDetail = async () => {
|
|
|
const dimensionId = props.modal?.params.id;
|
|
|
if (!dimensionId) {
|
|
|
- console.warn('缺少维度ID');
|
|
|
+ console.warn(t('dataReport.missingDimensionId'));
|
|
|
return;
|
|
|
}
|
|
|
|
|
@@ -155,38 +170,68 @@ const loadDimensionDetail = async () => {
|
|
|
try {
|
|
|
const params = {
|
|
|
id: dimensionId,
|
|
|
- timeInterval: filterForm.value.timeInterval || null,
|
|
|
- type: filterForm.value.summaryPeriod || null,
|
|
|
+ timeInterval: filterForm.value.timeInterval || 7, // 默认月7天
|
|
|
+ type: filterForm.value.summaryPeriod || 1, // 默认按日
|
|
|
granularity: filterForm.value.granularity || null
|
|
|
};
|
|
|
|
|
|
- // 添加时间范围参数
|
|
|
- if (filterForm.value.dateRange && filterForm.value.dateRange.length === 2) {
|
|
|
+ // 根据时间区间计算起止时间
|
|
|
+ if (filterForm.value.timeInterval && !filterForm.value.dateRange) {
|
|
|
+ const { startTime, endTime } = calculateTimeRange(filterForm.value.timeInterval);
|
|
|
+ params.startTime = startTime;
|
|
|
+ params.endTime = endTime;
|
|
|
+ } else if (filterForm.value.dateRange && filterForm.value.dateRange.length === 2) {
|
|
|
+ // 优先使用手动选择的日期范围
|
|
|
params.startTime = filterForm.value.dateRange[0];
|
|
|
params.endTime = filterForm.value.dateRange[1];
|
|
|
} else {
|
|
|
- params.startTime = null;
|
|
|
- params.endTime = null;
|
|
|
+ // 默认过去7天
|
|
|
+ const { startTime, endTime } = calculateTimeRange(7);
|
|
|
+ params.startTime = startTime;
|
|
|
+ params.endTime = endTime;
|
|
|
}
|
|
|
|
|
|
+ console.log('🔍 详情查询参数:', params);
|
|
|
+
|
|
|
const { code, data } = await api.report.dimensions.detail(params);
|
|
|
+ // const { code, data } = dsDetailData
|
|
|
|
|
|
if (code === '200' && data) {
|
|
|
dimensionData.value = data;
|
|
|
processChartData(data);
|
|
|
chartType.value = data.viewType || 'line';
|
|
|
} else {
|
|
|
- ElMessage.error('获取维度详情失败');
|
|
|
+ ElMessage.error(t('dataReport.getDimensionDetailFailed'));
|
|
|
}
|
|
|
} catch (error) {
|
|
|
console.error('获取维度详情失败:', error);
|
|
|
- ElMessage.error('获取维度详情失败,请重试');
|
|
|
+ ElMessage.error(t('dataReport.getDimensionDetailFailed'));
|
|
|
} finally {
|
|
|
chartLoading.value = false;
|
|
|
}
|
|
|
};
|
|
|
|
|
|
-// 处理图表数据
|
|
|
+// 根据时间区间计算起止时间
|
|
|
+const calculateTimeRange = (days) => {
|
|
|
+ const endDate = new Date();
|
|
|
+ const startDate = new Date();
|
|
|
+
|
|
|
+ if (days === 1) {
|
|
|
+ // 昨天
|
|
|
+ startDate.setDate(endDate.getDate() - 1);
|
|
|
+ endDate.setDate(endDate.getDate() - 1);
|
|
|
+ } else {
|
|
|
+ // 过去 N 天
|
|
|
+ startDate.setDate(endDate.getDate() - days);
|
|
|
+ }
|
|
|
+
|
|
|
+ return {
|
|
|
+ startTime: startDate.toISOString().split('T')[0],
|
|
|
+ endTime: endDate.toISOString().split('T')[0]
|
|
|
+ };
|
|
|
+};
|
|
|
+
|
|
|
+// 处理图表数据 - 与index.vue保持一致的逻辑
|
|
|
const processChartData = (data) => {
|
|
|
if (!data || !data.sections || data.sections.length === 0) {
|
|
|
chartData.value = [];
|
|
@@ -203,14 +248,15 @@ const processChartData = (data) => {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+ // 转换为report-chart组件期望的格式: {x, y, series}
|
|
|
const result = [];
|
|
|
|
|
|
- // 为每个非汇总section生成数据
|
|
|
+ // 为每个section生成数据点(包含汇总数据,与index.vue一致)
|
|
|
data.sections.forEach(section => {
|
|
|
- if (section.statistics && !section.name.includes('汇总')) {
|
|
|
+ if (section.statistics) {
|
|
|
section.statistics.forEach(stat => {
|
|
|
result.push({
|
|
|
- x: stat.cutDay,
|
|
|
+ x: formatDateByPeriod(stat.cutDay, filterForm.value.summaryPeriod),
|
|
|
y: stat.statisticsValue,
|
|
|
series: section.name
|
|
|
});
|
|
@@ -218,9 +264,30 @@ const processChartData = (data) => {
|
|
|
}
|
|
|
});
|
|
|
|
|
|
+ console.log('📈 详情页数据点:', result.length, '周期:', filterForm.value.summaryPeriod);
|
|
|
chartData.value = result;
|
|
|
};
|
|
|
|
|
|
+// 根据汇总周期格式化日期显示
|
|
|
+const formatDateByPeriod = (dateStr, period) => {
|
|
|
+ const date = new Date(dateStr);
|
|
|
+
|
|
|
+ switch (period) {
|
|
|
+ case 1: // 按日
|
|
|
+ return dateStr; // 保持原格式 YYYY-MM-DD
|
|
|
+ case 2: // 按周
|
|
|
+ const weekStart = new Date(date);
|
|
|
+ weekStart.setDate(date.getDate() - date.getDay());
|
|
|
+ return `${weekStart.getFullYear()}-W${Math.ceil(weekStart.getDate() / 7)}`;
|
|
|
+ case 3: // 按月
|
|
|
+ return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`;
|
|
|
+ case 4: // 按年
|
|
|
+ return `${date.getFullYear()}`;
|
|
|
+ default:
|
|
|
+ return dateStr;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
|
|
|
// 组件挂载时加载数据
|
|
|
onMounted(() => {
|