ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/model/UserPoint.java
@@ -69,4 +69,13 @@ private String phone; @ApiModelProperty(value = "开始时间") @TableField(exist = false) private LocalDateTime startTime; @ApiModelProperty(value = "结束时间") @TableField(exist = false) private LocalDateTime endTime; } ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/UserPointController.java
@@ -1,31 +1,44 @@ package com.ruoyi.account.controller; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.account.api.model.AppUser; import com.ruoyi.account.api.model.UserPoint; import com.ruoyi.account.mapper.UserPointMapper; import com.ruoyi.account.service.AppUserService; import com.ruoyi.account.service.UserPointService; import com.ruoyi.account.vo.UserPointDetailVO; import com.ruoyi.account.vo.UserPointStatistics; import com.ruoyi.account.vo.UserPointVO; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.utils.poi.ExcelUtil; import com.ruoyi.common.core.web.controller.BaseController; import com.ruoyi.common.core.web.page.TableDataInfo; import com.ruoyi.common.security.service.TokenService; import com.ruoyi.common.security.utils.SecurityUtils; import com.ruoyi.system.api.model.LoginUser; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import io.swagger.models.auth.In; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.springframework.format.annotation.DateTimeFormat; import org.springframework.util.CollectionUtils; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import java.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.YearMonth; import java.util.List; import java.util.Map; import java.util.stream.Collectors; /** * <p> @@ -43,6 +56,8 @@ private UserPointService userPointService; @Resource private AppUserService appUserService; @Resource private TokenService tokenService; /** @@ -110,17 +125,51 @@ * 积分统计 */ @GetMapping("/statistics") @ApiOperation(value = "积分统计", tags = "管理后台-财务统计-用户积分统计") public R<UserPointStatistics> statistics(UserPoint userPoint) { List<AppUser> appUserList = appUserService.list(); Integer totalPoint = 0; Integer consumePoint = 0; Integer sharePoint = 0; List<UserPoint> userPointList = userPointService.list(); UserPointStatistics userPointStatistics = new UserPointStatistics(); userPointStatistics.setTotalPoint(totalPoint); userPointStatistics.setConsumePoint(consumePoint); userPointStatistics.setSharePoint(sharePoint); return null; return R.ok(userPointService.getStatistics(userPoint)); } /** * 变更记录 */ @GetMapping("/list") @ApiOperation(value = "积分变更记录", tags = "管理后台-财务统计-用户积分统计") public R<Page<UserPoint>> list(@ApiParam("页码") @RequestParam Integer pageNum, @ApiParam("大小") Integer pageSize, UserPoint userPoint) { List<String> userIds = appUserService.listObjs(new LambdaQueryWrapper<AppUser>() .select(AppUser::getId) .eq(AppUser::getPhone, userPoint.getPhone()) .like(AppUser::getName, userPoint.getUserName()), String::valueOf); Page<UserPoint> page = userPointService.page(Page.of(pageNum, pageSize), new LambdaQueryWrapper<UserPoint>() .in(!CollectionUtils.isEmpty(userIds), UserPoint::getAppUserId, userIds) .eq(UserPoint::getType, userPoint.getType()) .between(UserPoint::getCreateTime, userPoint.getStartTime(), userPoint.getEndTime()) .orderByDesc(UserPoint::getCreateTime)); return R.ok(page); } /** * 导出 */ @GetMapping("/export") @ApiOperation(value = "积分变更记录导出", tags = "管理后台-财务统计-用户积分统计") public void export(HttpServletResponse response, UserPoint userPoint) { List<String> userIds = appUserService.listObjs(new LambdaQueryWrapper<AppUser>() .select(AppUser::getId) .eq(AppUser::getPhone, userPoint.getPhone()) .like(AppUser::getName, userPoint.getUserName()), String::valueOf); List<UserPoint> userPointList = userPointService.list(new LambdaQueryWrapper<UserPoint>() .in(!CollectionUtils.isEmpty(userIds), UserPoint::getAppUserId, userIds) .eq(UserPoint::getType, userPoint.getType()) .between(UserPoint::getCreateTime, userPoint.getStartTime(), userPoint.getEndTime()) .orderByDesc(UserPoint::getCreateTime)); ExcelUtil<UserPoint> util = new ExcelUtil<UserPoint>(UserPoint.class); util.exportExcel(response, userPointList, "用户积分统计"); } } ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/mapper/UserPointMapper.java
@@ -16,4 +16,7 @@ public interface UserPointMapper extends BaseMapper<UserPoint> { List<UserPoint> findLatestUserPointByTypeForUser(Long userId); List<UserPoint> findLatestChangeByType(UserPoint userPoint); } ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/UserPointService.java
@@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.account.api.model.UserPoint; import com.ruoyi.account.vo.UserPointDetailVO; import com.ruoyi.account.vo.UserPointStatistics; import com.ruoyi.account.vo.UserPointVO; import java.math.BigDecimal; @@ -25,4 +26,6 @@ List<UserPointDetailVO> getUserPointDetail(Long userId, LocalDateTime startTime, LocalDateTime endTime, Integer type); void transferPoint(BigDecimal point, String phone); UserPointStatistics getStatistics(UserPoint userPoint); } ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/UserPointServiceImpl.java
@@ -12,6 +12,7 @@ import com.ruoyi.account.service.UserPointService; import com.ruoyi.account.service.VipSettingService; import com.ruoyi.account.vo.UserPointDetailVO; import com.ruoyi.account.vo.UserPointStatistics; import com.ruoyi.account.vo.UserPointVO; import com.ruoyi.common.core.exception.ServiceException; import com.ruoyi.common.core.utils.PhoneNumberValidator; @@ -51,6 +52,8 @@ private VipSettingService vipSettingService; @Resource private PointSettingService pointSettingService; @Resource private UserPointMapper userPointMapper; @Override public UserPointVO getUserPoint(Long userId) { @@ -121,8 +124,9 @@ } Integer buyPointOpen = pointSetting.getBuyPointOpen(); List<UserPoint> userPointList = list(new LambdaQueryWrapper<UserPoint>() .eq(UserPoint::getAppUserId, userid)); UserPoint userPoint = new UserPoint(); userPoint.setAppUserId(userid); List<UserPoint> userPointList = userPointMapper.findLatestChangeByType(userPoint); Map<Integer, Integer> userBalanceMap = userPointList.stream() .collect(Collectors.toMap(UserPoint::getType, UserPoint::getBalance)); @@ -155,4 +159,36 @@ private int getAdjustedPoint(Map<Integer, Integer> userBalanceMap, int pointTypeCode, boolean isOpen) { return isOpen ? 0 : Optional.ofNullable(userBalanceMap.get(pointTypeCode)).orElse(0); } @Override public UserPointStatistics getStatistics(UserPoint userPoint) { LoginUser loginUser = tokenService.getLoginUser(); userPoint.setAppUserId(loginUser.getUserid()); List<UserPoint> userPointList = userPointMapper.findLatestChangeByType(userPoint); Map<Integer, Integer> userBalanceMap = userPointList.stream() .collect(Collectors.toMap(UserPoint::getType, UserPoint::getBalance)); Integer consumePoint = Optional.ofNullable(userBalanceMap.get(PointChangeType.CONSUME.getCode())).orElse(0); Integer sharePoint = Optional.ofNullable(userBalanceMap.get(PointChangeType.COMMISSION_RETURN.getCode())).orElse(0); Integer pullNewPoint = Optional.ofNullable(userBalanceMap.get(PointChangeType.NEW_USER_REFERRAL.getCode())).orElse(0); Integer registerPoint = Optional.ofNullable(userBalanceMap.get(PointChangeType.REGISTRATION.getCode())).orElse(0); Integer workPoint = Optional.ofNullable(userBalanceMap.get(PointChangeType.WORK_PERFORMANCE.getCode())).orElse(0); Integer shopAchievementPoint = Optional.ofNullable(userBalanceMap.get(PointChangeType.TECHNICIAN_PERFORMANCE.getCode())).orElse(0); Integer exchangeGoodsPoint = Optional.ofNullable(userBalanceMap.get(PointChangeType.EXCHANGE_GOODS.getCode())).orElse(0); Integer storeAchievementPoint = Optional.ofNullable(userBalanceMap.get(PointChangeType.STORE_PERFORMANCE.getCode())).orElse(0); Integer storeCommissionPoint = Optional.ofNullable(userBalanceMap.get(PointChangeType.STORE_COMMISSION_RETURN.getCode())).orElse(0); Integer transferPoint = Optional.ofNullable(userBalanceMap.get(PointChangeType.TRANSFER_POINTS.getCode())).orElse(0); Integer totalPoint = consumePoint + sharePoint + pullNewPoint + registerPoint + workPoint + shopAchievementPoint + exchangeGoodsPoint + storeAchievementPoint + storeCommissionPoint + transferPoint; UserPointStatistics userPointStatistics = new UserPointStatistics(); userPointStatistics.setTotalPoint(totalPoint); userPointStatistics.setConsumePoint(consumePoint); userPointStatistics.setSharePoint(sharePoint); userPointStatistics.setPullNewPoint(pullNewPoint); userPointStatistics.setRegisterPoint(registerPoint); userPointStatistics.setWorkPoint(workPoint); userPointStatistics.setShopAchievementPoint(shopAchievementPoint); return userPointStatistics; } } ruoyi-service/ruoyi-account/src/main/resources/mapper/account/UserPointMapper.xml
@@ -22,10 +22,43 @@ t1.* FROM t_user_point t1 INNER JOIN ( SELECT type, MAX( create_time ) AS max_create_time FROM t_user_point WHERE app_user_id = 1864118151377129473 GROUP BY type ) t2 ON t1.type = t2.type INNER JOIN ( SELECT type, MAX( create_time ) AS max_create_time FROM t_user_point WHERE app_user_id = #{userId} GROUP BY type ) t2 ON t1.type = t2.type AND t1.create_time = t2.max_create_time WHERE t1.app_user_id = #{userId} </select> <select id="findLatestChangeByType" resultType="com.ruoyi.account.api.model.UserPoint"> SELECT id, type, historical_point, variable_point, balance, create_time, app_user_id, object_id FROM ( SELECT id, type, historical_point, variable_point, balance, create_time, app_user_id, object_id, ROW_NUMBER() OVER (PARTITION BY type ORDER BY create_time DESC) AS rn FROM t_user_point ) AS subquery WHERE rn = 1 <if test="type != null"> AND type = #{type} </if> <if test="appUserId != null"> AND app_user_id = #{appUserId} </if> </select> </mapper>