From 15c200aa7e0ced518364a68769503472b542c9f4 Mon Sep 17 00:00:00 2001 From: Administrator <15274802129@163.com> Date: Tue, 08 Jul 2025 14:03:57 +0800 Subject: [PATCH] feat(mall): 添加会员数据统计功能 --- src/main/java/cc/mrbird/febs/mall/controller/member/AdminMallMemberController.java | 12 ++ src/main/resources/templates/febs/views/modules/mallMember/dataInfo.html | 222 +++++++++++++++++++++++++++++++++++++ src/main/java/cc/mrbird/febs/mall/controller/member/ViewMallMemberController.java | 10 + src/main/java/cc/mrbird/febs/mall/vo/AdminDataInfoVo.java | 20 +++ src/main/java/cc/mrbird/febs/mall/service/IAdminMallMemberService.java | 2 src/main/java/cc/mrbird/febs/mall/service/impl/AdminMallMemberServiceImpl.java | 41 ++++++ src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallMemberServiceImpl.java | 9 + 7 files changed, 316 insertions(+), 0 deletions(-) diff --git a/src/main/java/cc/mrbird/febs/mall/controller/member/AdminMallMemberController.java b/src/main/java/cc/mrbird/febs/mall/controller/member/AdminMallMemberController.java index d6d33f8..6c75d69 100644 --- a/src/main/java/cc/mrbird/febs/mall/controller/member/AdminMallMemberController.java +++ b/src/main/java/cc/mrbird/febs/mall/controller/member/AdminMallMemberController.java @@ -4,25 +4,31 @@ import cc.mrbird.febs.common.controller.BaseController; import cc.mrbird.febs.common.entity.FebsResponse; import cc.mrbird.febs.common.entity.QueryRequest; +import cc.mrbird.febs.common.enumerates.OrderPayMethodEnum; +import cc.mrbird.febs.common.enumerates.OrderStatusEnum; import cc.mrbird.febs.mall.dto.*; import cc.mrbird.febs.mall.entity.*; import cc.mrbird.febs.mall.service.IAdminMallMemberService; import cc.mrbird.febs.mall.service.IApiMallMemberService; import cc.mrbird.febs.mall.vo.*; +import cc.mrbird.febs.system.entity.User; import cc.mrbird.febs.vip.entity.MallVipBenefitsRecord; import cc.mrbird.febs.vip.mapper.MallVipBenefitsRecordMapper; import cc.mrbird.febs.vip.service.IMallVipBenefitsService; import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; +import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import java.util.Date; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -38,6 +44,12 @@ private final IMallVipBenefitsService mallVipBenefitsService; private final MallVipBenefitsRecordMapper mallVipBenefitsRecordMapper; + @GetMapping("dataInfo") + public FebsResponse dataInfo() { + + return mallMemberService.dataInfo(); + } + /** * 平台账单 * diff --git a/src/main/java/cc/mrbird/febs/mall/controller/member/ViewMallMemberController.java b/src/main/java/cc/mrbird/febs/mall/controller/member/ViewMallMemberController.java index 345f802..614e08d 100644 --- a/src/main/java/cc/mrbird/febs/mall/controller/member/ViewMallMemberController.java +++ b/src/main/java/cc/mrbird/febs/mall/controller/member/ViewMallMemberController.java @@ -40,6 +40,16 @@ * 平台账单 * @return */ + @GetMapping("dataInfo") + @RequiresPermissions("dataInfo:view") + public String dataInfo() { + return FebsUtil.view("modules/mallMember/dataInfo"); + } + + /** + * 平台账单 + * @return + */ @GetMapping("mallDataList") @RequiresPermissions("mallDataList:view") public String mallDataList() { diff --git a/src/main/java/cc/mrbird/febs/mall/service/IAdminMallMemberService.java b/src/main/java/cc/mrbird/febs/mall/service/IAdminMallMemberService.java index c762a22..89b6b37 100644 --- a/src/main/java/cc/mrbird/febs/mall/service/IAdminMallMemberService.java +++ b/src/main/java/cc/mrbird/febs/mall/service/IAdminMallMemberService.java @@ -145,4 +145,6 @@ FebsResponse checkOrder(Long id); FebsResponse checkLeader(Long id); + + FebsResponse dataInfo(); } diff --git a/src/main/java/cc/mrbird/febs/mall/service/impl/AdminMallMemberServiceImpl.java b/src/main/java/cc/mrbird/febs/mall/service/impl/AdminMallMemberServiceImpl.java index 254e019..fee552f 100644 --- a/src/main/java/cc/mrbird/febs/mall/service/impl/AdminMallMemberServiceImpl.java +++ b/src/main/java/cc/mrbird/febs/mall/service/impl/AdminMallMemberServiceImpl.java @@ -18,6 +18,7 @@ import cc.mrbird.febs.pay.model.MemberWithdrawalDto; import cc.mrbird.febs.pay.service.IXcxPayService; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.date.DateUnit; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.ObjectUtil; @@ -27,6 +28,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import lombok.RequiredArgsConstructor; @@ -35,6 +37,7 @@ import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; +import java.util.Arrays; import java.util.Date; import java.util.List; @@ -995,4 +998,42 @@ return new FebsResponse().success().message("操作成功"); } + + @Override + public FebsResponse dataInfo() { + AdminDataInfoVo adminDataInfoVo = new AdminDataInfoVo(); + + List<MallMember> mallMembers = this.baseMapper.selectList(null); + if(CollUtil.isNotEmpty(mallMembers)){ + adminDataInfoVo.setTotalMember(mallMembers.size()); + + adminDataInfoVo.setTotalDayMember( + Math.toIntExact(mallMembers.stream().filter(mallMember -> DateUtil.compare(mallMember.getCreatedTime(), DateUtil.beginOfDay(new Date())) >= 0).count())); + adminDataInfoVo.setTotalWeekMember( + Math.toIntExact(mallMembers.stream().filter(mallMember -> DateUtil.compare(mallMember.getCreatedTime(), DateUtil.beginOfWeek(new Date())) >= 0).count())); + adminDataInfoVo.setTotalMonthMember( + Math.toIntExact(mallMembers.stream().filter(mallMember -> DateUtil.compare(mallMember.getCreatedTime(), DateUtil.beginOfMonth(new Date())) >= 0).count())); + } + + List<Integer> typeList = Arrays.asList(ScoreFlowTypeEnum.WECHAT_PAY.getValue(), ScoreFlowTypeEnum.PAY_BALANCE.getValue()); + List<MallMoneyFlow> mallMoneyFlows = mallMoneyFlowMapper.selectList( + Wrappers.lambdaQuery(MallMoneyFlow.class) + .in(MallMoneyFlow::getType, typeList) + ); + if(CollUtil.isNotEmpty(mallMoneyFlows)){ + adminDataInfoVo.setTotalAmount(mallMoneyFlows.stream().map(MallMoneyFlow::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add).negate()); + adminDataInfoVo.setTotalDayAmount( + mallMoneyFlows.stream().filter(mallMoneyFlow -> DateUtil.compare(mallMoneyFlow.getCreatedTime(), DateUtil.beginOfDay(new Date())) >= 0) + .map(MallMoneyFlow::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add).negate()); + adminDataInfoVo.setTotalWeekAmount( + mallMoneyFlows.stream().filter(mallMoneyFlow -> DateUtil.compare(mallMoneyFlow.getCreatedTime(), DateUtil.beginOfWeek(new Date())) >= 0) + .map(MallMoneyFlow::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add).negate()); + adminDataInfoVo.setTotalMonthAmount( + mallMoneyFlows.stream().filter(mallMoneyFlow -> DateUtil.compare(mallMoneyFlow.getCreatedTime(), DateUtil.beginOfMonth(new Date())) >= 0) + .map(MallMoneyFlow::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add).negate()); + + } + + return new FebsResponse().success().data(adminDataInfoVo); + } } diff --git a/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallMemberServiceImpl.java b/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallMemberServiceImpl.java index f127194..2f722a6 100644 --- a/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallMemberServiceImpl.java +++ b/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallMemberServiceImpl.java @@ -808,6 +808,15 @@ } String phone = apiXcxSaveInfoDto.getPhone(); if(StrUtil.isNotEmpty(phone)){ + + MallMember entity = this.baseMapper.selectOne( + Wrappers.lambdaQuery(MallMember.class) + .eq(MallMember::getPhone, phone) + .last("LIMIT 1") + ); + if(ObjectUtil.isNotNull( entity) && !entity.getId().equals(memberId)){ + throw new FebsException("手机号码已使用"); + } mallMember.setPhone(phone); } String avatarUrl = apiXcxSaveInfoDto.getAvatarUrl(); diff --git a/src/main/java/cc/mrbird/febs/mall/vo/AdminDataInfoVo.java b/src/main/java/cc/mrbird/febs/mall/vo/AdminDataInfoVo.java new file mode 100644 index 0000000..0eb84b5 --- /dev/null +++ b/src/main/java/cc/mrbird/febs/mall/vo/AdminDataInfoVo.java @@ -0,0 +1,20 @@ +package cc.mrbird.febs.mall.vo; + +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class AdminDataInfoVo { + + private Integer totalMember = 0;//总数 + private Integer totalDayMember = 0;//昨日新增 + private Integer totalWeekMember = 0;//七日内新增 + private Integer totalMonthMember = 0;//30天内新增 + + private BigDecimal totalAmount = BigDecimal.ZERO;//总数 + private BigDecimal totalDayAmount = BigDecimal.ZERO;//新增 + private BigDecimal totalWeekAmount = BigDecimal.ZERO;//本周新增 + private BigDecimal totalMonthAmount = BigDecimal.ZERO;//本月新增 + +} diff --git a/src/main/resources/templates/febs/views/modules/mallMember/dataInfo.html b/src/main/resources/templates/febs/views/modules/mallMember/dataInfo.html new file mode 100644 index 0000000..cf36f4b --- /dev/null +++ b/src/main/resources/templates/febs/views/modules/mallMember/dataInfo.html @@ -0,0 +1,222 @@ +<style> + #data-info .welcome-info { + border: 1px solid #f1f1f1; + margin-bottom: .5rem; + padding: .5rem; + background: #FFFFFF; + } + + #data-info .welcome-info-wrapper { + padding: .2rem; + display: inline-block + } + + #data-info .welcome-info-wrapper .user-header { + display: inline-block; + vertical-align: middle + } + + #data-info .welcome-info-wrapper .user-header img { + width: 5rem; + margin: .5rem 1rem; + border-radius: 50% + } + + #data-info .welcome-info-wrapper .user-info { + display: inline-block; + vertical-align: middle + } + + #data-info .welcome-info-wrapper .user-info .random-message { + font-size: 1rem; + margin-bottom: .2rem; + max-width: 21rem + } + + #data-info .welcome-info-wrapper .user-info .user-dept, #data-info .welcome-info-wrapper .user-info .user-login-info { + color: rgba(0, 0, 0, 0.45); + } + + #data-info .login-count-table { + width: 100%; + margin: 1rem; + } + + #data-info .login-count-table .count { + padding-top: .8rem; + font-size: 1rem; + font-weight: 600; + color: #1890ff + } + + #data-info .project-table { + padding: .5rem; + border: 1px solid #f1f1f1; + width: 100% + } + + #data-info .project-table-td { + padding: .5rem 0.7rem; + border: 1px solid #f1f1f1; + } + + #data-info .project-table-td a { + color: #42b983; + font-size: .9rem; + font-weight: 600; + } + + #data-info .project-desc { + color: rgba(0, 0, 0, 0.45); + } + /*.layui-card:last-child{*/ + /* background: #F8F8F8;*/ + /*}*/ + .box{ + background: #FFFFFF; + padding: 30px 30px; + border-radius: 4px; + } + .box .name{ + font-size: 14px; + color: #333333; + } + .box .num{ + font-size: 24px; + color: #1890ff; + font-weight: bold; + margin-top: 10px; + } + .m-title{ + position: relative; + font-size: 16px; + font-weight: bold; + color: #000000; + padding-left: 20px; + margin: 0 0 10px; + } + .m-title::before{ + content: ''; + position: absolute; + left: 0; + width: 4px; + height: 20px; + background: #1890ff; + } +</style> +<div class="layui-fluid layui-anim febs-anim-up" id="data-info" lay-title="数据看板"> + <div class="layui-row layui-col-space8 febs-container"> + <div class="layui-col-md12 layui-col-sm12 layui-col-xs12"> + <div class="layui-card" style="background: #F8F8F8;"> + <div class="layui-card-body layui-anim layui-anim-fadein"> + </div> + + <div class="layui-card-body layui-anim layui-anim-fadein"> + <div class="layui-row"> + <div class="m-title">会员注册</div> + <div class="layui-row layui-col-space15"> + <div class="layui-col-md3"> + <div class="layui-panel"> + <div class="box"> + <p class="name">总计</p> + <p class="num"><span id="totalMember"></span></p> + </div> + </div> + </div> + <div class="layui-col-md3"> + <div class="layui-panel"> + <div class="box"> + <p class="name">今日新增</p> + <p class="num"><span id="totalDayMember"></span></p> + </div> + </div> + </div> + <div class="layui-col-md3"> + <div class="layui-panel"> + <div class="box"> + <p class="name">本周新增</p> + <p class="num"><span id="totalWeekMember"></span></p> + </div> + </div> + </div> + <div class="layui-col-md3"> + <div class="layui-panel"> + <div class="box"> + <p class="name">本月新增</p> + <p class="num"><span id="totalMonthMember"></span></p> + </div> + </div> + </div> + </div> + </div> + </div> + + <div class="layui-card-body layui-anim layui-anim-fadein"> + <div class="layui-row"> + <div class="m-title">交易数据</div> + <div class="layui-row layui-col-space15"> + <div class="layui-col-md3"> + <div class="layui-panel"> + <div class="box"> + <p class="name">累计</p> + <p class="num"><span id="totalAmount"></span></p> + </div> + </div> + </div> + <div class="layui-col-md3"> + <div class="layui-panel"> + <div class="box"> + <p class="name">今日新增</p> + <p class="num"><span id="totalDayAmount"></span></p> + </div> + </div> + </div> + <div class="layui-col-md3"> + <div class="layui-panel"> + <div class="box"> + <p class="name">本周新增</p> + <p class="num"><span id="totalWeekAmount"></span></p> + </div> + </div> + </div> + <div class="layui-col-md3"> + <div class="layui-panel"> + <div class="box"> + <p class="name">本月新增</p> + <p class="num"><span id="totalMonthAmount"></span></p> + </div> + </div> + </div> + </div> + </div> + </div> + + + + </div> + </div> + </div> +</div> +<script data-th-inline="javascript" type="text/javascript"> + layui.use(['apexcharts', 'febs', 'jquery', 'util'], function () { + var $ = layui.jquery, + util = layui.util, + $view = $('#data-info'), + febs = layui.febs; + + febs.get(ctx + 'admin/mallMember/dataInfo', null, function (r) { + handleSuccess(r.data); + }); + + function handleSuccess(data) { + $view.find('#totalMember').text(data.totalMember).end() + .find('#totalDayMember').text(data.totalDayMember).end() + .find('#totalWeekMember').text(data.totalWeekMember).end() + .find('#totalMonthMember').text(data.totalMonthMember).end() + .find('#totalAmount').text(data.totalAmount).end() + .find('#totalDayAmount').text(data.totalDayAmount).end() + .find('#totalWeekAmount').text(data.totalWeekAmount).end() + .find('#totalMonthAmount').text(data.totalMonthAmount).end(); + } + }); +</script> -- Gitblit v1.9.1