diff --git a/components/analytics/AnalyticsComboChart.uvue b/components/analytics/AnalyticsComboChart.uvue index 4bcfed8e..fd3ef7b2 100644 --- a/components/analytics/AnalyticsComboChart.uvue +++ b/components/analytics/AnalyticsComboChart.uvue @@ -26,9 +26,33 @@ export default { }, watch: { - xLabels: { handler() { this.updateOption() }, deep: true }, - gmv: { handler() { this.updateOption() }, deep: true }, - orders: { handler() { this.updateOption() }, deep: true }, + xLabels: { + handler() { + if (this.xLabels && this.xLabels.length > 0) { + this.updateOption() + } + }, + deep: true, + immediate: false + }, + gmv: { + handler() { + if (this.gmv && this.gmv.length > 0) { + this.updateOption() + } + }, + deep: true, + immediate: false + }, + orders: { + handler() { + if (this.orders && this.orders.length > 0) { + this.updateOption() + } + }, + deep: true, + immediate: false + }, height: { handler() { this.heightPx = `${this.height}px` @@ -38,11 +62,53 @@ export default { mounted() { this.heightPx = `${this.height}px` - this.updateOption() + // 延迟初始化,确保 props 已传递 + setTimeout(() => { + if (this.xLabels && this.xLabels.length > 0 && this.gmv && this.gmv.length > 0) { + this.updateOption() + } + }, 100) }, methods: { + // 工具函数:将 UTS 对象转换为纯 JavaScript 对象 + toPlainObject(obj: any): any { + if (obj == null) return null + if (typeof obj !== 'object') return obj + if (Array.isArray(obj)) { + return obj.map((item) => this.toPlainObject(item)) + } + const plain: any = {} + for (const key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) { + const value = obj[key] + if (typeof value === 'function' || key.startsWith('_') || key === 'toJSON') { + continue + } + if (value != null && typeof value === 'object' && !Array.isArray(value)) { + let isSimple = true + for (const k in value) { + if (typeof value[k] === 'object' && value[k] !== null) { + isSimple = false + break + } + } + plain[key] = isSimple ? { ...value } : this.toPlainObject(value) + } else { + plain[key] = value + } + } + } + return plain + }, + updateOption() { + // 检查数据是否有效 + if (!this.xLabels || !this.gmv || !this.orders || + this.xLabels.length === 0 || this.gmv.length === 0 || this.orders.length === 0) { + return + } + const x = (this.xLabels as Array).map((s) => String(s)) const bar = (this.gmv as Array).map((v) => { const n = Number(v) @@ -53,7 +119,8 @@ export default { return isFinite(n) ? n : 0 }) - this.chartOption = { + // 构建图表配置并转换为纯 JS 对象 + const option = { grid: { left: 60, right: 60, top: 70, bottom: 40 }, tooltip: { trigger: 'axis', @@ -154,6 +221,9 @@ export default { } ] } + + // 转换为纯 JS 对象确保 ECharts 能正确接收 + this.chartOption = this.toPlainObject(option) } } } @@ -162,9 +232,15 @@ export default { diff --git a/components/analytics/AnalyticsRegionMap.uvue b/components/analytics/AnalyticsRegionMap.uvue new file mode 100644 index 00000000..6b98d489 --- /dev/null +++ b/components/analytics/AnalyticsRegionMap.uvue @@ -0,0 +1,379 @@ + + + + + diff --git a/components/supadb/aksupa.uts b/components/supadb/aksupa.uts index 50f67294..a70170ea 100644 --- a/components/supadb/aksupa.uts +++ b/components/supadb/aksupa.uts @@ -769,7 +769,7 @@ async select(table : string, filter ?: string | null, options ?: AkSupaSelectOpt //console.log(url) // 确定HTTP方法:如果是head模式,使用HEAD方法 - let httpMethod = 'GET'; + let httpMethod: 'GET' | 'HEAD' = 'GET'; if (options != null && options.head == true) { httpMethod = 'HEAD'; //console.log('使用 HEAD 方法进行 count 查询'); diff --git a/pages/mall/analytics/index.uvue b/pages/mall/analytics/index.uvue index de0c6998..f61591b8 100644 --- a/pages/mall/analytics/index.uvue +++ b/pages/mall/analytics/index.uvue @@ -31,10 +31,6 @@ 实时 GMV - - - - ¥{{ formatMoney(realTime.gmv) }} @@ -42,15 +38,11 @@ {{ formatPct(realTime.gmv_growth) }} - + 实时订单 - - - - {{ formatInt(realTime.orders) }} @@ -58,29 +50,21 @@ {{ formatPct(realTime.order_growth) }} - + 在线用户 - - - - {{ formatInt(realTime.online_users) }} 最近 5 分钟 实时 - + 转化率 - - - - {{ formatPct(realTime.conversion_rate) }} @@ -88,9 +72,9 @@ {{ formatPct(realTime.conversion_growth) }} - + - + @@ -112,70 +96,119 @@ {{ selectedPeriodText }} · 柱:GMV(元) · 线:订单数 - + + {{ loading ? '加载中...' : '暂无数据' }} + + + + - - - - 用户结构(环形图) - 未消费 / 首购 / 复购 / 回流 - - - - - - - - + + + + + + 用户结构(环形图) + 未消费 / 首购 / 复购 / 回流 + + + {{ loading ? '加载中...' : '暂无数据' }} + + + + + + + + 流量来源(条形) 占比% - - - + + + {{ loading ? '加载中...' : '暂无数据' }} + + + + + + - - - - - 热销商品 TOP - 按销量 - - - - {{ p.rank }} - {{ p.name }} - {{ p.sales }} 件 - - - + + + + + + 热销商品 TOP + 按销量 + + + + + + {{ p.rank }} + {{ p.name }} + {{ p.sales }} 件 + + + + {{ p.rank }} + {{ p.name }} + {{ p.sales }} 件 + + + + + - - - 商家排行 TOP - 按 GMV - - - - {{ m.rank }} - {{ m.name }} - - ¥{{ formatMoney(m.sales) }} - - {{ m.growth >= 0 ? '+' : '' }}{{ m.growth }}% - - - - - - - + + + + 商家排行 TOP + 按 GMV + + + + + + {{ m.rank }} + {{ m.name }} + + ¥{{ formatMoney(m.sales) }} + + {{ m.growth >= 0 ? '+' : '' }}{{ m.growth }}% + + + + + + {{ m.rank }} + {{ m.name }} + + ¥{{ formatMoney(m.sales) }} + + {{ m.growth >= 0 ? '+' : '' }}{{ m.growth }}% + + + + + + + + @@ -213,9 +246,9 @@ ⚙️ 自定义报表 创建专属报表 - - - + + + @@ -226,7 +259,7 @@ diff --git a/uni_modules/charts/EChartsView.vue b/uni_modules/charts/EChartsView.vue index 04ad80bc..4c321382 100644 --- a/uni_modules/charts/EChartsView.vue +++ b/uni_modules/charts/EChartsView.vue @@ -23,38 +23,391 @@ export default {