diff --git a/apps/web-antd/src/views/mall/home/index.vue b/apps/web-antd/src/views/mall/home/index.vue
index 21b6279b4..e398fd177 100644
--- a/apps/web-antd/src/views/mall/home/index.vue
+++ b/apps/web-antd/src/views/mall/home/index.vue
@@ -1,159 +1,45 @@
@@ -164,14 +50,71 @@ function navTo(nav: WorkbenchProjectItem | WorkbenchQuickNavItem) {
url="https://doc.iocoder.cn/mall/build/"
/>
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/web-antd/src/views/mall/home/modules/comparison-card.vue b/apps/web-antd/src/views/mall/home/modules/comparison-card.vue
new file mode 100644
index 000000000..b746dd7af
--- /dev/null
+++ b/apps/web-antd/src/views/mall/home/modules/comparison-card.vue
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+ {{ title }}
+ {{ tag }}
+
+
+
+ {{ prefix }}{{ formattedValue }}
+
+
+ {{ Math.abs(percent).toFixed(2) }}%
+
+
+
+
+
+ 昨日数据
+ {{ prefix }}{{ formattedReference }}
+
+
+
+
+
+
+
+
diff --git a/apps/web-antd/src/views/mall/home/modules/member-funnel-card.vue b/apps/web-antd/src/views/mall/home/modules/member-funnel-card.vue
new file mode 100644
index 000000000..4543c2ca5
--- /dev/null
+++ b/apps/web-antd/src/views/mall/home/modules/member-funnel-card.vue
@@ -0,0 +1,151 @@
+
+
+
+
+
+
+ 会员概览
+
+
+
+
+
+
+
+
+ 注册用户数量:{{
+ analyseData?.comparison?.value?.registerUserCount || 0
+ }}
+
+
+ 环比增长率:{{
+ calculateRelativeRate(
+ analyseData?.comparison?.value?.registerUserCount,
+ analyseData?.comparison?.reference?.registerUserCount,
+ ).toFixed(2)
+ }}%
+
+
+
+
+ {{
+ analyseData?.visitUserCount || 0
+ }}
+ 访客
+
+
+
+
+
+
+ 活跃用户数量:{{
+ analyseData?.comparison?.value?.visitUserCount || 0
+ }}
+
+
+ 环比增长率:{{
+ calculateRelativeRate(
+ analyseData?.comparison?.value?.visitUserCount,
+ analyseData?.comparison?.reference?.visitUserCount,
+ ).toFixed(2)
+ }}%
+
+
+
+
+ {{
+ analyseData?.orderUserCount || 0
+ }}
+ 下单
+
+
+
+
+
+
+
+ 充值用户数量:{{
+ analyseData?.comparison?.value?.rechargeUserCount || 0
+ }}
+
+
+ 环比增长率:{{
+ calculateRelativeRate(
+ analyseData?.comparison?.value?.rechargeUserCount,
+ analyseData?.comparison?.reference?.rechargeUserCount,
+ ).toFixed(2)
+ }}%
+
+
+
+
+ 客单价:{{ fenToYuan(analyseData?.atv || 0) }}
+
+
+
+
+
+ {{
+ analyseData?.payUserCount || 0
+ }}
+ 成交用户
+
+
+
+
+
+
+
+
diff --git a/apps/web-antd/src/views/mall/home/modules/member-statistics-card.vue b/apps/web-antd/src/views/mall/home/modules/member-statistics-card.vue
new file mode 100644
index 000000000..1cc40dac2
--- /dev/null
+++ b/apps/web-antd/src/views/mall/home/modules/member-statistics-card.vue
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/web-antd/src/views/mall/home/modules/member-statistics-chart-options.ts b/apps/web-antd/src/views/mall/home/modules/member-statistics-chart-options.ts
new file mode 100644
index 000000000..0d45d5e9c
--- /dev/null
+++ b/apps/web-antd/src/views/mall/home/modules/member-statistics-chart-options.ts
@@ -0,0 +1,59 @@
+import dayjs from 'dayjs';
+
+/**
+ * 会员统计图表配置
+ */
+export function getMemberStatisticsChartOptions(list: any[]): any {
+ return {
+ dataset: {
+ dimensions: ['date', 'count'],
+ source: list,
+ },
+ grid: {
+ left: 20,
+ right: 20,
+ bottom: 20,
+ top: 80,
+ containLabel: true,
+ },
+ legend: {
+ top: 50,
+ },
+ series: [{ name: '注册量', type: 'line', smooth: true, areaStyle: {} }],
+ toolbox: {
+ feature: {
+ // 数据区域缩放
+ dataZoom: {
+ yAxisIndex: false, // Y轴不缩放
+ },
+ brush: {
+ type: ['lineX', 'clear'], // 区域缩放按钮、还原按钮
+ },
+ saveAsImage: { show: true, name: '会员统计' }, // 保存为图片
+ },
+ },
+ tooltip: {
+ trigger: 'axis',
+ axisPointer: {
+ type: 'cross',
+ },
+ padding: [5, 10],
+ },
+ xAxis: {
+ type: 'category',
+ boundaryGap: false,
+ axisTick: {
+ show: false,
+ },
+ axisLabel: {
+ formatter: (date: string) => dayjs(date).format('MM-DD'),
+ },
+ },
+ yAxis: {
+ axisTick: {
+ show: false,
+ },
+ },
+ };
+}
+
diff --git a/apps/web-antd/src/views/mall/home/modules/member-terminal-card.vue b/apps/web-antd/src/views/mall/home/modules/member-terminal-card.vue
new file mode 100644
index 000000000..1abef2b48
--- /dev/null
+++ b/apps/web-antd/src/views/mall/home/modules/member-terminal-card.vue
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/web-antd/src/views/mall/home/modules/member-terminal-chart-options.ts b/apps/web-antd/src/views/mall/home/modules/member-terminal-chart-options.ts
new file mode 100644
index 000000000..f6077d743
--- /dev/null
+++ b/apps/web-antd/src/views/mall/home/modules/member-terminal-chart-options.ts
@@ -0,0 +1,31 @@
+/**
+ * 会员终端统计图配置
+ */
+export function getTerminalChartOptions(data: any[]): any {
+ return {
+ tooltip: {
+ trigger: 'item',
+ confine: true,
+ formatter: '{a}
{b} : {c} ({d}%)',
+ },
+ legend: {
+ orient: 'vertical',
+ left: 'right',
+ },
+ roseType: 'area',
+ series: [
+ {
+ name: '会员终端',
+ type: 'pie',
+ label: {
+ show: false,
+ },
+ labelLine: {
+ show: false,
+ },
+ data,
+ },
+ ],
+ };
+}
+
diff --git a/apps/web-antd/src/views/mall/home/modules/operation-data-card.vue b/apps/web-antd/src/views/mall/home/modules/operation-data-card.vue
new file mode 100644
index 000000000..16e0238f5
--- /dev/null
+++ b/apps/web-antd/src/views/mall/home/modules/operation-data-card.vue
@@ -0,0 +1,119 @@
+
+
+
+
+
+
+
+ {{ item.name }}
+
+
+
+
+
diff --git a/apps/web-antd/src/views/mall/home/modules/shortcut-card.vue b/apps/web-antd/src/views/mall/home/modules/shortcut-card.vue
new file mode 100644
index 000000000..07f20e1a9
--- /dev/null
+++ b/apps/web-antd/src/views/mall/home/modules/shortcut-card.vue
@@ -0,0 +1,95 @@
+
+
+
+
+
+
+
+
+
+
{{ menu.name }}
+
+
+
+
+
diff --git a/apps/web-antd/src/views/mall/home/modules/trade-trend-card.vue b/apps/web-antd/src/views/mall/home/modules/trade-trend-card.vue
new file mode 100644
index 000000000..32a5b680c
--- /dev/null
+++ b/apps/web-antd/src/views/mall/home/modules/trade-trend-card.vue
@@ -0,0 +1,203 @@
+
+
+
+
+
+
+ 交易量趋势
+
+
+ {{ value.name }}
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/web-antd/src/views/mall/home/modules/trade-trend-chart-options.ts b/apps/web-antd/src/views/mall/home/modules/trade-trend-chart-options.ts
new file mode 100644
index 000000000..12455b968
--- /dev/null
+++ b/apps/web-antd/src/views/mall/home/modules/trade-trend-chart-options.ts
@@ -0,0 +1,78 @@
+import dayjs from 'dayjs';
+
+/**
+ * 交易量趋势图表配置
+ */
+export function getTradeTrendChartOptions(
+ dates: string[],
+ series: any[],
+ timeRangeType: number,
+): any {
+ return {
+ grid: {
+ left: 20,
+ right: 20,
+ bottom: 20,
+ top: 80,
+ containLabel: true,
+ },
+ legend: {
+ top: 50,
+ data: series.map((item) => item.name),
+ },
+ series,
+ toolbox: {
+ feature: {
+ // 数据区域缩放
+ dataZoom: {
+ yAxisIndex: false, // Y轴不缩放
+ },
+ brush: {
+ type: ['lineX', 'clear'], // 区域缩放按钮、还原按钮
+ },
+ saveAsImage: { show: true, name: '订单量趋势' }, // 保存为图片
+ },
+ },
+ tooltip: {
+ trigger: 'axis',
+ axisPointer: {
+ type: 'cross',
+ },
+ padding: [5, 10],
+ },
+ xAxis: {
+ type: 'category',
+ inverse: true,
+ boundaryGap: false,
+ axisTick: {
+ show: false,
+ },
+ data: dates,
+ axisLabel: {
+ formatter: (date: string) => {
+ switch (timeRangeType) {
+ case 1: // DAY30
+ return dayjs(date).format('MM-DD');
+ case 7: // WEEK
+ {
+ const weekDay = dayjs(date).day();
+ return weekDay === 0 ? '周日' : `周${weekDay}`;
+ }
+ case 30: // MONTH
+ return dayjs(date).format('D');
+ case 365: // YEAR
+ return dayjs(date).format('M') + '月';
+ default:
+ return date;
+ }
+ },
+ },
+ },
+ yAxis: {
+ axisTick: {
+ show: false,
+ },
+ },
+ };
+}
+