From f832d26a0d12cc4751786eab27146e16ea452f32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BB=AE=E6=A2=A6?= Date: Mon, 25 Sep 2023 16:04:32 +0800 Subject: [PATCH 01/10] =?UTF-8?q?=E7=AB=99=E5=86=85=E4=BF=A1=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E5=A2=9E=E5=8A=A0=20Member=20=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../template/NotifyTemplateSendForm.vue | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/views/system/notify/template/NotifyTemplateSendForm.vue b/src/views/system/notify/template/NotifyTemplateSendForm.vue index 78103d71..964f6b98 100644 --- a/src/views/system/notify/template/NotifyTemplateSendForm.vue +++ b/src/views/system/notify/template/NotifyTemplateSendForm.vue @@ -15,7 +15,21 @@ type="textarea" /> - + + + + {{ dict.label }} + + + + + + + import * as UserApi from '@/api/system/user' import * as NotifyTemplateApi from '@/api/system/notify/template' +import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' defineOptions({ name: 'SystemNotifyTemplateSendForm' }) @@ -57,6 +72,7 @@ const formData = ref({ content: '', params: {}, userId: null, + userType: 1, templateCode: '', templateParams: new Map() }) @@ -122,7 +138,8 @@ const resetForm = () => { params: {}, mobile: '', templateCode: '', - templateParams: new Map() + templateParams: new Map(), + userType: 1 } as any formRef.value?.resetFields() } From 36bb90fbb8246fc7e40b3f0794fc4600d50cc6ff Mon Sep 17 00:00:00 2001 From: puhui999 Date: Sun, 15 Oct 2023 00:54:28 +0800 Subject: [PATCH 02/10] =?UTF-8?q?=E8=90=A5=E9=94=80=E6=B4=BB=E5=8A=A8?= =?UTF-8?q?=EF=BC=9A=E6=96=B0=E5=A2=9E=E6=96=87=E7=AB=A0=E5=88=86=E7=B1=BB?= =?UTF-8?q?=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mall/promotion/articleCategory/index.ts | 39 +++ .../articleCategory/ArticleCategoryForm.vue | 117 +++++++++ .../mall/promotion/articleCategory/index.vue | 225 ++++++++++++++++++ 3 files changed, 381 insertions(+) create mode 100644 src/api/mall/promotion/articleCategory/index.ts create mode 100644 src/views/mall/promotion/articleCategory/ArticleCategoryForm.vue create mode 100644 src/views/mall/promotion/articleCategory/index.vue diff --git a/src/api/mall/promotion/articleCategory/index.ts b/src/api/mall/promotion/articleCategory/index.ts new file mode 100644 index 00000000..5795a41b --- /dev/null +++ b/src/api/mall/promotion/articleCategory/index.ts @@ -0,0 +1,39 @@ +import request from '@/config/axios' + +export interface ArticleCategoryVO { + id: number + name: string + picUrl: string + status: number + sort: number +} + +// 查询分类列表 +export const getArticleCategoryPage = async (params) => { + return await request.get({ url: `/promotion/article-category/page`, params }) +} + +// 查询分类详情 +export const getArticleCategory = async (id: number) => { + return await request.get({ url: `/promotion/article-category/get?id=` + id }) +} + +// 新增分类 +export const createArticleCategory = async (data: ArticleCategoryVO) => { + return await request.post({ url: `/promotion/article-category/create`, data }) +} + +// 修改分类 +export const updateArticleCategory = async (data: ArticleCategoryVO) => { + return await request.put({ url: `/promotion/article-category/update`, data }) +} + +// 删除分类 +export const deleteArticleCategory = async (id: number) => { + return await request.delete({ url: `/promotion/article-category/delete?id=` + id }) +} + +// 导出分类 Excel +export const exportArticleCategory = async (params) => { + return await request.download({ url: `/promotion/article-category/export-excel`, params }) +} diff --git a/src/views/mall/promotion/articleCategory/ArticleCategoryForm.vue b/src/views/mall/promotion/articleCategory/ArticleCategoryForm.vue new file mode 100644 index 00000000..4b7f2948 --- /dev/null +++ b/src/views/mall/promotion/articleCategory/ArticleCategoryForm.vue @@ -0,0 +1,117 @@ + + diff --git a/src/views/mall/promotion/articleCategory/index.vue b/src/views/mall/promotion/articleCategory/index.vue new file mode 100644 index 00000000..d201b3a3 --- /dev/null +++ b/src/views/mall/promotion/articleCategory/index.vue @@ -0,0 +1,225 @@ + + + From befffb3f7d7f94f1c4028b0dea595b43bb67d356 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Sun, 15 Oct 2023 16:14:09 +0800 Subject: [PATCH 03/10] =?UTF-8?q?=E8=90=A5=E9=94=80=E6=B4=BB=E5=8A=A8?= =?UTF-8?q?=EF=BC=9A=E6=96=B0=E5=A2=9E=E6=96=87=E7=AB=A0=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/mall/product/spu.ts | 2 +- src/api/mall/promotion/article/index.ts | 47 +++ .../mall/promotion/articleCategory/index.ts | 17 +- .../mall/promotion/article/ArticleForm.vue | 236 +++++++++++++ .../category}/ArticleCategoryForm.vue | 2 + .../category}/index.vue | 2 +- src/views/mall/promotion/article/index.vue | 321 ++++++++++++++++++ 7 files changed, 619 insertions(+), 8 deletions(-) create mode 100644 src/api/mall/promotion/article/index.ts create mode 100644 src/views/mall/promotion/article/ArticleForm.vue rename src/views/mall/promotion/{articleCategory => article/category}/ArticleCategoryForm.vue (98%) rename src/views/mall/promotion/{articleCategory => article/category}/index.vue (99%) create mode 100644 src/views/mall/promotion/article/index.vue diff --git a/src/api/mall/product/spu.ts b/src/api/mall/product/spu.ts index c78bef47..5cc4d8fe 100644 --- a/src/api/mall/product/spu.ts +++ b/src/api/mall/product/spu.ts @@ -104,5 +104,5 @@ export const exportSpu = async (params) => { // 获得商品 SPU 精简列表 export const getSpuSimpleList = async () => { - return request.get({ url: '/product/spu/get-simple-list' }) + return request.get({ url: '/product/spu/list-all-simple' }) } diff --git a/src/api/mall/promotion/article/index.ts b/src/api/mall/promotion/article/index.ts new file mode 100644 index 00000000..c2941d05 --- /dev/null +++ b/src/api/mall/promotion/article/index.ts @@ -0,0 +1,47 @@ +import request from '@/config/axios' + +export interface ArticleVO { + id: number + categoryId: number + title: string + author: string + picUrl: string + introduction: string + browseCount: string + sort: number + status: number + spuId: number + recommendHot: boolean + recommendBanner: boolean + content: string +} + +// 查询文章管理列表 +export const getArticlePage = async (params) => { + return await request.get({ url: `/promotion/article/page`, params }) +} + +// 查询文章管理详情 +export const getArticle = async (id: number) => { + return await request.get({ url: `/promotion/article/get?id=` + id }) +} + +// 新增文章管理 +export const createArticle = async (data: ArticleVO) => { + return await request.post({ url: `/promotion/article/create`, data }) +} + +// 修改文章管理 +export const updateArticle = async (data: ArticleVO) => { + return await request.put({ url: `/promotion/article/update`, data }) +} + +// 删除文章管理 +export const deleteArticle = async (id: number) => { + return await request.delete({ url: `/promotion/article/delete?id=` + id }) +} + +// 导出文章管理 Excel +export const exportArticle = async (params) => { + return await request.download({ url: `/promotion/article/export-excel`, params }) +} diff --git a/src/api/mall/promotion/articleCategory/index.ts b/src/api/mall/promotion/articleCategory/index.ts index 5795a41b..2950d759 100644 --- a/src/api/mall/promotion/articleCategory/index.ts +++ b/src/api/mall/promotion/articleCategory/index.ts @@ -8,32 +8,37 @@ export interface ArticleCategoryVO { sort: number } -// 查询分类列表 +// 查询文章分类列表 export const getArticleCategoryPage = async (params) => { return await request.get({ url: `/promotion/article-category/page`, params }) } -// 查询分类详情 +// 查询文章分类精简信息列表 +export const getSimpleArticleCategoryList = async () => { + return await request.get({ url: `/promotion/article-category/list-all-simple` }) +} + +// 查询文章分类详情 export const getArticleCategory = async (id: number) => { return await request.get({ url: `/promotion/article-category/get?id=` + id }) } -// 新增分类 +// 新增文章分类 export const createArticleCategory = async (data: ArticleCategoryVO) => { return await request.post({ url: `/promotion/article-category/create`, data }) } -// 修改分类 +// 修改文章分类 export const updateArticleCategory = async (data: ArticleCategoryVO) => { return await request.put({ url: `/promotion/article-category/update`, data }) } -// 删除分类 +// 删除文章分类 export const deleteArticleCategory = async (id: number) => { return await request.delete({ url: `/promotion/article-category/delete?id=` + id }) } -// 导出分类 Excel +// 导出文章分类 Excel export const exportArticleCategory = async (params) => { return await request.download({ url: `/promotion/article-category/export-excel`, params }) } diff --git a/src/views/mall/promotion/article/ArticleForm.vue b/src/views/mall/promotion/article/ArticleForm.vue new file mode 100644 index 00000000..36fc1340 --- /dev/null +++ b/src/views/mall/promotion/article/ArticleForm.vue @@ -0,0 +1,236 @@ + + diff --git a/src/views/mall/promotion/articleCategory/ArticleCategoryForm.vue b/src/views/mall/promotion/article/category/ArticleCategoryForm.vue similarity index 98% rename from src/views/mall/promotion/articleCategory/ArticleCategoryForm.vue rename to src/views/mall/promotion/article/category/ArticleCategoryForm.vue index 4b7f2948..39b1fc0f 100644 --- a/src/views/mall/promotion/articleCategory/ArticleCategoryForm.vue +++ b/src/views/mall/promotion/article/category/ArticleCategoryForm.vue @@ -38,6 +38,8 @@ import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' import * as ArticleCategoryApi from '@/api/mall/promotion/articleCategory' +defineOptions({ name: 'PromotionArticleCategoryForm' }) + const { t } = useI18n() // 国际化 const message = useMessage() // 消息弹窗 diff --git a/src/views/mall/promotion/articleCategory/index.vue b/src/views/mall/promotion/article/category/index.vue similarity index 99% rename from src/views/mall/promotion/articleCategory/index.vue rename to src/views/mall/promotion/article/category/index.vue index d201b3a3..32d385c3 100644 --- a/src/views/mall/promotion/articleCategory/index.vue +++ b/src/views/mall/promotion/article/category/index.vue @@ -135,7 +135,7 @@ import * as ArticleCategoryApi from '@/api/mall/promotion/articleCategory' import ArticleCategoryForm from './ArticleCategoryForm.vue' import { createImageViewer } from '@/components/ImageViewer' -defineOptions({ name: 'ArticleCategory' }) +defineOptions({ name: 'PromotionArticleCategory' }) const message = useMessage() // 消息弹窗 const { t } = useI18n() // 国际化 diff --git a/src/views/mall/promotion/article/index.vue b/src/views/mall/promotion/article/index.vue new file mode 100644 index 00000000..7f5f4b70 --- /dev/null +++ b/src/views/mall/promotion/article/index.vue @@ -0,0 +1,321 @@ + + + From 3802fee661b59cb43f07b3b44a8f8e94a500d111 Mon Sep 17 00:00:00 2001 From: owen Date: Mon, 16 Oct 2023 09:51:19 +0800 Subject: [PATCH 04/10] =?UTF-8?q?=E5=95=86=E5=9F=8E=EF=BC=9A=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E5=95=86=E5=9F=8E=E9=A6=96=E9=A1=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/mall/statistics/member.ts | 32 +++ src/api/mall/statistics/pay.ts | 6 + src/api/mall/statistics/trade.ts | 54 +++++ .../ShortcutDateRangePicker/index.vue | 89 ++++++++ src/utils/index.ts | 13 ++ .../mall/home/components/ComparisonCard.vue | 42 ++++ .../home/components/MemberStatisticsCard.vue | 91 ++++++++ .../home/components/OperationDataCard.vue | 91 ++++++++ .../mall/home/components/ShortcutCard.vue | 79 +++++++ .../mall/home/components/TradeTrendCard.vue | 208 +++++++++++++++++ src/views/mall/home/index.vue | 113 ++++++++++ .../member/components/MemberFunnelCard.vue | 119 ++++++++++ .../member/components/MemberTerminalCard.vue | 69 ++++++ src/views/mall/statistics/member/index.vue | 213 ++---------------- src/views/mall/statistics/trade/index.vue | 94 +------- 15 files changed, 1038 insertions(+), 275 deletions(-) create mode 100644 src/api/mall/statistics/pay.ts create mode 100644 src/components/ShortcutDateRangePicker/index.vue create mode 100644 src/views/mall/home/components/ComparisonCard.vue create mode 100644 src/views/mall/home/components/MemberStatisticsCard.vue create mode 100644 src/views/mall/home/components/OperationDataCard.vue create mode 100644 src/views/mall/home/components/ShortcutCard.vue create mode 100644 src/views/mall/home/components/TradeTrendCard.vue create mode 100644 src/views/mall/home/index.vue create mode 100644 src/views/mall/statistics/member/components/MemberFunnelCard.vue create mode 100644 src/views/mall/statistics/member/components/MemberTerminalCard.vue diff --git a/src/api/mall/statistics/member.ts b/src/api/mall/statistics/member.ts index d4680d3d..e0d77e40 100644 --- a/src/api/mall/statistics/member.ts +++ b/src/api/mall/statistics/member.ts @@ -54,6 +54,20 @@ export interface MemberTerminalStatisticsRespVO { userCount: number } +/** 会员数量统计 Response VO */ +export interface MemberCountRespVO { + /** 用户访问量 */ + visitUserCount: string + /** 新增用户数量 */ + createUserCount: number +} + +/** 会员注册数量 Response VO */ +export interface MemberRegisterCountRespVO { + date: string + count: number +} + // 查询会员统计 export const getMemberSummary = () => { return request.get({ @@ -89,3 +103,21 @@ export const getMemberTerminalStatisticsList = () => { url: '/statistics/member/get-terminal-statistics-list' }) } + +// 获得用户数量量对照 +export const getUserCountComparison = () => { + return request.get>({ + url: '/statistics/member/user-count-comparison' + }) +} + +// 获得会员注册数量列表 +export const getMemberRegisterCountList = ( + beginTime: dayjs.ConfigType, + endTime: dayjs.ConfigType +) => { + return request.get({ + url: '/statistics/member/register-count-list', + params: { times: [formatDate(beginTime), formatDate(endTime)] } + }) +} diff --git a/src/api/mall/statistics/pay.ts b/src/api/mall/statistics/pay.ts new file mode 100644 index 00000000..1593f38d --- /dev/null +++ b/src/api/mall/statistics/pay.ts @@ -0,0 +1,6 @@ +import request from '@/config/axios' + +/** 获取钱包充值金额 */ +export const getWalletRechargePrice = async () => { + return await request.get({ url: `/statistics/pay/wallet-recharge-price` }) +} diff --git a/src/api/mall/statistics/trade.ts b/src/api/mall/statistics/trade.ts index f7829ccb..76da08ca 100644 --- a/src/api/mall/statistics/trade.ts +++ b/src/api/mall/statistics/trade.ts @@ -33,6 +33,36 @@ export interface TradeTrendSummaryRespVO { orderRefundPrice: number } +/** 交易订单数量 Response VO */ +export interface TradeOrderCountRespVO { + /** 待发货 */ + undelivered?: number + /** 待核销 */ + pickUp?: number + /** 退款中 */ + afterSaleApply?: number + /** 提现待审核 */ + auditingWithdraw?: number +} + +/** 交易订单统计 Response VO */ +export interface TradeOrderSummaryRespVO { + /** 支付订单商品数 */ + orderPayCount?: number + /** 总支付金额,单位:分 */ + orderPayPrice?: number +} + +/** 订单量趋势统计 Response VO */ +export interface TradeOrderTrendRespVO { + /** 日期 */ + date: string + /** 订单数量 */ + orderPayCount: number + /** 订单支付金额 */ + orderPayPrice: number +} + // 查询交易统计 export const getTradeStatisticsSummary = () => { return request.get>({ @@ -64,6 +94,30 @@ export const exportTradeTrend = (params: TradeTrendReqVO) => { }) } +// 获得交易订单数量 +export const getOrderCount = async () => { + return await request.get({ url: `/statistics/trade/order-count` }) +} + +// 获得交易订单数量对照 +export const getOrderComparison = async () => { + return await request.get>({ + url: `/statistics/trade/order-comparison` + }) +} + +// 获得订单量趋势统计 +export const getOrderCountTrendComparison = ( + type: number, + beginTime: dayjs.ConfigType, + endTime: dayjs.ConfigType +) => { + return request.get[]>({ + url: '/statistics/trade/order-count-trend', + params: { type, beginTime: formatDate(beginTime), endTime: formatDate(endTime) } + }) +} + /** 时间参数需要格式化, 确保接口能识别 */ const formatDateParam = (params: TradeTrendReqVO) => { return { times: [formatDate(params.times[0]), formatDate(params.times[1])] } as TradeTrendReqVO diff --git a/src/components/ShortcutDateRangePicker/index.vue b/src/components/ShortcutDateRangePicker/index.vue new file mode 100644 index 00000000..d7fa90cb --- /dev/null +++ b/src/components/ShortcutDateRangePicker/index.vue @@ -0,0 +1,89 @@ + + diff --git a/src/utils/index.ts b/src/utils/index.ts index 6c9a5df2..e6b3173c 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -233,3 +233,16 @@ export const yuanToFen = (amount: string | number): number => { export const fenToYuan = (price: string | number): number => { return formatToFraction(price) } + +/** + * 计算环比 + * + * @param value 当前数值 + * @param reference 对比数值 + */ +export const calculateRelativeRate = (value?: number, reference?: number) => { + // 防止除0 + if (!reference) return 0 + + return ((100 * ((value || 0) - reference)) / reference).toFixed(0) +} diff --git a/src/views/mall/home/components/ComparisonCard.vue b/src/views/mall/home/components/ComparisonCard.vue new file mode 100644 index 00000000..ee1c2f0c --- /dev/null +++ b/src/views/mall/home/components/ComparisonCard.vue @@ -0,0 +1,42 @@ + + diff --git a/src/views/mall/home/components/MemberStatisticsCard.vue b/src/views/mall/home/components/MemberStatisticsCard.vue new file mode 100644 index 00000000..2f9d7ab5 --- /dev/null +++ b/src/views/mall/home/components/MemberStatisticsCard.vue @@ -0,0 +1,91 @@ + + diff --git a/src/views/mall/home/components/OperationDataCard.vue b/src/views/mall/home/components/OperationDataCard.vue new file mode 100644 index 00000000..cae09a3e --- /dev/null +++ b/src/views/mall/home/components/OperationDataCard.vue @@ -0,0 +1,91 @@ + + diff --git a/src/views/mall/home/components/ShortcutCard.vue b/src/views/mall/home/components/ShortcutCard.vue new file mode 100644 index 00000000..9fdd5cd4 --- /dev/null +++ b/src/views/mall/home/components/ShortcutCard.vue @@ -0,0 +1,79 @@ + + diff --git a/src/views/mall/home/components/TradeTrendCard.vue b/src/views/mall/home/components/TradeTrendCard.vue new file mode 100644 index 00000000..6aa9fdcc --- /dev/null +++ b/src/views/mall/home/components/TradeTrendCard.vue @@ -0,0 +1,208 @@ + + diff --git a/src/views/mall/home/index.vue b/src/views/mall/home/index.vue new file mode 100644 index 00000000..95e2e1da --- /dev/null +++ b/src/views/mall/home/index.vue @@ -0,0 +1,113 @@ + + + diff --git a/src/views/mall/statistics/member/components/MemberFunnelCard.vue b/src/views/mall/statistics/member/components/MemberFunnelCard.vue new file mode 100644 index 00000000..15c954e1 --- /dev/null +++ b/src/views/mall/statistics/member/components/MemberFunnelCard.vue @@ -0,0 +1,119 @@ + + + diff --git a/src/views/mall/statistics/member/components/MemberTerminalCard.vue b/src/views/mall/statistics/member/components/MemberTerminalCard.vue new file mode 100644 index 00000000..7bbab76c --- /dev/null +++ b/src/views/mall/statistics/member/components/MemberTerminalCard.vue @@ -0,0 +1,69 @@ + + diff --git a/src/views/mall/statistics/member/index.vue b/src/views/mall/statistics/member/index.vue index e76e861c..713f7776 100644 --- a/src/views/mall/statistics/member/index.vue +++ b/src/views/mall/statistics/member/index.vue @@ -44,118 +44,20 @@ - - -
-
-
-
-
- 注册用户数量:{{ analyseData?.comparison?.value?.userCount || 0 }} -
-
- 环比增长率:{{ - calculateRelativeRate( - analyseData?.comparison?.value?.userCount, - analyseData?.comparison?.reference?.userCount - ) - }}% -
-
-
-
- {{ analyseData?.visitorCount || 0 }} - 访客 -
-
-
-
-
-
- 活跃用户数量:{{ analyseData?.comparison?.value?.activeUserCount || 0 }} -
-
- 环比增长率:{{ - calculateRelativeRate( - analyseData?.comparison?.value?.activeUserCount, - analyseData?.comparison?.reference?.activeUserCount - ) - }}% -
-
-
-
- {{ analyseData?.orderUserCount || 0 }} - 下单 -
-
-
-
-
-
-
- 充值用户数量:{{ analyseData?.comparison?.value?.rechargeUserCount || 0 }} -
-
- 环比增长率:{{ - calculateRelativeRate( - analyseData?.comparison?.value?.rechargeUserCount, - analyseData?.comparison?.reference?.rechargeUserCount - ) - }}% -
-
-
-
客单价:{{ fenToYuan(analyseData?.atv || 0) }}
-
-
-
-
- {{ analyseData?.payUserCount || 0 }} - 成交用户 -
-
-
-
+ +
- - - + +
- + + @@ -206,7 +108,10 @@ - + + @@ -214,63 +119,34 @@