diff --git a/apps/web-ele/src/api/mall/statistics/member.ts b/apps/web-ele/src/api/mall/statistics/member.ts
index fb7a6b01..bcc99304 100644
--- a/apps/web-ele/src/api/mall/statistics/member.ts
+++ b/apps/web-ele/src/api/mall/statistics/member.ts
@@ -1,6 +1,6 @@
import type { MallDataComparisonResp } from './common';
-import { formatDate } from '@vben/utils';
+import { formatDate2 } from '@vben/utils';
import { requestClient } from '#/api/request';
@@ -84,7 +84,10 @@ export function getMemberAnalyse(params: MallMemberStatisticsApi.AnalyseReq) {
'/statistics/member/analyse',
{
params: {
- times: [formatDate(params.times[0]), formatDate(params.times[1])],
+ times: [
+ formatDate2(params.times[0] || new Date()),
+ formatDate2(params.times[1] || new Date()),
+ ],
},
},
);
@@ -124,7 +127,7 @@ export function getMemberRegisterCountList(beginTime: Date, endTime: Date) {
'/statistics/member/register-count-list',
{
params: {
- times: [formatDate(beginTime), formatDate(endTime)],
+ times: [formatDate2(beginTime), formatDate2(endTime)],
},
},
);
diff --git a/apps/web-ele/src/api/mall/statistics/trade.ts b/apps/web-ele/src/api/mall/statistics/trade.ts
index 1f866c63..151f5a4d 100644
--- a/apps/web-ele/src/api/mall/statistics/trade.ts
+++ b/apps/web-ele/src/api/mall/statistics/trade.ts
@@ -1,6 +1,6 @@
import type { MallDataComparisonResp } from './common';
-import { formatDate } from '@vben/utils';
+import { formatDate, formatDate2 } from '@vben/utils';
import { requestClient } from '#/api/request';
@@ -128,8 +128,8 @@ export function getOrderCountTrendComparison(
>('/statistics/trade/order-count-trend', {
params: {
type,
- beginTime: formatDate(beginTime),
- endTime: formatDate(endTime),
+ beginTime: formatDate2(beginTime),
+ endTime: formatDate2(endTime),
},
});
}
diff --git a/apps/web-ele/src/views/mall/home/components/member-funnel-card.vue b/apps/web-ele/src/views/mall/home/components/member-funnel-card.vue
new file mode 100644
index 00000000..d9f9b4d4
--- /dev/null
+++ b/apps/web-ele/src/views/mall/home/components/member-funnel-card.vue
@@ -0,0 +1,167 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 注册用户数量:{{
+ analyseData?.comparison?.value?.registerUserCount || 0
+ }}
+
+
+ 环比增长率:{{
+ calculateRelativeRate(
+ analyseData?.comparison?.value?.registerUserCount,
+ analyseData?.comparison?.reference?.registerUserCount,
+ )
+ }}%
+
+
+
+
+ {{
+ analyseData?.visitUserCount || 0
+ }}
+ 访客
+
+
+
+
+
+
+ 活跃用户数量:{{
+ analyseData?.comparison?.value?.visitUserCount || 0
+ }}
+
+
+ 环比增长率:{{
+ calculateRelativeRate(
+ analyseData?.comparison?.value?.visitUserCount,
+ analyseData?.comparison?.reference?.visitUserCount,
+ )
+ }}%
+
+
+
+
+ {{
+ analyseData?.orderUserCount || 0
+ }}
+ 下单
+
+
+
+
+
+
+
+ 充值用户数量:{{
+ analyseData?.comparison?.value?.rechargeUserCount || 0
+ }}
+
+
+ 环比增长率:{{
+ calculateRelativeRate(
+ analyseData?.comparison?.value?.rechargeUserCount,
+ analyseData?.comparison?.reference?.rechargeUserCount,
+ )
+ }}%
+
+
+
+
+ 客单价:{{ fenToYuan(analyseData?.atv || 0) }}
+
+
+
+
+
+ {{
+ analyseData?.payUserCount || 0
+ }}
+ 成交用户
+
+
+
+
+
+
+
diff --git a/apps/web-ele/src/views/mall/home/components/member-statistics-card.vue b/apps/web-ele/src/views/mall/home/components/member-statistics-card.vue
new file mode 100644
index 00000000..603e9bbc
--- /dev/null
+++ b/apps/web-ele/src/views/mall/home/components/member-statistics-card.vue
@@ -0,0 +1,101 @@
+
+
+
+
+
+
+
diff --git a/apps/web-ele/src/views/mall/home/components/member-terminal-card.vue b/apps/web-ele/src/views/mall/home/components/member-terminal-card.vue
new file mode 100644
index 00000000..6631ef7b
--- /dev/null
+++ b/apps/web-ele/src/views/mall/home/components/member-terminal-card.vue
@@ -0,0 +1,80 @@
+
+
+
+
+
+
diff --git a/apps/web-ele/src/views/mall/home/components/shortcut-date-range-picker.vue b/apps/web-ele/src/views/mall/home/components/shortcut-date-range-picker.vue
new file mode 100644
index 00000000..a8431d5c
--- /dev/null
+++ b/apps/web-ele/src/views/mall/home/components/shortcut-date-range-picker.vue
@@ -0,0 +1,87 @@
+
+
+
+
+ 昨天
+ 最近7天
+ 最近30天
+
+
+
+
+
diff --git a/apps/web-ele/src/views/mall/home/components/trade-trend-card.vue b/apps/web-ele/src/views/mall/home/components/trade-trend-card.vue
new file mode 100644
index 00000000..7385292b
--- /dev/null
+++ b/apps/web-ele/src/views/mall/home/components/trade-trend-card.vue
@@ -0,0 +1,226 @@
+
+
+
+
+
+
+
+
+
+ {{ value.name }}
+
+
+
+
+
+
+
+
+
diff --git a/apps/web-ele/src/views/mall/home/data.ts b/apps/web-ele/src/views/mall/home/data.ts
new file mode 100644
index 00000000..d88b257f
--- /dev/null
+++ b/apps/web-ele/src/views/mall/home/data.ts
@@ -0,0 +1,6 @@
+export enum TimeRangeTypeEnum {
+ DAY30 = 1,
+ MONTH = 30,
+ WEEK = 7,
+ YEAR = 365,
+} // 日期类型
diff --git a/apps/web-ele/src/views/mall/home/index.vue b/apps/web-ele/src/views/mall/home/index.vue
index 64cb16f2..2a4748fe 100644
--- a/apps/web-ele/src/views/mall/home/index.vue
+++ b/apps/web-ele/src/views/mall/home/index.vue
@@ -29,6 +29,11 @@ import { getUserCountComparison } from '#/api/mall/statistics/member';
import { getWalletRechargePrice } from '#/api/mall/statistics/pay';
import { getOrderComparison, getOrderCount } from '#/api/mall/statistics/trade';
+import MemberFunnelCard from './components/member-funnel-card.vue';
+import MemberStatisticsCard from './components/member-statistics-card.vue';
+import MemberTerminalCard from './components/member-terminal-card.vue';
+import TradeTrendCard from './components/trade-trend-card.vue';
+
/** 商城首页 */
defineOptions({ name: 'MallHome' });
@@ -287,7 +292,12 @@ function navTo(nav: WorkbenchProjectItem | WorkbenchQuickNavItem) {
url="https://doc.iocoder.cn/mall/build/"
/>
-
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/@core/base/shared/src/utils/date.ts b/packages/@core/base/shared/src/utils/date.ts
index b66654d0..8cc41b41 100644
--- a/packages/@core/base/shared/src/utils/date.ts
+++ b/packages/@core/base/shared/src/utils/date.ts
@@ -26,6 +26,15 @@ export function formatDateTime(time: Date | number | string | undefined) {
return formatDate(time, 'YYYY-MM-DD HH:mm:ss');
}
+export function formatDate2(date: Date, format?: string): string {
+ // 日期不存在,则返回空
+ if (!date) {
+ return '';
+ }
+ // 日期存在,则进行格式化
+ return date ? dayjs(date).format(format ?? 'YYYY-MM-DD HH:mm:ss') : '';
+}
+
export function isDate(value: any): value is Date {
return value instanceof Date;
}
diff --git a/packages/effects/common-ui/src/ui/dashboard/analysis/analysis-chart-card.vue b/packages/effects/common-ui/src/ui/dashboard/analysis/analysis-chart-card.vue
index 294d5173..87aef99c 100644
--- a/packages/effects/common-ui/src/ui/dashboard/analysis/analysis-chart-card.vue
+++ b/packages/effects/common-ui/src/ui/dashboard/analysis/analysis-chart-card.vue
@@ -15,7 +15,10 @@ withDefaults(defineProps(), {});
- {{ title }}
+
+ {{ title }}
+
+