mall数据库文件
This commit is contained in:
@@ -109,10 +109,11 @@
|
||||
</template>
|
||||
|
||||
<script lang="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'
|
||||
import { fetchCouponAnalysis } from '@/services/analytics/couponAnalysisService.uts'
|
||||
import { mapAnalyticsError } from '@/services/analytics/errorMapper.uts'
|
||||
|
||||
type TimePeriod = { value: string; label: string }
|
||||
type CouponData = {
|
||||
@@ -177,105 +178,13 @@ export default {
|
||||
methods: {
|
||||
async loadCouponData() {
|
||||
try {
|
||||
// 1) 计算时间范围
|
||||
const now = new Date()
|
||||
const start = new Date(now.getTime())
|
||||
if (this.selectedPeriod === '7d') start.setDate(start.getDate() - 7)
|
||||
else if (this.selectedPeriod === '30d') start.setDate(start.getDate() - 30)
|
||||
else if (this.selectedPeriod === '90d') start.setDate(start.getDate() - 90)
|
||||
else if (this.selectedPeriod === '1y') start.setFullYear(start.getFullYear() - 1)
|
||||
const startIso = start.toISOString()
|
||||
const endIso = now.toISOString()
|
||||
const data = await fetchCouponAnalysis(this.selectedPeriod)
|
||||
|
||||
// 2) 确保 Supabase 会话就绪
|
||||
await ensureSupabaseReady()
|
||||
|
||||
// 3) 优先调用后端 RPC(推荐在 Supabase 中创建对应函数)
|
||||
// - rpc_coupon_effectiveness_overview 概览 KPI
|
||||
// - rpc_coupon_type_stats 按券类型统计
|
||||
// - rpc_coupon_channel_stats 发放渠道统计
|
||||
// - rpc_coupon_trend_daily 每日发放/使用趋势
|
||||
// - rpc_coupon_conversion_effect GMV/订单转化效果
|
||||
|
||||
let overviewRow: UTSJSONObject | null = null
|
||||
let typeList: Array<UTSJSONObject> = []
|
||||
let channelList: Array<UTSJSONObject> = []
|
||||
let trendList: Array<UTSJSONObject> = []
|
||||
let conversionList: Array<UTSJSONObject> = []
|
||||
|
||||
// 3.1 概览 KPI
|
||||
const overviewRes = await supa.rpc('rpc_coupon_effectiveness_overview', {
|
||||
p_start: startIso,
|
||||
p_end: endIso
|
||||
})
|
||||
|
||||
if (overviewRes.status === 404) {
|
||||
// RPC 未创建:保留默认 0 值,由后续 SQL 实现补上真实逻辑
|
||||
console.warn('rpc_coupon_effectiveness_overview not found, using default zeros')
|
||||
} else if (overviewRes.error != null) {
|
||||
throw overviewRes.error
|
||||
} else {
|
||||
const anyData = overviewRes.data as any
|
||||
if (Array.isArray(anyData) && anyData.length > 0) {
|
||||
overviewRow = anyData[0] as UTSJSONObject
|
||||
}
|
||||
}
|
||||
|
||||
// 3.2 券类型统计
|
||||
const typeRes = await supa.rpc('rpc_coupon_type_stats', {
|
||||
p_start: startIso,
|
||||
p_end: endIso
|
||||
})
|
||||
if (typeRes.status === 404) {
|
||||
console.warn('rpc_coupon_type_stats not found, type analysis will be empty')
|
||||
} else if (typeRes.error != null) {
|
||||
throw typeRes.error
|
||||
} else {
|
||||
const typeAny = typeRes.data as any
|
||||
typeList = Array.isArray(typeAny) ? typeAny as Array<UTSJSONObject> : []
|
||||
}
|
||||
|
||||
// 3.3 渠道统计
|
||||
const channelRes = await supa.rpc('rpc_coupon_channel_stats', {
|
||||
p_start: startIso,
|
||||
p_end: endIso
|
||||
})
|
||||
if (channelRes.status === 404) {
|
||||
console.warn('rpc_coupon_channel_stats not found, channel analysis will be empty')
|
||||
} else if (channelRes.error != null) {
|
||||
throw channelRes.error
|
||||
} else {
|
||||
const chAny = channelRes.data as any
|
||||
channelList = Array.isArray(chAny) ? chAny as Array<UTSJSONObject> : []
|
||||
}
|
||||
|
||||
// 3.4 使用趋势
|
||||
const trendRes = await supa.rpc('rpc_coupon_trend_daily', {
|
||||
p_start: startIso,
|
||||
p_end: endIso
|
||||
})
|
||||
if (trendRes.status === 404) {
|
||||
console.warn('rpc_coupon_trend_daily not found, trend analysis will be empty')
|
||||
} else if (trendRes.error != null) {
|
||||
throw trendRes.error
|
||||
} else {
|
||||
const trAny = trendRes.data as any
|
||||
trendList = Array.isArray(trAny) ? trAny as Array<UTSJSONObject> : []
|
||||
}
|
||||
|
||||
// 3.5 转化效果(GMV/订单)
|
||||
const convRes = await supa.rpc('rpc_coupon_conversion_effect', {
|
||||
p_start: startIso,
|
||||
p_end: endIso
|
||||
})
|
||||
if (convRes.status === 404) {
|
||||
console.warn('rpc_coupon_conversion_effect not found, conversion chart will be empty')
|
||||
} else if (convRes.error != null) {
|
||||
throw convRes.error
|
||||
} else {
|
||||
const cvAny = convRes.data as any
|
||||
conversionList = Array.isArray(cvAny) ? cvAny as Array<UTSJSONObject> : []
|
||||
}
|
||||
const overviewRow = data.overviewRow
|
||||
const typeList = data.typeList
|
||||
const channelList = data.channelList
|
||||
const trendList = data.trendList
|
||||
const conversionList = data.conversionList
|
||||
|
||||
// 4) 计算 KPI 概览
|
||||
let totalIssued = 0
|
||||
@@ -326,9 +235,9 @@ export default {
|
||||
this.buildChartOptions()
|
||||
} catch (e) {
|
||||
console.error('loadCouponData failed:', e)
|
||||
this.updateTime()
|
||||
this.buildChartOptions()
|
||||
uni.showToast({ title: '优惠券分析数据加载失败', icon: 'none' })
|
||||
this.updateTime()
|
||||
this.buildChartOptions()
|
||||
uni.showToast({ title: mapAnalyticsError(e, { fallbackMessage: '优惠券分析数据加载失败' }), icon: 'none' })
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user