fix: 完善拼团、秒杀、砍价活动管理

This commit is contained in:
puhui999 2023-08-06 20:21:53 +08:00
parent 5f9184904a
commit 384359c9d4
27 changed files with 245 additions and 300 deletions

View File

@ -82,14 +82,20 @@ public class LocalDateTimeUtils {
|| startTime1.isBefore(endTime2) && endTime1.isAfter(endTime2); || startTime1.isBefore(endTime2) && endTime1.isAfter(endTime2);
} }
/**
* 判断时间段是否重叠
*
* @param startTime1 开始 time1
* @param endTime1 结束 time1
* @param startTime2 开始 time2
* @param endTime2 结束 time2
* @return 重叠true 不重叠false
*/
public static boolean isOverlap(LocalTime startTime1, LocalTime endTime1, LocalTime startTime2, LocalTime endTime2) { public static boolean isOverlap(LocalTime startTime1, LocalTime endTime1, LocalTime startTime2, LocalTime endTime2) {
// 日期部分使用了当前日期LocalDate.now() // 日期部分使用了当前日期LocalDate.now()
// TODO @puhui999LocalDate.now() 抽一个变量啊哈然后注释写下之后 4 个变量不用直接调方法的时候直接计算作为入参 LocalDate nowDate = LocalDate.now();
LocalDateTime startDateTime1 = LocalDateTime.of(LocalDate.now(), startTime1); return LocalDateTimeUtil.isOverlap(LocalDateTime.of(nowDate, startTime1), LocalDateTime.of(nowDate, endTime1),
LocalDateTime endDateTime1 = LocalDateTime.of(LocalDate.now(), endTime1); LocalDateTime.of(nowDate, startTime2), LocalDateTime.of(nowDate, endTime2));
LocalDateTime startDateTime2 = LocalDateTime.of(LocalDate.now(), startTime2);
LocalDateTime endDateTime2 = LocalDateTime.of(LocalDate.now(), endTime2);
return LocalDateTimeUtil.isOverlap(startDateTime1, endDateTime1, startDateTime2, endDateTime2);
} }
} }

View File

@ -0,0 +1,23 @@
package cn.iocoder.yudao.module.promotion.api.bargain;
import cn.iocoder.yudao.module.promotion.api.bargain.dto.BargainRecordCreateReqDTO;
import javax.validation.Valid;
// TODO @芋艿后面也再撸撸这几个接口
/**
* 砍价记录 API 接口
*
* @author HUIHUI
*/
public interface BargainRecordApi {
/**
* 创建开团记录
*
* @param reqDTO 请求 DTO
*/
void createRecord(@Valid BargainRecordCreateReqDTO reqDTO);
}

View File

@ -0,0 +1,79 @@
package cn.iocoder.yudao.module.promotion.api.bargain.dto;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
// TODO @芋艿这块要在看看
/**
* 砍价记录的创建 Request DTO
*
* @author HUIHUI
*/
@Data
public class BargainRecordCreateReqDTO {
/**
* 砍价活动编号
*/
@NotNull(message = "砍价活动编号不能为空")
private Long activityId;
/**
* spu 编号
*/
@NotNull(message = "spu 编号不能为空")
private Long spuId;
/**
* sku 编号
*/
@NotNull(message = "sku 编号不能为空")
private Long skuId;
/**
* 用户编号
*/
@NotNull(message = "用户编号不能为空")
private Long userId;
/**
* 订单编号
*/
@NotNull(message = "订单编号不能为空")
private Long orderId;
/**
* 商品名字
*/
@NotEmpty(message = "商品名字不能为空")
private String spuName;
/**
* 商品图片
*/
@NotEmpty(message = "商品图片不能为空")
private String picUrl;
/**
* 砍价商品单价
*/
@NotNull(message = "砍价底价不能为空")
private Integer bargainPrice;
/**
* 商品原价单位分
*/
@NotNull(message = "商品原价不能为空")
private Integer price;
/**
* 用户昵称
*/
@NotEmpty(message = "用户昵称不能为空")
private String nickname;
/**
* 用户头像
*/
@NotEmpty(message = "用户头像不能为空")
private String avatar;
/**
* 开团状态进行中 砍价成功 砍价失败
*/
@NotNull(message = "开团状态不能为空")
private Integer status;
}

View File

@ -1,10 +0,0 @@
package cn.iocoder.yudao.module.promotion.api.combination;
/**
* 拼团活动 API 接口
*
* @author HUIHUI
*/
public interface CombinationActivityApi {
}

View File

