Merge branch 'feature/mall_product' of https://gitee.com/CrazyWorld/ruoyi-vue-pro into feature/mall_product

# Conflicts:
#	yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/order/TradeOrderApi.java
#	yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/order/TradeOrderApiImpl.java
This commit is contained in:
YunaiV 2023-10-11 11:30:03 +08:00
commit 704087ce86
70 changed files with 1150 additions and 319 deletions

View File

@ -28,16 +28,22 @@ CREATE INDEX trade_statistics_time_index
ON trade_statistics (time);
-- 菜单
INSERT INTO `ruoyi-vue-pro`.system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name)
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name)
VALUES ('统计管理', '', 1, 4, 0, '/statistics', 'ep:data-line', '', '');
SELECT @parentId := LAST_INSERT_ID();
INSERT INTO `ruoyi-vue-pro`.system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name)
VALUES ('交易统计', '', 2, 4, @parentId, 'trade', 'fa-solid:credit-card', 'statistics/trade/index', 'TradeStatistics');
-- 交易统计
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name)
VALUES ('交易统计', '', 2, 1, @parentId, 'trade', 'fa-solid:credit-card', 'statistics/trade/index', 'TradeStatistics');
SELECT @parentId := LAST_INSERT_ID();
-- 按钮
INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
VALUES ('交易统计查询', 'statistics:trade:query', 3, 1, @parentId, '', '', '', 0);
INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
VALUES ('交易统计导出', 'statistics:trade:export', 3, 2, @parentId, '', '', '', 0);
-- 会员统计
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name)
VALUES ('会员统计', '', 2, 2, @parentId, 'member', 'ep:avatar', 'statistics/member/index', 'MemberStatistics');
SELECT @parentId := LAST_INSERT_ID();
INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
VALUES ('会员统计查询', 'statistics:member:query', 3, 1, @parentId, '', '', '', 0);

View File

