营销活动:完善 review 提到的问题

This commit is contained in:
puhui999 2023-10-18 11:09:20 +08:00
parent 5842a361e2
commit 6081ce30d5
20 changed files with 163 additions and 91 deletions

View File

@ -34,10 +34,6 @@ public class ArticleBaseVO {
@Schema(description = "文章简介", requiredMode = Schema.RequiredMode.REQUIRED, example = "这是一个简介")
private String introduction;
// TODO @puhui999浏览量的字段应该不是后端新增设置的哈
@Schema(description = "浏览次数", requiredMode = Schema.RequiredMode.REQUIRED, example = "111")
private String browseCount;
@Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "排序不能为空")
private Integer sort;

View File

@ -22,6 +22,7 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@ -63,10 +64,11 @@ public class AppActivityController {
if (CollUtil.isEmpty(spuIds)) {
return new ArrayList<>();
}
LocalDateTime now = LocalDateTime.now();
List<AppActivityRespVO> activityList = new ArrayList<>();
// 拼团活动
List<CombinationActivityDO> combinationActivities = combinationActivityService.getCombinationActivityBySpuIdsAndStatus(
spuIds, CommonStatusEnum.ENABLE.getStatus());
// 拼团活动-获取开启的且开始的且没有结束的活动
List<CombinationActivityDO> combinationActivities = combinationActivityService.getCombinationActivityBySpuIdsAndStatusAndDateTimeLt(
spuIds, CommonStatusEnum.ENABLE.getStatus(), now);
if (CollUtil.isNotEmpty(combinationActivities)) {
combinationActivities.forEach(item -> {
activityList.add(new AppActivityRespVO().setId(item.getId())
@ -74,9 +76,9 @@ public class AppActivityController {
.setSpuId(item.getSpuId()).setStartTime(item.getStartTime()).setEndTime(item.getEndTime()));
});
}
// 秒杀活动
List<SeckillActivityDO> seckillActivities = seckillActivityService.getSeckillActivityBySpuIdsAndStatus(
spuIds, CommonStatusEnum.ENABLE.getStatus());
// 秒杀活动-获取开启的且开始的且没有结束的活动
List<SeckillActivityDO> seckillActivities = seckillActivityService.getSeckillActivityBySpuIdsAndStatusAndDateTimeLt(
spuIds, CommonStatusEnum.ENABLE.getStatus(), now);
if (CollUtil.isNotEmpty(seckillActivities)) {
seckillActivities.forEach(item -> {
activityList.add(new AppActivityRespVO().setId(item.getId())
@ -84,9 +86,9 @@ public class AppActivityController {
.setSpuId(item.getSpuId()).setStartTime(item.getStartTime()).setEndTime(item.getEndTime()));
});
}
// 砍价活动
List<BargainActivityDO> bargainActivities = bargainActivityService.getBargainActivityBySpuIdsAndStatus(
spuIds, CommonStatusEnum.ENABLE.getStatus());
// 砍价活动-获取开启的且开始的且没有结束的活动
List<BargainActivityDO> bargainActivities = bargainActivityService.getBargainActivityBySpuIdsAndStatusAndDateTimeLt(
spuIds, CommonStatusEnum.ENABLE.getStatus(), now);
if (CollUtil.isNotEmpty(bargainActivities)) {
bargainActivities.forEach(item -> {
activityList.add(new AppActivityRespVO().setId(item.getId())

View File

@ -13,6 +13,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.Comparator;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@ -31,7 +32,7 @@ public class AppArticleCategoryController {
public CommonResult<List<AppArticleCategoryRespVO>> getArticleCategoryList() {
List<ArticleCategoryDO> categoryList = articleCategoryService.getArticleCategoryListByStatus(
CommonStatusEnum.ENABLE.getStatus());
// TODO @puhui999排序下
categoryList.sort(Comparator.comparing(ArticleCategoryDO::getSort).reversed()); // sort 降序排列
return success(ArticleCategoryConvert.INSTANCE.convertList04(categoryList));
}

View File

@ -11,6 +11,7 @@ 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.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@ -55,5 +56,12 @@ public class AppArticleController {
return success(ArticleConvert.INSTANCE.convert01(articleService.getArticle(id)));
}
// TODO @puhui999增加浏览量实现一个接口先简单做用户规模不大 +1 即可psuniapp 那边也要接下噢
@PutMapping("/add-browseCount")
@Operation(summary = "增加文章浏览量")
@Parameter(name = "id", description = "文章编号", example = "1024")
public CommonResult<Boolean> addBrowseCount(@RequestParam("id") Long id) {
articleService.addBrowseCount(id);
return success(true);
}
}

View File

@ -204,25 +204,22 @@ public interface CombinationActivityConvert {
return respVO;
}
@Mapping(target = "id", ignore = true)
CombinationRecordDO convert5(CombinationRecordDO headRecord);
/**
* 转换生成虚拟成团虚拟记录
*
* @param virtualGroupHeadRecord 虚拟成团团长记录
* @param headRecord 虚拟成团团长记录
* @return 虚拟记录列表
*/
// TODO @puhui9991方法名建议改成 convertVirtualRecordList(CombinationRecordDO headRecord)2 220 225 可以搞成 mapstruct 一个方法默认都 copy 进去然后 set 226 232 的字段
default List<CombinationRecordDO> convertVirtualGroupList(CombinationRecordDO virtualGroupHeadRecord) {
default List<CombinationRecordDO> convertVirtualRecordList(CombinationRecordDO headRecord) {
List<CombinationRecordDO> createRecords = new ArrayList<>();
// 计算需要创建的虚拟成团记录数量
int count = virtualGroupHeadRecord.getUserSize() - virtualGroupHeadRecord.getUserCount();
int count = headRecord.getUserSize() - headRecord.getUserCount();
for (int i = 0; i < count; i++) {
// 基础信息和团长保持一致
CombinationRecordDO newRecord = new CombinationRecordDO().setActivityId(virtualGroupHeadRecord.getActivityId())
.setCombinationPrice(virtualGroupHeadRecord.getCombinationPrice()).setSpuId(virtualGroupHeadRecord.getSpuId()).setSpuName(virtualGroupHeadRecord.getSpuName())
.setPicUrl(virtualGroupHeadRecord.getPicUrl()).setSkuId(virtualGroupHeadRecord.getSkuId()).setHeadId(virtualGroupHeadRecord.getId())
.setStatus(virtualGroupHeadRecord.getStatus()) // 状态保持和创建时一致创建完成后会接着处理
.setVirtualGroup(virtualGroupHeadRecord.getVirtualGroup()).setExpireTime(virtualGroupHeadRecord.getExpireTime())
.setStartTime(virtualGroupHeadRecord.getStartTime()).setUserSize(virtualGroupHeadRecord.getUserSize()).setUserCount(virtualGroupHeadRecord.getUserCount());
CombinationRecordDO newRecord = convert5(headRecord);
// 虚拟信息
newRecord.setCount(0);
newRecord.setUserId(0L);

View File

@ -7,6 +7,8 @@ import cn.iocoder.yudao.module.promotion.controller.admin.article.vo.category.Ar
import cn.iocoder.yudao.module.promotion.dal.dataobject.article.ArticleCategoryDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* 文章分类 Mapper
*
@ -23,4 +25,8 @@ public interface ArticleCategoryMapper extends BaseMapperX<ArticleCategoryDO> {
.orderByDesc(ArticleCategoryDO::getSort));
}
default List<ArticleCategoryDO> selectListByStatus(Integer status) {
return selectList(ArticleCategoryDO::getStatus, status);
}
}

View File

@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.promotion.controller.admin.article.vo.article.ArticlePageReqVO;
import cn.iocoder.yudao.module.promotion.controller.app.article.vo.article.AppArticlePageReqVO;
import cn.iocoder.yudao.module.promotion.dal.dataobject.article.ArticleDO;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@ -42,5 +43,10 @@ public interface ArticleMapper extends BaseMapperX<ArticleDO> {
.eqIfPresent(ArticleDO::getCategoryId, pageReqVO.getCategoryId()));
}
default void updateBrowseCount(Long id) {
update(null, new LambdaUpdateWrapper<ArticleDO>()
.eq(ArticleDO::getId, id)
.setSql("browse_count = browse_count + 1"));
}
}

View File

@ -102,9 +102,19 @@ public interface BargainActivityMapper extends BaseMapperX<BargainActivityDO> {
.groupBy("spu_id"));
}
default List<BargainActivityDO> selectListByIds(Collection<Long> ids) {
/**
* 获取指定活动编号的活动列表且
* 开始时间和结束时间小于给定时间 dateTime 的活动列表
*
* @param ids 活动编号
* @param dateTime 指定日期
* @return 活动列表
*/
default List<BargainActivityDO> selectListByIdsAndDateTimeLt(Collection<Long> ids, LocalDateTime dateTime) {
return selectList(new LambdaQueryWrapperX<BargainActivityDO>()
.in(BargainActivityDO::getId, ids)
.lt(BargainActivityDO::getStartTime, dateTime)
.lt(BargainActivityDO::getEndTime, dateTime)
.orderByDesc(BargainActivityDO::getCreateTime));
}

View File

@ -10,6 +10,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@ -58,9 +59,19 @@ public interface CombinationActivityMapper extends BaseMapperX<CombinationActivi
.groupBy("spu_id"));
}
default List<CombinationActivityDO> selectListByIds(Collection<Long> ids) {
/**
* 获取指定活动编号的活动列表且
* 开始时间和结束时间小于给定时间 dateTime 的活动列表
*
* @param ids 活动编号
* @param dateTime 指定日期
* @return 活动列表
*/
default List<CombinationActivityDO> selectListByIdsAndDateTimeLt(Collection<Long> ids, LocalDateTime dateTime) {
return selectList(new LambdaQueryWrapperX<CombinationActivityDO>()
.in(CombinationActivityDO::getId, ids)
.lt(CombinationActivityDO::getStartTime, dateTime)
.lt(CombinationActivityDO::getEndTime, dateTime)
.orderByDesc(CombinationActivityDO::getCreateTime));
}

View File

@ -13,6 +13,7 @@ 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;
import java.util.List;
import java.util.Map;
@ -90,9 +91,19 @@ public interface SeckillActivityMapper extends BaseMapperX<SeckillActivityDO> {
.groupBy("spu_id"));
}
default List<SeckillActivityDO> selectListByIds(Collection<Long> ids) {
/**
* 获取指定活动编号的活动列表且
* 开始时间和结束时间小于给定时间 dateTime 的活动列表
*
* @param ids 活动编号
* @param dateTime 指定日期
* @return 活动列表
*/
default List<SeckillActivityDO> selectListByIdsAndDateTimeLt(Collection<Long> ids, LocalDateTime dateTime) {
return selectList(new LambdaQueryWrapperX<SeckillActivityDO>()
.in(SeckillActivityDO::getId, ids)
.lt(SeckillActivityDO::getStartTime, dateTime)
.lt(SeckillActivityDO::getEndTime, dateTime)
.orderByDesc(SeckillActivityDO::getCreateTime));
}

View File

@ -1,13 +1,11 @@
package cn.iocoder.yudao.module.promotion.service.article;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.promotion.controller.admin.article.vo.category.ArticleCategoryCreateReqVO;
import cn.iocoder.yudao.module.promotion.controller.admin.article.vo.category.ArticleCategoryPageReqVO;
import cn.iocoder.yudao.module.promotion.controller.admin.article.vo.category.ArticleCategoryUpdateReqVO;
import cn.iocoder.yudao.module.promotion.convert.article.ArticleCategoryConvert;
import cn.iocoder.yudao.module.promotion.dal.dataobject.article.ArticleCategoryDO;
import cn.iocoder.yudao.module.promotion.dal.dataobject.article.ArticleDO;
import cn.iocoder.yudao.module.promotion.dal.mysql.article.ArticleCategoryMapper;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
@ -59,9 +57,8 @@ public class ArticleCategoryServiceImpl implements ArticleCategoryService {
// 校验存在
validateArticleCategoryExists(id);
// 校验是不是存在关联文章
// TODO @puhui999最好获得数量哈
List<ArticleDO> articleList = articleService.getArticleByCategoryId(id);
if (CollUtil.isNotEmpty(articleList)) {
Long count = articleService.getArticleCountByCategoryId(id);
if (count > 0) {
throw exception(ARTICLE_CATEGORY_DELETE_FAIL_HAVE_ARTICLES);
}
@ -87,8 +84,7 @@ public class ArticleCategoryServiceImpl implements ArticleCategoryService {
@Override
public List<ArticleCategoryDO> getArticleCategoryListByStatus(Integer status) {
// TODO @puhui999selectListByStatus
return articleCategoryMapper.selectList(ArticleCategoryDO::getStatus, status);
return articleCategoryMapper.selectListByStatus(status);
}
}

View File

@ -80,4 +80,19 @@ public interface ArticleService {
*/
List<ArticleDO> getArticleByCategoryId(Long categoryId);
/**
* 获得指定分类的文章数量
*
* @param categoryId 文章分类编号
* @return 文章数量
*/
Long getArticleCountByCategoryId(Long categoryId);
/**
* 增加文章浏览量
*
* @param id 文章编号
*/
void addBrowseCount(Long id);
}

View File

@ -10,6 +10,7 @@ import cn.iocoder.yudao.module.promotion.dal.dataobject.article.ArticleCategoryD
import cn.iocoder.yudao.module.promotion.dal.dataobject.article.ArticleDO;
import cn.iocoder.yudao.module.promotion.dal.mysql.article.ArticleMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
@ -104,4 +105,19 @@ public class ArticleServiceImpl implements ArticleService {
return articleMapper.selectList(ArticleDO::getCategoryId, categoryId);
}
@Override
public Long getArticleCountByCategoryId(Long categoryId) {
return articleMapper.selectCount(ArticleDO::getCategoryId, categoryId);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void addBrowseCount(Long id) {
// 校验文章是否存在
validateArticleExists(id);
// 增加浏览次数 TODO 先简单做用户规模不大 +1
articleMapper.updateBrowseCount(id);
}
}

View File

@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity.Ba
import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainActivityDO;
import javax.validation.Valid;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
import java.util.Set;
@ -102,10 +103,11 @@ public interface BargainActivityService {
/**
* 获取指定 spu 编号最近参加的活动每个 spuId 只返回一条记录
*
* @param spuIds spu 编号
* @param status 状态
* @param spuIds spu 编号
* @param status 状态
* @param dateTime 日期时间
* @return 砍价活动列表
*/
List<BargainActivityDO> getBargainActivityBySpuIdsAndStatus(Collection<Long> spuIds, Integer status);
List<BargainActivityDO> getBargainActivityBySpuIdsAndStatusAndDateTimeLt(Collection<Long> spuIds, Integer status, LocalDateTime dateTime);
}

View File

@ -182,15 +182,15 @@ public class BargainActivityServiceImpl implements BargainActivityService {
}
@Override
public List<BargainActivityDO> getBargainActivityBySpuIdsAndStatus(Collection<Long> spuIds, Integer status) {
public List<BargainActivityDO> getBargainActivityBySpuIdsAndStatusAndDateTimeLt(Collection<Long> spuIds, Integer status, LocalDateTime dateTime) {
// 1. 查询出指定 spuId spu 参加的活动最接近现在的一条记录多个的话一个 spuId 对应一个最近的活动编号
// TODO @puhui999我想了下这种是不是只展示当前正在进行中的已经结束或者未开始的可能没啥意义
List<Map<String, Object>> spuIdAndActivityIdMaps = bargainActivityMapper.selectSpuIdAndActivityIdMapsBySpuIdsAndStatus(spuIds, status);
if (CollUtil.isEmpty(spuIdAndActivityIdMaps)) {
return Collections.emptyList();
}
// 2. 查询活动详情
return bargainActivityMapper.selectListByIds(convertSet(spuIdAndActivityIdMaps, map -> MapUtil.getLong(map, "activityId")));
return bargainActivityMapper.selectListByIdsAndDateTimeLt(
convertSet(spuIdAndActivityIdMaps, map -> MapUtil.getLong(map, "activityId")), dateTime);
}
}

View File

@ -9,6 +9,7 @@ import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationA
import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationProductDO;
import javax.validation.Valid;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@ -120,10 +121,11 @@ public interface CombinationActivityService {
/**
* 获取指定 spu 编号最近参加的活动每个 spuId 只返回一条记录
*
* @param spuIds spu 编号
* @param status 状态
* @param spuIds spu 编号
* @param status 状态
* @param dateTime 日期时间
* @return 拼团活动列表
*/
List<CombinationActivityDO> getCombinationActivityBySpuIdsAndStatus(Collection<Long> spuIds, Integer status);
List<CombinationActivityDO> getCombinationActivityBySpuIdsAndStatusAndDateTimeLt(Collection<Long> spuIds, Integer status, LocalDateTime dateTime);
}

View File

@ -25,6 +25,7 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@ -228,14 +229,15 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic
}
@Override
public List<CombinationActivityDO> getCombinationActivityBySpuIdsAndStatus(Collection<Long> spuIds, Integer status) {
public List<CombinationActivityDO> getCombinationActivityBySpuIdsAndStatusAndDateTimeLt(Collection<Long> spuIds, Integer status, LocalDateTime dateTime) {
// 1.查询出指定 spuId spu 参加的活动最接近现在的一条记录多个的话一个 spuId 对应一个最近的活动编号
List<Map<String, Object>> spuIdAndActivityIdMaps = combinationActivityMapper.selectSpuIdAndActivityIdMapsBySpuIdsAndStatus(spuIds, status);
if (CollUtil.isEmpty(spuIdAndActivityIdMaps)) {
return Collections.emptyList();
}
// 2.查询活动详情
return combinationActivityMapper.selectListByIds(convertSet(spuIdAndActivityIdMaps, map -> MapUtil.getLong(map, "activityId")));
return combinationActivityMapper.selectListByIdsAndDateTimeLt(
convertSet(spuIdAndActivityIdMaps, map -> MapUtil.getLong(map, "activityId")), dateTime);
}
}

View File

@ -6,6 +6,7 @@ import cn.hutool.extra.spring.SpringUtil;
import cn.iocoder.yudao.framework.common.core.KeyValue;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
@ -22,6 +23,7 @@ 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 lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
@ -45,6 +47,7 @@ import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
* @author HUIHUI
*/
@Service
@Slf4j
@Validated
public class CombinationRecordServiceImpl implements CombinationRecordService {
@ -353,21 +356,21 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
// 3. 逐个处理拼团过期 or 虚拟成团
KeyValue<Integer, Integer> keyValue = new KeyValue<>(0, 0); // 统计过期拼团和虚拟成团
for (CombinationRecordDO recordDO : headExpireRecords) {
// TODO @puhui999recordDO 非必要的情况下不用带 DO直接 record;
for (CombinationRecordDO record : headExpireRecords) {
try {
CombinationActivityDO activity = activityMap.get(recordDO.getActivityId());
CombinationActivityDO activity = activityMap.get(record.getActivityId());
if (activity == null || !activity.getVirtualGroup()) { // 取不到活动的或者不是虚拟拼团的
// 3.1. 处理过期的拼团
getSelf().handleExpireRecord(recordDO);
getSelf().handleExpireRecord(record);
keyValue.setKey(keyValue.getKey() + 1);
} else {
// 3.2. 处理虚拟成团
getSelf().handleVirtualGroupRecord(recordDO);
getSelf().handleVirtualGroupRecord(record);
keyValue.setValue(keyValue.getValue() + 1);
}
} catch (Exception ignored) { // 处理异常继续循环
// TODO @puhui999需要打印异常日志
log.error("[拼团过期 or 虚拟成团][record({}) 处理异常请进行处理record 数据是:{}]",
record.getId(), JsonUtils.toJsonString(record));
}
}
return keyValue;
@ -376,68 +379,52 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
/**
* 处理过期拼团
*
* @param headExpireRecord 过期拼团团长记录列表
* @param headRecord 过期拼团团长记录
*/
@Transactional(rollbackFor = Exception.class)
public void handleExpireRecord(CombinationRecordDO headExpireRecord) {
// TODO @puhui999这里的 null 其实不用判断真出现应该要处个 npe因为就是要错哈
// TODO @puhui999headExpireRecord 可以简化成 headRecord
if (headExpireRecord == null) {
return;
}
public void handleExpireRecord(CombinationRecordDO headRecord) {
// 1.更新拼团记录
List<CombinationRecordDO> headsAndRecords = updateBatchCombinationRecords(headExpireRecord,
List<CombinationRecordDO> headAndRecords = updateBatchCombinationRecords(headRecord,
CombinationRecordStatusEnum.FAILED);
// TODO @puhui999这里的 null 其实不用判断真出现应该要处个 npe因为就是要错哈
if (headsAndRecords == null) {
return;
}
// 2.订单取消
headsAndRecords.forEach(item -> tradeOrderApi.cancelPaidOrder(item.getUserId(), item.getOrderId()));
headAndRecords.forEach(item -> tradeOrderApi.cancelPaidOrder(item.getUserId(), item.getOrderId()));
}
/**
* 处理虚拟拼团
*
* @param virtualGroupHeadRecord 虚拟成团团长记录列表
* @param headRecord 虚拟成团团长记录
*/
@Transactional(rollbackFor = Exception.class)
public void handleVirtualGroupRecord(CombinationRecordDO virtualGroupHeadRecord) {
// TODO @puhui999这里的 null 其实不用判断真出现应该要处个 npe因为就是要错哈
// TODO @puhui999headExpireRecord 可以简化成 headRecord
if (virtualGroupHeadRecord == null) {
return;
}
public void handleVirtualGroupRecord(CombinationRecordDO headRecord) {
// 1. 团员补齐
combinationRecordMapper.insertBatch(CombinationActivityConvert.INSTANCE.convertVirtualGroupList(virtualGroupHeadRecord));
combinationRecordMapper.insertBatch(CombinationActivityConvert.INSTANCE.convertVirtualRecordList(headRecord));
// 2. 更新拼团记录
updateBatchCombinationRecords(virtualGroupHeadRecord, CombinationRecordStatusEnum.SUCCESS);
updateBatchCombinationRecords(headRecord, CombinationRecordStatusEnum.SUCCESS);
}
// TODO @puhui999写下方法注释
/**
* 更新拼团记录
*
* @param headRecord 团长记录
* @param status 状态-拼团失败 FAILED 成功 SUCCESS
* @return 整团记录包含团长和团成员
*/
private List<CombinationRecordDO> updateBatchCombinationRecords(CombinationRecordDO headRecord, CombinationRecordStatusEnum status) {
// 1. 查询团成员包含团长
List<CombinationRecordDO> records = combinationRecordMapper.selectListByHeadId(headRecord.getId());
// TODO @puhui999是不是不用判断空哈例如说就一个团长然后过期
if (CollUtil.isEmpty(records)) {
return null;
}
records.add(headRecord);// 把团长加进去
// 2. 批量更新拼团记录 status endTime
List<CombinationRecordDO> updateRecords = new ArrayList<>(records.size());
LocalDateTime now = LocalDateTime.now();
records.forEach(item -> {
// TODO @puhui999record 改成 updateRecord
CombinationRecordDO record = new CombinationRecordDO().setId(item.getId())
CombinationRecordDO updateRecord = new CombinationRecordDO().setId(item.getId())
.setStatus(status.getStatus()).setEndTime(now);
if (CombinationRecordStatusEnum.isSuccess(status.getStatus())) { // 虚拟成团完事更改状态成功后还需要把参与人数修改为成团需要人数
record.setUserCount(record.getUserSize());
updateRecord.setUserCount(updateRecord.getUserSize());
}
updateRecords.add(record);
updateRecords.add(updateRecord);
});
combinationRecordMapper.updateBatch(updateRecords);
return records;

View File

@ -10,6 +10,7 @@ import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillActivityD
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillProductDO;
import javax.validation.Valid;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
@ -131,10 +132,11 @@ public interface SeckillActivityService {
/**
* 获取指定 spu 编号最近参加的活动每个 spuId 只返回一条记录
*
* @param spuIds spu 编号
* @param status 状态
* @param spuIds spu 编号
* @param status 状态
* @param dateTime 日期时间
* @return 秒杀活动列表
*/
List<SeckillActivityDO> getSeckillActivityBySpuIdsAndStatus(Collection<Long> spuIds, Integer status);
List<SeckillActivityDO> getSeckillActivityBySpuIdsAndStatusAndDateTimeLt(Collection<Long> spuIds, Integer status, LocalDateTime dateTime);
}

View File

@ -28,6 +28,7 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@ -324,14 +325,15 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
}
@Override
public List<SeckillActivityDO> getSeckillActivityBySpuIdsAndStatus(Collection<Long> spuIds, Integer status) {
public List<SeckillActivityDO> getSeckillActivityBySpuIdsAndStatusAndDateTimeLt(Collection<Long> spuIds, Integer status, LocalDateTime dateTime) {
// 1.查询出指定 spuId spu 参加的活动最接近现在的一条记录多个的话一个 spuId 对应一个最近的活动编号
List<Map<String, Object>> spuIdAndActivityIdMaps = seckillActivityMapper.selectSpuIdAndActivityIdMapsBySpuIdsAndStatus(spuIds, status);
if (CollUtil.isEmpty(spuIdAndActivityIdMaps)) {
return Collections.emptyList();
}
// 2.查询活动详情
return seckillActivityMapper.selectListByIds(convertSet(spuIdAndActivityIdMaps, map -> MapUtil.getLong(map, "activityId")));
return seckillActivityMapper.selectListByIdsAndDateTimeLt(
convertSet(spuIdAndActivityIdMaps, map -> MapUtil.getLong(map, "activityId")), dateTime);
}
}