mall数据库文件
This commit is contained in:
@@ -116,11 +116,11 @@
|
||||
</template>
|
||||
|
||||
<script lang="uts">
|
||||
import supa from '@/components/supadb/aksupainstance.uts'
|
||||
import { 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 { fetchDeliveryAnalysis } from '@/services/analytics/deliveryAnalysisService.uts'
|
||||
import { mapAnalyticsError } from '@/services/analytics/errorMapper.uts'
|
||||
|
||||
type DeliveryData = {
|
||||
avg_delivery_time: number
|
||||
@@ -186,126 +186,9 @@ export default {
|
||||
methods: {
|
||||
async loadDeliveryData() {
|
||||
try {
|
||||
// 根据时间维度计算起始时间
|
||||
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()
|
||||
|
||||
await ensureSupabaseReady()
|
||||
|
||||
// 1) 查询周期内已送达任务(按 assigned_at 统计周期,口径:接单 assigned_at -> 送达 delivered_at)
|
||||
// 表结构来源:doc_mall/database/complete_mall_database.sql
|
||||
// 1) 趋势:RPC(数据库侧聚合)
|
||||
const endIso = now.toISOString()
|
||||
|
||||
// 优先走 RPC(需要在 Supabase 执行 DELIVERY_ANALYSIS_RPCS.sql 创建函数)
|
||||
let trendList: Array<UTSJSONObject> = []
|
||||
let topList: Array<UTSJSONObject> = []
|
||||
|
||||
const trendRes = await supa.rpc('rpc_delivery_efficiency_daily', {
|
||||
p_start: startIso,
|
||||
p_end: endIso
|
||||
})
|
||||
|
||||
if (trendRes.status === 404) {
|
||||
// RPC 不存在:降级到直查表聚合(测试阶段兜底)
|
||||
const taskRes = await supa
|
||||
.from('ml_delivery_tasks')
|
||||
.select('id,driver_id,assigned_at,delivered_at,delivery_fee', {})
|
||||
.eq('status', 5)
|
||||
.gte('assigned_at', startIso)
|
||||
.order('assigned_at', { ascending: true })
|
||||
.execute()
|
||||
|
||||
if (taskRes.error != null) throw taskRes.error
|
||||
|
||||
const rowsAny = (taskRes.data != null ? taskRes.data : []) as any
|
||||
const tasks = Array.isArray(rowsAny) ? rowsAny as Array<UTSJSONObject> : []
|
||||
|
||||
const dayAgg = new Map<string, UTSJSONObject>()
|
||||
const driverAgg = new Map<string, number>()
|
||||
|
||||
for (let i = 0; i < tasks.length; i++) {
|
||||
const t = tasks[i]
|
||||
const assignedAt = t.getString('assigned_at') ?? ''
|
||||
const deliveredAt = t.getString('delivered_at') ?? ''
|
||||
const driverId = t.getString('driver_id') ?? ''
|
||||
if (assignedAt.trim() === '' || deliveredAt.trim() === '') continue
|
||||
|
||||
const day = assignedAt.length >= 10 ? assignedAt.substring(0, 10) : assignedAt
|
||||
const a = new Date(assignedAt)
|
||||
const d = new Date(deliveredAt)
|
||||
const diffMin = Math.max(0, (d.getTime() - a.getTime()) / 60000)
|
||||
const fee = t.getNumber('delivery_fee') ?? 0
|
||||
|
||||
const old = dayAgg.get(day)
|
||||
if (old == null) {
|
||||
const obj = new UTSJSONObject()
|
||||
obj.set('day', day)
|
||||
obj.set('completed_orders', 1)
|
||||
obj.set('sum_minutes', diffMin)
|
||||
obj.set('total_fee', fee)
|
||||
dayAgg.set(day, obj)
|
||||
} else {
|
||||
old.set('completed_orders', (old.getNumber('completed_orders') ?? 0) + 1)
|
||||
old.set('sum_minutes', (old.getNumber('sum_minutes') ?? 0) + diffMin)
|
||||
old.set('total_fee', (old.getNumber('total_fee') ?? 0) + fee)
|
||||
}
|
||||
|
||||
if (driverId.trim() !== '') {
|
||||
const c = driverAgg.get(driverId) ?? 0
|
||||
driverAgg.set(driverId, c + 1)
|
||||
}
|
||||
}
|
||||
|
||||
const keys = Array.from(dayAgg.keys()).sort()
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
const k = keys[i]
|
||||
const agg = dayAgg.get(k) as UTSJSONObject
|
||||
const cnt = agg.getNumber('completed_orders') ?? 0
|
||||
const sumMin = agg.getNumber('sum_minutes') ?? 0
|
||||
const tFee = agg.getNumber('total_fee') ?? 0
|
||||
|
||||
const row = new UTSJSONObject()
|
||||
row.set('day', k)
|
||||
row.set('completed_orders', cnt)
|
||||
row.set('avg_delivery_minutes', cnt > 0 ? (sumMin / cnt) : 0)
|
||||
row.set('total_fee', tFee)
|
||||
row.set('avg_fee', cnt > 0 ? (tFee / cnt) : 0)
|
||||
trendList.push(row)
|
||||
}
|
||||
|
||||
// TOP:仅用 driverAgg 计算(姓名/评分未知,先兜底)
|
||||
const ids = Array.from(driverAgg.keys()).sort((a, b) => (driverAgg.get(b) ?? 0) - (driverAgg.get(a) ?? 0))
|
||||
const topN = Math.min(10, ids.length)
|
||||
for (let i = 0; i < topN; i++) {
|
||||
const id = ids[i]
|
||||
const row = new UTSJSONObject()
|
||||
row.set('driver_id', id)
|
||||
row.set('driver_name', '未知')
|
||||
row.set('orders', driverAgg.get(id) ?? 0)
|
||||
row.set('rating_avg', 0)
|
||||
topList.push(row)
|
||||
}
|
||||
} else {
|
||||
if (trendRes.error != null) throw trendRes.error
|
||||
const trendAny = (trendRes.data != null ? trendRes.data : []) as any
|
||||
trendList = Array.isArray(trendAny) ? trendAny as Array<UTSJSONObject> : []
|
||||
|
||||
const topRes = await supa.rpc('rpc_delivery_efficiency_top_drivers', {
|
||||
p_start: startIso,
|
||||
p_end: endIso,
|
||||
p_limit: 10
|
||||
})
|
||||
|
||||
if (topRes.error != null) throw topRes.error
|
||||
const topAny = (topRes.data != null ? topRes.data : []) as any
|
||||
topList = Array.isArray(topAny) ? topAny as Array<UTSJSONObject> : []
|
||||
}
|
||||
const data = await fetchDeliveryAnalysis(this.selectedPeriod)
|
||||
const trendList = data.trendList
|
||||
const topList = data.topList
|
||||
|
||||
// 3) 转成页面内部 trendRows 格式
|
||||
const trendRows: Array<UTSJSONObject> = []
|
||||
@@ -397,7 +280,7 @@ export default {
|
||||
console.error('loadDeliveryData failed:', e)
|
||||
this.updateTime()
|
||||
this.buildChartOptions()
|
||||
uni.showToast({ title: '配送分析数据加载失败', icon: 'none' })
|
||||
uni.showToast({ title: mapAnalyticsError(e, { fallbackMessage: '配送分析数据加载失败' }), icon: 'none' })
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user