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

This commit is contained in:
comlibmb
2026-01-29 17:30:39 +08:00
parent 3e89513e8b
commit b53d2376ff
13 changed files with 1161 additions and 889 deletions

View File

@@ -105,7 +105,7 @@
</template>
<script lang="uts">
import supa from '@/components/supadb/aksupainstance.uts'
import supa, { ensureSupabaseReady } from '@/components/supadb/aksupainstance.uts'
import AnalyticsSidebarMenu from '@/components/analytics/AnalyticsSidebarMenu.uvue'
import AnalyticsTopBar from '@/components/analytics/AnalyticsTopBar.uvue'
import EChartsView from '@/uni_modules/charts/EChartsView.vue'
@@ -160,9 +160,106 @@ export default {
methods: {
async loadDetailData() {
// TODO: 实现详细数据加载
this.updateTime()
this.buildChartOptions()
try {
const now = new Date()
const end = new Date(now.getTime())
const start = new Date(now.getTime())
if (this.timeRangeText === '最近7天') {
start.setDate(start.getDate() - 7)
} else if (this.timeRangeText === '最近30天') {
start.setDate(start.getDate() - 30)
} else if (this.timeRangeText === '最近90天') {
start.setDate(start.getDate() - 90)
} else {
// 自定义暂时按最近30天处理
start.setDate(start.getDate() - 30)
}
const startIso = start.toISOString()
const endIso = end.toISOString()
await ensureSupabaseReady()
// 当前周期明细:复用 rpc_analytics_market_trend_daily按天 GMV / 订单 / 用户)
let currentRows: Array<UTSJSONObject> = []
let compareRows: Array<UTSJSONObject> = []
const curRes = await supa.rpc('rpc_analytics_market_trend_daily', {
p_start: startIso,
p_end: endIso
})
if (curRes.status === 404) {
console.warn('rpc_analytics_market_trend_daily not found, data-detail will be empty')
} else if (curRes.error != null) {
console.error('rpc_analytics_market_trend_daily error:', curRes.error)
} else {
const anyData = curRes.data as any
currentRows = Array.isArray(anyData) ? anyData as Array<UTSJSONObject> : []
}
// 对比周期:与当前周期长度相同的上一段时间
const spanMs = end.getTime() - start.getTime()
const prevEnd = new Date(start.getTime())
const prevStart = new Date(start.getTime() - spanMs)
const prevStartIso = prevStart.toISOString()
const prevEndIso = prevEnd.toISOString()
const prevRes = await supa.rpc('rpc_analytics_market_trend_daily', {
p_start: prevStartIso,
p_end: prevEndIso
})
if (prevRes.status === 404) {
console.warn('rpc_analytics_market_trend_daily not found for compare period')
} else if (prevRes.error != null) {
console.error('rpc_analytics_market_trend_daily (compare) error:', prevRes.error)
} else {
const anyPrev = prevRes.data as any
compareRows = Array.isArray(anyPrev) ? anyPrev as Array<UTSJSONObject> : []
}
// 映射到表格数据
const table: Array<any> = []
for (let i = 0; i < currentRows.length; i++) {
const r = currentRows[i]
const dayStr = r.getString('day') ?? ''
table.push({
id: dayStr + '_' + i.toString(),
date: dayStr,
gmv: r.getNumber('gmv') ?? 0,
orders: r.getNumber('orders') ?? 0,
users: r.getNumber('users') ?? 0
} as any)
}
this.tableData = table
// 简单生成钻取卡片:总 GMV / 总订单 / 总用户
let totalGmv = 0
let totalOrders = 0
let totalUsers = 0
for (let i = 0; i < table.length; i++) {
const row = table[i]
totalGmv += row.gmv as number
totalOrders += row.orders as number
totalUsers += row.users as number
}
this.drillDownItems = [
{ id: 'gmv_total', label: '当前周期 GMV 总计', value: this.formatCellValue(totalGmv, 'money'), type: 'gmv' } as DrillDownItem,
{ id: 'orders_total', label: '当前周期订单总数', value: this.formatCellValue(totalOrders, 'number'), type: 'orders' } as DrillDownItem,
{ id: 'users_total', label: '当前周期下单用户数', value: this.formatCellValue(totalUsers, 'number'), type: 'users' } as DrillDownItem
]
;(this as any)._currentRows = currentRows
;(this as any)._compareRows = compareRows
this.updateTime()
this.buildChartOptions()
} catch (e) {
console.error('loadDetailData failed:', e)
this.updateTime()
this.buildChartOptions()
uni.showToast({ title: '详细数据加载失败', icon: 'none' })
}
},
selectTimeRange() {
@@ -201,7 +298,16 @@ export default {
this.sortKey = key
this.sortOrder = 'asc'
}
// TODO: 实现排序逻辑
const data = this.tableData.slice()
data.sort((a: any, b: any) => {
const va = a[key]
const vb = b[key]
const na = typeof va === 'number' ? va : Number(va)
const nb = typeof vb === 'number' ? vb : Number(vb)
if (this.sortOrder === 'asc') return na - nb
return nb - na
})
this.tableData = data
},
formatCellValue(value: any, type: string): string {
@@ -245,8 +351,58 @@ export default {
},
buildChartOptions() {
// TODO: 构建图表配置
this.compareChartOption = {}
const curAny = (this as any)._currentRows as any
const prevAny = (this as any)._compareRows as any
const curRows = Array.isArray(curAny) ? curAny as Array<UTSJSONObject> : []
const prevRows = Array.isArray(prevAny) ? prevAny as Array<UTSJSONObject> : []
if (!this.compareMode || curRows.length === 0) {
this.compareChartOption = {}
return
}
const curDays: string[] = []
const curGmv: number[] = []
const prevGmv: number[] = []
for (let i = 0; i < curRows.length; i++) {
const r = curRows[i]
const dayStr = r.getString('day') ?? ''
curDays.push(dayStr.length >= 10 ? dayStr.substring(5, 10) : dayStr)
curGmv.push(r.getNumber('gmv') ?? 0)
}
// 对比周期的数据按顺序对齐(长度可能不同,超出部分用 0 填充)
for (let i = 0; i < curRows.length; i++) {
const rPrev = i < prevRows.length ? prevRows[i] : null
if (rPrev == null) {
prevGmv.push(0)
} else {
prevGmv.push(rPrev.getNumber('gmv') ?? 0)
}
}
this.compareChartOption = {
tooltip: { trigger: 'axis' },
legend: { data: ['当前周期 GMV', '对比周期 GMV'], top: 'bottom' },
grid: { left: 50, right: 20, top: 30, bottom: 60 },
xAxis: { type: 'category', data: curDays },
yAxis: { type: 'value', name: 'GMV' },
series: [
{
name: '当前周期 GMV',
type: 'line',
smooth: true,
data: curGmv
},
{
name: '对比周期 GMV',
type: 'line',
smooth: true,
data: prevGmv
}
]
}
},
handleMenu() {