mirror of
				https://github.com/YunaiV/ruoyi-vue-pro.git
				synced 2025-11-04 08:06:12 +08:00 
			
		
		
		
	Merge remote-tracking branch 'origin/feature/mall_product' into feature/mall_product
This commit is contained in:
		@ -132,7 +132,9 @@ public class AreaUtils {
 | 
			
		||||
        return convertList(areas.values(), func, area -> type.getType().equals(area.getType()));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // TODO @疯狂:注释写下;
 | 
			
		||||
    public static Integer getParentIdByType(Integer id, @NonNull AreaTypeEnum type) {
 | 
			
		||||
        // TODO @疯狂:这种不要用 while true;因为万一脏数据,可能会死循环;可以转换成 for (int i = 0; i < Byte.MAX; i++) 一般是优先层级;
 | 
			
		||||
        do {
 | 
			
		||||
            Area area = AreaUtils.getArea(id);
 | 
			
		||||
            if (area == null) {
 | 
			
		||||
 | 
			
		||||
@ -6,8 +6,6 @@ import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationValidate
 | 
			
		||||
 | 
			
		||||
import javax.validation.Valid;
 | 
			
		||||
 | 
			
		||||
// TODO @芋艿:后面也再撸撸这几个接口
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 拼团记录 API 接口
 | 
			
		||||
 *
 | 
			
		||||
@ -30,7 +28,7 @@ public interface CombinationRecordApi {
 | 
			
		||||
     * 创建开团记录
 | 
			
		||||
     *
 | 
			
		||||
     * @param reqDTO 请求 DTO
 | 
			
		||||
     * @return key 开团记录编号 value 团长编号
 | 
			
		||||
     * @return key 开团记录编号、value 团长编号
 | 
			
		||||
     */
 | 
			
		||||
    KeyValue<Long, Long> createCombinationRecord(@Valid CombinationRecordCreateReqDTO reqDTO);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -29,6 +29,7 @@ public class CombinationRecordApiImpl implements CombinationRecordApi {
 | 
			
		||||
        recordService.validateCombinationRecord(userId, activityId, headId, skuId, count);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // TODO @puhui999:搞个创建的 RespDTO 哈;
 | 
			
		||||
    @Override
 | 
			
		||||
    public KeyValue<Long, Long> createCombinationRecord(CombinationRecordCreateReqDTO reqDTO) {
 | 
			
		||||
        return recordService.createCombinationRecord(reqDTO);
 | 
			
		||||
 | 
			
		||||
@ -40,6 +40,9 @@ public class CombinationRecordController {
 | 
			
		||||
    @Lazy
 | 
			
		||||
    private CombinationRecordService combinationRecordService;
 | 
			
		||||
 | 
			
		||||
    // TODO @puhui999:getBargainRecordPage 和 getBargainRecordPage 是不是可以合并;然后 CombinationRecordReqPageVO 加一个 headId;
 | 
			
		||||
    // 然后如果 headId 非空,并且第一页,单独多查询一条 head ;放到第 0 个位置;相当于说,第一页特殊一点;
 | 
			
		||||
 | 
			
		||||
    @GetMapping("/page")
 | 
			
		||||
    @Operation(summary = "获得拼团记录分页")
 | 
			
		||||
    @PreAuthorize("@ss.hasPermission('promotion:combination-record:query')")
 | 
			
		||||
@ -47,6 +50,7 @@ public class CombinationRecordController {
 | 
			
		||||
        PageResult<CombinationRecordDO> recordPage = combinationRecordService.getCombinationRecordPage(pageVO);
 | 
			
		||||
        List<CombinationActivityDO> activities = combinationActivityService.getCombinationActivityListByIds(
 | 
			
		||||
                convertSet(recordPage.getList(), CombinationRecordDO::getActivityId));
 | 
			
		||||
        // TODO @puhui999:商品没读取
 | 
			
		||||
        return success(CombinationActivityConvert.INSTANCE.convert(recordPage, activities));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -27,7 +27,6 @@ import io.swagger.v3.oas.annotations.Operation;
 | 
			
		||||
import io.swagger.v3.oas.annotations.Parameter;
 | 
			
		||||
import io.swagger.v3.oas.annotations.Parameters;
 | 
			
		||||
import io.swagger.v3.oas.annotations.tags.Tag;
 | 
			
		||||
import org.springframework.context.annotation.Lazy;
 | 
			
		||||
import org.springframework.validation.annotation.Validated;
 | 
			
		||||
import org.springframework.web.bind.annotation.*;
 | 
			
		||||
 | 
			
		||||
@ -49,20 +48,15 @@ public class AppBargainRecordController {
 | 
			
		||||
    @Resource
 | 
			
		||||
    private BargainHelpService bargainHelpService;
 | 
			
		||||
    @Resource
 | 
			
		||||
    @Lazy
 | 
			
		||||
    private BargainRecordService bargainRecordService;
 | 
			
		||||
    @Resource
 | 
			
		||||
    @Lazy
 | 
			
		||||
    private BargainActivityService bargainActivityService;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @Resource
 | 
			
		||||
    private TradeOrderApi tradeOrderApi;
 | 
			
		||||
    @Resource
 | 
			
		||||
    @Lazy
 | 
			
		||||
    private MemberUserApi memberUserApi;
 | 
			
		||||
    @Resource
 | 
			
		||||
    @Lazy
 | 
			
		||||
    private ProductSpuApi productSpuApi;
 | 
			
		||||
 | 
			
		||||
    @GetMapping("/get-summary")
 | 
			
		||||
 | 
			
		||||
@ -9,7 +9,6 @@ import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainActivityD
 | 
			
		||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 | 
			
		||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 | 
			
		||||
import org.apache.ibatis.annotations.Mapper;
 | 
			
		||||
import org.apache.ibatis.annotations.Param;
 | 
			
		||||
 | 
			
		||||
import java.time.LocalDateTime;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
@ -87,6 +86,7 @@ public interface BargainActivityMapper extends BaseMapperX<BargainActivityDO> {
 | 
			
		||||
                .last("LIMIT " + count));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // TODO @puhui999:是不是返回 BargainActivityDO 更干净哈?
 | 
			
		||||
    /**
 | 
			
		||||
     * 查询出指定 spuId 的 spu 参加的活动最接近现在的一条记录。多个的话,一个 spuId 对应一个最近的活动编号
 | 
			
		||||
     *
 | 
			
		||||
@ -94,7 +94,7 @@ public interface BargainActivityMapper extends BaseMapperX<BargainActivityDO> {
 | 
			
		||||
     * @param status 状态
 | 
			
		||||
     * @return 包含 spuId 和 activityId 的 map 对象列表
 | 
			
		||||
     */
 | 
			
		||||
    default List<Map<String, Object>> selectSpuIdAndActivityIdMapsBySpuIdsAndStatus(@Param("spuIds") Collection<Long> spuIds, @Param("status") Integer status) {
 | 
			
		||||
    default List<Map<String, Object>> selectSpuIdAndActivityIdMapsBySpuIdsAndStatus(Collection<Long> spuIds, Integer status) {
 | 
			
		||||
        return selectMaps(new QueryWrapper<BargainActivityDO>()
 | 
			
		||||
                .select("spu_id AS spuId, MAX(DISTINCT(id)) AS activityId") // 时间越大 id 也越大 直接用 id
 | 
			
		||||
                .in("spu_id", spuIds)
 | 
			
		||||
 | 
			
		||||
@ -120,6 +120,7 @@ public interface CombinationRecordMapper extends BaseMapperX<CombinationRecordDO
 | 
			
		||||
     */
 | 
			
		||||
    default Long selectCountByHeadAndStatusAndVirtualGroup(Integer status, Boolean virtualGroup, Long headId) {
 | 
			
		||||
        return selectCount(new QueryWrapper<CombinationRecordDO>()
 | 
			
		||||
                // TODO @puhui999:这种偏逻辑性的,不要给 mapper 哈;可以考虑拆成 2 个 mapper,上层也是 2 个 service;
 | 
			
		||||
                .select(status == null && virtualGroup == null && headId == null, "DISTINCT (user_id)")
 | 
			
		||||
                .eq(status != null, "status", status)
 | 
			
		||||
                .eq(virtualGroup != null, "virtual_group", virtualGroup)
 | 
			
		||||
 | 
			
		||||
@ -22,7 +22,7 @@ public class CombinationRecordExpireJob implements JobHandler {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    @TenantJob
 | 
			
		||||
    public String execute(String param) throws Exception {
 | 
			
		||||
    public String execute(String param) {
 | 
			
		||||
        KeyValue<Integer, Integer> keyValue = combinationRecordService.expireCombinationRecord();
 | 
			
		||||
        return StrUtil.format("过期拼团 {} 个, 虚拟成团 {} 个", keyValue.getKey(), keyValue.getValue());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -94,7 +94,6 @@ public class BargainActivityServiceImpl implements BargainActivityService {
 | 
			
		||||
        } else if (count > 0) {
 | 
			
		||||
            bargainActivityMapper.updateStock(id, count);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void validateBargainConflict(Long spuId, Long activityId) {
 | 
			
		||||
@ -184,12 +183,13 @@ public class BargainActivityServiceImpl implements BargainActivityService {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public List<BargainActivityDO> getBargainActivityBySpuIdsAndStatus(Collection<Long> spuIds, Integer status) {
 | 
			
		||||
        // 1.查询出指定 spuId 的 spu 参加的活动最接近现在的一条记录。多个的话,一个 spuId 对应一个最近的活动编号
 | 
			
		||||
        // 1. 查询出指定 spuId 的 spu 参加的活动最接近现在的一条记录。多个的话,一个 spuId 对应一个最近的活动编号
 | 
			
		||||
        // TODO @puhui999:我想了下,这种是不是只展示当前正在进行中的。已经结束、或者未开始的,可能没啥意义?
 | 
			
		||||
        List<Map<String, Object>> spuIdAndActivityIdMaps = bargainActivityMapper.selectSpuIdAndActivityIdMapsBySpuIdsAndStatus(spuIds, status);
 | 
			
		||||
        if (CollUtil.isEmpty(spuIdAndActivityIdMaps)) {
 | 
			
		||||
            return Collections.emptyList();
 | 
			
		||||
        }
 | 
			
		||||
        // 2.查询活动详情
 | 
			
		||||
        // 2. 查询活动详情
 | 
			
		||||
        return bargainActivityMapper.selectListByIds(convertSet(spuIdAndActivityIdMaps, map -> MapUtil.getLong(map, "activityId")));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -146,7 +146,6 @@ public interface CombinationRecordService {
 | 
			
		||||
     */
 | 
			
		||||
    PageResult<CombinationRecordDO> getCombinationRecordPage2(CombinationRecordReqPage2VO pageVO);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 【拼团活动】获得拼团记录数量 Map
 | 
			
		||||
     *
 | 
			
		||||
@ -159,7 +158,6 @@ public interface CombinationRecordService {
 | 
			
		||||
                                                              @Nullable Integer status,
 | 
			
		||||
                                                              @Nullable Long headId);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获取拼团记录
 | 
			
		||||
     *
 | 
			
		||||
 | 
			
		||||
@ -23,7 +23,6 @@ import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationR
 | 
			
		||||
import cn.iocoder.yudao.module.promotion.dal.mysql.combination.CombinationRecordMapper;
 | 
			
		||||
import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum;
 | 
			
		||||
import cn.iocoder.yudao.module.trade.api.order.TradeOrderApi;
 | 
			
		||||
import org.springframework.context.annotation.Lazy;
 | 
			
		||||
import org.springframework.scheduling.annotation.Async;
 | 
			
		||||
import org.springframework.stereotype.Service;
 | 
			
		||||
import org.springframework.transaction.annotation.Transactional;
 | 
			
		||||
@ -52,7 +51,6 @@ import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
 | 
			
		||||
public class CombinationRecordServiceImpl implements CombinationRecordService {
 | 
			
		||||
 | 
			
		||||
    @Resource
 | 
			
		||||
    @Lazy
 | 
			
		||||
    private CombinationActivityService combinationActivityService;
 | 
			
		||||
    @Resource
 | 
			
		||||
    private CombinationRecordMapper combinationRecordMapper;
 | 
			
		||||
@ -60,16 +58,13 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
 | 
			
		||||
    @Resource
 | 
			
		||||
    private MemberUserApi memberUserApi;
 | 
			
		||||
    @Resource
 | 
			
		||||
    @Lazy
 | 
			
		||||
    private ProductSpuApi productSpuApi;
 | 
			
		||||
    @Resource
 | 
			
		||||
    @Lazy
 | 
			
		||||
    private ProductSkuApi productSkuApi;
 | 
			
		||||
 | 
			
		||||
    @Resource
 | 
			
		||||
    private TradeOrderApi tradeOrderApi;
 | 
			
		||||
 | 
			
		||||
    // TODO @芋艿:在详细预览下;
 | 
			
		||||
    @Override
 | 
			
		||||
    @Transactional(rollbackFor = Exception.class)
 | 
			
		||||
    public void updateCombinationRecordStatusByUserIdAndOrderId(Integer status, Long userId, Long orderId) {
 | 
			
		||||
@ -77,6 +72,7 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
 | 
			
		||||
        CombinationRecordDO record = validateCombinationRecord(userId, orderId);
 | 
			
		||||
 | 
			
		||||
        // 更新状态
 | 
			
		||||
        // TODO @puhui999:不要整个更新,new 一个出来;why?例如说,两个线程都去更新,这样存在相互覆盖的问题
 | 
			
		||||
        record.setStatus(status);
 | 
			
		||||
        combinationRecordMapper.updateById(record);
 | 
			
		||||
    }
 | 
			
		||||
@ -169,16 +165,16 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
 | 
			
		||||
    @Override
 | 
			
		||||
    @Transactional(rollbackFor = Exception.class)
 | 
			
		||||
    public KeyValue<Long, Long> createCombinationRecord(CombinationRecordCreateReqDTO reqDTO) {
 | 
			
		||||
        // 1.校验拼团活动
 | 
			
		||||
        // 1. 校验拼团活动
 | 
			
		||||
        KeyValue<CombinationActivityDO, CombinationProductDO> keyValue = validateCombinationRecord(reqDTO.getUserId(),
 | 
			
		||||
                reqDTO.getActivityId(), reqDTO.getHeadId(), reqDTO.getSkuId(), reqDTO.getCount());
 | 
			
		||||
 | 
			
		||||
        // 2.组合数据创建拼团记录
 | 
			
		||||
        // 2. 组合数据创建拼团记录
 | 
			
		||||
        MemberUserRespDTO user = memberUserApi.getUser(reqDTO.getUserId());
 | 
			
		||||
        ProductSpuRespDTO spu = productSpuApi.getSpu(reqDTO.getSpuId());
 | 
			
		||||
        ProductSkuRespDTO sku = productSkuApi.getSku(reqDTO.getSkuId());
 | 
			
		||||
        CombinationRecordDO record = CombinationActivityConvert.INSTANCE.convert(reqDTO, keyValue.getKey(), user, spu, sku);
 | 
			
		||||
        // 2.1.如果是团长需要设置 headId 为 CombinationRecordDO#HEAD_ID_GROUP
 | 
			
		||||
        // 2.1. 如果是团长需要设置 headId 为 CombinationRecordDO#HEAD_ID_GROUP
 | 
			
		||||
        if (record.getHeadId() == null) {
 | 
			
		||||
            record.setStartTime(LocalDateTime.now())
 | 
			
		||||
                    .setExpireTime(keyValue.getKey().getStartTime().plusHours(keyValue.getKey().getLimitDuration()))
 | 
			
		||||
@ -191,12 +187,10 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
 | 
			
		||||
        }
 | 
			
		||||
        combinationRecordMapper.insert(record);
 | 
			
		||||
 | 
			
		||||
        if (ObjUtil.equal(CombinationRecordDO.HEAD_ID_GROUP, record.getHeadId())) {
 | 
			
		||||
            return new KeyValue<>(record.getId(), record.getHeadId());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 3、更新拼团记录
 | 
			
		||||
        // 3. 更新拼团记录
 | 
			
		||||
        if (ObjUtil.notEqual(CombinationRecordDO.HEAD_ID_GROUP, record.getHeadId())) {
 | 
			
		||||
            updateCombinationRecordWhenCreate(reqDTO.getHeadId(), keyValue.getKey());
 | 
			
		||||
        }
 | 
			
		||||
        return new KeyValue<>(record.getId(), record.getHeadId());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -349,6 +343,7 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public KeyValue<Integer, Integer> expireCombinationRecord() {
 | 
			
		||||
        // TODO @puhui999:数字一般是 1. 2. 这种格式哈
 | 
			
		||||
        // 1。获取所有正在进行中的过期的父拼团
 | 
			
		||||
        List<CombinationRecordDO> headExpireRecords = combinationRecordMapper.selectListByHeadIdAndStatusAndExpireTimeLt(
 | 
			
		||||
                CombinationRecordDO.HEAD_ID_GROUP, CombinationRecordStatusEnum.IN_PROGRESS.getStatus(), LocalDateTime.now());
 | 
			
		||||
@ -356,18 +351,21 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
 | 
			
		||||
            return new KeyValue<>(0, 0);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 2.获取拼团活动
 | 
			
		||||
        // 2. 获取拼团活动
 | 
			
		||||
        // TODO @puhui999:在自己模块里,变量可以简略点;例如说 activityList
 | 
			
		||||
        List<CombinationActivityDO> combinationActivities = combinationActivityService.getCombinationActivityListByIds(
 | 
			
		||||
                convertSet(headExpireRecords, CombinationRecordDO::getActivityId));
 | 
			
		||||
        Map<Long, CombinationActivityDO> activityMap = convertMap(combinationActivities, CombinationActivityDO::getId);
 | 
			
		||||
 | 
			
		||||
        // 3.校验是否虚拟成团
 | 
			
		||||
        // TODO @puhui999:job 一般不建议异步跑;因为可能下次跑,结果上次还没跑完;
 | 
			
		||||
        // TODO 这里,我们可以每个 record 处理下;然后按照是否需要虚拟拼团,各搞一个方法逻辑 + 事务;这样,保证 job 里面尽量不要大事务,而是 n 个独立小事务的处理。
 | 
			
		||||
        // 3. 校验是否虚拟成团
 | 
			
		||||
        List<CombinationRecordDO> virtualGroupHeadRecords = new ArrayList<>(); // 虚拟成团
 | 
			
		||||
        for (Iterator<CombinationRecordDO> iterator = headExpireRecords.iterator(); iterator.hasNext(); ) {
 | 
			
		||||
            CombinationRecordDO record = iterator.next();
 | 
			
		||||
            // 3.1 不匹配,则直接跳过
 | 
			
		||||
            CombinationActivityDO activityDO = activityMap.get(record.getActivityId());
 | 
			
		||||
            if (activityDO == null || !activityDO.getVirtualGroup()) { // 取不到活动的或者不是虚拟拼团的
 | 
			
		||||
            CombinationActivityDO activity = activityMap.get(record.getActivityId());
 | 
			
		||||
            if (activity == null || !activity.getVirtualGroup()) { // 取不到活动的或者不是虚拟拼团的
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            // 3.2 匹配,则移除,添加到虚拟成团中,并结束寻找
 | 
			
		||||
@ -380,7 +378,6 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
 | 
			
		||||
        getSelf().handleExpireRecord(headExpireRecords);
 | 
			
		||||
        // 5.虚拟成团
 | 
			
		||||
        getSelf().handleVirtualGroupRecord(virtualGroupHeadRecords);
 | 
			
		||||
 | 
			
		||||
        return new KeyValue<>(headExpireRecords.size(), virtualGroupHeadRecords.size());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -401,7 +398,6 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
 | 
			
		||||
        headsAndRecords.forEach(item -> {
 | 
			
		||||
            tradeOrderApi.cancelPaidOrder(item.getUserId(), item.getOrderId());
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Async
 | 
			
		||||
@ -410,9 +406,9 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 1.团员补齐
 | 
			
		||||
        // 1. 团员补齐
 | 
			
		||||
        combinationRecordMapper.insertBatch(CombinationActivityConvert.INSTANCE.convertVirtualGroupList(virtualGroupHeadRecords));
 | 
			
		||||
        // 2.更新拼团记录
 | 
			
		||||
        // 2. 更新拼团记录
 | 
			
		||||
        updateBatchCombinationRecords(virtualGroupHeadRecords, CombinationRecordStatusEnum.SUCCESS);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -7,15 +7,17 @@ import org.apache.ibatis.annotations.Param;
 | 
			
		||||
import java.time.LocalDateTime;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * API 访问日志统计 Mapper
 | 
			
		||||
 * API 访问日志的统计 Mapper
 | 
			
		||||
 *
 | 
			
		||||
 * @author owen
 | 
			
		||||
 */
 | 
			
		||||
@Mapper
 | 
			
		||||
public interface ApiAccessLogStatisticsMapper extends BaseMapperX<Object> {
 | 
			
		||||
 | 
			
		||||
    Integer selectCountByIp(@Param("beginTime") LocalDateTime beginTime, @Param("endTime") LocalDateTime endTime);
 | 
			
		||||
    Integer selectCountByIp(@Param("beginTime") LocalDateTime beginTime,
 | 
			
		||||
                            @Param("endTime") LocalDateTime endTime);
 | 
			
		||||
 | 
			
		||||
    Integer selectCountByUserId(@Param("beginTime") LocalDateTime beginTime, @Param("endTime") LocalDateTime endTime);
 | 
			
		||||
    Integer selectCountByUserId(@Param("beginTime") LocalDateTime beginTime,
 | 
			
		||||
                                @Param("endTime") LocalDateTime endTime);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -10,7 +10,7 @@ import java.time.LocalDateTime;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 会员统计 Mapper
 | 
			
		||||
 * 会员信息的统计 Mapper
 | 
			
		||||
 *
 | 
			
		||||
 * @author owen
 | 
			
		||||
 */
 | 
			
		||||
@ -21,6 +21,7 @@ public interface MemberStatisticsMapper extends BaseMapperX<Object> {
 | 
			
		||||
 | 
			
		||||
    List<MemberSexStatisticsRespVO> selectSummaryListBySex();
 | 
			
		||||
 | 
			
		||||
    Integer selectUserCount(@Param("beginTime") LocalDateTime beginTime, @Param("endTime") LocalDateTime endTime);
 | 
			
		||||
    Integer selectUserCount(@Param("beginTime") LocalDateTime beginTime,
 | 
			
		||||
                            @Param("endTime") LocalDateTime endTime);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -10,7 +10,7 @@ import org.apache.ibatis.annotations.Param;
 | 
			
		||||
import java.time.LocalDateTime;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 交易统计 Mapper
 | 
			
		||||
 * 支付钱包的统计 Mapper
 | 
			
		||||
 *
 | 
			
		||||
 * @author owen
 | 
			
		||||
 */
 | 
			
		||||
@ -29,6 +29,7 @@ public interface PayWalletStatisticsMapper extends BaseMapperX<TradeStatisticsDO
 | 
			
		||||
                                                            @Param("endTime") LocalDateTime endTime,
 | 
			
		||||
                                                            @Param("bizType") Integer bizType);
 | 
			
		||||
 | 
			
		||||
    // TODO @疯狂:是不是搞个单独的 BO 呀;
 | 
			
		||||
    MemberSummaryRespVO selectRechargeSummaryGroupByWalletId(@Param("beginTime") LocalDateTime beginTime,
 | 
			
		||||
                                                             @Param("endTime") LocalDateTime endTime,
 | 
			
		||||
                                                             @Param("payStatus") Boolean payStatus);
 | 
			
		||||
 | 
			
		||||
@ -9,7 +9,7 @@ import org.apache.ibatis.annotations.Param;
 | 
			
		||||
import java.time.LocalDateTime;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 交易统计 Mapper
 | 
			
		||||
 * 售后订单的统计 Mapper
 | 
			
		||||
 *
 | 
			
		||||
 * @author owen
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
@ -8,7 +8,7 @@ import org.apache.ibatis.annotations.Param;
 | 
			
		||||
import java.time.LocalDateTime;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 交易统计 Mapper
 | 
			
		||||
 * 订单分销的统计 Mapper
 | 
			
		||||
 *
 | 
			
		||||
 * @author owen
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
@ -10,7 +10,7 @@ import java.time.LocalDateTime;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 交易统计 Mapper
 | 
			
		||||
 * 交易订单的统计 Mapper
 | 
			
		||||
 *
 | 
			
		||||
 * @author owen
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
@ -19,6 +19,7 @@ import java.util.List;
 | 
			
		||||
@Mapper
 | 
			
		||||
public interface TradeStatisticsMapper extends BaseMapperX<TradeStatisticsDO> {
 | 
			
		||||
 | 
			
		||||
    // TODO @疯狂:这个要不要也挪到 xml 里,保持统一?
 | 
			
		||||
    @Select("SELECT IFNULL(SUM(order_create_count), 0) AS count, IFNULL(SUM(order_pay_price), 0) AS summary " +
 | 
			
		||||
            "FROM trade_statistics " +
 | 
			
		||||
            "WHERE time BETWEEN #{beginTime} AND #{endTime} AND deleted = FALSE")
 | 
			
		||||
@ -33,4 +34,5 @@ public interface TradeStatisticsMapper extends BaseMapperX<TradeStatisticsDO> {
 | 
			
		||||
 | 
			
		||||
    Integer selectExpensePriceByTimeBetween(@Param("beginTime") LocalDateTime beginTime,
 | 
			
		||||
                                            @Param("endTime") LocalDateTime endTime);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.statistics.service.infra;
 | 
			
		||||
import java.time.LocalDateTime;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * API 访问日志统计 Service 接口
 | 
			
		||||
 * API 访问日志的统计 Service 接口
 | 
			
		||||
 *
 | 
			
		||||
 * @author owen
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
@ -8,7 +8,7 @@ import javax.annotation.Resource;
 | 
			
		||||
import java.time.LocalDateTime;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * API 访问日志统计 Service 实现类
 | 
			
		||||
 * API 访问日志的统计 Service 实现类
 | 
			
		||||
 *
 | 
			
		||||
 * @author owen
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
@ -9,7 +9,7 @@ import java.time.LocalDateTime;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 会员统计 Service 接口
 | 
			
		||||
 * 会员信息的统计 Service 接口
 | 
			
		||||
 *
 | 
			
		||||
 * @author owen
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
@ -24,7 +24,7 @@ import java.util.Optional;
 | 
			
		||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 会员统计 Service 实现类
 | 
			
		||||
 * 会员信息的统计 Service 实现类
 | 
			
		||||
 *
 | 
			
		||||
 * @author owen
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
@ -6,7 +6,7 @@ import cn.iocoder.yudao.module.statistics.service.trade.bo.WalletSummaryRespBO;
 | 
			
		||||
import java.time.LocalDateTime;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 钱包统计 Service 接口
 | 
			
		||||
 * 钱包的统计 Service 接口
 | 
			
		||||
 *
 | 
			
		||||
 * @author owen
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
@ -12,7 +12,7 @@ import javax.annotation.Resource;
 | 
			
		||||
import java.time.LocalDateTime;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 钱包统计 Service 实现类
 | 
			
		||||
 * 钱包的统计 Service 实现类
 | 
			
		||||
 *
 | 
			
		||||
 * @author owen
 | 
			
		||||
 */
 | 
			
		||||
@ -31,11 +31,10 @@ public class PayWalletStatisticsServiceImpl implements PayWalletStatisticsServic
 | 
			
		||||
                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());
 | 
			
		||||
 | 
			
		||||
        // 拼接
 | 
			
		||||
        paySummary.setOrderWalletPayPrice(walletPayPrice)
 | 
			
		||||
                .setRechargeRefundCount(refundSummary.getRechargeRefundCount())
 | 
			
		||||
                .setRechargeRefundPrice(refundSummary.getRechargeRefundPrice());
 | 
			
		||||
        return paySummary;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -7,7 +7,7 @@ import java.time.LocalDateTime;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 交易订单统计 Service 接口
 | 
			
		||||
 * 交易订单的统计 Service 接口
 | 
			
		||||
 *
 | 
			
		||||
 * @author owen
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
@ -45,16 +45,15 @@ public class TradeStatisticsServiceImpl implements TradeStatisticsService {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public TradeStatisticsComparisonRespVO<TradeSummaryRespVO> getTradeSummaryComparison() {
 | 
			
		||||
        // 昨天的数据
 | 
			
		||||
        // 1.1 昨天的数据
 | 
			
		||||
        TradeSummaryRespBO yesterdayData = getTradeSummaryByDays(-1);
 | 
			
		||||
        // 前天的数据(用于对照昨天的数据)
 | 
			
		||||
        // 1.2 前天的数据(用于对照昨天的数据)
 | 
			
		||||
        TradeSummaryRespBO beforeYesterdayData = getTradeSummaryByDays(-2);
 | 
			
		||||
 | 
			
		||||
        // 本月数据;
 | 
			
		||||
        // 2.1 本月数据
 | 
			
		||||
        TradeSummaryRespBO monthData = getTradeSummaryByMonths(0);
 | 
			
		||||
        // 上月数据(用于对照本月的数据)
 | 
			
		||||
        // 2.2 上月数据(用于对照本月的数据)
 | 
			
		||||
        TradeSummaryRespBO lastMonthData = getTradeSummaryByMonths(-1);
 | 
			
		||||
 | 
			
		||||
        // 转换返回
 | 
			
		||||
        return TradeStatisticsConvert.INSTANCE.convert(yesterdayData, beforeYesterdayData, monthData, lastMonthData);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -81,31 +80,31 @@ public class TradeStatisticsServiceImpl implements TradeStatisticsService {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String statisticsYesterdayTrade() {
 | 
			
		||||
        // 处理统计参数
 | 
			
		||||
        LocalDateTime yesterday = LocalDateTime.now().minusDays(1);
 | 
			
		||||
        LocalDateTime beginTime = LocalDateTimeUtil.beginOfDay(yesterday);
 | 
			
		||||
        LocalDateTime endTime = LocalDateTimeUtil.endOfDay(yesterday);
 | 
			
		||||
        // 统计
 | 
			
		||||
        // 1.1 统计订单
 | 
			
		||||
        StopWatch stopWatch = new StopWatch("交易统计");
 | 
			
		||||
        stopWatch.start("统计订单");
 | 
			
		||||
        TradeOrderSummaryRespBO orderSummary = tradeOrderStatisticsService.getOrderSummary(beginTime, endTime);
 | 
			
		||||
        stopWatch.stop();
 | 
			
		||||
 | 
			
		||||
        // 1.2 统计售后
 | 
			
		||||
        stopWatch.start("统计售后");
 | 
			
		||||
        AfterSaleSummaryRespBO afterSaleSummary = afterSaleStatisticsService.getAfterSaleSummary(beginTime, endTime);
 | 
			
		||||
        stopWatch.stop();
 | 
			
		||||
 | 
			
		||||
        // 1.3 统计佣金
 | 
			
		||||
        stopWatch.start("统计佣金");
 | 
			
		||||
        Integer brokerageSettlementPrice = brokerageStatisticsService.getBrokerageSettlementPriceSummary(beginTime, endTime);
 | 
			
		||||
        stopWatch.stop();
 | 
			
		||||
 | 
			
		||||
        // 1.4 统计充值
 | 
			
		||||
        stopWatch.start("统计充值");
 | 
			
		||||
        WalletSummaryRespBO walletSummary = payWalletStatisticsService.getWalletSummary(beginTime, endTime);
 | 
			
		||||
        stopWatch.stop();
 | 
			
		||||
        // 插入数据
 | 
			
		||||
        TradeStatisticsDO entity = TradeStatisticsConvert.INSTANCE.convert(yesterday, orderSummary, afterSaleSummary, brokerageSettlementPrice, walletSummary);
 | 
			
		||||
 | 
			
		||||
        // 2. 插入数据
 | 
			
		||||
        TradeStatisticsDO entity = TradeStatisticsConvert.INSTANCE.convert(yesterday, orderSummary, afterSaleSummary,
 | 
			
		||||
                brokerageSettlementPrice, walletSummary);
 | 
			
		||||
        tradeStatisticsMapper.insert(entity);
 | 
			
		||||
        // 返回计时结果
 | 
			
		||||
        return stopWatch.prettyPrint();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -9,6 +9,7 @@ import lombok.Data;
 | 
			
		||||
 */
 | 
			
		||||
@Data
 | 
			
		||||
public class WalletSummaryRespBO {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 总支付金额(余额),单位:分
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
@ -1,20 +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 deleted = FALSE
 | 
			
		||||
          AND create_time BETWEEN #{beginTime} AND #{endTime}
 | 
			
		||||
        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 deleted = FALSE
 | 
			
		||||
        WHERE user_id > 0
 | 
			
		||||
          AND create_time BETWEEN #{beginTime} AND #{endTime}
 | 
			
		||||
          AND deleted = FALSE
 | 
			
		||||
        GROUP BY user_id
 | 
			
		||||
    </select>
 | 
			
		||||
 | 
			
		||||
</mapper>
 | 
			
		||||
 | 
			
		||||
@ -8,6 +8,7 @@
 | 
			
		||||
        FROM member_user
 | 
			
		||||
        WHERE deleted = FALSE
 | 
			
		||||
        GROUP BY area_id
 | 
			
		||||
        <!-- TODO @疯狂:order by 是不是交给内存哈 -->
 | 
			
		||||
        ORDER BY userCount DESC
 | 
			
		||||
    </select>
 | 
			
		||||
 | 
			
		||||
@ -17,6 +18,7 @@
 | 
			
		||||
        FROM member_user
 | 
			
		||||
        WHERE deleted = FALSE
 | 
			
		||||
        GROUP BY sex
 | 
			
		||||
        <!-- TODO @疯狂:order by 是不是交给内存哈 -->
 | 
			
		||||
        ORDER BY userCount DESC
 | 
			
		||||
    </select>
 | 
			
		||||
 | 
			
		||||
@ -31,4 +33,5 @@
 | 
			
		||||
            AND create_time <= #{endTime}
 | 
			
		||||
        </if>
 | 
			
		||||
    </select>
 | 
			
		||||
 | 
			
		||||
</mapper>
 | 
			
		||||
@ -7,8 +7,8 @@
 | 
			
		||||
               SUM(pay_price) AS rechargePayPrice
 | 
			
		||||
        FROM pay_wallet_recharge
 | 
			
		||||
        WHERE pay_status = #{payStatus}
 | 
			
		||||
          AND deleted = FALSE
 | 
			
		||||
          AND pay_time BETWEEN #{beginTime} AND #{endTime}
 | 
			
		||||
          AND deleted = FALSE
 | 
			
		||||
    </select>
 | 
			
		||||
 | 
			
		||||
    <select id="selectRechargeSummaryByRefundTimeBetween"
 | 
			
		||||
@ -17,16 +17,16 @@
 | 
			
		||||
               SUM(pay_price) AS rechargeRefundPrice
 | 
			
		||||
        FROM pay_wallet_recharge
 | 
			
		||||
        WHERE refund_status = #{refundStatus}
 | 
			
		||||
          AND deleted = FALSE
 | 
			
		||||
          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 deleted = FALSE
 | 
			
		||||
          AND create_time BETWEEN #{beginTime} AND #{endTime}
 | 
			
		||||
          AND deleted = FALSE
 | 
			
		||||
    </select>
 | 
			
		||||
 | 
			
		||||
    <select id="selectRechargeSummaryGroupByWalletId"
 | 
			
		||||
@ -35,13 +35,14 @@
 | 
			
		||||
               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 <= #{endTime}
 | 
			
		||||
        </if>
 | 
			
		||||
            AND deleted = FALSE
 | 
			
		||||
        GROUP BY wallet_id
 | 
			
		||||
    </select>
 | 
			
		||||
 | 
			
		||||
</mapper>
 | 
			
		||||
 | 
			
		||||
@ -1,12 +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 deleted = FALSE
 | 
			
		||||
          AND refund_time BETWEEN #{beginTime} AND #{endTime}
 | 
			
		||||
        WHERE refund_time BETWEEN #{beginTime} AND #{endTime}
 | 
			
		||||
          AND deleted = FALSE
 | 
			
		||||
    </select>
 | 
			
		||||
 | 
			
		||||
</mapper>
 | 
			
		||||
 | 
			
		||||
@ -1,12 +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 deleted = FALSE
 | 
			
		||||
          AND unfreeze_time BETWEEN #{beginTime} AND #{endTime}
 | 
			
		||||
          AND deleted = FALSE
 | 
			
		||||
    </select>
 | 
			
		||||
 | 
			
		||||
</mapper>
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,7 @@
 | 
			
		||||
<?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,
 | 
			
		||||
@ -33,25 +34,25 @@
 | 
			
		||||
    <select id="selectUserCountByPayTimeBetween" resultType="java.lang.Integer">
 | 
			
		||||
        SELECT COUNT(1)
 | 
			
		||||
        FROM trade_order
 | 
			
		||||
        WHERE deleted = FALSE
 | 
			
		||||
        WHERE pay_time BETWEEN #{beginTime} AND #{endTime}
 | 
			
		||||
          AND pay_status = TRUE
 | 
			
		||||
          AND pay_time BETWEEN #{beginTime} AND #{endTime}
 | 
			
		||||
          AND deleted = FALSE
 | 
			
		||||
        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}
 | 
			
		||||
        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 deleted = FALSE
 | 
			
		||||
          AND create_time BETWEEN #{beginTime} AND #{endTime}
 | 
			
		||||
          AND deleted = FALSE
 | 
			
		||||
    </select>
 | 
			
		||||
 | 
			
		||||
    <select id="selectSummaryPriceByPayTimeBetween" resultType="java.lang.Integer">
 | 
			
		||||
@ -61,4 +62,5 @@
 | 
			
		||||
          AND deleted = FALSE
 | 
			
		||||
          AND create_time BETWEEN #{beginTime} AND #{endTime}
 | 
			
		||||
    </select>
 | 
			
		||||
 | 
			
		||||
</mapper>
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,7 @@
 | 
			
		||||
<?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
 | 
			
		||||
@ -48,4 +49,5 @@
 | 
			
		||||
            AND time <= #{endTime}
 | 
			
		||||
        </if>
 | 
			
		||||
    </select>
 | 
			
		||||
 | 
			
		||||
</mapper>
 | 
			
		||||
 | 
			
		||||
@ -1,10 +0,0 @@
 | 
			
		||||
package cn.iocoder.yudao.module.trade.api.aftersale;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 售后 API 接口
 | 
			
		||||
 *
 | 
			
		||||
 * @author owen
 | 
			
		||||
 */
 | 
			
		||||
public interface TradeAfterSaleApi {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -1,10 +0,0 @@
 | 
			
		||||
package cn.iocoder.yudao.module.trade.api.brokerage;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 分销 API 接口
 | 
			
		||||
 *
 | 
			
		||||
 * @author owen
 | 
			
		||||
 */
 | 
			
		||||
public interface TradeBrokerageApi {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -28,16 +28,7 @@ public interface TradeOrderApi {
 | 
			
		||||
     */
 | 
			
		||||
    TradeOrderRespDTO getOrder(Long id);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 更新拼团相关信息到订单
 | 
			
		||||
     *
 | 
			
		||||
     * @param orderId             订单编号
 | 
			
		||||
     * @param activityId          拼团活动编号
 | 
			
		||||
     * @param combinationRecordId 拼团记录编号
 | 
			
		||||
     * @param headId              团长编号
 | 
			
		||||
     */
 | 
			
		||||
    void updateOrderCombinationInfo(Long orderId, Long activityId, Long combinationRecordId, Long headId);
 | 
			
		||||
 | 
			
		||||
    // TODO 芋艿:需要优化下;
 | 
			
		||||
    /**
 | 
			
		||||
     * 取消支付订单
 | 
			
		||||
     *
 | 
			
		||||
 | 
			
		||||
@ -1,21 +0,0 @@
 | 
			
		||||
package cn.iocoder.yudao.module.trade.api.aftersale;
 | 
			
		||||
 | 
			
		||||
import cn.iocoder.yudao.module.trade.service.aftersale.AfterSaleService;
 | 
			
		||||
import org.springframework.stereotype.Service;
 | 
			
		||||
import org.springframework.validation.annotation.Validated;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Resource;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 售后 API 接口实现类
 | 
			
		||||
 *
 | 
			
		||||
 * @author owen
 | 
			
		||||
 */
 | 
			
		||||
@Service
 | 
			
		||||
@Validated
 | 
			
		||||
public class TradeAfterSaleApiImpl implements TradeAfterSaleApi {
 | 
			
		||||
 | 
			
		||||
    @Resource
 | 
			
		||||
    private AfterSaleService afterSaleService;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -1,21 +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;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 订单 API 接口实现类
 | 
			
		||||
 *
 | 
			
		||||
 * @author HUIHUI
 | 
			
		||||
 */
 | 
			
		||||
@Service
 | 
			
		||||
@Validated
 | 
			
		||||
public class TradeBrokerageApiImpl implements TradeBrokerageApi {
 | 
			
		||||
 | 
			
		||||
    @Resource
 | 
			
		||||
    private BrokerageRecordService brokerageRecordService;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -2,10 +2,8 @@ package cn.iocoder.yudao.module.trade.api.order;
 | 
			
		||||
 | 
			
		||||
import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderRespDTO;
 | 
			
		||||
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.context.annotation.Lazy;
 | 
			
		||||
import org.springframework.stereotype.Service;
 | 
			
		||||
import org.springframework.validation.annotation.Validated;
 | 
			
		||||
 | 
			
		||||
@ -13,9 +11,6 @@ import javax.annotation.Resource;
 | 
			
		||||
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 接口实现类
 | 
			
		||||
 *
 | 
			
		||||
@ -28,7 +23,6 @@ public class TradeOrderApiImpl implements TradeOrderApi {
 | 
			
		||||
    @Resource
 | 
			
		||||
    private TradeOrderUpdateService tradeOrderUpdateService;
 | 
			
		||||
    @Resource
 | 
			
		||||
    @Lazy
 | 
			
		||||
    private TradeOrderQueryService tradeOrderQueryService;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
@ -41,11 +35,6 @@ public class TradeOrderApiImpl implements TradeOrderApi {
 | 
			
		||||
        return TradeOrderConvert.INSTANCE.convert(tradeOrderQueryService.getOrder(id));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @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);
 | 
			
		||||
 | 
			
		||||
@ -93,6 +93,7 @@ public interface TradeOrderMapper extends BaseMapperX<TradeOrderDO> {
 | 
			
		||||
        return selectOne(TradeOrderDO::getPickUpVerifyCode, pickUpVerifyCode);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // TODO @hui999:是不是只针对 combinationActivityId 的查询呀?
 | 
			
		||||
    default TradeOrderDO selectByUserIdAndActivityIdAndStatus(Long userId, Long activityId, Integer status) {
 | 
			
		||||
        return selectOne(new LambdaQueryWrapperX<TradeOrderDO>()
 | 
			
		||||
                .and(q -> q.eq(TradeOrderDO::getUserId, userId)
 | 
			
		||||
 | 
			
		||||
@ -657,7 +657,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
 | 
			
		||||
    public void updateOrderAddress(TradeOrderUpdateAddressReqVO reqVO) {
 | 
			
		||||
        // 校验交易订单
 | 
			
		||||
        TradeOrderDO order = validateOrderExists(reqVO.getId());
 | 
			
		||||
        // 只有待发货状态才可以修改订单收货地址;
 | 
			
		||||
        // 只有待发货状态,才可以修改订单收货地址;
 | 
			
		||||
        if (!TradeOrderStatusEnum.isUndelivered(order.getStatus())) {
 | 
			
		||||
            throw exception(ORDER_UPDATE_ADDRESS_FAIL_STATUS_NOT_DELIVERED);
 | 
			
		||||
        }
 | 
			
		||||
@ -823,11 +823,11 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
 | 
			
		||||
    @Override
 | 
			
		||||
    @Transactional(rollbackFor = Exception.class)
 | 
			
		||||
    public void cancelPaidOrder(Long userId, Long orderId) {
 | 
			
		||||
        // TODO 芋艿:这里实现要优化下;
 | 
			
		||||
        TradeOrderDO order = tradeOrderMapper.selectOrderByIdAndUserId(orderId, userId);
 | 
			
		||||
        if (order == null) {
 | 
			
		||||
            throw exception(ORDER_NOT_FOUND);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        cancelOrder0(order, TradeOrderCancelTypeEnum.MEMBER_CANCEL);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -10,7 +10,6 @@ import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum;
 | 
			
		||||
import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum;
 | 
			
		||||
import cn.iocoder.yudao.module.trade.service.order.TradeOrderQueryService;
 | 
			
		||||
import cn.iocoder.yudao.module.trade.service.order.TradeOrderUpdateService;
 | 
			
		||||
import org.springframework.context.annotation.Lazy;
 | 
			
		||||
import org.springframework.stereotype.Component;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Resource;
 | 
			
		||||
@ -29,14 +28,11 @@ import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.ORDER_DELIV
 | 
			
		||||
public class TradeCombinationOrderHandler implements TradeOrderHandler {
 | 
			
		||||
 | 
			
		||||
    @Resource
 | 
			
		||||
    @Lazy
 | 
			
		||||
    private TradeOrderUpdateService orderUpdateService;
 | 
			
		||||
    @Resource
 | 
			
		||||
    @Lazy
 | 
			
		||||
    private TradeOrderQueryService orderQueryService;
 | 
			
		||||
 | 
			
		||||
    @Resource
 | 
			
		||||
    @Lazy
 | 
			
		||||
    private CombinationRecordApi combinationRecordApi;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
@ -51,7 +47,9 @@ public class TradeCombinationOrderHandler implements TradeOrderHandler {
 | 
			
		||||
        TradeOrderItemDO item = orderItems.get(0);
 | 
			
		||||
        combinationRecordApi.validateCombinationRecord(order.getUserId(), order.getCombinationActivityId(),
 | 
			
		||||
                order.getCombinationHeadId(), item.getSkuId(), item.getCount());
 | 
			
		||||
        // 2. 校验该用户是否存在未支付的拼团活动订单;就是还没支付的时候,重复下单了;需要校验下;不然的话,一个拼团可以下多个单子了;
 | 
			
		||||
 | 
			
		||||
        // 2. 校验该用户是否存在未支付的拼团活动订单,避免一个拼团可以下多个单子了
 | 
			
		||||
        // TODO @puhui999:只校验未支付的拼团订单噢
 | 
			
		||||
        TradeOrderDO activityOrder = orderQueryService.getActivityOrderByUserIdAndActivityIdAndStatus(
 | 
			
		||||
                order.getUserId(), order.getCombinationActivityId(), TradeOrderStatusEnum.UNPAID.getStatus());
 | 
			
		||||
        if (activityOrder != null) {
 | 
			
		||||
 | 
			
		||||
@ -1,10 +0,0 @@
 | 
			
		||||
package cn.iocoder.yudao.module.pay.api.wallet;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 钱包 API 接口
 | 
			
		||||
 *
 | 
			
		||||
 * @author owen
 | 
			
		||||
 */
 | 
			
		||||
public interface PayWalletApi {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -1,24 +0,0 @@
 | 
			
		||||
package cn.iocoder.yudao.module.pay.api.wallet;
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 钱包 API 接口实现类
 | 
			
		||||
 *
 | 
			
		||||
 * @author owen
 | 
			
		||||
 */
 | 
			
		||||
@Service
 | 
			
		||||
@Validated
 | 
			
		||||
public class PayWalletApiImpl implements PayWalletApi {
 | 
			
		||||
 | 
			
		||||
    @Resource
 | 
			
		||||
    private PayWalletRechargeService payWalletRechargeService;
 | 
			
		||||
    @Resource
 | 
			
		||||
    private PayWalletTransactionService payWalletTransactionService;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user