@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.promotion.api.combination; package cn.iocoder.yudao.module.promotion.api.combination;
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO; import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO;
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordUpdateReqDTO;
import javax.validation.Valid; import javax.validation.Valid;
@ -17,7 +18,7 @@ public interface CombinationRecordApi {
* *
* @param reqDTO 请求 DTO * @param reqDTO 请求 DTO
*/ */
void createCombinationRecord(@Valid CombinationRecordCreateReqDTO reqDTO); void createRecord(@Valid CombinationRecordCreateReqDTO reqDTO);
/** /**
* 查询拼团记录是否成功 * 查询拼团记录是否成功
@ -26,25 +27,13 @@ public interface CombinationRecordApi {
* @param orderId 订单编号 * @param orderId 订单编号
* @return 拼团是否成功 * @return 拼团是否成功
*/ */
boolean isCombinationRecordSuccess(Long userId, Long orderId); boolean isRecordSuccess(Long userId, Long orderId);
// TODO @puhui999updateRecordStatus updateRecordStatusAndStartTime 看看后续是不是可以统一掉
/** /**
* 更新开团记录状态 * 更新开团记录状态
* *
* @param userId 用户编号 * @param reqDTO 请求 DTO
* @param orderId 订单编号
* @param status 状态值
*/ */
void updateCombinationRecordStatus(Long userId, Long orderId, Integer status); void updateRecordStatus(CombinationRecordUpdateReqDTO reqDTO);
/**
* 更新开团记录状态和开始时间
*
* @param userId 用户编号
* @param orderId 订单编号
* @param status 状态值
*/
void updateCombinationRecordStatusAndStartTime(Long userId, Long orderId, Integer status);
} }

View File

@ -70,7 +70,7 @@ public class CombinationRecordCreateReqDTO {
@NotEmpty(message = "用户头像不能为空") @NotEmpty(message = "用户头像不能为空")
private String avatar; private String avatar;
/** /**
* 开团状态正在开团 拼团成功 拼团失败 TODO 等待支付 * 开团状态正在开团 拼团成功 拼团失败
*/ */
@NotNull(message = "开团状态不能为空") @NotNull(message = "开团状态不能为空")
private Integer status; private Integer status;

View File

@ -0,0 +1,39 @@
package cn.iocoder.yudao.module.promotion.api.combination.dto;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
/**
* 拼团记录的更新 Request DTO
*
* @author HUIHUI
*/
@Data
public class CombinationRecordUpdateReqDTO {
/**
* 用户编号
*/
@NotNull(message = "用户编号不能为空")
private Long userId;
/**
* 订单编号
*/
@NotNull(message = "订单编号不能为空")
private Long orderId;
/**
* 开团状态正在开团 拼团成功 拼团失败
*/
@NotNull(message = "开团状态不能为空")
private Integer status;
/**
* 团开始时间
*/
private LocalDateTime startTime;
}

View File

@ -16,10 +16,9 @@ import java.util.Arrays;
@Getter @Getter
public enum CombinationRecordStatusEnum implements IntArrayValuable { public enum CombinationRecordStatusEnum implements IntArrayValuable {
WAITING(0, "未付款"), IN_PROGRESS(0, "进行中"),
IN_PROGRESS(1, "进行中"), SUCCESS(1, "拼团成功"),
SUCCESS(2, "拼团成功"), FAILED(2, "拼团失败");
FAILED(3, "拼团失败");
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CombinationRecordStatusEnum::getStatus).toArray(); public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CombinationRecordStatusEnum::getStatus).toArray();

View File

@ -1,12 +1,12 @@
package cn.iocoder.yudao.module.promotion.api.combination; package cn.iocoder.yudao.module.promotion.api.combination;
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO; import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO;
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordUpdateReqDTO;
import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum; import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum;
import cn.iocoder.yudao.module.promotion.service.combination.CombinationRecordService; import cn.iocoder.yudao.module.promotion.service.combination.CombinationRecordService;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.time.LocalDateTime;
/** /**
* 拼团活动 API 实现类 * 拼团活动 API 实现类
@ -20,23 +20,22 @@ public class CombinationRecordApiImpl implements CombinationRecordApi {
private CombinationRecordService recordService; private CombinationRecordService recordService;
@Override @Override
public void createCombinationRecord(CombinationRecordCreateReqDTO reqDTO) { public void createRecord(CombinationRecordCreateReqDTO reqDTO) {
recordService.createCombinationRecord(reqDTO); recordService.createCombinationRecord(reqDTO);
} }
@Override @Override
public boolean isCombinationRecordSuccess(Long userId, Long orderId) { public boolean isRecordSuccess(Long userId, Long orderId) {
return CombinationRecordStatusEnum.isSuccess(recordService.getCombinationRecord(userId, orderId).getStatus()); return CombinationRecordStatusEnum.isSuccess(recordService.getCombinationRecord(userId, orderId).getStatus());
} }
@Override @Override
public void updateCombinationRecordStatus(Long userId, Long orderId, Integer status) { public void updateRecordStatus(CombinationRecordUpdateReqDTO reqDTO) {
recordService.updateCombinationRecordStatusByUserIdAndOrderId(userId, orderId, status); if (null == reqDTO.getStartTime()) {
recordService.updateCombinationRecordStatusByUserIdAndOrderId(reqDTO);
} else {
recordService.updateCombinationRecordStatusAndStartTimeByUserIdAndOrderId(reqDTO);
} }
@Override
public void updateCombinationRecordStatusAndStartTime(Long userId, Long orderId, Integer status) {
recordService.updateCombinationRecordStatusAndStartTimeByUserIdAndOrderId(userId, orderId, status, LocalDateTime.now());
} }
} }

View File

@ -29,21 +29,8 @@ public class BargainActivityRespVO extends BargainActivityBaseVO {
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime; private LocalDateTime createTime;
@Schema(description = "开团人数", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "砍价成功数量", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "开团人数不能为空") private Integer successCount;
private Integer userSize;
@Schema(description = "开团组数", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "开团组数不能为空")
private Integer totalNum;
@Schema(description = "成团组数", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "成团组数不能为空")
private Integer successNum;
@Schema(description = "虚拟成团", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "虚拟成团不能为空")
private Integer virtualGroup;
@Schema(description = "活动状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") @Schema(description = "活动状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
@NotNull(message = "活动状态不能为空") @NotNull(message = "活动状态不能为空")

View File

@ -7,7 +7,7 @@ import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*; import lombok.*;
/** /**
* 砍价助力 DO * 砍价助力 DO TODO
* *
* @author HUIHUI * @author HUIHUI
*/ */

View File

@ -9,7 +9,7 @@ import lombok.*;
import java.time.LocalDateTime; import java.time.LocalDateTime;
/** /**
* 砍价记录 DO * 砍价记录 DO TODO
* *
* @author HUIHUI * @author HUIHUI
*/ */

View File

@ -52,7 +52,7 @@ public class CombinationRecordDO extends BaseDO {
/** /**
* 团长编号 * 团长编号
* *
* 关联 {@link CombinationRecordDO#getUserId()} * 关联 {@link CombinationRecordDO#getId()}
*/ */
private Long headId; private Long headId;
/** /**

View File

@ -1,12 +1,9 @@
package cn.iocoder.yudao.module.promotion.dal.mysql.bargain; package cn.iocoder.yudao.module.promotion.dal.mysql.bargain;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainRecordDO; import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainRecordDO;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/** /**
* 砍价记录 Mapper * 砍价记录 Mapper
* *
@ -15,34 +12,4 @@ import java.util.List;
@Mapper @Mapper
public interface BargainRecordMapper extends BaseMapperX<BargainRecordDO> { public interface BargainRecordMapper extends BaseMapperX<BargainRecordDO> {
// TODO @puhui999selectByUserIdAndOrderId
default BargainRecordDO selectRecord(Long userId, Long orderId) {
return selectOne(BargainRecordDO::getUserId, userId,
BargainRecordDO::getOrderId, orderId);
}
/**
* 查询砍价记录
*
* @param headId 团长编号
* @param activityId 活动编号
* @return 砍价记录
*/
default BargainRecordDO selectRecordByHeadId(Long headId, Long activityId, Integer status) {
return selectOne(new LambdaQueryWrapperX<BargainRecordDO>()
.eq(BargainRecordDO::getUserId, headId)
.eq(BargainRecordDO::getActivityId, activityId)
.eq(BargainRecordDO::getStatus, status));
}
default List<BargainRecordDO> selectListByHeadIdAndStatus(Long headId, Integer status) {
return selectList(new LambdaQueryWrapperX<BargainRecordDO>()
//.eq(BargainRecordDO::getHeadId, headId)
.eq(BargainRecordDO::getStatus, status));
}
default List<BargainRecordDO> selectListByStatus(Integer status) {
return selectList(BargainRecordDO::getStatus, status);
}
} }

View File

@ -15,8 +15,7 @@ import java.util.List;
@Mapper @Mapper
public interface CombinationRecordMapper extends BaseMapperX<CombinationRecordDO> { public interface CombinationRecordMapper extends BaseMapperX<CombinationRecordDO> {
// TODO @puhui999selectByUserIdAndOrderId default CombinationRecordDO selectByUserIdAndOrderId(Long userId, Long orderId) {
default CombinationRecordDO selectRecord(Long userId, Long orderId) {
return selectOne(CombinationRecordDO::getUserId, userId, return selectOne(CombinationRecordDO::getUserId, userId,
CombinationRecordDO::getOrderId, orderId); CombinationRecordDO::getOrderId, orderId);
} }

View File

@ -48,14 +48,6 @@ public interface BargainActivityService {
*/ */
BargainActivityDO getBargainActivity(Long id); BargainActivityDO getBargainActivity(Long id);
/**
* 获得砍价活动列表
*
* @param ids 编号
* @return 砍价活动列表
*/
List<BargainActivityDO> getBargainActivityList(Collection<Long> ids);
/** /**
* 获得砍价活动分页 * 获得砍价活动分页
* *

View File

@ -1,10 +1,6 @@
package cn.iocoder.yudao.module.promotion.service.bargain; package cn.iocoder.yudao.module.promotion.service.bargain;
import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainRecordDO;
import java.time.LocalDateTime;
/** /**
* 商品活动记录 service * 商品活动记录 service
* *
@ -12,40 +8,6 @@ import java.time.LocalDateTime;
*/ */
public interface BargainRecordService { public interface BargainRecordService {
/** // TODO
* 更新砍价状态
*
* @param userId 用户编号
* @param orderId 订单编号
* @param status 状态
*/
void updateBargainRecordStatusByUserIdAndOrderId(Long userId, Long orderId, Integer status);
///**
// * 创建砍价记录
// *
// * @param reqDTO 创建信息
// */
//void createBargainRecord(BargainRecordCreateReqDTO reqDTO);
/**
* 更新砍价状态和开始时间
*
* @param userId 用户编号
* @param orderId 订单编号
* @param status 状态
* @param startTime 开始时间
*/
void updateBargainRecordStatusAndStartTimeByUserIdAndOrderId(Long userId, Long orderId,
Integer status, LocalDateTime startTime);
/**
* 获得砍价状态
*
* @param userId 用户编号
* @param orderId 订单编号
* @return 砍价状态
*/
BargainRecordDO getBargainRecord(Long userId, Long orderId);
} }

View File

@ -18,7 +18,6 @@ import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.product.Bar
import cn.iocoder.yudao.module.promotion.convert.bargain.BargainActivityConvert; import cn.iocoder.yudao.module.promotion.convert.bargain.BargainActivityConvert;
import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainActivityDO; import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainActivityDO;
import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainProductDO; import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainProductDO;
import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainRecordDO;
import cn.iocoder.yudao.module.promotion.dal.mysql.bargain.BargainActivityMapper; import cn.iocoder.yudao.module.promotion.dal.mysql.bargain.BargainActivityMapper;
import cn.iocoder.yudao.module.promotion.dal.mysql.bargain.BargainProductMapper; import cn.iocoder.yudao.module.promotion.dal.mysql.bargain.BargainProductMapper;
import cn.iocoder.yudao.module.promotion.dal.mysql.bargain.BargainRecordMapper; import cn.iocoder.yudao.module.promotion.dal.mysql.bargain.BargainRecordMapper;
@ -27,7 +26,6 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
@ -186,11 +184,6 @@ public class BargainServiceImpl implements BargainActivityService, BargainRecord
return validateBargainActivityExists(id); return validateBargainActivityExists(id);
} }
@Override
public List<BargainActivityDO> getBargainActivityList(Collection<Long> ids) {
return bargainActivityMapper.selectBatchIds(ids);
}
@Override @Override
public PageResult<BargainActivityDO> getBargainActivityPage(BargainActivityPageReqVO pageReqVO) { public PageResult<BargainActivityDO> getBargainActivityPage(BargainActivityPageReqVO pageReqVO) {
return bargainActivityMapper.selectPage(pageReqVO); return bargainActivityMapper.selectPage(pageReqVO);
@ -201,93 +194,4 @@ public class BargainServiceImpl implements BargainActivityService, BargainRecord
return bargainProductMapper.selectListByActivityIds(ids); return bargainProductMapper.selectListByActivityIds(ids);
} }
@Override
public void updateBargainRecordStatusByUserIdAndOrderId(Long userId, Long orderId, Integer status) {
// 校验砍价是否存在
// 更新状态
recordMapper.updateById(validateBargainRecord(userId, orderId).setStatus(status));
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updateBargainRecordStatusAndStartTimeByUserIdAndOrderId(Long userId, Long orderId, Integer status, LocalDateTime startTime) {
BargainRecordDO recordDO = validateBargainRecord(userId, orderId);
// 更新状态
recordDO.setStatus(status);
// 更新开始时间
//recordDO.setStartTime(startTime);
//recordMapper.updateById(recordDO);
//
//// 更新砍价参入人数
//List<BargainRecordDO> recordDOs = recordMapper.selectListByHeadIdAndStatus(recordDO.getHeadId(), status);
//if (CollUtil.isNotEmpty(recordDOs)) {
// recordDOs.forEach(item -> {
// item.setUserCount(recordDOs.size());
// // 校验砍价是否满足要求
// if (ObjectUtil.equal(recordDOs.size(), recordDO.getUserSize())) {
// item.setStatus(BargainRecordStatusEnum.SUCCESS.getStatus());
// }
// });
//}
//recordMapper.updateBatch(recordDOs);
}
private BargainRecordDO validateBargainRecord(Long userId, Long orderId) {
// 校验砍价是否存在
BargainRecordDO recordDO = recordMapper.selectRecord(userId, orderId);
if (recordDO == null) {
throw exception(BARGAIN_RECORD_NOT_EXISTS);
}
return recordDO;
}
//@Override
//public void createBargainRecord(BargainRecordCreateReqDTO reqDTO) {
// // 1.1 校验砍价活动
// BargainActivityDO activity = validateBargainActivityExists(reqDTO.getActivityId());
// // 1.2 需要校验下他当前是不是已经参加了该砍价
// BargainRecordDO recordDO = recordMapper.selectRecord(reqDTO.getUserId(), reqDTO.getOrderId());
// if (recordDO != null) {
// throw exception(BARGAIN_RECORD_EXISTS);
// }
// // 1.3 父砍价是否存在,是否已经满了
// if (reqDTO.getHeadId() != null) {
// BargainRecordDO recordDO1 = recordMapper.selectRecordByHeadId(reqDTO.getHeadId(), reqDTO.getActivityId(), BargainRecordStatusEnum.IN_PROGRESS.getStatus());
// if (recordDO1 == null) {
// throw exception(BARGAIN_RECORD_HEAD_NOT_EXISTS);
// }
// // 校验砍价是否满足要求
// if (ObjectUtil.equal(recordDO1.getUserCount(), recordDO1.getUserSize())) {
// throw exception(BARGAIN_RECORD_USER_FULL);
// }
// }
// // TODO @puhui999应该还有一些校验后续补噶例如说一个团自己已经参与进去了不能再参与进去
//
// // 2. 创建砍价记录
// BargainRecordDO record = BargainActivityConvert.INSTANCE.convert(reqDTO);
// if (reqDTO.getHeadId() == null) {
// // TODO @puhui999不是自己呀headId 是父团长的 BargainRecordDO.id
// record.setHeadId(reqDTO.getUserId());
// }
// record.setVirtualGroup(false);
// // TODO @puhui999过期时间应该是 Date
// record.setExpireTime(activity.getLimitDuration());
// record.setUserSize(activity.getUserSize());
// recordMapper.insert(record);
//}
@Override
public BargainRecordDO getBargainRecord(Long userId, Long orderId) {
return validateBargainRecord(userId, orderId);
}
/**
* APP 端获取开团记录
*
* @return 开团记录
*/
public List<BargainRecordDO> getRecordListByStatus(Integer status) {
return recordMapper.selectListByStatus(status);
}
} }

View File

@ -1,10 +1,9 @@
package cn.iocoder.yudao.module.promotion.service.combination; package cn.iocoder.yudao.module.promotion.service.combination;
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO; import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO;
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordUpdateReqDTO;
import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationRecordDO; import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationRecordDO;
import java.time.LocalDateTime;
/** /**
* 商品活动记录 service * 商品活动记录 service
* *
@ -15,11 +14,9 @@ public interface CombinationRecordService {
/** /**
* 更新拼团状态 * 更新拼团状态
* *
* @param userId 用户编号 * @param reqDTO 请求 DTO
* @param orderId 订单编号
* @param status 状态
*/ */
void updateCombinationRecordStatusByUserIdAndOrderId(Long userId, Long orderId, Integer status); void updateCombinationRecordStatusByUserIdAndOrderId(CombinationRecordUpdateReqDTO reqDTO);
/** /**
* 创建拼团记录 * 创建拼团记录
@ -31,13 +28,9 @@ public interface CombinationRecordService {
/** /**
* 更新拼团状态和开始时间 * 更新拼团状态和开始时间
* *
* @param userId 用户编号 * @param reqDTO 请求 DTO
* @param orderId 订单编号
* @param status 状态
* @param startTime 开始时间
*/ */
void updateCombinationRecordStatusAndStartTimeByUserIdAndOrderId(Long userId, Long orderId, void updateCombinationRecordStatusAndStartTimeByUserIdAndOrderId(CombinationRecordUpdateReqDTO reqDTO);
Integer status, LocalDateTime startTime);
/** /**
* 获得拼团状态 * 获得拼团状态

View File

@ -11,6 +11,7 @@ import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO; import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO;
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordUpdateReqDTO;
import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityCreateReqVO; import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityCreateReqVO;
import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityPageReqVO; import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityPageReqVO;
import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityUpdateReqVO; import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityUpdateReqVO;
@ -29,7 +30,6 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
@ -204,27 +204,27 @@ public class CombinationServiceImpl implements CombinationActivityService, Combi
} }
@Override @Override
public void updateCombinationRecordStatusByUserIdAndOrderId(Long userId, Long orderId, Integer status) { public void updateCombinationRecordStatusByUserIdAndOrderId(CombinationRecordUpdateReqDTO reqDTO) {
// 校验拼团是否存在 // 校验拼团是否存在
CombinationRecordDO recordDO = validateCombinationRecord(userId, orderId); CombinationRecordDO recordDO = validateCombinationRecord(reqDTO.getUserId(), reqDTO.getOrderId());
// 更新状态 // 更新状态
recordDO.setStatus(status); recordDO.setStatus(reqDTO.getStatus());
recordMapper.updateById(recordDO); recordMapper.updateById(recordDO);
} }
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void updateCombinationRecordStatusAndStartTimeByUserIdAndOrderId(Long userId, Long orderId, Integer status, LocalDateTime startTime) { public void updateCombinationRecordStatusAndStartTimeByUserIdAndOrderId(CombinationRecordUpdateReqDTO reqDTO) {
CombinationRecordDO recordDO = validateCombinationRecord(userId, orderId); CombinationRecordDO recordDO = validateCombinationRecord(reqDTO.getUserId(), reqDTO.getOrderId());
// 更新状态 // 更新状态
recordDO.setStatus(status); recordDO.setStatus(reqDTO.getStatus());
// 更新开始时间 // 更新开始时间
recordDO.setStartTime(startTime); recordDO.setStartTime(reqDTO.getStartTime());
recordMapper.updateById(recordDO); recordMapper.updateById(recordDO);
// 更新拼团参入人数 // 更新拼团参入人数
List<CombinationRecordDO> recordDOs = recordMapper.selectListByHeadIdAndStatus(recordDO.getHeadId(), status); List<CombinationRecordDO> recordDOs = recordMapper.selectListByHeadIdAndStatus(recordDO.getHeadId(), reqDTO.getStatus());
if (CollUtil.isNotEmpty(recordDOs)) { if (CollUtil.isNotEmpty(recordDOs)) {
recordDOs.forEach(item -> { recordDOs.forEach(item -> {
item.setUserCount(recordDOs.size()); item.setUserCount(recordDOs.size());
@ -239,7 +239,7 @@ public class CombinationServiceImpl implements CombinationActivityService, Combi
private CombinationRecordDO validateCombinationRecord(Long userId, Long orderId) { private CombinationRecordDO validateCombinationRecord(Long userId, Long orderId) {
// 校验拼团是否存在 // 校验拼团是否存在
CombinationRecordDO recordDO = recordMapper.selectRecord(userId, orderId); CombinationRecordDO recordDO = recordMapper.selectByUserIdAndOrderId(userId, orderId);
if (recordDO == null) { if (recordDO == null) {
throw exception(COMBINATION_RECORD_NOT_EXISTS); throw exception(COMBINATION_RECORD_NOT_EXISTS);
} }
@ -251,7 +251,7 @@ public class CombinationServiceImpl implements CombinationActivityService, Combi
// 1.1 校验拼团活动 // 1.1 校验拼团活动
CombinationActivityDO activity = validateCombinationActivityExists(reqDTO.getActivityId()); CombinationActivityDO activity = validateCombinationActivityExists(reqDTO.getActivityId());
// 1.2 需要校验下他当前是不是已经参加了该拼团 // 1.2 需要校验下他当前是不是已经参加了该拼团
CombinationRecordDO recordDO = recordMapper.selectRecord(reqDTO.getUserId(), reqDTO.getOrderId()); CombinationRecordDO recordDO = recordMapper.selectByUserIdAndOrderId(reqDTO.getUserId(), reqDTO.getOrderId());
if (recordDO != null) { if (recordDO != null) {
throw exception(COMBINATION_RECORD_EXISTS); throw exception(COMBINATION_RECORD_EXISTS);
} }
@ -270,10 +270,6 @@ public class CombinationServiceImpl implements CombinationActivityService, Combi
// 2. 创建拼团记录 // 2. 创建拼团记录
CombinationRecordDO record = CombinationActivityConvert.INSTANCE.convert(reqDTO); CombinationRecordDO record = CombinationActivityConvert.INSTANCE.convert(reqDTO);
if (reqDTO.getHeadId() == null) {
// TODO @puhui999不是自己呀headId 是父团长的 CombinationRecordDO.id
record.setHeadId(reqDTO.getUserId());
}
record.setVirtualGroup(false); record.setVirtualGroup(false);
// TODO @puhui999过期时间应该是 Date // TODO @puhui999过期时间应该是 Date
record.setExpireTime(activity.getLimitDuration()); record.setExpireTime(activity.getLimitDuration());

View File

@ -62,6 +62,7 @@ public interface ErrorCodeConstants {
ErrorCode EXPRESS_NOT_EXISTS = new ErrorCode(1011004000, "快递公司不存在"); ErrorCode EXPRESS_NOT_EXISTS = new ErrorCode(1011004000, "快递公司不存在");
ErrorCode EXPRESS_CODE_DUPLICATE = new ErrorCode(1011004001, "已经存在该编码的快递公司"); ErrorCode EXPRESS_CODE_DUPLICATE = new ErrorCode(1011004001, "已经存在该编码的快递公司");
ErrorCode EXPRESS_CLIENT_NOT_PROVIDE = new ErrorCode(1011004002, "需要接入快递服务商比如【快递100】"); ErrorCode EXPRESS_CLIENT_NOT_PROVIDE = new ErrorCode(1011004002, "需要接入快递服务商比如【快递100】");
ErrorCode EXPRESS_STATUS_NOT_ENABLE = new ErrorCode(1011004003, "快递公司未启用");
ErrorCode EXPRESS_API_QUERY_ERROR = new ErrorCode(1011004101, "快递查询接口异常"); ErrorCode EXPRESS_API_QUERY_ERROR = new ErrorCode(1011004101, "快递查询接口异常");
ErrorCode EXPRESS_API_QUERY_FAILED = new ErrorCode(1011004102, "快递查询返回失败,原因:{}"); ErrorCode EXPRESS_API_QUERY_FAILED = new ErrorCode(1011004102, "快递查询返回失败,原因:{}");

View File

@ -0,0 +1,12 @@
package cn.iocoder.yudao.module.trade.enums;
/**
* 通知模板枚举类
*
* @author HUIHUI
*/
public interface MessageTemplateConstants {
String ORDER_DELIVERY = "order_delivery"; // 短信模版编号
}

View File

@ -0,0 +1,4 @@
package cn.iocoder.yudao.module.trade.enums.notify;
public interface TradeNotifyEnums {
}

View File

@ -1,6 +1,6 @@
package cn.iocoder.yudao.module.trade.service.message; package cn.iocoder.yudao.module.trade.service.message;
import cn.iocoder.yudao.module.trade.service.message.dto.TradeOrderMessageWhenDeliveryOrderReqDTO; import cn.iocoder.yudao.module.trade.service.message.bo.TradeOrderMessageWhenDeliveryOrderReqBO;
/** /**
* Trade 消息 service 接口 * Trade 消息 service 接口
@ -10,10 +10,10 @@ import cn.iocoder.yudao.module.trade.service.message.dto.TradeOrderMessageWhenDe
public interface TradeMessageService { public interface TradeMessageService {
/** /**
* 订单发货时发送消息 * 订单发货时发送通知
* *
* @param reqDTO 发送消息 * @param reqBO 发送消息
*/ */
void sendMessageWhenDeliveryOrder(TradeOrderMessageWhenDeliveryOrderReqDTO reqDTO); void sendMessageWhenDeliveryOrder(TradeOrderMessageWhenDeliveryOrderReqBO reqBO);
} }

View File

@ -2,7 +2,8 @@ package cn.iocoder.yudao.module.trade.service.message;
import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi; import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi;
import cn.iocoder.yudao.module.system.api.notify.dto.NotifySendSingleToUserReqDTO; import cn.iocoder.yudao.module.system.api.notify.dto.NotifySendSingleToUserReqDTO;
import cn.iocoder.yudao.module.trade.service.message.dto.TradeOrderMessageWhenDeliveryOrderReqDTO; import cn.iocoder.yudao.module.trade.enums.MessageTemplateConstants;
import cn.iocoder.yudao.module.trade.service.message.bo.TradeOrderMessageWhenDeliveryOrderReqBO;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@ -23,18 +24,16 @@ public class TradeMessageServiceImpl implements TradeMessageService {
private NotifyMessageSendApi notifyMessageSendApi; private NotifyMessageSendApi notifyMessageSendApi;
@Override @Override
public void sendMessageWhenDeliveryOrder(TradeOrderMessageWhenDeliveryOrderReqDTO reqDTO) { public void sendMessageWhenDeliveryOrder(TradeOrderMessageWhenDeliveryOrderReqBO reqBO) {
// 1构造消息 // 1构造消息
Map<String, Object> msgMap = new HashMap<>(); Map<String, Object> msgMap = new HashMap<>(2);
msgMap.put("orderId", reqDTO.getOrderId()); msgMap.put("orderId", reqBO.getOrderId());
// TODO puhui999应该不是 msg 应该是涉及到的模版参数哈msg 太大了 msgMap.put("deliveryMessage", reqBO.getMessage());
msgMap.put("msg", reqDTO.getMessage());
// 2发送站内信 // 2发送站内信
notifyMessageSendApi.sendSingleMessageToMember( notifyMessageSendApi.sendSingleMessageToMember(
new NotifySendSingleToUserReqDTO() new NotifySendSingleToUserReqDTO()
.setUserId(reqDTO.getUserId()) .setUserId(reqBO.getUserId())
// TODO puhui999短信模版编号枚举起来 .setTemplateCode(MessageTemplateConstants.ORDER_DELIVERY)
.setTemplateCode("order_delivery")
.setTemplateParams(msgMap)); .setTemplateParams(msgMap));
} }

View File

@ -1,18 +1,17 @@
package cn.iocoder.yudao.module.trade.service.message.dto; package cn.iocoder.yudao.module.trade.service.message.bo;
import lombok.Data; import lombok.Data;
import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
// TODO @puhui999改成 ReqBO 包名也换了service 我们还是同一用 bo 对象
/** /**
* 订单发货时 Req DTO * 订单发货时通知创建 Req BO
* *
* @author HUIHUI * @author HUIHUI
*/ */
@Data @Data
public class TradeOrderMessageWhenDeliveryOrderReqDTO { public class TradeOrderMessageWhenDeliveryOrderReqBO {
/** /**
* 订单编号 * 订单编号

View File

@ -5,6 +5,7 @@ import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.core.KeyValue; import cn.iocoder.yudao.framework.common.core.KeyValue;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.enums.TerminalEnum; import cn.iocoder.yudao.framework.common.enums.TerminalEnum;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils; import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
@ -21,6 +22,7 @@ import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDT
import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO; import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO;
import cn.iocoder.yudao.module.promotion.api.combination.CombinationRecordApi; import cn.iocoder.yudao.module.promotion.api.combination.CombinationRecordApi;
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordUpdateReqDTO;
import cn.iocoder.yudao.module.promotion.api.coupon.CouponApi; import cn.iocoder.yudao.module.promotion.api.coupon.CouponApi;
import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponUseReqDTO; import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponUseReqDTO;
import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum; import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum;
@ -45,7 +47,7 @@ import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties
import cn.iocoder.yudao.module.trade.service.cart.TradeCartService; import cn.iocoder.yudao.module.trade.service.cart.TradeCartService;
import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressService; import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressService;
import cn.iocoder.yudao.module.trade.service.message.TradeMessageService; import cn.iocoder.yudao.module.trade.service.message.TradeMessageService;
import cn.iocoder.yudao.module.trade.service.message.dto.TradeOrderMessageWhenDeliveryOrderReqDTO; import cn.iocoder.yudao.module.trade.service.message.bo.TradeOrderMessageWhenDeliveryOrderReqBO;
import cn.iocoder.yudao.module.trade.service.price.TradePriceService; import cn.iocoder.yudao.module.trade.service.price.TradePriceService;
import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO;
import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO;
@ -173,9 +175,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
if (equal(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) { if (equal(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) {
MemberUserRespDTO user = memberUserApi.getUser(userId); MemberUserRespDTO user = memberUserApi.getUser(userId);
// TODO 拼团一次应该只能选择一种规格的商品 // TODO 拼团一次应该只能选择一种规格的商品
// TODO @puhui999应该是前置校验哈然后不应该设置状态而是交给拼团记录那处理 combinationRecordApi.createRecord(TradeOrderConvert.INSTANCE.convert(order, orderItems.get(0), createReqVO, user));
combinationRecordApi.createCombinationRecord(TradeOrderConvert.INSTANCE.convert(order, orderItems.get(0), createReqVO, user)
.setStatus(CombinationRecordStatusEnum.WAITING.getStatus()));
} }
// TODO 秒杀扣减库存是下单就扣除还是等待订单支付成功再扣除 // TODO 秒杀扣减库存是下单就扣除还是等待订单支付成功再扣除
if (equal(TradeOrderTypeEnum.SECKILL.getType(), order.getType())) { if (equal(TradeOrderTypeEnum.SECKILL.getType(), order.getType())) {
@ -311,7 +311,8 @@ public class TradeOrderServiceImpl implements TradeOrderService {
// 1拼团活动 // 1拼团活动
if (equal(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) { if (equal(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) {
// 更新拼团状态 TODO puhui999订单支付失败或订单支付过期删除这条拼团记录 // 更新拼团状态 TODO puhui999订单支付失败或订单支付过期删除这条拼团记录
combinationRecordApi.updateCombinationRecordStatusAndStartTime(order.getUserId(), order.getId(), CombinationRecordStatusEnum.IN_PROGRESS.getStatus()); combinationRecordApi.updateRecordStatus(new CombinationRecordUpdateReqDTO().setUserId(order.getUserId())
.setOrderId(order.getId()).setStatus(CombinationRecordStatusEnum.IN_PROGRESS.getStatus()).setStartTime(LocalDateTime.now()));
} }
// TODO 芋艿发送订单变化的消息 // TODO 芋艿发送订单变化的消息
@ -394,11 +395,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
// 2.1 快递发货 // 2.1 快递发货
if (equal(deliveryReqVO.getType(), DeliveryTypeEnum.EXPRESS.getMode())) { if (equal(deliveryReqVO.getType(), DeliveryTypeEnum.EXPRESS.getMode())) {
// 校验快递公司 // 校验快递公司
// TODO @puhui999getDeliveryExpress 直接封装一个校验的会不会好点因为还有开启关闭啥的 validateDeliveryExpress(deliveryReqVO);
DeliveryExpressDO deliveryExpress = deliveryExpressService.getDeliveryExpress(deliveryReqVO.getLogisticsId());
if (deliveryExpress == null) {
throw exception(EXPRESS_NOT_EXISTS);
}
updateOrderObj.setLogisticsId(deliveryReqVO.getLogisticsId()).setLogisticsNo(deliveryReqVO.getLogisticsNo()); updateOrderObj.setLogisticsId(deliveryReqVO.getLogisticsId()).setLogisticsNo(deliveryReqVO.getLogisticsNo());
} }
// 2.2 用户自提 // 2.2 用户自提
@ -425,13 +422,23 @@ public class TradeOrderServiceImpl implements TradeOrderService {
// TODO 芋艿发送订单变化的消息 // TODO 芋艿发送订单变化的消息
// 发送站内信 // 发送站内信
tradeMessageService.sendMessageWhenDeliveryOrder(new TradeOrderMessageWhenDeliveryOrderReqDTO().setOrderId(order.getId()) tradeMessageService.sendMessageWhenDeliveryOrder(new TradeOrderMessageWhenDeliveryOrderReqBO().setOrderId(order.getId())
.setUserId(userId).setMessage(TradeOrderDeliveryStatusEnum.DELIVERED.getName())); .setUserId(userId).setMessage(TradeOrderDeliveryStatusEnum.DELIVERED.getName()));
// TODO 芋艿OrderLog // TODO 芋艿OrderLog
// TODO 设计lili是不是发货后才支持售后 // TODO 设计lili是不是发货后才支持售后
} }
private void validateDeliveryExpress(TradeOrderDeliveryReqVO deliveryReqVO) {
DeliveryExpressDO deliveryExpress = deliveryExpressService.getDeliveryExpress(deliveryReqVO.getLogisticsId());
if (deliveryExpress == null) {
throw exception(EXPRESS_NOT_EXISTS);
}
if (deliveryExpress.getStatus().equals(CommonStatusEnum.DISABLE.getStatus())) {
throw exception(EXPRESS_STATUS_NOT_ENABLE);
}
}
/** /**
* 校验交易订单满足被发货的条件 * 校验交易订单满足被发货的条件
* *
@ -458,8 +465,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
// 订单类型拼团 // 订单类型拼团
if (equal(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) { if (equal(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) {
// 校验订单拼团是否成功 // 校验订单拼团是否成功
// TODO 用户 ID 使用当前登录用户的还是订单保存的 if (combinationRecordApi.isRecordSuccess(order.getUserId(), order.getId())) {
if (combinationRecordApi.isCombinationRecordSuccess(order.getUserId(), order.getId())) {
throw exception(ORDER_DELIVERY_FAIL_COMBINATION_RECORD_STATUS_NOT_SUCCESS); throw exception(ORDER_DELIVERY_FAIL_COMBINATION_RECORD_STATUS_NOT_SUCCESS);
} }
} }