接入数据库
This commit is contained in:
@@ -186,10 +186,79 @@ export default {
|
||||
},
|
||||
|
||||
methods: {
|
||||
calcDateRange() {
|
||||
const now = new Date()
|
||||
const endDate = new Date(now.getFullYear(), now.getMonth(), now.getDate())
|
||||
const days = this.selectedPeriod === '7d' ? 7 : this.selectedPeriod === '30d' ? 30 : this.selectedPeriod === '90d' ? 90 : 365
|
||||
const startDate = new Date(endDate.getTime() - (days - 1) * 24 * 60 * 60 * 1000)
|
||||
return { startDate, endDate }
|
||||
},
|
||||
|
||||
async loadUserData() {
|
||||
// TODO: 实现用户数据加载
|
||||
this.updateTime()
|
||||
this.buildChartOptions()
|
||||
try {
|
||||
this.updateTime()
|
||||
const { startDate, endDate } = this.calcDateRange()
|
||||
const startStr = startDate.toISOString().slice(0, 10)
|
||||
const endStr = endDate.toISOString().slice(0, 10)
|
||||
|
||||
const p = new UTSJSONObject()
|
||||
p.set('p_start_date', startStr)
|
||||
p.set('p_end_date', endStr)
|
||||
|
||||
// KPI(新 RPC)
|
||||
const res: any = await supa.rpc('rpc_analytics_user_kpis', p)
|
||||
const row = Array.isArray(res.data) && res.data.length > 0 ? res.data[0] : (res.data || {})
|
||||
const safe = (v: any): number => {
|
||||
const n = Number(v)
|
||||
return isFinite(n) ? n : 0
|
||||
}
|
||||
this.userData = {
|
||||
total_users: Math.round(safe(row.total_users)),
|
||||
user_growth: safe(row.user_growth),
|
||||
new_users: Math.round(safe(row.new_users)),
|
||||
new_user_growth: safe(row.new_user_growth),
|
||||
active_rate: safe(row.active_rate),
|
||||
active_growth: safe(row.active_growth),
|
||||
repurchase_rate: safe(row.repurchase_rate),
|
||||
repurchase_growth: safe(row.repurchase_growth)
|
||||
}
|
||||
|
||||
// 增长趋势(新 RPC)
|
||||
const tRes: any = await supa.rpc('rpc_analytics_user_growth_trend', p)
|
||||
const rows: Array<any> = Array.isArray(tRes.data) ? (tRes.data as Array<any>) : []
|
||||
const x: Array<string> = []
|
||||
const newArr: Array<number> = []
|
||||
const totalArr: Array<number> = []
|
||||
for (let i = 0; i < rows.length; i++) {
|
||||
const d = `${rows[i].date}`
|
||||
x.push(d.slice(5))
|
||||
newArr.push(Number(rows[i].new_users) || 0)
|
||||
totalArr.push(Number(rows[i].total_users) || 0)
|
||||
}
|
||||
|
||||
// 构建图表(先把“用户增长趋势”做成真实动态图)
|
||||
this.growthChartOption = {
|
||||
grid: { left: 40, right: 18, top: 20, bottom: 40 },
|
||||
tooltip: { trigger: 'axis' },
|
||||
legend: { data: ['新用户', '总用户'], bottom: 0 },
|
||||
xAxis: { type: 'category', data: x, axisLabel: { color: 'rgba(0,0,0,0.55)' } },
|
||||
yAxis: { type: 'value', axisLabel: { color: 'rgba(0,0,0,0.55)' }, splitLine: { lineStyle: { color: 'rgba(0,0,0,0.06)' } } },
|
||||
series: [
|
||||
{ name: '新用户', type: 'bar', data: newArr, barWidth: 14, itemStyle: { borderRadius: 6 } },
|
||||
{ name: '总用户', type: 'line', data: totalArr, smooth: true, symbolSize: 6 }
|
||||
]
|
||||
}
|
||||
|
||||
// 其余图表:先用“有文案的占位”避免空白(后续可按业务字段继续增强)
|
||||
this.retentionChartOption = { title: { text: '留存率(待接入)', left: 'center', top: 10, textStyle: { fontSize: 12, color: 'rgba(0,0,0,0.55)' } }, series: [] }
|
||||
this.activityChartOption = { title: { text: '活跃度(待接入)', left: 'center', top: 10, textStyle: { fontSize: 12, color: 'rgba(0,0,0,0.55)' } }, series: [] }
|
||||
this.comparisonChartOption = { title: { text: '新老用户对比(待接入)', left: 'center', top: 10, textStyle: { fontSize: 12, color: 'rgba(0,0,0,0.55)' } }, series: [] }
|
||||
this.profileChartOption = { title: { text: '用户画像(待接入:需要性别/年龄/地域字段)', left: 'center', top: 10, textStyle: { fontSize: 12, color: 'rgba(0,0,0,0.55)' } }, series: [] }
|
||||
} catch (e) {
|
||||
console.error('loadUserData failed', e)
|
||||
} finally {
|
||||
this.updateTime()
|
||||
}
|
||||
},
|
||||
|
||||
selectPeriod(p: string) {
|
||||
@@ -228,14 +297,7 @@ export default {
|
||||
return `${sign}${v.toFixed(1)}%`
|
||||
},
|
||||
|
||||
buildChartOptions() {
|
||||
// TODO: 构建图表配置
|
||||
this.growthChartOption = {}
|
||||
this.retentionChartOption = {}
|
||||
this.activityChartOption = {}
|
||||
this.comparisonChartOption = {}
|
||||
this.profileChartOption = {}
|
||||
},
|
||||
buildChartOptions() {},
|
||||
|
||||
handleMenu() {
|
||||
this.showSidebarMenu = true
|
||||
|
||||
Reference in New Issue
Block a user