|
|
@ -17,13 +17,14 @@ |
|
|
start-placeholder="开始时间" |
|
|
start-placeholder="开始时间" |
|
|
end-placeholder="结束时间" |
|
|
end-placeholder="结束时间" |
|
|
size="default" |
|
|
size="default" |
|
|
|
|
|
@change="handleChartDateChange" |
|
|
/> |
|
|
/> |
|
|
</div> |
|
|
</div> |
|
|
<div class="filter-right"> |
|
|
<div class="filter-right"> |
|
|
<el-button-group> |
|
|
<el-button-group> |
|
|
<el-button type="danger">每日</el-button> |
|
|
|
|
|
<el-button>近七日</el-button> |
|
|
|
|
|
<el-button>近三十日</el-button> |
|
|
|
|
|
|
|
|
<el-button :type="chartMode === 'day' ? 'danger' : 'default'" @click="handleModeChange('day')">每日</el-button> |
|
|
|
|
|
<el-button :type="chartMode === 'week' ? 'danger' : 'default'" @click="handleModeChange('week')">近七日</el-button> |
|
|
|
|
|
<el-button :type="chartMode === 'month' ? 'danger' : 'default'" @click="handleModeChange('month')">近三十日</el-button> |
|
|
</el-button-group> |
|
|
</el-button-group> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
@ -88,44 +89,104 @@ |
|
|
</template> |
|
|
</template> |
|
|
|
|
|
|
|
|
<script setup> |
|
|
<script setup> |
|
|
import { ref, onMounted, nextTick } from 'vue'; |
|
|
|
|
|
|
|
|
import { ref, onMounted, nextTick, watch } from 'vue'; |
|
|
|
|
|
import { useRoute, useRouter } from 'vue-router'; |
|
|
import * as echarts from 'echarts'; |
|
|
import * as echarts from 'echarts'; |
|
|
|
|
|
import { getUserDeepChartTrend } from '../../api/platformData'; |
|
|
|
|
|
|
|
|
|
|
|
const route = useRoute(); |
|
|
|
|
|
const router = useRouter(); |
|
|
|
|
|
|
|
|
// 图表筛选 |
|
|
// 图表筛选 |
|
|
const chartDateRange = ref(''); |
|
|
const chartDateRange = ref(''); |
|
|
|
|
|
const chartMode = ref(route.query.mode || 'day'); // day, week, month |
|
|
const chartRef = ref(null); |
|
|
const chartRef = ref(null); |
|
|
|
|
|
let chartInstance = null; |
|
|
|
|
|
|
|
|
// 表格筛选 |
|
|
|
|
|
const tableAccount = ref(''); |
|
|
|
|
|
const tableRegion = ref(''); |
|
|
|
|
|
const tableDateRange = ref(''); |
|
|
|
|
|
const currentPage = ref(1); |
|
|
|
|
|
const pageSize = ref(50); |
|
|
|
|
|
|
|
|
// 初始化 URL 参数 |
|
|
|
|
|
const initQueryParams = () => { |
|
|
|
|
|
const { mode, startTime, endTime } = route.query; |
|
|
|
|
|
|
|
|
// 表格数据 |
|
|
|
|
|
const tableData = ref([ |
|
|
|
|
|
{ index: 1, account: 'DC900480004', name: 'Thea Elowen Hale', region: '中国', loginCount: 99, totalDuration: '99小时99分钟99秒', avgDuration: '99小时99分钟99秒', deepMate: '99小时99分钟99秒', deepExplore: '99小时99分钟99秒' }, |
|
|
|
|
|
{ index: 2, account: 'DC900480004', name: '欧帝三萃', region: '美国', loginCount: 99, totalDuration: '99小时99分钟99秒', avgDuration: '99小时99分钟99秒', deepMate: '99小时99分钟99秒', deepExplore: '99小时99分钟99秒' }, |
|
|
|
|
|
{ index: 3, account: 'DC900480004', name: 'Thea Elowen Hale', region: '新加坡', loginCount: 99, totalDuration: '99小时99分钟99秒', avgDuration: '99小时99分钟99秒', deepMate: '99小时99分钟99秒', deepExplore: '99小时99分钟99秒' }, |
|
|
|
|
|
{ index: 4, account: 'DC900480004', name: 'viên แก้ว หลาว', region: '泰国', loginCount: 99, totalDuration: '99小时99分钟99秒', avgDuration: '99小时99分钟99秒', deepMate: '99小时99分钟99秒', deepExplore: '99小时99分钟99秒' }, |
|
|
|
|
|
{ index: 5, account: 'DC900480004', name: 'viên แก้ว หลาว', region: '越南', loginCount: 99, totalDuration: '99小时99分钟99秒', avgDuration: '99小时99分钟99秒', deepMate: '99小时99分钟99秒', deepExplore: '99小时99分钟99秒' }, |
|
|
|
|
|
{ index: 6, account: 'DC900480004', name: 'Cien Yong Hao', region: '中国', loginCount: 9999, totalDuration: '99小时99分钟99秒', avgDuration: '99小时99分钟99秒', deepMate: '99小时99分钟99秒', deepExplore: '99小时99分钟99秒' }, |
|
|
|
|
|
{ index: 7, account: 'DC900480004', name: 'Cien Yong Hao', region: '美国', loginCount: 999, totalDuration: '99小时99分钟99秒', avgDuration: '99小时99分钟99秒', deepMate: '99小时99分钟99秒', deepExplore: '99小时99分钟99秒' }, |
|
|
|
|
|
{ index: 8, account: 'DC900480004', name: 'Tiên Linh Vinh Hảo', region: '新加坡', loginCount: 999, totalDuration: '99小时99分钟99秒', avgDuration: '99小时99分钟99秒', deepMate: '99小时99分钟99秒', deepExplore: '99小时99分钟99秒' }, |
|
|
|
|
|
{ index: 9, account: 'DC900480004', name: 'Tiên Linh Vinh Hảo', region: '新加坡', loginCount: 999, totalDuration: '99小时99分钟99秒', avgDuration: '99小时99分钟99秒', deepMate: '99小时99分钟99秒', deepExplore: '99小时99分钟99秒' }, |
|
|
|
|
|
{ index: 10, account: 'DC900480004', name: 'Tiên Linh Vinh Hảo', region: '香港', loginCount: 999, totalDuration: '99小时99分钟99秒', avgDuration: '99小时99分钟99秒', deepMate: '99小时99分钟99秒', deepExplore: '99小时99分钟99秒' }, |
|
|
|
|
|
]); |
|
|
|
|
|
|
|
|
if (mode) { |
|
|
|
|
|
chartMode.value = mode; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
const headerCellStyle = { |
|
|
|
|
|
background: '#f5f7fa', |
|
|
|
|
|
color: '#333', |
|
|
|
|
|
fontWeight: 'bold' |
|
|
|
|
|
|
|
|
if (startTime && endTime) { |
|
|
|
|
|
chartDateRange.value = [new Date(startTime), new Date(endTime)]; |
|
|
|
|
|
} |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
const initChart = () => { |
|
|
|
|
|
if (chartRef.value) { |
|
|
|
|
|
const chart = echarts.init(chartRef.value); |
|
|
|
|
|
chart.setOption({ |
|
|
|
|
|
|
|
|
initQueryParams(); |
|
|
|
|
|
|
|
|
|
|
|
const updateUrlParams = () => { |
|
|
|
|
|
const query = { ...route.query }; |
|
|
|
|
|
query.mode = chartMode.value; |
|
|
|
|
|
|
|
|
|
|
|
if (chartDateRange.value && chartDateRange.value.length === 2) { |
|
|
|
|
|
query.startTime = formatDate(chartDateRange.value[0]); |
|
|
|
|
|
query.endTime = formatDate(chartDateRange.value[1]); |
|
|
|
|
|
} else { |
|
|
|
|
|
delete query.startTime; |
|
|
|
|
|
delete query.endTime; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
router.replace({ query }); |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
const handleChartDateChange = () => { |
|
|
|
|
|
updateUrlParams(); |
|
|
|
|
|
fetchChartData(); |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
const handleModeChange = (mode) => { |
|
|
|
|
|
chartMode.value = mode; |
|
|
|
|
|
updateUrlParams(); |
|
|
|
|
|
fetchChartData(); |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// 格式化日期 |
|
|
|
|
|
const formatDate = (date) => { |
|
|
|
|
|
if (!date) return ''; |
|
|
|
|
|
const d = new Date(date); |
|
|
|
|
|
const pad = (n) => n < 10 ? '0' + n : n; |
|
|
|
|
|
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`; |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
const fetchChartData = async () => { |
|
|
|
|
|
const params = { |
|
|
|
|
|
mode: chartMode.value |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
if (chartDateRange.value && chartDateRange.value.length === 2) { |
|
|
|
|
|
params.startTime = formatDate(chartDateRange.value[0]); |
|
|
|
|
|
params.endTime = formatDate(chartDateRange.value[1]); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
|
const res = await getUserDeepChartTrend(params); |
|
|
|
|
|
console.log("获取DeepChart趋势数据响应:", res); |
|
|
|
|
|
const data = res.data || res; // 兼容处理 |
|
|
|
|
|
|
|
|
|
|
|
if (Array.isArray(data)) { |
|
|
|
|
|
updateChart(data); |
|
|
|
|
|
} |
|
|
|
|
|
} catch (e) { |
|
|
|
|
|
console.error('获取DeepChart趋势数据失败:', e); |
|
|
|
|
|
} |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
const updateChart = (data) => { |
|
|
|
|
|
if (!chartRef.value) return; |
|
|
|
|
|
|
|
|
|
|
|
if (!chartInstance) { |
|
|
|
|
|
chartInstance = echarts.init(chartRef.value); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const dates = data.map(item => item.time_point); |
|
|
|
|
|
const activeUsers = data.map(item => item.active_users); |
|
|
|
|
|
const useCounts = data.map(item => item.use_count); |
|
|
|
|
|
|
|
|
|
|
|
const option = { |
|
|
tooltip: { |
|
|
tooltip: { |
|
|
trigger: 'axis', |
|
|
trigger: 'axis', |
|
|
axisPointer: { type: 'cross' } |
|
|
axisPointer: { type: 'cross' } |
|
|
@ -149,20 +210,18 @@ const initChart = () => { |
|
|
xAxis: { |
|
|
xAxis: { |
|
|
type: 'category', |
|
|
type: 'category', |
|
|
boundaryGap: false, |
|
|
boundaryGap: false, |
|
|
data: ['六天前', '五天前', '四天前', '三天前', '两天前', '昨天', '今天'] |
|
|
|
|
|
|
|
|
data: dates |
|
|
}, |
|
|
}, |
|
|
yAxis: [ |
|
|
yAxis: [ |
|
|
{ |
|
|
{ |
|
|
type: 'value', |
|
|
type: 'value', |
|
|
min: 0, |
|
|
min: 0, |
|
|
max: 1400, |
|
|
|
|
|
position: 'left', |
|
|
position: 'left', |
|
|
axisLabel: { formatter: '{value}' } |
|
|
axisLabel: { formatter: '{value}' } |
|
|
}, |
|
|
}, |
|
|
{ |
|
|
{ |
|
|
type: 'value', |
|
|
type: 'value', |
|
|
min: 0, |
|
|
min: 0, |
|
|
max: 1400, |
|
|
|
|
|
position: 'right', |
|
|
position: 'right', |
|
|
axisLabel: { formatter: '{value}' } |
|
|
axisLabel: { formatter: '{value}' } |
|
|
} |
|
|
} |
|
|
@ -172,7 +231,7 @@ const initChart = () => { |
|
|
name: 'DeepChart活跃人数', |
|
|
name: 'DeepChart活跃人数', |
|
|
type: 'line', |
|
|
type: 'line', |
|
|
yAxisIndex: 0, |
|
|
yAxisIndex: 0, |
|
|
data: [300, 600, 320, 320, 400, 550, 650], |
|
|
|
|
|
|
|
|
data: activeUsers, |
|
|
itemStyle: { color: '#e74c3c' }, |
|
|
itemStyle: { color: '#e74c3c' }, |
|
|
symbol: 'circle', |
|
|
symbol: 'circle', |
|
|
symbolSize: 8, |
|
|
symbolSize: 8, |
|
|
@ -182,14 +241,51 @@ const initChart = () => { |
|
|
name: 'DeepChart使用次数', |
|
|
name: 'DeepChart使用次数', |
|
|
type: 'line', |
|
|
type: 'line', |
|
|
yAxisIndex: 1, |
|
|
yAxisIndex: 1, |
|
|
data: [1350, 1250, 1100, 1050, 1050, 1300, 1000], |
|
|
|
|
|
|
|
|
data: useCounts, |
|
|
itemStyle: { color: '#2ecc71' }, |
|
|
itemStyle: { color: '#2ecc71' }, |
|
|
symbol: 'circle', |
|
|
symbol: 'circle', |
|
|
symbolSize: 8, |
|
|
symbolSize: 8, |
|
|
lineStyle: { width: 3 } |
|
|
lineStyle: { width: 3 } |
|
|
} |
|
|
} |
|
|
] |
|
|
] |
|
|
}); |
|
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
chartInstance.setOption(option); |
|
|
|
|
|
}; |
|
|
|
|
|
const tableAccount = ref(''); |
|
|
|
|
|
const tableRegion = ref(''); |
|
|
|
|
|
const tableDateRange = ref(''); |
|
|
|
|
|
const currentPage = ref(1); |
|
|
|
|
|
const pageSize = ref(50); |
|
|
|
|
|
|
|
|
|
|
|
// 表格数据 |
|
|
|
|
|
const tableData = ref([ |
|
|
|
|
|
{ index: 1, account: 'DC900480004', name: 'Thea Elowen Hale', region: '中国', loginCount: 99, totalDuration: '99小时99分钟99秒', avgDuration: '99小时99分钟99秒', deepMate: '99小时99分钟99秒', deepExplore: '99小时99分钟99秒' }, |
|
|
|
|
|
{ index: 2, account: 'DC900480004', name: '欧帝三萃', region: '美国', loginCount: 99, totalDuration: '99小时99分钟99秒', avgDuration: '99小时99分钟99秒', deepMate: '99小时99分钟99秒', deepExplore: '99小时99分钟99秒' }, |
|
|
|
|
|
{ index: 3, account: 'DC900480004', name: 'Thea Elowen Hale', region: '新加坡', loginCount: 99, totalDuration: '99小时99分钟99秒', avgDuration: '99小时99分钟99秒', deepMate: '99小时99分钟99秒', deepExplore: '99小时99分钟99秒' }, |
|
|
|
|
|
{ index: 4, account: 'DC900480004', name: 'viên แก้ว หลาว', region: '泰国', loginCount: 99, totalDuration: '99小时99分钟99秒', avgDuration: '99小时99分钟99秒', deepMate: '99小时99分钟99秒', deepExplore: '99小时99分钟99秒' }, |
|
|
|
|
|
{ index: 5, account: 'DC900480004', name: 'viên แก้ว หลาว', region: '越南', loginCount: 99, totalDuration: '99小时99分钟99秒', avgDuration: '99小时99分钟99秒', deepMate: '99小时99分钟99秒', deepExplore: '99小时99分钟99秒' }, |
|
|
|
|
|
{ index: 6, account: 'DC900480004', name: 'Cien Yong Hao', region: '中国', loginCount: 9999, totalDuration: '99小时99分钟99秒', avgDuration: '99小时99分钟99秒', deepMate: '99小时99分钟99秒', deepExplore: '99小时99分钟99秒' }, |
|
|
|
|
|
{ index: 7, account: 'DC900480004', name: 'Cien Yong Hao', region: '美国', loginCount: 999, totalDuration: '99小时99分钟99秒', avgDuration: '99小时99分钟99秒', deepMate: '99小时99分钟99秒', deepExplore: '99小时99分钟99秒' }, |
|
|
|
|
|
{ index: 8, account: 'DC900480004', name: 'Tiên Linh Vinh Hảo', region: '新加坡', loginCount: 999, totalDuration: '99小时99分钟99秒', avgDuration: '99小时99分钟99秒', deepMate: '99小时99分钟99秒', deepExplore: '99小时99分钟99秒' }, |
|
|
|
|
|
{ index: 9, account: 'DC900480004', name: 'Tiên Linh Vinh Hảo', region: '新加坡', loginCount: 999, totalDuration: '99小时99分钟99秒', avgDuration: '99小时99分钟99秒', deepMate: '99小时99分钟99秒', deepExplore: '99小时99分钟99秒' }, |
|
|
|
|
|
{ index: 10, account: 'DC900480004', name: 'Tiên Linh Vinh Hảo', region: '香港', loginCount: 999, totalDuration: '99小时99分钟99秒', avgDuration: '99小时99分钟99秒', deepMate: '99小时99分钟99秒', deepExplore: '99小时99分钟99秒' }, |
|
|
|
|
|
]); |
|
|
|
|
|
|
|
|
|
|
|
const headerCellStyle = { |
|
|
|
|
|
background: '#f5f7fa', |
|
|
|
|
|
color: '#333', |
|
|
|
|
|
fontWeight: 'bold' |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
const initChart = () => { |
|
|
|
|
|
if (chartRef.value) { |
|
|
|
|
|
// 初始化图表实例 |
|
|
|
|
|
if (!chartInstance) { |
|
|
|
|
|
chartInstance = echarts.init(chartRef.value); |
|
|
|
|
|
} |
|
|
|
|
|
// 初始加载数据 |
|
|
|
|
|
fetchChartData(); |
|
|
} |
|
|
} |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|