@ -2,6 +2,7 @@ package cn.iocoder.yudao.framework.common.util.collection;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ArrayUtil;
import com.google.common.collect.ImmutableMap;
import java.util.*;
@ -50,6 +51,13 @@ public class CollectionUtils {
return new ArrayList<>(convertMap(from, keyMapper, Function.identity(), cover).values());
}
public static <T, U> List<U> convertList(T[] from, Function<T, U> func) {
if (ArrayUtil.isEmpty(from)) {
return new ArrayList<>();
}
return convertList(Arrays.asList(from), func);
}
public static <T, U> List<U> convertList(Collection<T> from, Function<T, U> func) {
if (CollUtil.isEmpty(from)) {
return new ArrayList<>();
@ -169,8 +177,8 @@ public class CollectionUtils {
/**
* 对比老新两个列表找出新增修改删除的数据
*
* @param oldList 老列表
* @param newList 新列表
* @param oldList 老列表
* @param newList 新列表
* @param sameFunc 对比函数返回 true 表示相同返回 false 表示不同
* 注意same 是通过每个元素的标识判断它们是不是同一个数据
* @return [新增列表修改列表删除列表]

View File

@ -7,12 +7,16 @@ import cn.hutool.core.text.csv.CsvUtil;
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
import cn.iocoder.yudao.framework.ip.core.Area;
import cn.iocoder.yudao.framework.ip.core.enums.AreaTypeEnum;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
/**
* 区域工具类
@ -108,7 +112,7 @@ public class AreaUtils {
// 递归父节点
area = area.getParent();
if (area == null
|| ObjectUtils.equalsAny(area.getId(), Area.ID_GLOBAL, Area.ID_CHINA)) { // 跳过父节点为中国的情况
|| ObjectUtils.equalsAny(area.getId(), Area.ID_GLOBAL, Area.ID_CHINA)) { // 跳过父节点为中国的情况
break;
}
sb.insert(0, separator);
@ -116,4 +120,35 @@ public class AreaUtils {
return sb.toString();
}
/**
* 获取指定类型的区域列表
*
* @param type 区域类型
* @param func 转换函数
* @param <T> 结果类型
* @return 区域列表
*/
public static <T> List<T> getByType(AreaTypeEnum type, Function<Area, T> func) {
return convertList(areas.values(), func, area -> type.getType().equals(area.getType()));
}
public static Integer getParentIdByType(Integer id, @NonNull AreaTypeEnum type) {
do {
Area area = AreaUtils.getArea(id);
if (area == null) {
return null;
}
if (type.getType().equals(area.getType())) {
return area.getId();
}
if (area.getParent() == null || area.getParent().getId() == null) {
return null;
}
id = area.getParent().getId();
} while (true);
}
}

View File

@ -59,6 +59,11 @@
<artifactId>yudao-spring-boot-starter-biz-tenant</artifactId>
</dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-biz-ip</artifactId>
</dependency>
<!-- Web 相关 -->
<dependency>
<groupId>cn.iocoder.boot</groupId>

View File

@ -1,21 +1,25 @@
package cn.iocoder.yudao.module.statistics.controller.admin.member;
import cn.hutool.core.util.ArrayUtil;
import cn.iocoder.yudao.framework.common.enums.TerminalEnum;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.statistics.controller.admin.member.vo.MemberAreaStatisticsRespVO;
import cn.iocoder.yudao.module.statistics.controller.admin.member.vo.MemberSexStatisticsRespVO;
import cn.iocoder.yudao.module.statistics.controller.admin.member.vo.MemberSummaryRespVO;
import cn.iocoder.yudao.module.statistics.controller.admin.member.vo.MemberTerminalStatisticsRespVO;
import cn.iocoder.yudao.module.statistics.controller.admin.trade.vo.TradeStatisticsComparisonRespVO;
import cn.iocoder.yudao.module.statistics.controller.admin.member.vo.*;
import cn.iocoder.yudao.module.statistics.service.member.MemberStatisticsService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
@Tag(name = "管理后台 - 会员统计")
@RestController
@RequestMapping("/statistics/member")
@ -23,36 +27,47 @@ import java.util.List;
@Slf4j
public class MemberStatisticsController {
// TODO @疯狂一个类似 getTradeTrendSummaryComparison 的接口
// TODO @疯狂一个类似 getTradeStatisticsList 的接口
@Resource
private MemberStatisticsService memberStatisticsService;
@GetMapping("/summary")
@Operation(summary = "获得会员统计")
public CommonResult<TradeStatisticsComparisonRespVO<MemberSummaryRespVO>> getMemberSummary() {
// TODO 疯狂目前先直接计算
return null;
@PreAuthorize("@ss.hasPermission('statistics:member:query')")
public CommonResult<MemberSummaryRespVO> getMemberSummary() {
return success(memberStatisticsService.getMemberSummary());
}
@GetMapping("/analyse")
@Operation(summary = "获得会员分析数据")
@PreAuthorize("@ss.hasPermission('statistics:member:query')")
public CommonResult<MemberAnalyseRespVO> getMemberAnalyse(MemberAnalyseReqVO reqVO) {
return success(memberStatisticsService.getMemberAnalyse(
ArrayUtil.get(reqVO.getTimes(), 0), ArrayUtil.get(reqVO.getTimes(), 1)));
}
@GetMapping("/get-area-statistics-list")
@Operation(summary = "按照省份,获得会员统计列表")
@PreAuthorize("@ss.hasPermission('statistics:member:query')")
public CommonResult<List<MemberAreaStatisticsRespVO>> getMemberAreaStatisticsList() {
// TODO 疯狂目前先直接计算进行统计后续再考虑优化
return null;
return success(memberStatisticsService.getMemberAreaStatisticsList());
}
@GetMapping("/get-sex-statistics-list")
@Operation(summary = "按照性别,获得会员统计列表")
@PreAuthorize("@ss.hasPermission('statistics:member:query')")
public CommonResult<List<MemberSexStatisticsRespVO>> getMemberSexStatisticsList() {
// TODO 疯狂目前先直接计算进行统计后续再考虑优化
return null;
return success(memberStatisticsService.getMemberSexStatisticsList());
}
@GetMapping("/get-terminal-statistics-list")
@Operation(summary = "按照终端,获得会员统计列表")
@PreAuthorize("@ss.hasPermission('statistics:member:query')")
public CommonResult<List<MemberTerminalStatisticsRespVO>> getMemberTerminalStatisticsList() {
// TODO 疯狂目前先直接计算进行统计后续再考虑优化
// TODO 疯狂这个可以晚点写因为 user = = 上还没记录 terminal
return null;
List<MemberTerminalStatisticsRespVO> list = convertList(TerminalEnum.values(),
t -> new MemberTerminalStatisticsRespVO()
.setTerminal(t.getTerminal()).setUserCount(t.getTerminal() * 100));
return success(list);
}
}

View File

@ -0,0 +1,19 @@
package cn.iocoder.yudao.module.statistics.controller.admin.member.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "管理后台 - 会员分析对照数据 Response VO")
@Data
public class MemberAnalyseComparisonRespVO {
@Schema(description = "会员数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Integer userCount;
@Schema(description = "活跃用户数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Integer activeUserCount;
@Schema(description = "充值会员数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "221")
private Integer rechargeUserCount;
}

View File

@ -0,0 +1,19 @@
package cn.iocoder.yudao.module.statistics.controller.admin.member.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 会员分析 Request VO")
@Data
public class MemberAnalyseReqVO {
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@Schema(description = "时间范围")
private LocalDateTime[] times;
}

View File

@ -0,0 +1,26 @@
package cn.iocoder.yudao.module.statistics.controller.admin.member.vo;
import cn.iocoder.yudao.module.statistics.controller.admin.trade.vo.TradeStatisticsComparisonRespVO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "管理后台 - 会员分析 Response VO")
@Data
public class MemberAnalyseRespVO {
@Schema(description = "访客数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Integer visitorCount;
@Schema(description = "下单用户数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Integer orderUserCount;
@Schema(description = "成交用户数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Integer payUserCount;
@Schema(description = "客单价", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Integer atv;
@Schema(description = "对照数据", requiredMode = Schema.RequiredMode.REQUIRED)
private TradeStatisticsComparisonRespVO<MemberAnalyseComparisonRespVO> comparison;
}

View File

@ -13,11 +13,4 @@ public class MemberSexStatisticsRespVO {
@Schema(description = "会员数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Integer userCount;
@Schema(description = "订单创建数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Integer orderCreateCount;
@Schema(description = "订单支付数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "512")
private Integer orderPayCount;
@Schema(description = "订单支付金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "622")
private Integer orderPayPrice;
}

View File

@ -15,6 +15,7 @@ public class MemberSummaryRespVO {
@Schema(description = "充值金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Integer rechargePrice;
@Schema(description = "支出金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Integer expensePrice;

View File

@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.statistics.controller.admin.member.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "管理后台 - 终端性别统计 Response VO")
@Schema(description = "管理后台 - 会员终端统计 Response VO")
@Data
public class MemberTerminalStatisticsRespVO {
@ -13,11 +13,4 @@ public class MemberTerminalStatisticsRespVO {
@Schema(description = "会员数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Integer userCount;
@Schema(description = "订单创建数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Integer orderCreateCount;
@Schema(description = "订单支付数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "512")
private Integer orderPayCount;
@Schema(description = "订单支付金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "622")
private Integer orderPayPrice;
}

View File

@ -0,0 +1,39 @@
package cn.iocoder.yudao.module.statistics.convert.member;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjUtil;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.framework.ip.core.Area;
import cn.iocoder.yudao.module.statistics.controller.admin.member.vo.MemberAreaStatisticsRespVO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
import java.util.Map;
import java.util.Optional;
/**
* 会员统计 Convert
*
* @author owen
*/
@Mapper
public interface MemberStatisticsConvert {
MemberStatisticsConvert INSTANCE = Mappers.getMapper(MemberStatisticsConvert.class);
default List<MemberAreaStatisticsRespVO> convertList(List<Area> areaList,
Map<Integer, Integer> userCountMap,
Map<Integer, MemberAreaStatisticsRespVO> orderMap) {
return CollectionUtils.convertList(areaList, area -> {
MemberAreaStatisticsRespVO orderVo = Optional.ofNullable(orderMap.get(area.getId())).orElseGet(MemberAreaStatisticsRespVO::new);
return new MemberAreaStatisticsRespVO()
.setAreaId(area.getId()).setAreaName(area.getName())
.setUserCount(MapUtil.getInt(userCountMap, area.getId(), 0))
.setOrderCreateCount(ObjUtil.defaultIfNull(orderVo.getOrderCreateCount(), 0))
.setOrderPayCount(ObjUtil.defaultIfNull(orderVo.getOrderPayCount(), 0))
.setOrderPayPrice(ObjUtil.defaultIfNull(orderVo.getOrderPayPrice(), 0));
});
}
}

View File

@ -1,14 +1,14 @@
package cn.iocoder.yudao.module.statistics.convert.trade;
import cn.iocoder.yudao.module.pay.api.wallet.dto.WalletSummaryRespDTO;
import cn.iocoder.yudao.module.statistics.service.trade.bo.WalletSummaryRespBO;
import cn.iocoder.yudao.module.statistics.controller.admin.trade.vo.TradeStatisticsComparisonRespVO;
import cn.iocoder.yudao.module.statistics.controller.admin.trade.vo.TradeSummaryRespVO;
import cn.iocoder.yudao.module.statistics.controller.admin.trade.vo.TradeTrendSummaryExcelVO;
import cn.iocoder.yudao.module.statistics.controller.admin.trade.vo.TradeTrendSummaryRespVO;
import cn.iocoder.yudao.module.statistics.dal.dataobject.trade.TradeStatisticsDO;
import cn.iocoder.yudao.module.statistics.service.trade.bo.TradeOrderSummaryRespBO;
import cn.iocoder.yudao.module.statistics.service.trade.bo.TradeSummaryRespBO;
import cn.iocoder.yudao.module.trade.api.aftersale.dto.AfterSaleSummaryRespDTO;
import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderSummaryRespDTO;
import cn.iocoder.yudao.module.statistics.service.trade.bo.AfterSaleSummaryRespBO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
@ -46,8 +46,8 @@ public interface TradeStatisticsConvert {
List<TradeTrendSummaryExcelVO> convertList02(List<TradeTrendSummaryRespVO> list);
TradeStatisticsDO convert(LocalDateTime time, TradeOrderSummaryRespDTO orderSummary,
AfterSaleSummaryRespDTO afterSaleSummary, Integer brokerageSettlementPrice,
WalletSummaryRespDTO walletSummary);
TradeStatisticsDO convert(LocalDateTime time, TradeOrderSummaryRespBO orderSummary,
AfterSaleSummaryRespBO afterSaleSummary, Integer brokerageSettlementPrice,
WalletSummaryRespBO walletSummary);
}

View File

@ -0,0 +1,21 @@
package cn.iocoder.yudao.module.statistics.dal.mysql.infra;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.time.LocalDateTime;
/**
* API 访问日志统计 Mapper
*
* @author owen
*/
@Mapper
public interface ApiAccessLogStatisticsMapper extends BaseMapperX<Object> {
Integer selectCountByIp(@Param("beginTime") LocalDateTime beginTime, @Param("endTime") LocalDateTime endTime);
Integer selectCountByUserId(@Param("beginTime") LocalDateTime beginTime, @Param("endTime") LocalDateTime endTime);
}

View File

@ -0,0 +1,26 @@
package cn.iocoder.yudao.module.statistics.dal.mysql.member;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.statistics.controller.admin.member.vo.MemberAreaStatisticsRespVO;
import cn.iocoder.yudao.module.statistics.controller.admin.member.vo.MemberSexStatisticsRespVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.time.LocalDateTime;
import java.util.List;
/**
* 会员统计 Mapper
*
* @author owen
*/
@Mapper
public interface MemberStatisticsMapper extends BaseMapperX<Object> {
List<MemberAreaStatisticsRespVO> selectSummaryListByAreaId();
List<MemberSexStatisticsRespVO> selectSummaryListBySex();
Integer selectUserCount(@Param("beginTime") LocalDateTime beginTime, @Param("endTime") LocalDateTime endTime);
}

View File

@ -0,0 +1,36 @@
package cn.iocoder.yudao.module.statistics.dal.mysql.pay;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.statistics.controller.admin.member.vo.MemberSummaryRespVO;
import cn.iocoder.yudao.module.statistics.service.trade.bo.WalletSummaryRespBO;
import cn.iocoder.yudao.module.statistics.dal.dataobject.trade.TradeStatisticsDO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.time.LocalDateTime;
/**
* 交易统计 Mapper
*
* @author owen
*/
@Mapper
public interface PayWalletStatisticsMapper extends BaseMapperX<TradeStatisticsDO> {
WalletSummaryRespBO selectRechargeSummaryByPayTimeBetween(@Param("beginTime") LocalDateTime beginTime,
@Param("endTime") LocalDateTime endTime,
@Param("payStatus") Boolean payStatus);
WalletSummaryRespBO selectRechargeSummaryByRefundTimeBetween(@Param("beginTime") LocalDateTime beginTime,
@Param("endTime") LocalDateTime endTime,
@Param("refundStatus") Integer refundStatus);
Integer selectPriceSummaryByBizTypeAndCreateTimeBetween(@Param("beginTime") LocalDateTime beginTime,
@Param("endTime") LocalDateTime endTime,
@Param("bizType") Integer bizType);
MemberSummaryRespVO selectRechargeSummaryGroupByWalletId(@Param("beginTime") LocalDateTime beginTime,
@Param("endTime") LocalDateTime endTime,
@Param("payStatus") Boolean payStatus);
}

View File

@ -0,0 +1,22 @@
package cn.iocoder.yudao.module.statistics.dal.mysql.trade;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.statistics.dal.dataobject.trade.TradeStatisticsDO;
import cn.iocoder.yudao.module.statistics.service.trade.bo.AfterSaleSummaryRespBO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.time.LocalDateTime;
/**
* 交易统计 Mapper
*
* @author owen
*/
@Mapper
public interface AfterSaleStatisticsMapper extends BaseMapperX<TradeStatisticsDO> {
AfterSaleSummaryRespBO selectSummaryByRefundTimeBetween(@Param("beginTime") LocalDateTime beginTime,
@Param("endTime") LocalDateTime endTime);
}

View File

@ -0,0 +1,23 @@
package cn.iocoder.yudao.module.statistics.dal.mysql.trade;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.statistics.dal.dataobject.trade.TradeStatisticsDO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.time.LocalDateTime;
/**
* 交易统计 Mapper
*
* @author owen
*/
@Mapper
public interface BrokerageStatisticsMapper extends BaseMapperX<TradeStatisticsDO> {
Integer selectSummaryPriceByStatusAndUnfreezeTimeBetween(@Param("bizType") Integer bizType,
@Param("status") Integer status,
@Param("beginTime") LocalDateTime beginTime,
@Param("endTime") LocalDateTime endTime);
}

View File

@ -0,0 +1,37 @@
package cn.iocoder.yudao.module.statistics.dal.mysql.trade;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.statistics.controller.admin.member.vo.MemberAreaStatisticsRespVO;
import cn.iocoder.yudao.module.statistics.dal.dataobject.trade.TradeStatisticsDO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.time.LocalDateTime;
import java.util.List;
/**
* 交易统计 Mapper
*
* @author owen
*/
@Mapper
public interface TradeOrderStatisticsMapper extends BaseMapperX<TradeStatisticsDO> {
List<MemberAreaStatisticsRespVO> selectSummaryListByAreaId();
Integer selectCountByCreateTimeBetween(@Param("beginTime") LocalDateTime beginTime,
@Param("endTime") LocalDateTime endTime);
Integer selectCountByPayTimeBetween(@Param("beginTime") LocalDateTime beginTime,
@Param("endTime") LocalDateTime endTime);
Integer selectSummaryPriceByPayTimeBetween(@Param("beginTime") LocalDateTime beginTime,
@Param("endTime") LocalDateTime endTime);
Integer selectUserCountByCreateTimeBetween(@Param("beginTime") LocalDateTime beginTime,
@Param("endTime") LocalDateTime endTime);
Integer selectUserCountByPayTimeBetween(@Param("beginTime") LocalDateTime beginTime,
@Param("endTime") LocalDateTime endTime);
}

View File

@ -30,4 +30,7 @@ public interface TradeStatisticsMapper extends BaseMapperX<TradeStatisticsDO> {
List<TradeTrendSummaryRespVO> selectListByTimeBetween(@Param("beginTime") LocalDateTime beginTime,
@Param("endTime") LocalDateTime endTime);
Integer selectExpensePriceByTimeBetween(@Param("beginTime") LocalDateTime beginTime,
@Param("endTime") LocalDateTime endTime);
}

View File

@ -0,0 +1,30 @@
package cn.iocoder.yudao.module.statistics.service.infra;
import java.time.LocalDateTime;
/**
* API 访问日志统计 Service 接口
*
* @author owen
*/
public interface ApiAccessLogStatisticsService {
/**
* 获取活跃用户数量
*
* @param beginTime 起始时间
* @param endTime 截止时间
* @return 活跃用户数量
*/
Integer getActiveUserCount(LocalDateTime beginTime, LocalDateTime endTime);
/**
* 获取访问用户数量
*
* @param beginTime 起始时间
* @param endTime 截止时间
* @return 访问用户数量
*/
Integer getVisitorUserCount(LocalDateTime beginTime, LocalDateTime endTime);
}

View File

@ -0,0 +1,31 @@
package cn.iocoder.yudao.module.statistics.service.infra;
import cn.iocoder.yudao.module.statistics.dal.mysql.infra.ApiAccessLogStatisticsMapper;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.time.LocalDateTime;
/**
* API 访问日志统计 Service 实现类
*
* @author owen
*/
@Service
@Validated
public class ApiAccessLogStatisticsServiceImpl implements ApiAccessLogStatisticsService {
@Resource
private ApiAccessLogStatisticsMapper apiAccessLogStatisticsMapper;
@Override
public Integer getActiveUserCount(LocalDateTime beginTime, LocalDateTime endTime) {
return apiAccessLogStatisticsMapper.selectCountByUserId(beginTime, endTime);
}
@Override
public Integer getVisitorUserCount(LocalDateTime beginTime, LocalDateTime endTime) {
return apiAccessLogStatisticsMapper.selectCountByIp(beginTime, endTime);
}
}

View File

@ -0,0 +1,48 @@
package cn.iocoder.yudao.module.statistics.service.member;
import cn.iocoder.yudao.module.statistics.controller.admin.member.vo.MemberAnalyseRespVO;
import cn.iocoder.yudao.module.statistics.controller.admin.member.vo.MemberAreaStatisticsRespVO;
import cn.iocoder.yudao.module.statistics.controller.admin.member.vo.MemberSexStatisticsRespVO;
import cn.iocoder.yudao.module.statistics.controller.admin.member.vo.MemberSummaryRespVO;
import java.time.LocalDateTime;
import java.util.List;
/**
* 会员统计 Service 接口
*
* @author owen
*/
public interface MemberStatisticsService {
/**
* 按照省份获得会员统计列表
*
* @return 会员统计列表
*/
List<MemberAreaStatisticsRespVO> getMemberAreaStatisticsList();
/**
* 按照性别获得会员统计列表
*
* @return 会员统计列表
*/
List<MemberSexStatisticsRespVO> getMemberSexStatisticsList();
/**
* 获取用户分析数据
*
* @param beginTime 起始时间
* @param endTime 截止时间
* @return 用户分析数据
*/
MemberAnalyseRespVO getMemberAnalyse(LocalDateTime beginTime, LocalDateTime endTime);
/**
* 获取会员统计
*
* @return 会员统计
*/
MemberSummaryRespVO getMemberSummary();
}

View File

@ -0,0 +1,114 @@
package cn.iocoder.yudao.module.statistics.service.member;
import cn.hutool.core.util.NumberUtil;
import cn.iocoder.yudao.framework.ip.core.enums.AreaTypeEnum;
import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
import cn.iocoder.yudao.module.statistics.controller.admin.member.vo.*;
import cn.iocoder.yudao.module.statistics.controller.admin.trade.vo.TradeStatisticsComparisonRespVO;
import cn.iocoder.yudao.module.statistics.convert.member.MemberStatisticsConvert;
import cn.iocoder.yudao.module.statistics.dal.mysql.member.MemberStatisticsMapper;
import cn.iocoder.yudao.module.statistics.service.infra.ApiAccessLogStatisticsService;
import cn.iocoder.yudao.module.statistics.service.pay.PayWalletStatisticsService;
import cn.iocoder.yudao.module.statistics.service.trade.TradeOrderStatisticsService;
import cn.iocoder.yudao.module.statistics.service.trade.TradeStatisticsService;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
/**
* 会员统计 Service 实现类
*
* @author owen
*/
@Service
@Validated
public class MemberStatisticsServiceImpl implements MemberStatisticsService {
@Resource
private MemberStatisticsMapper memberStatisticsMapper;
@Resource
private PayWalletStatisticsService payWalletStatisticsService;
@Resource
private TradeStatisticsService tradeStatisticsService;
@Resource
private TradeOrderStatisticsService tradeOrderStatisticsService;
@Resource
private ApiAccessLogStatisticsService apiAccessLogStatisticsService;
@Override
public List<MemberAreaStatisticsRespVO> getMemberAreaStatisticsList() {
// 统计用户
Map<Integer, Integer> userCountMap = convertMap(memberStatisticsMapper.selectSummaryListByAreaId(),
vo -> AreaUtils.getParentIdByType(vo.getAreaId(), AreaTypeEnum.PROVINCE),
MemberAreaStatisticsRespVO::getUserCount, Integer::sum);
// 统计订单
Map<Integer, MemberAreaStatisticsRespVO> orderMap = convertMap(tradeOrderStatisticsService.getSummaryListByAreaId(),
vo -> AreaUtils.getParentIdByType(vo.getAreaId(), AreaTypeEnum.PROVINCE),
vo -> vo,
(a, b) -> new MemberAreaStatisticsRespVO()
.setOrderCreateCount(a.getOrderCreateCount() + b.getOrderCreateCount())
.setOrderPayCount(a.getOrderPayCount() + b.getOrderPayCount())
.setOrderPayPrice(a.getOrderPayPrice() + b.getOrderPayPrice()));
// 拼接数据
return MemberStatisticsConvert.INSTANCE.convertList(AreaUtils.getByType(AreaTypeEnum.PROVINCE, area -> area), userCountMap, orderMap);
}
@Override
public List<MemberSexStatisticsRespVO> getMemberSexStatisticsList() {
return memberStatisticsMapper.selectSummaryListBySex();
}
@Override
public MemberAnalyseRespVO getMemberAnalyse(LocalDateTime beginTime, LocalDateTime endTime) {
// 对照数据
MemberAnalyseComparisonRespVO vo = getMemberAnalyseComparisonData(beginTime, endTime);
LocalDateTime referenceBeginTime = beginTime.minus(Duration.between(beginTime, endTime));
MemberAnalyseComparisonRespVO reference = getMemberAnalyseComparisonData(referenceBeginTime, beginTime);
Integer payUserCount = tradeOrderStatisticsService.getPayUserCount(beginTime, endTime);
// 计算客单价
int atv = 0;
if (payUserCount != null && payUserCount > 0) {
Integer payPrice = tradeOrderStatisticsService.getOrderPayPrice(beginTime, endTime);
atv = NumberUtil.div(payPrice, payUserCount).intValue();
}
return new MemberAnalyseRespVO()
.setVisitorCount(apiAccessLogStatisticsService.getVisitorUserCount(beginTime, endTime))
.setOrderUserCount(tradeOrderStatisticsService.getOrderUserCount(beginTime, endTime))
.setPayUserCount(payUserCount)
.setAtv(atv)
.setComparison(new TradeStatisticsComparisonRespVO<>(vo, reference));
}
@Override
public MemberSummaryRespVO getMemberSummary() {
MemberSummaryRespVO vo = payWalletStatisticsService.getUserRechargeSummary(null, null);
Integer expensePrice = tradeStatisticsService.getExpensePrice(null, null);
Integer userCount = memberStatisticsMapper.selectUserCount(null, null);
if (vo == null) {
vo = new MemberSummaryRespVO().setRechargeUserCount(0).setRechargePrice(0);
}
return vo.setUserCount(userCount).setExpensePrice(expensePrice);
}
private MemberAnalyseComparisonRespVO getMemberAnalyseComparisonData(LocalDateTime beginTime, LocalDateTime endTime) {
Integer rechargeUserCount = Optional.ofNullable(payWalletStatisticsService.getUserRechargeSummary(beginTime, endTime))
.map(MemberSummaryRespVO::getRechargeUserCount).orElse(0);
return new MemberAnalyseComparisonRespVO()
.setUserCount(memberStatisticsMapper.selectUserCount(beginTime, endTime))
.setActiveUserCount(apiAccessLogStatisticsService.getActiveUserCount(beginTime, endTime))
.setRechargeUserCount(rechargeUserCount);
}
}

View File

@ -0,0 +1,33 @@
package cn.iocoder.yudao.module.statistics.service.pay;
import cn.iocoder.yudao.module.statistics.controller.admin.member.vo.MemberSummaryRespVO;
import cn.iocoder.yudao.module.statistics.service.trade.bo.WalletSummaryRespBO;
import java.time.LocalDateTime;
/**
* 钱包统计 Service 接口
*
* @author owen
*/
public interface PayWalletStatisticsService {
/**
* 获取钱包统计
*
* @param beginTime 起始时间
* @param endTime 截止时间
* @return 钱包统计
*/
WalletSummaryRespBO getWalletSummary(LocalDateTime beginTime, LocalDateTime endTime);
/**
* 获取钱包充值统计
*
* @param beginTime 起始时间
* @param endTime 截止时间
* @return 钱包充值统计
*/
MemberSummaryRespVO getUserRechargeSummary(LocalDateTime beginTime, LocalDateTime endTime);
}

View File

@ -0,0 +1,47 @@
package cn.iocoder.yudao.module.statistics.service.pay;
import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum;
import cn.iocoder.yudao.module.pay.enums.refund.PayRefundStatusEnum;
import cn.iocoder.yudao.module.statistics.controller.admin.member.vo.MemberSummaryRespVO;
import cn.iocoder.yudao.module.statistics.dal.mysql.pay.PayWalletStatisticsMapper;
import cn.iocoder.yudao.module.statistics.service.trade.bo.WalletSummaryRespBO;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.time.LocalDateTime;
/**
* 钱包统计 Service 实现类
*
* @author owen
*/
@Service
@Validated
public class PayWalletStatisticsServiceImpl implements PayWalletStatisticsService {
@Resource
private PayWalletStatisticsMapper payWalletStatisticsMapper;
@Override
public WalletSummaryRespBO getWalletSummary(LocalDateTime beginTime, LocalDateTime endTime) {
WalletSummaryRespBO paySummary = payWalletStatisticsMapper.selectRechargeSummaryByPayTimeBetween(
beginTime, endTime, true);
WalletSummaryRespBO refundSummary = payWalletStatisticsMapper.selectRechargeSummaryByRefundTimeBetween(
beginTime, endTime, PayRefundStatusEnum.SUCCESS.getStatus());
Integer walletPayPrice = payWalletStatisticsMapper.selectPriceSummaryByBizTypeAndCreateTimeBetween(
beginTime, endTime, PayWalletBizTypeEnum.PAYMENT.getType());
paySummary.setOrderWalletPayPrice(walletPayPrice);
paySummary.setRechargeRefundCount(refundSummary.getRechargeRefundCount());
paySummary.setRechargeRefundPrice(refundSummary.getRechargeRefundPrice());
return paySummary;
}
@Override
public MemberSummaryRespVO getUserRechargeSummary(LocalDateTime beginTime, LocalDateTime endTime) {
return payWalletStatisticsMapper.selectRechargeSummaryGroupByWalletId(beginTime, endTime, true);
}
}

View File

@ -0,0 +1,23 @@
package cn.iocoder.yudao.module.statistics.service.trade;
import cn.iocoder.yudao.module.statistics.service.trade.bo.AfterSaleSummaryRespBO;
import java.time.LocalDateTime;
/**
* 售后统计 Service 接口
*
* @author owen
*/
public interface AfterSaleStatisticsService {
/**
* 获取售后单统计
*
* @param beginTime 起始时间
* @param endTime 截止时间
* @return 售后统计结果
*/
AfterSaleSummaryRespBO getAfterSaleSummary(LocalDateTime beginTime, LocalDateTime endTime);
}

View File

@ -0,0 +1,28 @@
package cn.iocoder.yudao.module.statistics.service.trade;
import cn.iocoder.yudao.module.statistics.dal.mysql.trade.AfterSaleStatisticsMapper;
import cn.iocoder.yudao.module.statistics.service.trade.bo.AfterSaleSummaryRespBO;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.time.LocalDateTime;
/**
* 售后统计 Service 实现类
*
* @author owen
*/
@Service
@Validated
public class AfterSaleStatisticsServiceImpl implements AfterSaleStatisticsService {
@Resource
private AfterSaleStatisticsMapper afterSaleStatisticsMapper;
@Override
public AfterSaleSummaryRespBO getAfterSaleSummary(LocalDateTime beginTime, LocalDateTime endTime) {
return afterSaleStatisticsMapper.selectSummaryByRefundTimeBetween(beginTime, endTime);
}
}

View File

@ -0,0 +1,21 @@
package cn.iocoder.yudao.module.statistics.service.trade;
import java.time.LocalDateTime;
/**
* 分销统计 Service 接口
*
* @author owen
*/
public interface BrokerageStatisticsService {
/**
* 获取已结算的佣金金额
*
* @param beginTime 起始时间
* @param endTime 截止时间
* @return 已结算的佣金金额
*/
Integer getBrokerageSettlementPriceSummary(LocalDateTime beginTime, LocalDateTime endTime);
}

View File

@ -0,0 +1,31 @@
package cn.iocoder.yudao.module.statistics.service.trade;
import cn.iocoder.yudao.module.statistics.dal.mysql.trade.BrokerageStatisticsMapper;
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum;
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordStatusEnum;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.time.LocalDateTime;
/**
* 分销统计 Service 实现类
*
* @author owen
*/
@Service
@Validated
public class BrokerageStatisticsServiceImpl implements BrokerageStatisticsService {
@Resource
private BrokerageStatisticsMapper brokerageStatisticsMapper;
@Override
public Integer getBrokerageSettlementPriceSummary(LocalDateTime beginTime, LocalDateTime endTime) {
return brokerageStatisticsMapper.selectSummaryPriceByStatusAndUnfreezeTimeBetween(
BrokerageRecordBizTypeEnum.ORDER.getType(), BrokerageRecordStatusEnum.SETTLEMENT.getStatus(),
beginTime, endTime);
}
}

View File

@ -0,0 +1,59 @@
package cn.iocoder.yudao.module.statistics.service.trade;
import cn.iocoder.yudao.module.statistics.controller.admin.member.vo.MemberAreaStatisticsRespVO;
import cn.iocoder.yudao.module.statistics.service.trade.bo.TradeOrderSummaryRespBO;
import java.time.LocalDateTime;
import java.util.List;
/**
* 交易订单统计 Service 接口
*
* @author owen
*/
public interface TradeOrderStatisticsService {
/**
* 获取订单统计
*
* @param beginTime 起始时间
* @param endTime 截止时间
* @return 订单统计结果
*/
TradeOrderSummaryRespBO getOrderSummary(LocalDateTime beginTime, LocalDateTime endTime);
/**
* 获取地区订单统计
*
* @return 订单统计结果
*/
List<MemberAreaStatisticsRespVO> getSummaryListByAreaId();
/**
* 获取下单用户数量
*
* @param beginTime 起始时间
* @param endTime 截止时间
* @return 支付下单数量
*/
Integer getOrderUserCount(LocalDateTime beginTime, LocalDateTime endTime);
/**
* 获取支付用户数量
*
* @param beginTime 起始时间
* @param endTime 截止时间
* @return 支付用户数量
*/
Integer getPayUserCount(LocalDateTime beginTime, LocalDateTime endTime);
/**
* 获取支付金额
*
* @param beginTime 起始时间
* @param endTime 截止时间
* @return 支付用户金额
*/
Integer getOrderPayPrice(LocalDateTime beginTime, LocalDateTime endTime);
}

View File

@ -0,0 +1,53 @@
package cn.iocoder.yudao.module.statistics.service.trade;
import cn.iocoder.yudao.module.statistics.controller.admin.member.vo.MemberAreaStatisticsRespVO;
import cn.iocoder.yudao.module.statistics.dal.mysql.trade.TradeOrderStatisticsMapper;
import cn.iocoder.yudao.module.statistics.service.trade.bo.TradeOrderSummaryRespBO;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
/**
* 交易订单统计 Service 实现类
*
* @author owen
*/
@Service
@Validated
public class TradeOrderStatisticsServiceImpl implements TradeOrderStatisticsService {
@Resource
private TradeOrderStatisticsMapper tradeOrderStatisticsMapper;
@Override
public TradeOrderSummaryRespBO getOrderSummary(LocalDateTime beginTime, LocalDateTime endTime) {
return new TradeOrderSummaryRespBO()
.setOrderCreateCount(tradeOrderStatisticsMapper.selectCountByCreateTimeBetween(beginTime, endTime))
.setOrderPayCount(tradeOrderStatisticsMapper.selectCountByPayTimeBetween(beginTime, endTime))
.setOrderPayPrice(tradeOrderStatisticsMapper.selectSummaryPriceByPayTimeBetween(beginTime, endTime));
}
@Override
public List<MemberAreaStatisticsRespVO> getSummaryListByAreaId() {
return tradeOrderStatisticsMapper.selectSummaryListByAreaId();
}
@Override
public Integer getOrderUserCount(LocalDateTime beginTime, LocalDateTime endTime) {
return tradeOrderStatisticsMapper.selectUserCountByCreateTimeBetween(beginTime, endTime);
}
@Override
public Integer getPayUserCount(LocalDateTime beginTime, LocalDateTime endTime) {
return tradeOrderStatisticsMapper.selectUserCountByPayTimeBetween(beginTime, endTime);
}
@Override
public Integer getOrderPayPrice(LocalDateTime beginTime, LocalDateTime endTime) {
return tradeOrderStatisticsMapper.selectSummaryPriceByPayTimeBetween(beginTime, endTime);
}
}

View File

@ -22,13 +22,20 @@ public interface TradeStatisticsService {
TradeStatisticsComparisonRespVO<TradeSummaryRespVO> getTradeSummaryComparison();
/**
* 获得交易状况统计
* 获得交易状况统计对照
*
* @return 统计数据对照
*/
TradeStatisticsComparisonRespVO<TradeTrendSummaryRespVO> getTradeTrendSummaryComparison(
LocalDateTime beginTime, LocalDateTime endTime);
/**
* 获得交易状况统计
*
* @return 统计数据对照
*/
Integer getExpensePrice(LocalDateTime beginTime, LocalDateTime endTime);
/**
* 获得交易状况明细
*

View File

@ -2,8 +2,8 @@ package cn.iocoder.yudao.module.statistics.service.trade;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
import cn.iocoder.yudao.module.pay.api.wallet.PayWalletApi;
import cn.iocoder.yudao.module.pay.api.wallet.dto.WalletSummaryRespDTO;
import cn.iocoder.yudao.module.statistics.service.pay.PayWalletStatisticsService;
import cn.iocoder.yudao.module.statistics.service.trade.bo.WalletSummaryRespBO;
import cn.iocoder.yudao.module.statistics.controller.admin.trade.vo.TradeStatisticsComparisonRespVO;
import cn.iocoder.yudao.module.statistics.controller.admin.trade.vo.TradeSummaryRespVO;
import cn.iocoder.yudao.module.statistics.controller.admin.trade.vo.TradeTrendSummaryRespVO;
@ -11,11 +11,8 @@ import cn.iocoder.yudao.module.statistics.convert.trade.TradeStatisticsConvert;
import cn.iocoder.yudao.module.statistics.dal.dataobject.trade.TradeStatisticsDO;
import cn.iocoder.yudao.module.statistics.dal.mysql.trade.TradeStatisticsMapper;
import cn.iocoder.yudao.module.statistics.service.trade.bo.TradeSummaryRespBO;
import cn.iocoder.yudao.module.trade.api.aftersale.TradeAfterSaleApi;
import cn.iocoder.yudao.module.trade.api.aftersale.dto.AfterSaleSummaryRespDTO;
import cn.iocoder.yudao.module.trade.api.brokerage.TradeBrokerageApi;
import cn.iocoder.yudao.module.trade.api.order.TradeOrderApi;
import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderSummaryRespDTO;
import cn.iocoder.yudao.module.statistics.service.trade.bo.AfterSaleSummaryRespBO;
import cn.iocoder.yudao.module.statistics.service.trade.bo.TradeOrderSummaryRespBO;
import org.springframework.stereotype.Service;
import org.springframework.util.StopWatch;
import org.springframework.validation.annotation.Validated;
@ -37,18 +34,14 @@ public class TradeStatisticsServiceImpl implements TradeStatisticsService {
@Resource
private TradeStatisticsMapper tradeStatisticsMapper;
// TODO @疯狂统计逻辑自己服务 mapper 去统计不要调用其它服务 API
// 主要的考虑点其它服务是在线的业务统计是离线业务尽量不占用他们的 db 资源
// 统计服务从建议使用从库或者从 mysql 抽取到单独的 clickhouse 或者其它的大数据组件
@Resource
private TradeOrderApi tradeOrderApi;
private TradeOrderStatisticsService tradeOrderStatisticsService;
@Resource
private TradeAfterSaleApi tradeAfterSaleApi;
private AfterSaleStatisticsService afterSaleStatisticsService;
@Resource
private TradeBrokerageApi tradeBrokerageApi;
private BrokerageStatisticsService brokerageStatisticsService;
@Resource
private PayWalletApi payWalletApi;
private PayWalletStatisticsService payWalletStatisticsService;
@Override
public TradeStatisticsComparisonRespVO<TradeSummaryRespVO> getTradeSummaryComparison() {
@ -76,6 +69,11 @@ public class TradeStatisticsServiceImpl implements TradeStatisticsService {
return TradeStatisticsConvert.INSTANCE.convert(value, reference);
}
@Override
public Integer getExpensePrice(LocalDateTime beginTime, LocalDateTime endTime) {
return tradeStatisticsMapper.selectExpensePriceByTimeBetween(beginTime, endTime);
}
@Override
public List<TradeTrendSummaryRespVO> getTradeStatisticsList(LocalDateTime beginTime, LocalDateTime endTime) {
return tradeStatisticsMapper.selectListByTimeBetween(beginTime, endTime);
@ -90,19 +88,19 @@ public class TradeStatisticsServiceImpl implements TradeStatisticsService {
// 统计
StopWatch stopWatch = new StopWatch("交易统计");
stopWatch.start("统计订单");
TradeOrderSummaryRespDTO orderSummary = tradeOrderApi.getOrderSummary(beginTime, endTime);
TradeOrderSummaryRespBO orderSummary = tradeOrderStatisticsService.getOrderSummary(beginTime, endTime);
stopWatch.stop();
stopWatch.start("统计售后");
AfterSaleSummaryRespDTO afterSaleSummary = tradeAfterSaleApi.getAfterSaleSummary(beginTime, endTime);
AfterSaleSummaryRespBO afterSaleSummary = afterSaleStatisticsService.getAfterSaleSummary(beginTime, endTime);
stopWatch.stop();
stopWatch.start("统计佣金");
Integer brokerageSettlementPrice = tradeBrokerageApi.getBrokerageSettlementPriceSummary(beginTime, endTime);
Integer brokerageSettlementPrice = brokerageStatisticsService.getBrokerageSettlementPriceSummary(beginTime, endTime);
stopWatch.stop();
stopWatch.start("统计充值");
WalletSummaryRespDTO walletSummary = payWalletApi.getWalletSummary(beginTime, endTime);
WalletSummaryRespBO walletSummary = payWalletStatisticsService.getWalletSummary(beginTime, endTime);
stopWatch.stop();
// 插入数据
TradeStatisticsDO entity = TradeStatisticsConvert.INSTANCE.convert(yesterday, orderSummary, afterSaleSummary, brokerageSettlementPrice, walletSummary);

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.trade.api.aftersale.dto;
package cn.iocoder.yudao.module.statistics.service.trade.bo;
import lombok.Data;
@ -8,7 +8,7 @@ import lombok.Data;
* @author owen
*/
@Data
public class AfterSaleSummaryRespDTO {
public class AfterSaleSummaryRespBO {
/**
* 退款订单数

View File

@ -1,19 +1,19 @@
package cn.iocoder.yudao.module.trade.api.order.dto;
package cn.iocoder.yudao.module.statistics.service.trade.bo;
import lombok.Data;
/**
* 订单统计 Response DTO
* 订单统计 Response BO
*
* @author owen
*/
@Data
public class TradeOrderSummaryRespDTO {
public class TradeOrderSummaryRespBO {
/**
* 创建订单数
*/
private Long orderCreateCount;
private Integer orderCreateCount;
/**
* 支付订单商品数
*/

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.pay.api.wallet.dto;
package cn.iocoder.yudao.module.statistics.service.trade.bo;
import lombok.Data;
@ -8,7 +8,7 @@ import lombok.Data;
* @author owen
*/
@Data
public class WalletSummaryRespDTO {
public class WalletSummaryRespBO {
/**
* 总支付金额余额单位
*/

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.iocoder.yudao.module.statistics.dal.mysql.infra.ApiAccessLogStatisticsMapper">
<select id="selectCountByIp" resultType="java.lang.Integer">
SELECT COUNT(1)
FROM infra_api_access_log
WHERE deleted = FALSE
AND create_time BETWEEN #{beginTime} AND #{endTime}
GROUP BY user_ip
</select>
<select id="selectCountByUserId" resultType="java.lang.Integer">
SELECT COUNT(1)
FROM infra_api_access_log
WHERE user_id != 0
AND deleted = FALSE
AND create_time BETWEEN #{beginTime} AND #{endTime}
GROUP BY user_id
</select>
</mapper>

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.iocoder.yudao.module.statistics.dal.mysql.member.MemberStatisticsMapper">
<select id="selectSummaryListByAreaId"
resultType="cn.iocoder.yudao.module.statistics.controller.admin.member.vo.MemberAreaStatisticsRespVO">
SELECT area_id, COUNT(1) AS userCount
FROM member_user
WHERE deleted = FALSE
GROUP BY area_id
ORDER BY userCount DESC
</select>
<select id="selectSummaryListBySex"
resultType="cn.iocoder.yudao.module.statistics.controller.admin.member.vo.MemberSexStatisticsRespVO">
SELECT sex, COUNT(1) AS userCount
FROM member_user
WHERE deleted = FALSE
GROUP BY sex
ORDER BY userCount DESC
</select>
<select id="selectUserCount" resultType="java.lang.Integer">
SELECT COUNT(1)
FROM member_user
WHERE deleted = FALSE
<if test="beginTime != null">
AND create_time >= #{beginTime}
</if>
<if test="endTime != null">
AND create_time &lt;= #{endTime}
</if>
</select>
</mapper>

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.iocoder.yudao.module.statistics.dal.mysql.pay.PayWalletStatisticsMapper">
<select id="selectRechargeSummaryByPayTimeBetween"
resultType="cn.iocoder.yudao.module.statistics.service.trade.bo.WalletSummaryRespBO">
SELECT COUNT(1) AS rechargePayCount,
SUM(pay_price) AS rechargePayPrice
FROM pay_wallet_recharge
WHERE pay_status = #{payStatus}
AND deleted = FALSE
AND pay_time BETWEEN #{beginTime} AND #{endTime}
</select>
<select id="selectRechargeSummaryByRefundTimeBetween"
resultType="cn.iocoder.yudao.module.statistics.service.trade.bo.WalletSummaryRespBO">
SELECT COUNT(1) AS rechargeRefundCount,
SUM(pay_price) AS rechargeRefundPrice
FROM pay_wallet_recharge
WHERE refund_status = #{refundStatus}
AND deleted = FALSE
AND refund_time BETWEEN #{beginTime} AND #{endTime}
</select>
<select id="selectPriceSummaryByBizTypeAndCreateTimeBetween" resultType="java.lang.Integer">
SELECT SUM(price)
FROM pay_wallet_transaction
WHERE biz_type = #{bizType}
AND deleted = FALSE
AND create_time BETWEEN #{beginTime} AND #{endTime}
</select>
<select id="selectRechargeSummaryGroupByWalletId"
resultType="cn.iocoder.yudao.module.statistics.controller.admin.member.vo.MemberSummaryRespVO">
SELECT COUNT(1) AS rechargeUserCount,
SUM(pay_price) AS rechargePrice
FROM pay_wallet_recharge
WHERE pay_status = #{payStatus}
AND deleted = FALSE
<if test="beginTime != null">
AND pay_time >= #{beginTime}
</if>
<if test="endTime != null">
AND pay_time &lt;= #{endTime}
</if>
GROUP BY wallet_id
</select>
</mapper>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.iocoder.yudao.module.statistics.dal.mysql.trade.AfterSaleStatisticsMapper">
<select id="selectSummaryByRefundTimeBetween"
resultType="cn.iocoder.yudao.module.statistics.service.trade.bo.AfterSaleSummaryRespBO">
SELECT COUNT(1) AS afterSaleCount,
SUM(refund_price) AS afterSaleRefundPrice
FROM trade_after_sale
WHERE deleted = FALSE
AND refund_time BETWEEN #{beginTime} AND #{endTime}
</select>
</mapper>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.iocoder.yudao.module.statistics.dal.mysql.trade.BrokerageStatisticsMapper">
<select id="selectSummaryPriceByStatusAndUnfreezeTimeBetween" resultType="java.lang.Integer">
SELECT SUM(price)
FROM trade_brokerage_record
WHERE biz_type = #{bizType}
AND status = #{status}
AND deleted = FALSE
AND unfreeze_time BETWEEN #{beginTime} AND #{endTime}
</select>
</mapper>

View File

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.iocoder.yudao.module.statistics.dal.mysql.trade.TradeOrderStatisticsMapper">
<select id="selectSummaryListByAreaId"
resultType="cn.iocoder.yudao.module.statistics.controller.admin.member.vo.MemberAreaStatisticsRespVO">
SELECT receiver_area_id AS areaId,
(SELECT COUNT(1)
FROM trade_order AS s
WHERE s.receiver_area_id = m.receiver_area_id) AS orderCreateCount,
(SELECT COUNT(1)
FROM trade_order AS s
WHERE s.receiver_area_id = m.receiver_area_id
AND s.pay_status = TRUE
AND s.deleted = FALSE) AS orderPayCount,
(SELECT SUM(s.pay_price)
FROM trade_order AS s
WHERE s.receiver_area_id = m.receiver_area_id
AND s.pay_status = TRUE
AND s.deleted = FALSE) AS orderPayPrice
FROM trade_order m
WHERE deleted = FALSE
GROUP BY receiver_area_id
</select>
<select id="selectUserCountByCreateTimeBetween" resultType="java.lang.Integer">
SELECT COUNT(1)
FROM trade_order
WHERE deleted = FALSE
AND create_time BETWEEN #{beginTime} AND #{endTime}
GROUP BY user_id
</select>
<select id="selectUserCountByPayTimeBetween" resultType="java.lang.Integer">
SELECT COUNT(1)
FROM trade_order
WHERE deleted = FALSE
AND pay_status = TRUE
AND pay_time BETWEEN #{beginTime} AND #{endTime}
GROUP BY user_id
</select>
<select id="selectCountByCreateTimeBetween" resultType="java.lang.Integer">
SELECT COUNT(1)
FROM trade_order
WHERE deleted = FALSE
AND create_time BETWEEN #{beginTime} AND #{endTime}
</select>
<select id="selectCountByPayTimeBetween" resultType="java.lang.Integer">
SELECT COUNT(1)
FROM trade_order
WHERE pay_status = TRUE
AND deleted = FALSE
AND create_time BETWEEN #{beginTime} AND #{endTime}
</select>
<select id="selectSummaryPriceByPayTimeBetween" resultType="java.lang.Integer">
SELECT SUM(pay_price)
FROM trade_order AS s
WHERE s.pay_status = TRUE
AND deleted = FALSE
AND create_time BETWEEN #{beginTime} AND #{endTime}
</select>
</mapper>

View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.iocoder.yudao.module.statistics.dal.mysql.trade.TradeStatisticsMapper">
<select id="selectByTimeBetween"
resultType="cn.iocoder.yudao.module.statistics.controller.admin.trade.vo.TradeTrendSummaryRespVO">
SELECT
@ -37,4 +36,16 @@
GROUP BY date
</select>
<select id="selectExpensePriceByTimeBetween" resultType="java.lang.Integer">
SELECT -- 支出金额 = 余额支付金额 + 支付佣金金额 + 商品退款金额
SUM(order_wallet_pay_price + brokerage_settlement_price + after_sale_refund_price) AS expensePrice
FROM trade_statistics
WHERE deleted = FALSE
<if test="beginTime != null">
AND time >= #{beginTime}
</if>
<if test="endTime != null">
AND time &lt;= #{endTime}
</if>
</select>
</mapper>

View File

@ -1,9 +1,5 @@
package cn.iocoder.yudao.module.trade.api.aftersale;
import cn.iocoder.yudao.module.trade.api.aftersale.dto.AfterSaleSummaryRespDTO;
import java.time.LocalDateTime;
/**
* 售后 API 接口
*
@ -11,13 +7,4 @@ import java.time.LocalDateTime;
*/
public interface TradeAfterSaleApi {
/**
* 获取售后单统计
*
* @param beginTime 起始时间
* @param endTime 截止时间
* @return 售后统计结果
*/
AfterSaleSummaryRespDTO getAfterSaleSummary(LocalDateTime beginTime, LocalDateTime endTime);
}

View File

@ -1,7 +1,5 @@
package cn.iocoder.yudao.module.trade.api.brokerage;
import java.time.LocalDateTime;
/**
* 分销 API 接口
*
@ -9,13 +7,4 @@ import java.time.LocalDateTime;
*/
public interface TradeBrokerageApi {
/**
* 获取已结算的佣金金额
*
* @param beginTime 起始时间
* @param endTime 截止时间
* @return 已结算的佣金金额
*/
Integer getBrokerageSettlementPriceSummary(LocalDateTime beginTime, LocalDateTime endTime);
}

View File

@ -1,9 +1,7 @@
package cn.iocoder.yudao.module.trade.api.order;
import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderRespDTO;
import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderSummaryRespDTO;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
@ -39,6 +37,16 @@ public interface TradeOrderApi {
*/
TradeOrderSummaryRespDTO getOrderSummary(LocalDateTime beginTime, LocalDateTime endTime);
/**
* 更新拼团相关信息到订单
*
* @param orderId 订单编号
* @param activityId 拼团活动编号
* @param combinationRecordId 拼团记录编号
* @param headId 团长编号
*/
void updateOrderCombinationInfo(Long orderId, Long activityId, Long combinationRecordId, Long headId);
// TODO 芋艿需要优化下
/**
* 取消支付订单

View File

@ -1,12 +1,10 @@
package cn.iocoder.yudao.module.trade.api.aftersale;
import cn.iocoder.yudao.module.trade.api.aftersale.dto.AfterSaleSummaryRespDTO;
import cn.iocoder.yudao.module.trade.service.aftersale.AfterSaleService;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.time.LocalDateTime;
/**
* 售后 API 接口实现类
@ -20,9 +18,4 @@ public class TradeAfterSaleApiImpl implements TradeAfterSaleApi {
@Resource
private AfterSaleService afterSaleService;
@Override
public AfterSaleSummaryRespDTO getAfterSaleSummary(LocalDateTime beginTime, LocalDateTime endTime) {
return afterSaleService.getAfterSaleSummary(beginTime, endTime);
}
}

View File

@ -5,7 +5,6 @@ import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.time.LocalDateTime;
/**
* 订单 API 接口实现类
@ -19,9 +18,4 @@ public class TradeBrokerageApiImpl implements TradeBrokerageApi {
@Resource
private BrokerageRecordService brokerageRecordService;
@Override
public Integer getBrokerageSettlementPriceSummary(LocalDateTime beginTime, LocalDateTime endTime) {
return brokerageRecordService.getBrokerageSettlementPriceSummary(beginTime, endTime);
}
}

View File

@ -1,18 +1,20 @@
package cn.iocoder.yudao.module.trade.api.order;
import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderRespDTO;
import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderSummaryRespDTO;
import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert;
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
import cn.iocoder.yudao.module.trade.service.order.TradeOrderQueryService;
import cn.iocoder.yudao.module.trade.service.order.TradeOrderUpdateService;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.ORDER_NOT_FOUND;
/**
* 订单 API 接口实现类
*
@ -42,6 +44,11 @@ public class TradeOrderApiImpl implements TradeOrderApi {
return tradeOrderQueryService.getOrderSummary(beginTime, endTime);
}
@Override
public void updateOrderCombinationInfo(Long orderId, Long activityId, Long combinationRecordId, Long headId) {
tradeOrderUpdateService.updateOrderCombinationInfo(orderId, activityId, combinationRecordId, headId);
}
@Override
public void cancelPaidOrder(Long userId, Long orderId) {
tradeOrderUpdateService.cancelPaidOrder(userId, orderId);

View File

@ -1,19 +1,14 @@
package cn.iocoder.yudao.module.trade.dal.mysql.aftersale;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.trade.api.aftersale.dto.AfterSaleSummaryRespDTO;
import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.AfterSalePageReqVO;
import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.AfterSaleDO;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.github.yulichang.toolkit.MPJWrappers;
import org.apache.ibatis.annotations.Mapper;
import java.time.LocalDateTime;
import java.util.Collection;
@Mapper
@ -53,12 +48,4 @@ public interface AfterSaleMapper extends BaseMapperX<AfterSaleDO> {
.in(AfterSaleDO::getStatus, statuses));
}
default AfterSaleSummaryRespDTO selectSummaryByRefundTimeBetween(LocalDateTime beginTime, LocalDateTime endTime) {
return BeanUtil.copyProperties(CollUtil.get(selectMaps(MPJWrappers.<AfterSaleDO>lambdaJoin()
.selectCount(AfterSaleDO::getId, AfterSaleSummaryRespDTO::getAfterSaleCount)
.selectSum(AfterSaleDO::getRefundPrice, AfterSaleSummaryRespDTO::getAfterSaleRefundPrice)
.between(AfterSaleDO::getRefundTime, beginTime, endTime)), 0),
AfterSaleSummaryRespDTO.class);
}
}

View File

@ -1,8 +1,6 @@
package cn.iocoder.yudao.module.trade.dal.mysql.brokerage;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
@ -111,13 +109,4 @@ public interface BrokerageRecordMapper extends BaseMapperX<BrokerageRecordDO> {
@Param("beginTime") LocalDateTime beginTime,
@Param("endTime") LocalDateTime endTime);
default Integer selectSummaryPriceByStatusAndUnfreezeTimeBetween(Integer bizType, Integer status,
LocalDateTime beginTime, LocalDateTime endTime) {
return Convert.toInt(CollUtil.getFirst(selectObjs(MPJWrappers.<BrokerageRecordDO>lambdaJoin()
.selectSum(BrokerageRecordDO::getPrice)
.eq(BrokerageRecordDO::getBizType, bizType)
.eq(BrokerageRecordDO::getStatus, status)
.between(BrokerageRecordDO::getUnfreezeTime, beginTime, endTime))), 0);
}
}

View File

@ -1,16 +1,12 @@
package cn.iocoder.yudao.module.trade.dal.mysql.order;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderSummaryRespDTO;
import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageReqVO;
import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderPageReqVO;
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.github.yulichang.toolkit.MPJWrappers;
import org.apache.ibatis.annotations.Mapper;
import java.time.LocalDateTime;
@ -93,19 +89,6 @@ public interface TradeOrderMapper extends BaseMapperX<TradeOrderDO> {
.eq(TradeOrderDO::getSeckillActivityId, seckillActivityId));
}
default TradeOrderSummaryRespDTO selectSummaryByPayTimeBetween(LocalDateTime beginTime, LocalDateTime endTime) {
return BeanUtil.copyProperties(CollUtil.get(selectMaps(MPJWrappers.<TradeOrderDO>lambdaJoin()
.selectCount(TradeOrderDO::getId, TradeOrderSummaryRespDTO::getOrderPayCount)
.selectSum(TradeOrderDO::getPayPrice, TradeOrderSummaryRespDTO::getOrderPayPrice)
.between(TradeOrderDO::getPayTime, beginTime, endTime)), 0),
TradeOrderSummaryRespDTO.class);
}
default Long selectCountByCreateTimeBetween(LocalDateTime beginTime, LocalDateTime endTime) {
return selectCount(new LambdaQueryWrapperX<TradeOrderDO>()
.between(TradeOrderDO::getCreateTime, beginTime, endTime));
}
default TradeOrderDO selectOneByPickUpVerifyCode(String pickUpVerifyCode) {
return selectOne(TradeOrderDO::getPickUpVerifyCode, pickUpVerifyCode);
}

View File

@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.trade.service.aftersale;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.trade.api.aftersale.dto.AfterSaleSummaryRespDTO;
import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.AfterSaleDisagreeReqVO;
import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.AfterSalePageReqVO;
import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.AfterSaleRefuseReqVO;
@ -10,8 +9,6 @@ import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppAfterSaleCre
import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppAfterSaleDeliveryReqVO;
import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.AfterSaleDO;
import java.time.LocalDateTime;
/**
* 售后订单 Service 接口
*
@ -127,13 +124,4 @@ public interface AfterSaleService {
*/
Long getApplyingAfterSaleCount(Long userId);
/**
* 获取售后单统计
*
* @param beginTime 起始时间
* @param endTime 截止时间
* @return 售后统计结果
*/
AfterSaleSummaryRespDTO getAfterSaleSummary(LocalDateTime beginTime, LocalDateTime endTime);
}

View File

@ -7,7 +7,6 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
import cn.iocoder.yudao.module.pay.api.refund.PayRefundApi;
import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO;
import cn.iocoder.yudao.module.trade.api.aftersale.dto.AfterSaleSummaryRespDTO;
import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.AfterSaleDisagreeReqVO;
import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.AfterSalePageReqVO;
import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.AfterSaleRefuseReqVO;
@ -411,9 +410,4 @@ public class AfterSaleServiceImpl implements AfterSaleService {
return tradeAfterSaleMapper.selectCountByUserIdAndStatus(userId, AfterSaleStatusEnum.APPLYING_STATUSES);
}
@Override
public AfterSaleSummaryRespDTO getAfterSaleSummary(LocalDateTime beginTime, LocalDateTime endTime) {
return tradeAfterSaleMapper.selectSummaryByRefundTimeBetween(beginTime,endTime);
}
}

View File

@ -156,13 +156,4 @@ public interface BrokerageRecordService {
*/
AppBrokerageProductPriceRespVO calculateProductBrokeragePrice(Long userId, Long spuId);
/**
* 获取已结算的佣金金额
*
* @param beginTime 起始时间
* @param endTime 截止时间
* @return 已结算的佣金金额
*/
Integer getBrokerageSettlementPriceSummary(LocalDateTime beginTime, LocalDateTime endTime);
}

View File

@ -356,13 +356,6 @@ public class BrokerageRecordServiceImpl implements BrokerageRecordService {
return respVO;
}
@Override
public Integer getBrokerageSettlementPriceSummary(LocalDateTime beginTime, LocalDateTime endTime) {
return brokerageRecordMapper.selectSummaryPriceByStatusAndUnfreezeTimeBetween(
BrokerageRecordBizTypeEnum.ORDER.getType(), BrokerageRecordStatusEnum.SETTLEMENT.getStatus(),
beginTime, endTime);
}
/**
* 获得自身的代理对象解决 AOP 生效问题
*

View File

@ -1,14 +1,12 @@
package cn.iocoder.yudao.module.trade.service.order;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderSummaryRespDTO;
import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageReqVO;
import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderPageReqVO;
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressTrackRespDTO;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
@ -148,13 +146,4 @@ public interface TradeOrderQueryService {
*/
List<TradeOrderItemDO> getOrderItemListByOrderId(Collection<Long> orderIds);
/**
* 获取订单统计
*
* @param beginTime 起始时间
* @param endTime 截止时间
* @return 订单统计结果
*/
TradeOrderSummaryRespDTO getOrderSummary(LocalDateTime beginTime, LocalDateTime endTime);
}

View File

@ -7,7 +7,6 @@ import cn.hutool.extra.spring.SpringUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderSummaryRespDTO;
import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageReqVO;
import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderPageReqVO;
import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO;
@ -25,7 +24,6 @@ import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@ -188,13 +186,6 @@ public class TradeOrderQueryServiceImpl implements TradeOrderQueryService {
.setPhone(receiverMobile));
}
@Override
public TradeOrderSummaryRespDTO getOrderSummary(LocalDateTime beginTime, LocalDateTime endTime) {
TradeOrderSummaryRespDTO dto = tradeOrderMapper.selectSummaryByPayTimeBetween(beginTime, endTime);
dto.setOrderCreateCount(tradeOrderMapper.selectCountByCreateTimeBetween(beginTime, endTime));
return dto;
}
// =================== Order Item ===================

View File

@ -1,9 +1,5 @@
package cn.iocoder.yudao.module.pay.api.wallet;
import cn.iocoder.yudao.module.pay.api.wallet.dto.WalletSummaryRespDTO;
import java.time.LocalDateTime;
/**
* 钱包 API 接口
*
@ -11,13 +7,4 @@ import java.time.LocalDateTime;
*/
public interface PayWalletApi {
/**
* 获取钱包统计
*
* @param beginTime 起始时间
* @param endTime 截止时间
* @return 钱包统计
*/
WalletSummaryRespDTO getWalletSummary(LocalDateTime beginTime, LocalDateTime endTime);
}

View File

@ -1,14 +1,11 @@
package cn.iocoder.yudao.module.pay.api.wallet;
import cn.iocoder.yudao.module.pay.api.wallet.dto.WalletSummaryRespDTO;
import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum;
import cn.iocoder.yudao.module.pay.service.wallet.PayWalletRechargeService;
import cn.iocoder.yudao.module.pay.service.wallet.PayWalletTransactionService;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.time.LocalDateTime;
/**
* 钱包 API 接口实现类
@ -24,11 +21,4 @@ public class PayWalletApiImpl implements PayWalletApi {
@Resource
private PayWalletTransactionService payWalletTransactionService;
@Override
public WalletSummaryRespDTO getWalletSummary(LocalDateTime beginTime, LocalDateTime endTime) {
WalletSummaryRespDTO walletSummary = payWalletRechargeService.getWalletSummary(beginTime, endTime);
walletSummary.setOrderWalletPayPrice(payWalletTransactionService.getPriceSummary(PayWalletBizTypeEnum.PAYMENT, beginTime, endTime));
return walletSummary;
}
}

View File

@ -1,17 +1,10 @@
package cn.iocoder.yudao.module.pay.dal.mysql.wallet;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.pay.api.wallet.dto.WalletSummaryRespDTO;
import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletRechargeDO;
import cn.iocoder.yudao.module.pay.enums.refund.PayRefundStatusEnum;
import com.github.yulichang.toolkit.MPJWrappers;
import org.apache.ibatis.annotations.Mapper;
import java.time.LocalDateTime;
@Mapper
public interface PayWalletRechargeMapper extends BaseMapperX<PayWalletRechargeDO> {
@ -25,24 +18,6 @@ public interface PayWalletRechargeMapper extends BaseMapperX<PayWalletRechargeDO
.eq(PayWalletRechargeDO::getId, id).eq(PayWalletRechargeDO::getRefundStatus, whereRefundStatus));
}
default WalletSummaryRespDTO selectRechargeSummaryByPayTimeBetween(LocalDateTime beginTime, LocalDateTime endTime) {
return BeanUtil.copyProperties(CollUtil.get(selectMaps(MPJWrappers.<PayWalletRechargeDO>lambdaJoin()
.selectCount(PayWalletRechargeDO::getId, WalletSummaryRespDTO::getRechargePayCount)
.selectSum(PayWalletRechargeDO::getPayPrice, WalletSummaryRespDTO::getRechargePayPrice)
.eq(PayWalletRechargeDO::getPayStatus, true)
.between(PayWalletRechargeDO::getPayTime, beginTime, endTime)), 0),
WalletSummaryRespDTO.class);
}
default WalletSummaryRespDTO selectRechargeSummaryByRefundTimeBetween(LocalDateTime beginTime, LocalDateTime endTime) {
return BeanUtil.copyProperties(CollUtil.get(selectMaps(MPJWrappers.<PayWalletRechargeDO>lambdaJoin()
.selectCount(PayWalletRechargeDO::getId, WalletSummaryRespDTO::getRechargeRefundCount)
.selectSum(PayWalletRechargeDO::getRefundPayPrice, WalletSummaryRespDTO::getRechargeRefundPrice)
.eq(PayWalletRechargeDO::getRefundStatus, PayRefundStatusEnum.SUCCESS.getStatus())
.between(PayWalletRechargeDO::getRefundTime, beginTime, endTime)), 0),
WalletSummaryRespDTO.class);
}
}

View File

@ -6,12 +6,9 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.transaction.AppPayWalletTransactionPageReqVO;
import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO;
import com.github.yulichang.toolkit.MPJWrappers;
import org.apache.ibatis.annotations.Mapper;
import java.time.LocalDateTime;
import java.util.Objects;
import java.util.Optional;
@Mapper
public interface PayWalletTransactionMapper extends BaseMapperX<PayWalletTransactionDO> {
@ -38,15 +35,6 @@ public interface PayWalletTransactionMapper extends BaseMapperX<PayWalletTransac
PayWalletTransactionDO::getBizType, bizType);
}
default Integer selectSummaryByBizTypeAndCreateTimeBetween(Integer type, LocalDateTime beginTime, LocalDateTime endTime) {
return Optional.ofNullable(selectOne(MPJWrappers.<PayWalletTransactionDO>lambdaJoin()
.selectSum(PayWalletTransactionDO::getPrice)
.eq(PayWalletTransactionDO::getBizType, type)
.between(PayWalletTransactionDO::getCreateTime, beginTime, endTime)))
.map(PayWalletTransactionDO::getPrice)
.orElse(0);
}
}

View File

@ -1,11 +1,8 @@
package cn.iocoder.yudao.module.pay.service.wallet;
import cn.iocoder.yudao.module.pay.api.wallet.dto.WalletSummaryRespDTO;
import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.recharge.AppPayWalletRechargeCreateReqVO;
import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletRechargeDO;
import java.time.LocalDateTime;
/**
* 钱包充值 Service 接口
*
@ -16,8 +13,8 @@ public interface PayWalletRechargeService {
/**
* 创建钱包充值记录发起充值
*
* @param userId 用户 id
* @param userType 用户类型
* @param userId 用户 id
* @param userType 用户类型
* @param createReqVO 钱包充值请求 VO
* @return 钱包充值记录
*/
@ -27,32 +24,25 @@ public interface PayWalletRechargeService {
/**
* 更新钱包充值成功
*
* @param id 钱包充值记录 id
* @param id 钱包充值记录 id
* @param payOrderId 支付订单 id
*/
void updateWalletRechargerPaid(Long id, Long payOrderId);
/**
* 发起钱包充值退款
* @param id 钱包充值编号
*
* @param id 钱包充值编号
* @param userIp 用户 ip 地址
*/
void refundWalletRecharge(Long id, String userIp);
/**
* 更新钱包充值记录为已退款
* @param id 钱包充值 id
*
* @param id 钱包充值 id
* @param payRefundId 退款单id
*/
void updateWalletRechargeRefunded(Long id, Long payRefundId);
/**
* 获取钱包统计
*
* @param beginTime 起始时间
* @param endTime 截止时间
* @return 钱包统计
*/
WalletSummaryRespDTO getWalletSummary(LocalDateTime beginTime, LocalDateTime endTime);
}

View File

@ -4,7 +4,6 @@ import cn.hutool.core.lang.Assert;
import cn.iocoder.yudao.framework.pay.core.enums.refund.PayRefundStatusRespEnum;
import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO;
import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO;
import cn.iocoder.yudao.module.pay.api.wallet.dto.WalletSummaryRespDTO;
import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.recharge.AppPayWalletRechargeCreateReqVO;
import cn.iocoder.yudao.module.pay.convert.wallet.PayWalletRechargeConvert;
import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO;
@ -258,15 +257,4 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService {
return payOrder;
}
@Override
public WalletSummaryRespDTO getWalletSummary(LocalDateTime beginTime, LocalDateTime endTime) {
WalletSummaryRespDTO paySummary = walletRechargeMapper.selectRechargeSummaryByPayTimeBetween(beginTime, endTime);
WalletSummaryRespDTO refundSummary = walletRechargeMapper.selectRechargeSummaryByRefundTimeBetween(beginTime, endTime);
paySummary.setRechargeRefundCount(refundSummary.getRechargeRefundCount());
paySummary.setRechargeRefundPrice(refundSummary.getRechargeRefundPrice());
return paySummary;
}
}

View File

@ -1,12 +1,9 @@
package cn.iocoder.yudao.module.pay.service.wallet;
import cn.iocoder.yudao.module.pay.api.wallet.dto.WalletSummaryRespDTO;
import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO;
import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO;
import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum;
import java.time.LocalDateTime;
/**
* 钱包 Service 接口
*

View File

@ -1,7 +1,6 @@
package cn.iocoder.yudao.module.pay.service.wallet;
import cn.hutool.core.lang.Assert;
import cn.iocoder.yudao.module.pay.api.wallet.dto.WalletSummaryRespDTO;
import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO;
import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO;
import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO;

View File

@ -7,7 +7,6 @@ import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum;
import cn.iocoder.yudao.module.pay.service.wallet.bo.WalletTransactionCreateReqBO;
import javax.validation.Valid;
import java.time.LocalDateTime;
/**
* 钱包余额流水 Service 接口
@ -50,14 +49,4 @@ public interface PayWalletTransactionService {
*/
PayWalletTransactionDO getWalletTransaction(String bizId, PayWalletBizTypeEnum type);
/**
* 获取支付金额合计
*
* @param bizType 业务类型
* @param beginTime 开始时间
* @param endTime 结束时间
* @return 支付金额合计
*/
Integer getPriceSummary(PayWalletBizTypeEnum bizType, LocalDateTime beginTime, LocalDateTime endTime);
}

View File

@ -13,7 +13,6 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.time.LocalDateTime;
/**
* 钱包流水 Service 实现类
@ -61,9 +60,4 @@ public class PayWalletTransactionServiceImpl implements PayWalletTransactionServ
return payWalletTransactionMapper.selectByBiz(bizId, type.getType());
}
@Override
public Integer getPriceSummary(PayWalletBizTypeEnum bizType, LocalDateTime beginTime, LocalDateTime endTime) {
return payWalletTransactionMapper.selectSummaryByBizTypeAndCreateTimeBetween(bizType.getType(), beginTime, endTime);
}
}

View File

@ -167,6 +167,7 @@ logging:
cn.iocoder.yudao.module.member.dal.mysql: debug
cn.iocoder.yudao.module.trade.dal.mysql: debug
cn.iocoder.yudao.module.promotion.dal.mysql: debug
cn.iocoder.yudao.module.statistics.dal.mysql: debug
debug: false