数据分析ui补充完善,接入数据库

This commit is contained in:
comlibmb
2026-02-01 20:17:37 +08:00
parent 6716398175
commit 19970db288
19 changed files with 393 additions and 435 deletions

View File

@@ -76,19 +76,34 @@
</view>
</view>
<!-- 时间维度:横排 -->
<!-- 时间维度筛选(快捷 + 自定义) -->
<view class="tabs">
<view
v-for="p in timePeriods"
:key="p.value"
class="tab"
:class="{ active: selectedPeriod === p.value }"
:class="{ active: selectedPeriod === p.value && !customRangeEnabled }"
@click="selectPeriod(p.value)"
>
{{ p.label }}
</view>
<view
class="tab"
:class="{ active: customRangeEnabled }"
@click="toggleCustomRange"
>
自定义
</view>
</view>
<AnalyticsDateRangePicker
v-if="customRangeEnabled"
:initialStartDate="selectedStartDate"
:initialEndDate="selectedEndDate"
@apply="onDateRangeApply"
@clear="onDateRangeClear"
/>
<!-- 核心趋势:占满横向(柱+折 组合图) -->
<view class="card card-full">
<view class="card-head">
@@ -252,10 +267,10 @@
<!-- 留白 -->
<view style="height: 24px;"></view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script setup lang="uts">
@@ -264,6 +279,7 @@ import { computed, reactive, ref, watch } from 'vue'
import AnalyticsComboChart from '@/components/analytics/AnalyticsComboChart.uvue'
import AnalyticsSidebarMenu from '@/components/analytics/AnalyticsSidebarMenu.uvue'
import AnalyticsTopBar from '@/components/analytics/AnalyticsTopBar.uvue'
import AnalyticsDateRangePicker from '@/components/analytics/AnalyticsDateRangePicker.uvue'
import EChartsView from '@/uni_modules/charts/EChartsView.vue'
import { fetchDashboardRealtime, fetchDashboardTrend, fetchDashboardUserSegments, fetchDashboardTrafficSources, fetchDashboardTopProducts, fetchDashboardTopMerchants } from '@/services/analytics/dashboardService.uts'
import { mapAnalyticsError } from '@/services/analytics/errorMapper.uts'
@@ -271,6 +287,10 @@ import type { TrendData, SegmentItem, TrafficItem, TopProductItem, TopMerchantIt
const lastUpdateTime = ref('')
const selectedPeriod = ref('7d')
const customRangeEnabled = ref(false)
const selectedStartDate = ref('')
const selectedEndDate = ref('')
const showMoreMenu = ref(false)
const showSidebarMenu = ref(false)
const currentPath = ref('/pages/mall/analytics/index')
@@ -333,7 +353,11 @@ function stopAutoRefresh() {
async function loadTrend() {
try {
const data = await fetchDashboardTrend(selectedPeriod.value)
const range = selectedStartDate.value && selectedEndDate.value
? { start: selectedStartDate.value, end: selectedEndDate.value }
: null
const data = await fetchDashboardTrend(selectedPeriod.value, range)
trend.x = data.x
trend.gmv = data.gmv
trend.orders = data.orders
@@ -362,7 +386,10 @@ async function loadRealTime() {
async function loadTopProducts() {
try {
const list = await fetchDashboardTopProducts(selectedPeriod.value, 50)
const range = selectedStartDate.value && selectedEndDate.value
? { start: selectedStartDate.value, end: selectedEndDate.value }
: null
const list = await fetchDashboardTopProducts(selectedPeriod.value, 50, range)
topProducts.splice(0, topProducts.length, ...list)
} catch (e) {
console.error('❌ loadTopProducts failed', e)
@@ -372,7 +399,10 @@ async function loadTopProducts() {
async function loadTopMerchants() {
try {
const list = await fetchDashboardTopMerchants(selectedPeriod.value, 50)
const range = selectedStartDate.value && selectedEndDate.value
? { start: selectedStartDate.value, end: selectedEndDate.value }
: null
const list = await fetchDashboardTopMerchants(selectedPeriod.value, 50, range)
topMerchants.splice(0, topMerchants.length, ...list)
} catch (e) {
console.error('❌ loadTopMerchants failed', e)
@@ -382,7 +412,10 @@ async function loadTopMerchants() {
async function loadUserSegments() {
try {
const list = await fetchDashboardUserSegments(selectedPeriod.value)
const range = selectedStartDate.value && selectedEndDate.value
? { start: selectedStartDate.value, end: selectedEndDate.value }
: null
const list = await fetchDashboardUserSegments(selectedPeriod.value, range)
userSegments.splice(0, userSegments.length, ...list)
} catch (e) {
console.error('❌ loadUserSegments failed', e)
@@ -392,7 +425,10 @@ async function loadUserSegments() {
async function loadTrafficSources() {
try {
const list = await fetchDashboardTrafficSources(selectedPeriod.value)
const range = selectedStartDate.value && selectedEndDate.value
? { start: selectedStartDate.value, end: selectedEndDate.value }
: null
const list = await fetchDashboardTrafficSources(selectedPeriod.value, range)
trafficSources.splice(0, trafficSources.length, ...list)
} catch (e) {
console.error('❌ loadTrafficSources failed', e)
@@ -713,6 +749,24 @@ function handleSettings() {
uni.showToast({ title: '设置', icon: 'none' })
}
function toggleCustomRange() {
customRangeEnabled.value = !customRangeEnabled.value
}
function onDateRangeApply(range: { start: string; end: string }) {
selectedStartDate.value = range.start
selectedEndDate.value = range.end
customRangeEnabled.value = true
refreshAll()
}
function onDateRangeClear() {
selectedStartDate.value = ''
selectedEndDate.value = ''
customRangeEnabled.value = false
refreshAll()
}
function formatInt(n: number): string {
const v = isFinite(n) ? Math.round(n) : 0
if (v >= 10000) return (v / 10000).toFixed(1) + '万'