数据分析ui补充完善,接入数据库
This commit is contained in:
@@ -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() {
|
||||
|
||||
Reference in New Issue
Block a user