Merge remote-tracking branch 'origin/feature/mall_product' into feature/mall_product
commit
2e207019b3
@ -0,0 +1,21 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.recrod;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@Schema(description = "管理后台 - 拼团记录分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class CombinationRecordReqPage2VO extends PageParam {
|
||||
|
||||
@Schema(description = "团长编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "团长编号不能为空")
|
||||
private Long headId;
|
||||
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
### /promotion/activity/list-by-spu-ids 获得多个商品,近期参与的每个活动
|
||||
GET {{appApi}}/promotion/activity/list-by-spu-ids?spuIds=222&spuIds=633
|
||||
Authorization: Bearer {{appToken}}
|
||||
Content-Type: application/json
|
||||
tenant-id: {{appTenentId}}
|
||||
@ -0,0 +1,30 @@
|
||||
package cn.iocoder.yudao.module.promotion.job.combination;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.framework.common.core.KeyValue;
|
||||
import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler;
|
||||
import cn.iocoder.yudao.framework.tenant.core.job.TenantJob;
|
||||
import cn.iocoder.yudao.module.promotion.service.combination.CombinationRecordService;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 拼团过期 Job
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Component
|
||||
public class CombinationRecordExpireJob implements JobHandler {
|
||||
|
||||
@Resource
|
||||
private CombinationRecordService combinationRecordService;
|
||||
|
||||
@Override
|
||||
@TenantJob
|
||||
public String execute(String param) {
|
||||
KeyValue<Integer, Integer> keyValue = combinationRecordService.expireCombinationRecord();
|
||||
return StrUtil.format("过期拼团 {} 个, 虚拟成团 {} 个", keyValue.getKey(), keyValue.getValue());
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,9 +0,0 @@
|
||||
/**
|
||||
* TODO
|
||||
* 1. 会员总数据
|
||||
* 2. 性别统计
|
||||
* 3. 渠道统计
|
||||
* 4. 地域统计
|
||||
* 5. 会员概览
|
||||
*/
|
||||
package cn.iocoder.yudao.module.statistics.controller.admin.member;
|
||||
@ -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;
|
||||
|
||||
}
|
||||
@ -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;
|
||||
|
||||
}
|
||||
@ -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;
|
||||
|
||||
}
|
||||
@ -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));
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
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);
|
||||
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
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);
|
||||
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
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);
|
||||
|
||||
// TODO @疯狂:是不是搞个单独的 BO 呀;
|
||||
MemberSummaryRespVO selectRechargeSummaryGroupByWalletId(@Param("beginTime") LocalDateTime beginTime,
|
||||
@Param("endTime") LocalDateTime endTime,
|
||||
@Param("payStatus") Boolean payStatus);
|
||||
|
||||
}
|
||||
@ -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);
|
||||
|
||||
}
|
||||
@ -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);
|
||||
|
||||
}
|
||||
@ -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);
|
||||
|
||||
}
|
||||
@ -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);
|
||||
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,113 @@
|
||||
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 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);
|
||||
}
|
||||
|
||||
@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));
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
@ -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);
|
||||
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
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)
|
||||
.setRechargeRefundCount(refundSummary.getRechargeRefundCount())
|
||||
.setRechargeRefundPrice(refundSummary.getRechargeRefundPrice());
|
||||
return paySummary;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MemberSummaryRespVO getUserRechargeSummary(LocalDateTime beginTime, LocalDateTime endTime) {
|
||||
return payWalletStatisticsMapper.selectRechargeSummaryGroupByWalletId(beginTime, endTime, true);
|
||||
}
|
||||
|
||||
}
|
||||
@ -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);
|
||||
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,13 +1,13 @@
|
||||
package cn.iocoder.yudao.module.trade.api.brokerage;
|
||||
package cn.iocoder.yudao.module.statistics.service.trade;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 分销 API 接口
|
||||
* 分销统计 Service 接口
|
||||
*
|
||||
* @author owen
|
||||
*/
|
||||
public interface TradeBrokerageApi {
|
||||
public interface BrokerageStatisticsService {
|
||||
|
||||
/**
|
||||
* 获取已结算的佣金金额
|
||||
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@ -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);
|
||||
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@ -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;
|
||||
/**
|
||||
* 支付订单商品数
|
||||
*/
|
||||
@ -0,0 +1,22 @@
|
||||
<?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 create_time BETWEEN #{beginTime} AND #{endTime}
|
||||
AND deleted = FALSE
|
||||
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 create_time BETWEEN #{beginTime} AND #{endTime}
|
||||
AND deleted = FALSE
|
||||
GROUP BY user_id
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
@ -0,0 +1,48 @@
|
||||
<?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 pay_time BETWEEN #{beginTime} AND #{endTime}
|
||||
AND deleted = FALSE
|
||||
</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 refund_time BETWEEN #{beginTime} AND #{endTime}
|
||||
AND deleted = FALSE
|
||||
</select>
|
||||
|
||||
<select id="selectPriceSummaryByBizTypeAndCreateTimeBetween" resultType="java.lang.Integer">
|
||||
SELECT SUM(price)
|
||||
FROM pay_wallet_transaction
|
||||
WHERE biz_type = #{bizType}
|
||||
AND create_time BETWEEN #{beginTime} AND #{endTime}
|
||||
AND deleted = FALSE
|
||||
</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}
|
||||
<if test="beginTime != null">
|
||||
AND pay_time >= #{beginTime}
|
||||
</if>
|
||||
<if test="endTime != null">
|
||||
AND pay_time <= #{endTime}
|
||||
</if>
|
||||
AND deleted = FALSE
|
||||
GROUP BY wallet_id
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
@ -0,0 +1,14 @@
|
||||
<?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 refund_time BETWEEN #{beginTime} AND #{endTime}
|
||||
AND deleted = FALSE
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
@ -0,0 +1,14 @@
|
||||
<?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 unfreeze_time BETWEEN #{beginTime} AND #{endTime}
|
||||
AND deleted = FALSE
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
@ -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(DISTINCT(user_id))
|
||||
FROM trade_order
|
||||
WHERE deleted = FALSE
|
||||
AND create_time BETWEEN #{beginTime} AND #{endTime}
|
||||
</select>
|
||||
|
||||
<select id="selectUserCountByPayTimeBetween" resultType="java.lang.Integer">
|
||||
SELECT COUNT(DISTINCT(user_id))
|
||||
FROM trade_order
|
||||
WHERE pay_time BETWEEN #{beginTime} AND #{endTime}
|
||||
AND pay_status = TRUE
|
||||
AND deleted = FALSE
|
||||
</select>
|
||||
|
||||
<select id="selectCountByCreateTimeBetween" resultType="java.lang.Integer">
|
||||
SELECT COUNT(1)
|
||||
FROM trade_order
|
||||
WHERE create_time BETWEEN #{beginTime} AND #{endTime}
|
||||
AND deleted = FALSE
|
||||
</select>
|
||||
|
||||
<select id="selectCountByPayTimeBetween" resultType="java.lang.Integer">
|
||||
SELECT COUNT(1)
|
||||
FROM trade_order
|
||||
WHERE pay_status = TRUE
|
||||
AND create_time BETWEEN #{beginTime} AND #{endTime}
|
||||
AND deleted = FALSE
|
||||
</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>
|
||||
@ -1,23 +0,0 @@
|
||||
package cn.iocoder.yudao.module.trade.api.aftersale;
|
||||
|
||||
import cn.iocoder.yudao.module.trade.api.aftersale.dto.AfterSaleSummaryRespDTO;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 售后 API 接口
|
||||
*
|
||||
* @author owen
|
||||
*/
|
||||
public interface TradeAfterSaleApi {
|
||||
|
||||
/**
|
||||
* 获取售后单统计
|
||||
*
|
||||
* @param beginTime 起始时间
|
||||
* @param endTime 截止时间
|
||||
* @return 售后统计结果
|
||||
*/
|
||||
AfterSaleSummaryRespDTO getAfterSaleSummary(LocalDateTime beginTime, LocalDateTime endTime);
|
||||
|
||||
}
|
||||
@ -1,28 +0,0 @@
|
||||
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 接口实现类
|
||||
*
|
||||
* @author owen
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class TradeAfterSaleApiImpl implements TradeAfterSaleApi {
|
||||
|
||||
@Resource
|
||||
private AfterSaleService afterSaleService;
|
||||
|
||||
@Override
|
||||
public AfterSaleSummaryRespDTO getAfterSaleSummary(LocalDateTime beginTime, LocalDateTime endTime) {
|
||||
return afterSaleService.getAfterSaleSummary(beginTime, endTime);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,27 +0,0 @@
|
||||
package cn.iocoder.yudao.module.trade.api.brokerage;
|
||||
|
||||
import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageRecordService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 订单 API 接口实现类
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class TradeBrokerageApiImpl implements TradeBrokerageApi {
|
||||
|
||||
@Resource
|
||||
private BrokerageRecordService brokerageRecordService;
|
||||
|
||||
@Override
|
||||
public Integer getBrokerageSettlementPriceSummary(LocalDateTime beginTime, LocalDateTime endTime) {
|
||||
return brokerageRecordService.getBrokerageSettlementPriceSummary(beginTime, endTime);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,55 +0,0 @@
|
||||
package cn.iocoder.yudao.module.trade.service.order.handler;
|
||||
|
||||
import cn.iocoder.yudao.module.promotion.api.bargain.BargainActivityApi;
|
||||
import cn.iocoder.yudao.module.promotion.api.bargain.BargainRecordApi;
|
||||
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.enums.order.TradeOrderTypeEnum;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 砍价订单 handler 实现类
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Component
|
||||
public class TradeBargainHandler implements TradeOrderHandler {
|
||||
|
||||
@Resource
|
||||
private BargainActivityApi bargainActivityApi;
|
||||
@Resource
|
||||
private BargainRecordApi bargainRecordApi;
|
||||
|
||||
@Override
|
||||
public void beforeOrderCreate(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {
|
||||
if (TradeOrderTypeEnum.isBargain(order.getType())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 扣减砍价活动的库存
|
||||
bargainActivityApi.updateBargainActivityStock(order.getBargainActivityId(),
|
||||
-orderItems.get(0).getCount());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterOrderCreate(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {
|
||||
if (TradeOrderTypeEnum.isBargain(order.getType())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 记录砍价记录对应的订单编号
|
||||
bargainRecordApi.updateBargainRecordOrderId(order.getBargainRecordId(), order.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {
|
||||
if (TradeOrderTypeEnum.isBargain(order.getType())) {
|
||||
return;
|
||||
}
|
||||
// TODO 芋艿:取消订单时,需要增加库存
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,78 @@
|
||||
package cn.iocoder.yudao.module.trade.service.order.handler;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.iocoder.yudao.module.promotion.api.bargain.BargainActivityApi;
|
||||
import cn.iocoder.yudao.module.promotion.api.bargain.BargainRecordApi;
|
||||
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.enums.order.TradeOrderTypeEnum;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 砍价订单的 {@link TradeOrderHandler} 实现类
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Component
|
||||
public class TradeBargainOrderHandler implements TradeOrderHandler {
|
||||
|
||||
@Resource
|
||||
private BargainActivityApi bargainActivityApi;
|
||||
@Resource
|
||||
private BargainRecordApi bargainRecordApi;
|
||||
|
||||
@Override
|
||||
public void beforeOrderCreate(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {
|
||||
if (!TradeOrderTypeEnum.isBargain(order.getType())) {
|
||||
return;
|
||||
}
|
||||
// 明确校验一下
|
||||
Assert.isTrue(orderItems.size() == 1, "砍价时,只允许选择一个商品");
|
||||
|
||||
// 扣减砍价活动的库存
|
||||
bargainActivityApi.updateBargainActivityStock(order.getBargainActivityId(),
|
||||
-orderItems.get(0).getCount());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterOrderCreate(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {
|
||||
if (!TradeOrderTypeEnum.isBargain(order.getType())) {
|
||||
return;
|
||||
}
|
||||
// 明确校验一下
|
||||
Assert.isTrue(orderItems.size() == 1, "砍价时,只允许选择一个商品");
|
||||
|
||||
// 记录砍价记录对应的订单编号
|
||||
bargainRecordApi.updateBargainRecordOrderId(order.getBargainRecordId(), order.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCancelOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {
|
||||
if (!TradeOrderTypeEnum.isBargain(order.getType())) {
|
||||
return;
|
||||
}
|
||||
// 明确校验一下
|
||||
Assert.isTrue(orderItems.size() == 1, "砍价时,只允许选择一个商品");
|
||||
|
||||
// 售后的订单项,已经在 afterCancelOrderItem 回滚库存,所以这里不需要重复回滚
|
||||
orderItems = filterOrderItemListByNoneAfterSale(orderItems);
|
||||
if (CollUtil.isEmpty(orderItems)) {
|
||||
return;
|
||||
}
|
||||
afterCancelOrderItem(order, orderItems.get(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCancelOrderItem(TradeOrderDO order, TradeOrderItemDO orderItem) {
|
||||
if (!TradeOrderTypeEnum.isBargain(order.getType())) {
|
||||
return;
|
||||
}
|
||||
// 恢复(增加)砍价活动的库存
|
||||
bargainActivityApi.updateBargainActivityStock(order.getBargainActivityId(), orderItem.getCount());
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
package cn.iocoder.yudao.module.trade.service.order.handler;
|
||||
|
||||
import cn.iocoder.yudao.module.promotion.api.coupon.CouponApi;
|
||||
import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponUseReqDTO;
|
||||
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
|
||||
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 优惠劵的 {@link TradeOrderHandler} 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Component
|
||||
public class TradeCouponOrderHandler implements TradeOrderHandler {
|
||||
|
||||
@Resource
|
||||
private CouponApi couponApi;
|
||||
|
||||
@Override
|
||||
public void afterOrderCreate(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {
|
||||
if (order.getCouponId() == null || order.getCouponId() <= 0) {
|
||||
return;
|
||||
}
|
||||
// 不在前置扣减的原因,是因为优惠劵要记录使用的订单号
|
||||
couponApi.useCoupon(new CouponUseReqDTO().setId(order.getCouponId()).setUserId(order.getUserId())
|
||||
.setOrderId(order.getId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCancelOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {
|
||||
if (order.getCouponId() == null || order.getCouponId() <= 0) {
|
||||
return;
|
||||
}
|
||||
// 退回优惠劵
|
||||
couponApi.returnUsedCoupon(order.getCouponId());
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
package cn.iocoder.yudao.module.trade.service.order.handler;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
|
||||
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.dal.dataobject.order.TradeOrderItemDO;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.Collections.singletonList;
|
||||
|
||||
/**
|
||||
* 商品 SKU 库存的 {@link TradeOrderHandler} 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Component
|
||||
public class TradeProductSkuOrderHandler implements TradeOrderHandler {
|
||||
|
||||
@Resource
|
||||
private ProductSkuApi productSkuApi;
|
||||
|
||||
@Override
|
||||
public void beforeOrderCreate(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {
|
||||
productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convertNegative(orderItems));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCancelOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {
|
||||
// 售后的订单项,已经在 afterCancelOrderItem 回滚库存,所以这里不需要重复回滚
|
||||
orderItems = filterOrderItemListByNoneAfterSale(orderItems);
|
||||
if (CollUtil.isEmpty(orderItems)) {
|
||||
return;
|
||||
}
|
||||
productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convert(orderItems));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCancelOrderItem(TradeOrderDO order, TradeOrderItemDO orderItem) {
|
||||
productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convert(singletonList(orderItem)));
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,42 +0,0 @@
|
||||
package cn.iocoder.yudao.module.trade.service.order.handler;
|
||||
|
||||
import cn.iocoder.yudao.module.promotion.api.seckill.SeckillActivityApi;
|
||||
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.enums.order.TradeOrderTypeEnum;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 秒杀订单 handler 实现类
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Component
|
||||
public class TradeSeckillHandler implements TradeOrderHandler {
|
||||
|
||||
@Resource
|
||||
private SeckillActivityApi seckillActivityApi;
|
||||
|
||||
@Override
|
||||
public void beforeOrderCreate(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {
|
||||
if (TradeOrderTypeEnum.isSeckill(order.getType())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 扣减秒杀活动的库存
|
||||
seckillActivityApi.updateSeckillStock(order.getSeckillActivityId(),
|
||||
orderItems.get(0).getSkuId(), orderItems.get(0).getCount());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {
|
||||
if (TradeOrderTypeEnum.isSeckill(order.getType())) {
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,64 @@
|
||||
package cn.iocoder.yudao.module.trade.service.order.handler;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.iocoder.yudao.module.promotion.api.seckill.SeckillActivityApi;
|
||||
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.enums.order.TradeOrderTypeEnum;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 秒杀订单的 {@link TradeOrderHandler} 实现类
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Component
|
||||
public class TradeSeckillOrderHandler implements TradeOrderHandler {
|
||||
|
||||
@Resource
|
||||
private SeckillActivityApi seckillActivityApi;
|
||||
|
||||
@Override
|
||||
public void beforeOrderCreate(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {
|
||||
if (!TradeOrderTypeEnum.isSeckill(order.getType())) {
|
||||
return;
|
||||
}
|
||||
// 明确校验一下
|
||||
Assert.isTrue(orderItems.size() == 1, "秒杀时,只允许选择一个商品");
|
||||
|
||||
// 扣减秒杀活动的库存
|
||||
seckillActivityApi.updateSeckillStockDecr(order.getSeckillActivityId(),
|
||||
orderItems.get(0).getSkuId(), orderItems.get(0).getCount());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCancelOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {
|
||||
if (!TradeOrderTypeEnum.isSeckill(order.getType())) {
|
||||
return;
|
||||
}
|
||||
// 明确校验一下
|
||||
Assert.isTrue(orderItems.size() == 1, "秒杀时,只允许选择一个商品");
|
||||
|
||||
// 售后的订单项,已经在 afterCancelOrderItem 回滚库存,所以这里不需要重复回滚
|
||||
orderItems = filterOrderItemListByNoneAfterSale(orderItems);
|
||||
if (CollUtil.isEmpty(orderItems)) {
|
||||
return;
|
||||
}
|
||||
afterCancelOrderItem(order, orderItems.get(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCancelOrderItem(TradeOrderDO order, TradeOrderItemDO orderItem) {
|
||||
if (!TradeOrderTypeEnum.isSeckill(order.getType())) {
|
||||
return;
|
||||
}
|
||||
// 恢复秒杀活动的库存
|
||||
seckillActivityApi.updateSeckillStockIncr(order.getSeckillActivityId(),
|
||||
orderItem.getSkuId(), orderItem.getCount());
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,23 +0,0 @@
|
||||
package cn.iocoder.yudao.module.pay.api.wallet;
|
||||
|
||||
import cn.iocoder.yudao.module.pay.api.wallet.dto.WalletSummaryRespDTO;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 钱包 API 接口
|
||||
*
|
||||
* @author owen
|
||||
*/
|
||||
public interface PayWalletApi {
|
||||
|
||||
/**
|
||||
* 获取钱包统计
|
||||
*
|
||||
* @param beginTime 起始时间
|
||||
* @param endTime 截止时间
|
||||
* @return 钱包统计
|
||||
*/
|
||||
WalletSummaryRespDTO getWalletSummary(LocalDateTime beginTime, LocalDateTime endTime);
|
||||
|
||||
}
|
||||
@ -1,34 +0,0 @@
|
||||
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 接口实现类
|
||||
*
|
||||
* @author owen
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class PayWalletApiImpl implements PayWalletApi {
|
||||
|
||||
@Resource
|
||||
private PayWalletRechargeService payWalletRechargeService;
|
||||
@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;
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue