促销活动代码迁移

This commit is contained in:
YunaiV
2020-08-22 23:48:31 +08:00
parent 42c6389023
commit c94fae173e
29 changed files with 171 additions and 906 deletions

View File

@@ -1,118 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>promotion</artifactId>
<groupId>cn.iocoder.mall</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>promotion-service-impl</artifactId>
<dependencies>
<!-- Mall 相关 -->
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>promotion-service-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>system-service-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>product-rpc-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- DB 相关 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<!-- RPC 相关 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>
<!-- Registry 和 Config 相关 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- Transaction 相关 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-seata</artifactId>
</dependency>
<!-- Job 相关 -->
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
</dependency>
<!-- 工具类相关 -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<!-- 测试相关 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>mall-spring-boot-starter-mybatis</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>mall-spring-boot-starter-mybatis</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 提供给 mapstruct 使用 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@@ -1,28 +0,0 @@
package cn.iocoder.mall.promotion.biz.convert;
import cn.iocoder.mall.promotion.api.bo.PromotionActivityBO;
import cn.iocoder.mall.promotion.biz.dataobject.PromotionActivityDO;
import org.mapstruct.Mapper;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public interface PromotionActivityConvert {
PromotionActivityConvert INSTANCE = Mappers.getMapper(PromotionActivityConvert.class);
@Mappings({})
PromotionActivityBO convertToBO(PromotionActivityDO activity);
@Mappings({})
List<PromotionActivityBO> convertToBO(List<PromotionActivityDO> activityList);
// @Mappings({})
// PromotionActivityDO convert(PromotionActivityAddDTO activityAddDTO);
//
// @Mappings({})
// PromotionActivityDO convert(PromotionActivityUpdateDTO activityUpdateDTO);
}

View File

@@ -1,29 +0,0 @@
package cn.iocoder.mall.promotion.biz.dao;
import cn.iocoder.mall.promotion.biz.dataobject.PromotionActivityDO;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.Collection;
import java.util.List;
@Repository
public interface PromotionActivityMapper {
PromotionActivityDO selectById(@Param("id") Integer id);
List<PromotionActivityDO> selectListByStatus(@Param("statuses") Collection<Integer> statuses);
void insert(PromotionActivityDO activity);
List<PromotionActivityDO> selectListByPage(@Param("title") String title,
@Param("activityType") Integer activityType,
@Param("statuses") Collection<Integer> statuses,
@Param("offset") Integer offset,
@Param("limit") Integer limit);
Integer selectCountByPage(@Param("title") String title,
@Param("activityType") Integer activityType,
@Param("statuses") Collection<Integer> statuses);
}

View File

@@ -1,47 +0,0 @@
package cn.iocoder.mall.promotion.biz.dataobject;
import cn.iocoder.mall.mybatis.core.dataobject.DeletableDO;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* Banner 广告页
*/
@Data
@Accessors(chain = true)
public class BannerDO extends DeletableDO {
/**
* 编号
*/
private Integer id;
/**
* 标题
*/
private String title;
/**
* 跳转链接
*/
private String url;
/**
* 图片链接
*/
private String picUrl;
/**
* 排序
*/
private Integer sort;
/**
* 状态
*
* {@link cn.iocoder.common.framework.enums.CommonStatusEnum}
*/
private Integer status;
/**
* 备注
*/
private String memo;
// TODO 芋艿 点击次数。&& 其他数据相关
}

View File

@@ -1,46 +0,0 @@
package cn.iocoder.mall.promotion.biz.dataobject;
import cn.iocoder.mall.mybatis.core.dataobject.DeletableDO;
import cn.iocoder.mall.promotion.api.enums.ProductRecommendTypeEnum;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 商品推荐 DO
*/
@Data
@Accessors(chain = true)
public class ProductRecommendDO extends DeletableDO {
/**
* 编号
*/
private Integer id;
/**
* 类型
*
* {@link ProductRecommendTypeEnum}
*/
private Integer type;
/**
* 商品 Spu 编号
*/
private Integer productSpuId;
// TODO 芋艿,商品 spu 名
/**
* 排序
*/
private Integer sort;
/**
* 状态
*
* {@link cn.iocoder.common.framework.enums.CommonStatusEnum}
*/
private Integer status;
/**
* 备注
*/
private String memo;
}

View File

@@ -1,107 +0,0 @@
package cn.iocoder.mall.promotion.biz.service;
import cn.iocoder.mall.promotion.api.PromotionActivityService;
import cn.iocoder.mall.promotion.api.bo.PromotionActivityBO;
import cn.iocoder.mall.promotion.api.bo.PromotionActivityPageBO;
import cn.iocoder.mall.promotion.api.enums.PromotionActivityTypeEnum;
import cn.iocoder.mall.promotion.api.enums.RangeTypeEnum;
import cn.iocoder.mall.promotion.api.dto.PromotionActivityPageDTO;
import cn.iocoder.mall.promotion.biz.convert.PromotionActivityConvert;
import cn.iocoder.mall.promotion.biz.dao.PromotionActivityMapper;
import cn.iocoder.mall.promotion.biz.dataobject.PromotionActivityDO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
@Service // 实际上不用添加。添加的原因是,必须 Spring 报错提示
@org.apache.dubbo.config.annotation.Service(validation = "true", version = "${dubbo.provider.PromotionActivityService.version}")
public class PromotionActivityServiceImpl implements PromotionActivityService {
@Autowired
private PromotionActivityMapper promotionActivityMapper;
@Override
public List<PromotionActivityBO> getPromotionActivityListBySpuId(Integer spuId, Collection<Integer> activityStatuses) {
return this.getPromotionActivityListBySpuIds(Collections.singleton(spuId), activityStatuses);
}
@Override
public List<PromotionActivityBO> getPromotionActivityListBySpuIds(Collection<Integer> spuIds, Collection<Integer> activityStatuses) {
if (spuIds.isEmpty() || activityStatuses.isEmpty()) {
return Collections.emptyList();
}
// 查询指定状态的促销活动
List<PromotionActivityDO> activityList = promotionActivityMapper.selectListByStatus(activityStatuses);
if (activityList.isEmpty()) {
return Collections.emptyList();
}
// 匹配商品
for (Iterator<PromotionActivityDO> iterator = activityList.iterator(); iterator.hasNext();) {
PromotionActivityDO activity = iterator.next();
boolean matched = false;
for (Integer spuId : spuIds) {
if (PromotionActivityTypeEnum.TIME_LIMITED_DISCOUNT.getValue().equals(activity.getActivityType())) {
matched = isSpuMatchTimeLimitDiscount(spuId, activity);
} else if (PromotionActivityTypeEnum.FULL_PRIVILEGE.getValue().equals(activity.getActivityType())) {
matched = isSpuMatchFullPrivilege(spuId, activity);
}
if (matched) {
break;
}
}
// 不匹配,则进行移除
if (!matched) {
iterator.remove();
} else { // 匹配,则做一些后续的处理
// 如果是限时折扣,移除不在 spuId 数组中的折扣规则
if (PromotionActivityTypeEnum.TIME_LIMITED_DISCOUNT.getValue().equals(activity.getActivityType())) {
activity.getTimeLimitedDiscount().getItems().removeIf(item -> !spuIds.contains(item.getSpuId()));
}
}
}
// 返回最终结果
return PromotionActivityConvert.INSTANCE.convertToBO(activityList);
}
@Override
public PromotionActivityPageBO getPromotionActivityPage(PromotionActivityPageDTO promotionActivityPageDTO) {
PromotionActivityPageBO promotionActivityPageBO = new PromotionActivityPageBO();
// 查询分页数据
int offset = (promotionActivityPageDTO.getPageNo() - 1) * promotionActivityPageDTO.getPageSize();
promotionActivityPageBO.setList(PromotionActivityConvert.INSTANCE.convertToBO(promotionActivityMapper.selectListByPage(
promotionActivityPageDTO.getTitle(), promotionActivityPageDTO.getActivityType(),
promotionActivityPageDTO.getStatuses(),
offset, promotionActivityPageDTO.getPageSize())));
// 查询分页总数
promotionActivityPageBO.setTotal(promotionActivityMapper.selectCountByPage(
promotionActivityPageDTO.getTitle(), promotionActivityPageDTO.getActivityType(),
promotionActivityPageDTO.getStatuses()));
return promotionActivityPageBO;
}
private boolean isSpuMatchTimeLimitDiscount(Integer spuId, PromotionActivityDO activity) {
Assert.isTrue(PromotionActivityTypeEnum.TIME_LIMITED_DISCOUNT.getValue().equals(activity.getActivityType()),
"传入的必须的促销活动必须是限时折扣");
return activity.getTimeLimitedDiscount().getItems().stream()
.anyMatch(item -> spuId.equals(item.getSpuId()));
}
private boolean isSpuMatchFullPrivilege(Integer spuId, PromotionActivityDO activity) {
Assert.isTrue(PromotionActivityTypeEnum.FULL_PRIVILEGE.getValue().equals(activity.getActivityType()),
"传入的必须的促销活动必须是满减送");
PromotionActivityDO.FullPrivilege fullPrivilege = activity.getFullPrivilege();
if (RangeTypeEnum.ALL.getValue().equals(fullPrivilege.getRangeType())) {
return true;
} else if (RangeTypeEnum.PRODUCT_INCLUDE_PART.getValue().equals(fullPrivilege.getRangeType())) {
return fullPrivilege.getRangeValues().contains(spuId);
} else {
throw new IllegalArgumentException(String.format("促销活动(%s) 可用范围的类型是不正确", activity.toString()));
}
}
}

View File

@@ -1,135 +0,0 @@
<?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.mall.promotion.biz.dao.PromotionActivityMapper">
<sql id="FIELDS">
id, title, activity_type, status, start_time,
end_time, invalid_time, delete_time, time_limited_discount, full_privilege,
create_time, update_time
</sql>
<resultMap id="PromotionActivityResultMap" type="PromotionActivityDO">
<result property="timeLimitedDiscount" column="time_limited_discount" javaType="cn.iocoder.mall.promotion.biz.dataobject.PromotionActivityDO$TimeLimitedDiscount" typeHandler="cn.iocoder.mall.mybatis.core.type.JSONTypeHandler"/>
<result property="fullPrivilege" column="full_privilege" javaType="cn.iocoder.mall.promotion.biz.dataobject.PromotionActivityDO$FullPrivilege" typeHandler="cn.iocoder.mall.mybatis.core.type.JSONTypeHandler"/>
</resultMap>
<!-- <select id="selectListByPidAndStatusOrderBySort" resultType="PromotionActivityDO">-->
<!-- SELECT-->
<!-- <include refid="FIELDS" />-->
<!-- FROM banner-->
<!-- WHERE pid = #{pid}-->
<!-- AND status = #{status}-->
<!-- AND deleted = 0-->
<!-- ORDER BY sort ASC-->
<!-- </select>-->
<!-- <select id="selectList" resultType="PromotionActivityDO">-->
<!-- SELECT-->
<!-- <include refid="FIELDS" />-->
<!-- FROM banner-->
<!-- WHERE deleted = 0-->
<!-- </select>-->
<select id="selectById" parameterType="Integer" resultMap="PromotionActivityResultMap">
SELECT
<include refid="FIELDS" />
FROM promotion_activity
WHERE id = #{id}
</select>
<select id="selectListByStatus" resultMap="PromotionActivityResultMap">
SELECT
<include refid="FIELDS" />
FROM promotion_activity
WHERE status IN
<foreach item="status" collection="statuses" separator="," open="(" close=")" index="">
#{status}
</foreach>
</select>
<!-- <select id="selectListByStatus" parameterType="Integer" resultType="PromotionActivityDO">-->
<!-- SELECT-->
<!-- <include refid="FIELDS" />-->
<!-- FROM banner-->
<!-- <where>-->
<!-- <if test="status != null">-->
<!-- status = #{status}-->
<!-- </if>-->
<!-- AND deleted = 0-->
<!-- </where>-->
<!-- </select>-->
<select id="selectListByPage" resultMap="PromotionActivityResultMap">
SELECT
<include refid="FIELDS" />
FROM promotion_activity
WHERE activity_type = #{activityType}
<if test="title != null">
AND title LIKE "%"#{title}"%"
</if>
AND status IN
<foreach item="status" collection="statuses" separator="," open="(" close=")" index="">
#{status}
</foreach>
LIMIT #{offset}, #{limit}
</select>
<select id="selectCountByPage" resultType="Integer">
SELECT
COUNT(1)
FROM promotion_activity
WHERE activity_type = #{activityType}
<if test="title != null">
AND title LIKE "%"#{title}"%"
</if>
AND status IN
<foreach item="status" collection="statuses" separator="," open="(" close=")" index="">
#{status}
</foreach>
</select>
<insert id="insert" parameterType="PromotionActivityDO" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
INSERT INTO promotion_activity (
title, activity_type, status, start_time,
end_time, invalid_time, delete_time,
time_limited_discount,
full_privilege,
create_time
) VALUES (
#{title}, #{activityType}, #{status}, #{startTime},
#{endTime}, #{invalidTime}, #{deleteTime},
#{timeLimitedDiscount, typeHandler=cn.iocoder.common.framework.mybatis.JSONTypeHandler},
#{fullPrivilege, typeHandler=cn.iocoder.common.framework.mybatis.JSONTypeHandler},
#{createTime}
)
</insert>
<!-- <update id="update" parameterType="PromotionActivityDO">-->
<!-- UPDATE banner-->
<!-- <set>-->
<!-- <if test="title != null">-->
<!-- title = #{title},-->
<!-- </if>-->
<!-- <if test="url != null">-->
<!-- url = #{url},-->
<!-- </if>-->
<!-- <if test="picUrl != null">-->
<!-- pic_url = #{picUrl} ,-->
<!-- </if>-->
<!-- <if test="sort != null">-->
<!-- sort = #{sort},-->
<!-- </if>-->
<!-- <if test="status != null">-->
<!-- status = #{status},-->
<!-- </if>-->
<!-- <if test="memo != null">-->
<!-- memo = #{memo},-->
<!-- </if>-->
<!-- <if test="deleted != null">-->
<!-- deleted = #{deleted}-->
<!-- </if>-->
<!-- </set>-->
<!-- WHERE id = #{id}-->
<!-- </update>-->
</mapper>

View File

@@ -1,58 +0,0 @@
package cn.iocoder.mall.promotion.application.controller.admins;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.promotion.api.PromotionActivityService;
import cn.iocoder.mall.promotion.api.bo.PromotionActivityPageBO;
import cn.iocoder.mall.promotion.api.enums.PromotionActivityStatusEnum;
import cn.iocoder.mall.promotion.api.dto.PromotionActivityPageDTO;
import io.swagger.annotations.Api;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.Arrays;
import java.util.Collections;
import static cn.iocoder.common.framework.vo.CommonResult.success;
@RestController
@RequestMapping("admins/promotion_activity")
@Api("促销活动模块")
public class AdminsPromotionActivityController {
@Reference(validation = "true", version = "${dubbo.provider.PromotionActivityService.version}")
private PromotionActivityService promotionActivityService;
@GetMapping("/page") // TODO 芋艿BO => VO
public CommonResult<PromotionActivityPageBO> page(@RequestParam(value = "title", required = false) String title,
@RequestParam(value = "activityType") Integer activityType,
@RequestParam(value = "status") String status,
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
PromotionActivityPageDTO promotionActivityPageDTO = new PromotionActivityPageDTO()
.setTitle(title).setActivityType(activityType).setPageNo(pageNo).setPageSize(pageSize);
switch (status) {
case "WAIT":
promotionActivityPageDTO.setStatuses(Collections.singleton(PromotionActivityStatusEnum.WAIT.getValue()));
break;
case "RUN":
promotionActivityPageDTO.setStatuses(Collections.singleton(PromotionActivityStatusEnum.RUN.getValue()));
break;
case "END":
promotionActivityPageDTO.setStatuses(Collections.singleton(PromotionActivityStatusEnum.END.getValue()));
break;
case "INVALID":
promotionActivityPageDTO.setStatuses(Collections.singleton(PromotionActivityStatusEnum.INVALID.getValue()));
break;
default:
promotionActivityPageDTO.setStatuses(Arrays.asList(PromotionActivityStatusEnum.WAIT.getValue(),
PromotionActivityStatusEnum.RUN.getValue(), PromotionActivityStatusEnum.END.getValue(),
PromotionActivityStatusEnum.INVALID.getValue()));
}
// 执行查询
return success(promotionActivityService.getPromotionActivityPage(promotionActivityPageDTO));
}
}

View File

@@ -1,20 +0,0 @@
package cn.iocoder.mall.promotion.application.vo.admins;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.List;
@ApiModel("Banner 分页 VO")
@Data
@Accessors(chain = true)
public class AdminsBannerPageVO {
@ApiModelProperty(value = "Banner 数组")
private List<AdminsBannerVO> list;
@ApiModelProperty(value = "Banner 总数")
private Integer total;
}

View File

@@ -1,6 +0,0 @@
swagger:
enable: false
title: 营销子系统
description: 营销子系统
version: 1.0.0
base-package: cn.iocoder.mall.promotion.application.controller

View File

@@ -1,33 +0,0 @@
spring:
application:
name: promotion-application
# Spring Cloud 配置项
cloud:
# Spring Cloud Sentinel 配置项
sentinel:
transport:
dashboard: s1.iocoder.cn:12088 # Sentinel Dashboard 服务地址
eager: true # 项目启动时,直接连接到 Sentinel
# server
server:
port: 18085
servlet:
context-path: /promotion-api/
swagger:
enable: true
title: 促销子系统
description: 促销子系统
version: 1.0.0
base-package: cn.iocoder.mall.promotion.application.controller
management:
endpoints:
web:
exposure:
include: health,info,env,metrics,prometheus
metrics:
enabled: true