清理已迁移的 cart 代码
parent
a347d2a1d3
commit
239c38cf64
|
@ -1,28 +0,0 @@
|
|||
package cn.iocoder.mall.managementweb.convert.promotion;
|
||||
|
||||
import cn.iocoder.common.framework.vo.PageResult;
|
||||
import cn.iocoder.mall.managementweb.controller.promotion.brand.vo.BannerCreateReqVO;
|
||||
import cn.iocoder.mall.managementweb.controller.promotion.brand.vo.BannerPageReqVO;
|
||||
import cn.iocoder.mall.managementweb.controller.promotion.brand.vo.BannerRespVO;
|
||||
import cn.iocoder.mall.managementweb.controller.promotion.brand.vo.BannerUpdateReqVO;
|
||||
import cn.iocoder.mall.promotion.api.rpc.banner.dto.BannerCreateReqDTO;
|
||||
import cn.iocoder.mall.promotion.api.rpc.banner.dto.BannerPageReqDTO;
|
||||
import cn.iocoder.mall.promotion.api.rpc.banner.dto.BannerRespDTO;
|
||||
import cn.iocoder.mall.promotion.api.rpc.banner.dto.BannerUpdateReqDTO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
@Mapper
|
||||
public interface BannerConvert {
|
||||
|
||||
BannerConvert INSTANCE = Mappers.getMapper(BannerConvert.class);
|
||||
|
||||
BannerCreateReqDTO convert(BannerCreateReqVO bean);
|
||||
|
||||
BannerUpdateReqDTO convert(BannerUpdateReqVO bean);
|
||||
|
||||
BannerPageReqDTO convert(BannerPageReqVO bean);
|
||||
|
||||
PageResult<BannerRespVO> convertPage(PageResult<BannerRespDTO> page);
|
||||
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
package cn.iocoder.mall.managementweb.manager.promotion.brand;
|
||||
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.common.framework.vo.PageResult;
|
||||
import cn.iocoder.mall.managementweb.controller.promotion.brand.vo.BannerCreateReqVO;
|
||||
import cn.iocoder.mall.managementweb.controller.promotion.brand.vo.BannerPageReqVO;
|
||||
import cn.iocoder.mall.managementweb.controller.promotion.brand.vo.BannerRespVO;
|
||||
import cn.iocoder.mall.managementweb.controller.promotion.brand.vo.BannerUpdateReqVO;
|
||||
import cn.iocoder.mall.managementweb.convert.promotion.BannerConvert;
|
||||
import cn.iocoder.mall.promotion.api.rpc.banner.BannerFeign;
|
||||
import cn.iocoder.mall.promotion.api.rpc.banner.dto.BannerRespDTO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* Banner Manager
|
||||
*/
|
||||
@Service
|
||||
public class BannerManager {
|
||||
|
||||
@Autowired
|
||||
private BannerFeign bannerFeign;
|
||||
|
||||
/**
|
||||
* 创建 Banner
|
||||
*
|
||||
* @param createVO 创建 Banner VO
|
||||
* @return Banner
|
||||
*/
|
||||
public Integer createBanner(BannerCreateReqVO createVO) {
|
||||
CommonResult<Integer> createBannerResult = bannerFeign.createBanner(BannerConvert.INSTANCE.convert(createVO));
|
||||
createBannerResult.checkError();
|
||||
return createBannerResult.getData();
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新 Banner
|
||||
*
|
||||
* @param updateVO 更新 Banner VO
|
||||
*/
|
||||
public void updateBanner(BannerUpdateReqVO updateVO) {
|
||||
CommonResult<Boolean> updateBannerResult = bannerFeign.updateBanner(BannerConvert.INSTANCE.convert(updateVO));
|
||||
updateBannerResult.checkError();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除 Banner
|
||||
*
|
||||
* @param bannerId Banner 编号
|
||||
*/
|
||||
public void deleteBanner(Integer bannerId) {
|
||||
CommonResult<Boolean> deleteBannerResult = bannerFeign.deleteBanner(bannerId);
|
||||
deleteBannerResult.checkError();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得 Banner 分页
|
||||
*
|
||||
* @param pageVO Banner 分页查询
|
||||
* @return Banner 分页结果
|
||||
*/
|
||||
public PageResult<BannerRespVO> pageBanner(BannerPageReqVO pageVO) {
|
||||
CommonResult<PageResult<BannerRespDTO>> pageBannerResult = bannerFeign.pageBanner(BannerConvert.INSTANCE.convert(pageVO));
|
||||
pageBannerResult.checkError();
|
||||
return BannerConvert.INSTANCE.convertPage(pageBannerResult.getData());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
|
||||
## 订单
|
||||
|
||||
|
||||
TODO
|
||||
|
||||
|
||||
**退货**
|
||||
|
||||
1. 商家未发货,退货原因
|
||||
|
||||
- 拍错/勿拍/多拍
|
||||
- 缺货
|
||||
|
||||
2. 商家已发货,退货原因
|
||||
|
||||
- 七天无理由
|
||||
- 质量问题
|
||||
- 不想要了
|
||||
- 其他
|
||||
|
|
@ -1,129 +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.order.biz.dao.cart.CartMapper">
|
||||
|
||||
<sql id="FIELDS">
|
||||
id, status, delete_time, selected, user_id,
|
||||
spu_id, sku_id, quantity, order_id, order_create_time,
|
||||
create_time
|
||||
</sql>
|
||||
|
||||
<select id="selectById" parameterType="Integer" resultType="CartItemDO">
|
||||
SELECT
|
||||
<include refid="FIELDS" />
|
||||
FROM cart_item
|
||||
WHERE id = #{id}
|
||||
-- AND deleted = 0
|
||||
</select>
|
||||
|
||||
<select id="selectByIds" resultType="CartItemDO">
|
||||
SELECT
|
||||
<include refid="FIELDS" />
|
||||
FROM cart_item
|
||||
WHERE id IN
|
||||
<foreach item="id" collection="ids" separator="," open="(" close=")" index="">
|
||||
#{id}
|
||||
</foreach>
|
||||
-- AND deleted = 0
|
||||
</select>
|
||||
|
||||
<select id="selectByUserIdAndSkuIdAndStatus" resultType="CartItemDO">
|
||||
SELECT
|
||||
<include refid="FIELDS" />
|
||||
FROM cart_item
|
||||
WHERE user_id = #{userId}
|
||||
AND sku_id = #{skuId}
|
||||
AND status = #{status}
|
||||
-- AND deleted = 0
|
||||
LIMIT 1
|
||||
</select>
|
||||
|
||||
<select id="selectByUserIdAndStatusAndSelected" resultType="CartItemDO">
|
||||
SELECT
|
||||
<include refid="FIELDS" />
|
||||
FROM cart_item
|
||||
WHERE user_id = #{userId}
|
||||
AND status = #{status}
|
||||
<if test="selected != null">
|
||||
AND selected = #{selected}
|
||||
</if>
|
||||
-- AND deleted = 0
|
||||
</select>
|
||||
|
||||
<select id="selectQuantitySumByUserIdAndStatus" resultType="Integer">
|
||||
SELECT
|
||||
SUM(quantity)
|
||||
FROM cart_item
|
||||
WHERE user_id = #{userId}
|
||||
AND status = #{status}
|
||||
-- AND deleted = 0
|
||||
</select>
|
||||
|
||||
<insert id="insert" parameterType="CartItemDO" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
|
||||
INSERT INTO cart_item (
|
||||
status, delete_time, selected, user_id,
|
||||
spu_id, sku_id, quantity, order_id, order_create_time,
|
||||
create_time
|
||||
) VALUES (
|
||||
#{status}, #{deleteTime}, #{selected}, #{userId},
|
||||
#{spuId}, #{skuId}, #{quantity}, #{orderId}, #{orderCreateTime},
|
||||
#{createTime}
|
||||
)
|
||||
</insert>
|
||||
|
||||
<update id="update" parameterType="CartItemDO">
|
||||
UPDATE cart_item
|
||||
<set>
|
||||
<if test="status != null">
|
||||
status = #{status},
|
||||
</if>
|
||||
<if test="deleteTime != null">
|
||||
delete_time = #{deleteTime},
|
||||
</if>
|
||||
<if test="selected != null">
|
||||
selected = #{selected},
|
||||
</if>
|
||||
<if test="quantity != null">
|
||||
quantity = #{quantity},
|
||||
</if>
|
||||
<if test="orderId != null">
|
||||
order_id = #{orderId},
|
||||
</if>
|
||||
<if test="orderCreateTime != null">
|
||||
order_create_time = #{orderCreateTime},
|
||||
</if>
|
||||
<if test="price != null">
|
||||
price = #{price},
|
||||
</if>
|
||||
<if test="quantity != null">
|
||||
quantity = #{quantity},
|
||||
</if>
|
||||
</set>
|
||||
WHERE id = #{id}
|
||||
</update>
|
||||
|
||||
<update id="updateQuantity" parameterType="CartItemDO">
|
||||
UPDATE cart_item
|
||||
SET quantity = quantity + #{quantityIncr}
|
||||
WHERE id = #{id}
|
||||
</update>
|
||||
|
||||
<update id="updateListByUserIdAndSkuId">
|
||||
UPDATE cart_item
|
||||
<set>
|
||||
<if test="selected != null">
|
||||
selected = #{selected},
|
||||
</if>
|
||||
<if test="status != null">
|
||||
status = #{status},
|
||||
</if>
|
||||
</set>
|
||||
WHERE user_id = #{userId}
|
||||
AND sku_id IN
|
||||
<foreach item="skuId" collection="skuIds" separator="," open="(" close=")" index="">
|
||||
#{skuId}
|
||||
</foreach>
|
||||
-- AND deleted = 0
|
||||
</update>
|
||||
|
||||
</mapper>
|
|
@ -1,64 +0,0 @@
|
|||
package cn.iocoder.mall.productservice.dal.mysql.dataobject.sku;
|
||||
|
||||
import cn.iocoder.common.framework.enums.CommonStatusEnum;
|
||||
import cn.iocoder.mall.mybatis.core.dataobject.DeletableDO;
|
||||
import cn.iocoder.mall.productservice.dal.mysql.dataobject.attr.ProductAttrValueDO;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 商品 SKU
|
||||
*/
|
||||
@TableName("product_sku")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Accessors(chain = true)
|
||||
public class ProductSkuDO extends DeletableDO {
|
||||
|
||||
/**
|
||||
* sku 编号
|
||||
*/
|
||||
private Integer id;
|
||||
/**
|
||||
* 商品编号
|
||||
*/
|
||||
private Integer spuId;
|
||||
|
||||
// TODO 店铺编号
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*
|
||||
* 枚举 {@link CommonStatusEnum}
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 图片地址
|
||||
*/
|
||||
private String picUrl;
|
||||
/**
|
||||
* 规格值({@link ProductAttrValueDO#getId()})数组
|
||||
*
|
||||
* 数组,以逗号分隔
|
||||
*/
|
||||
private String attrs;
|
||||
/**
|
||||
* 价格,单位:分
|
||||
*/
|
||||
private Integer price;
|
||||
/**
|
||||
* 库存数量
|
||||
*/
|
||||
private Integer quantity;
|
||||
// /**
|
||||
// * 商品在付款减库存的状态下,该Sku上未付款的订单数量
|
||||
// */
|
||||
// private Integer withHoldQuantity;
|
||||
// /**
|
||||
// * 销量
|
||||
// */
|
||||
// private Integer soldNum;
|
||||
|
||||
}
|
|
@ -1,82 +0,0 @@
|
|||
package cn.iocoder.mall.productservice.dal.mysql.dataobject.spu;
|
||||
|
||||
import cn.iocoder.mall.mybatis.core.dataobject.DeletableDO;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 商品 SPU
|
||||
*
|
||||
* TODO 芋艿,后面增加商品普通参数。例如说,正面材料,背面材料,屏幕尺寸。
|
||||
*/
|
||||
@TableName("product_spu")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Accessors(chain = true)
|
||||
public class ProductSpuDO extends DeletableDO {
|
||||
|
||||
/**
|
||||
* SPU 编号
|
||||
*/
|
||||
private Integer id;
|
||||
|
||||
// TODO 店铺编号 先不考虑,因为第一个版本,不做 B2B2C
|
||||
|
||||
// ========== 基本信息 =========
|
||||
/**
|
||||
* SPU 名字
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 卖点
|
||||
*/
|
||||
private String sellPoint;
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
private String description;
|
||||
/**
|
||||
* 分类编号
|
||||
*/
|
||||
private Integer cid;
|
||||
/**
|
||||
* 商品主图地址
|
||||
*
|
||||
* 数组,以逗号分隔
|
||||
*
|
||||
* 建议尺寸:800*800像素,你可以拖拽图片调整顺序,最多上传15张
|
||||
*/
|
||||
private String picUrls;
|
||||
|
||||
// TODO 运费信息
|
||||
|
||||
// ========== 其他信息 =========
|
||||
/**
|
||||
* 是否上架商品(是否可见)。
|
||||
*
|
||||
* true 为已上架
|
||||
* false 为已下架
|
||||
*/
|
||||
private Boolean visible;
|
||||
/**
|
||||
* 排序字段
|
||||
*/
|
||||
private Integer sort;
|
||||
|
||||
// ========== Sku 相关字段 =========
|
||||
/**
|
||||
* 价格
|
||||
*
|
||||
* 目前的计算方式是,以 Sku 最小价格为准
|
||||
*/
|
||||
private Integer price;
|
||||
/**
|
||||
* 库存数量
|
||||
*
|
||||
* 目前的计算方式是,以 Sku 库存累加为准
|
||||
*/
|
||||
private Integer quantity;
|
||||
|
||||
}
|
|
@ -17,8 +17,6 @@ public interface ProductSkuMapper extends BaseMapper<ProductSkuDO> {
|
|||
.eq("status", status));
|
||||
}
|
||||
|
||||
void insertList(@Param("productSkuDOs") List<ProductSkuDO> productSkuDOs);
|
||||
|
||||
default List<ProductSkuDO> selectList(ProductSkuListQueryBO queryBO) {
|
||||
return selectList(new QueryWrapperX<ProductSkuDO>().eqIfPresent("id", queryBO.getProductSkuId())
|
||||
.inIfPresent("id", queryBO.getProductSkuIds())
|
||||
|
|
|
@ -32,17 +32,6 @@ public class ProductSkuManager {
|
|||
@Autowired
|
||||
private ProductAttrService productAttrService;
|
||||
|
||||
/**
|
||||
* 获得商品 SKU
|
||||
*
|
||||
* @param productSkuId 商品 SKU编号
|
||||
* @return 商品 SKU
|
||||
*/
|
||||
public ProductSkuRespDTO getProductSku(Integer productSkuId) {
|
||||
ProductSkuBO productSkuBO = productSkuService.getProductSku(productSkuId);
|
||||
return ProductSkuConvert.INSTANCE.convert(productSkuBO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得商品 SKU 列表
|
||||
*
|
||||
|
|
|
@ -51,17 +51,6 @@ public class ProductSpuManager {
|
|||
@Autowired
|
||||
private ProductMQProducer productMQProducer;
|
||||
|
||||
/**
|
||||
* 获得商品 SPU
|
||||
*
|
||||
* @param productSpuId 商品 SPU编号
|
||||
* @return 商品 SPU
|
||||
*/
|
||||
public ProductSpuRespDTO getProductSpu(Integer productSpuId) {
|
||||
ProductSpuBO productSpuBO = productSpuService.getProductSpu(productSpuId);
|
||||
return ProductSpuConvert.INSTANCE.convert(productSpuBO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得商品 SPU列表
|
||||
*
|
||||
|
@ -84,25 +73,6 @@ public class ProductSpuManager {
|
|||
return ProductSpuConvert.INSTANCE.convertPage(pageResultBO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加或修改商品 SPU 时,校验商品分类是否合法
|
||||
*
|
||||
* @param cid 商品分类编号
|
||||
* @return 商品分类
|
||||
*/
|
||||
private ProductCategoryBO checkProductCategory(Integer cid) {
|
||||
ProductCategoryBO categoryBO = productCategoryService.getProductCategory(cid);
|
||||
if (categoryBO == null) {
|
||||
// 不存在
|
||||
throw ServiceExceptionUtil.exception(PRODUCT_CATEGORY_NOT_EXISTS);
|
||||
}
|
||||
if (ProductCategoryIdEnum.ROOT.getId().equals(categoryBO.getPid())) {
|
||||
// 商品只能添加到二级分类下
|
||||
throw ServiceExceptionUtil.exception(PRODUCT_SPU_CATEGORY_MUST_BE_LEVEL2);
|
||||
}
|
||||
return categoryBO;
|
||||
}
|
||||
|
||||
/**
|
||||
* 顺序获得商品 SPU 编号数组
|
||||
*
|
||||
|
|
|
@ -22,15 +22,6 @@ public class ProductSkuService {
|
|||
@Autowired
|
||||
private ProductSkuMapper productSkuMapper;
|
||||
|
||||
public void createProductSkus(Integer spuId, List<ProductSkuCreateOrUpdateBO> createSkuBOs) {
|
||||
List<ProductSkuDO> skus = ProductSkuConvert.INSTANCE.convertList(createSkuBOs);
|
||||
skus.forEach(sku -> {
|
||||
sku.setStatus(CommonStatusEnum.ENABLE.getValue());
|
||||
sku.setSpuId(spuId);
|
||||
});
|
||||
productSkuMapper.insertList(skus);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得 sku 数组中,指定规格的 sku
|
||||
*
|
||||
|
@ -54,17 +45,6 @@ public class ProductSkuService {
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得商品 SKU
|
||||
*
|
||||
* @param productSkuId 商品 SKU 编号
|
||||
* @return 商品 SKU
|
||||
*/
|
||||
public ProductSkuBO getProductSku(Integer productSkuId) {
|
||||
ProductSkuDO productSkuDO = productSkuMapper.selectById(productSkuId);
|
||||
return ProductSkuConvert.INSTANCE.convert(productSkuDO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得商品 SKU 列表
|
||||
*
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
package cn.iocoder.mall.productservice.service.sku.bo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 商品 SKU BO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ProductSkuBO {
|
||||
|
||||
/**
|
||||
* sku 编号
|
||||
*/
|
||||
private Integer id;
|
||||
/**
|
||||
* 商品编号
|
||||
*/
|
||||
private Integer spuId;
|
||||
/**
|
||||
* 状态
|
||||
*
|
||||
* 1-正常
|
||||
* 2-禁用
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 图片地址
|
||||
*/
|
||||
private String picUrl;
|
||||
/**
|
||||
* 规格值编号数组
|
||||
*/
|
||||
private List<Integer> attrValueIds;
|
||||
/**
|
||||
* 价格,单位:分
|
||||
*/
|
||||
private Integer price;
|
||||
/**
|
||||
* 库存数量
|
||||
*/
|
||||
private Integer quantity;
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createTime;
|
||||
/**
|
||||
* 最后更新时间
|
||||
*/
|
||||
private Date updateTime;
|
||||
/**
|
||||
* 是否删除
|
||||
*/
|
||||
private Integer deleted;
|
||||
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
package cn.iocoder.mall.productservice.service.spu.bo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 商品 SPU 信息 BO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ProductSpuBO {
|
||||
|
||||
/**
|
||||
* 商品 SPU 编号
|
||||
*/
|
||||
private Integer id;
|
||||
/**
|
||||
* SPU 名字
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 卖点
|
||||
*/
|
||||
private String sellPoint;
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
private String description;
|
||||
/**
|
||||
* 分类编号
|
||||
*/
|
||||
private Integer cid;
|
||||
/**
|
||||
* 商品主图地址
|
||||
*/
|
||||
private List<String> picUrls;
|
||||
/**
|
||||
* 是否上架商品
|
||||
*/
|
||||
private Boolean visible;
|
||||
/**
|
||||
* 排序字段
|
||||
*/
|
||||
private Integer sort;
|
||||
/**
|
||||
* 价格
|
||||
*/
|
||||
private Integer price;
|
||||
/**
|
||||
* 库存数量
|
||||
*/
|
||||
private Integer quantity;
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createTime;
|
||||
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
package cn.iocoder.mall.productservice.service.spu.bo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 商品 SPU 创建 BO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ProductSpuCreateBO {
|
||||
|
||||
/**
|
||||
* SPU 名字
|
||||
*/
|
||||
@NotEmpty(message = "SPU 名字不能为空")
|
||||
private String name;
|
||||
/**
|
||||
* 卖点
|
||||
*/
|
||||
@NotEmpty(message = "卖点不能为空")
|
||||
private String sellPoint;
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
@NotEmpty(message = "描述不能为空")
|
||||
private String description;
|
||||
/**
|
||||
* 分类编号
|
||||
*/
|
||||
@NotNull(message = "分类编号不能为空")
|
||||
private Integer cid;
|
||||
/**
|
||||
* 商品主图地址
|
||||
*/
|
||||
@NotEmpty(message = "商品主图地址不能为空")
|
||||
private List<String> picUrls;
|
||||
/**
|
||||
* 是否上架商品
|
||||
*/
|
||||
@NotNull(message = "是否上架商品不能为空")
|
||||
private Boolean visible;
|
||||
/**
|
||||
* 排序字段
|
||||
*/
|
||||
@NotNull(message = "排序字段不能为空")
|
||||
private Integer sort;
|
||||
/**
|
||||
* 价格
|
||||
*/
|
||||
@NotNull(message = "价格不能为空")
|
||||
private Integer price;
|
||||
/**
|
||||
* 库存数量
|
||||
*/
|
||||
@NotNull(message = "库存数量不能为空")
|
||||
private Integer quantity;
|
||||
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
package cn.iocoder.mall.productservice.service.spu.bo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 商品 SPU 更新 BO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ProductSpuUpdateBO {
|
||||
|
||||
/**
|
||||
* 商品 SPU 编号
|
||||
*/
|
||||
@NotNull(message = "商品 SPU 编号不能为空")
|
||||
private Integer id;
|
||||
/**
|
||||
* SPU 名字
|
||||
*/
|
||||
@NotEmpty(message = "SPU 名字不能为空")
|
||||
private String name;
|
||||
/**
|
||||
* 卖点
|
||||
*/
|
||||
@NotEmpty(message = "卖点不能为空")
|
||||
private String sellPoint;
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
@NotEmpty(message = "描述不能为空")
|
||||
private String description;
|
||||
/**
|
||||
* 分类编号
|
||||
*/
|
||||
@NotNull(message = "分类编号不能为空")
|
||||
private Integer cid;
|
||||
/**
|
||||
* 商品主图地址
|
||||
*/
|
||||
@NotEmpty(message = "商品主图地址不能为空")
|
||||
private List<String> picUrls;
|
||||
/**
|
||||
* 是否上架商品
|
||||
*/
|
||||
@NotNull(message = "是否上架商品不能为空")
|
||||
private Boolean visible;
|
||||
/**
|
||||
* 排序字段
|
||||
*/
|
||||
private Integer sort;
|
||||
/**
|
||||
* 价格
|
||||
*/
|
||||
@NotNull(message = "价格不能为空")
|
||||
private Integer price;
|
||||
/**
|
||||
* 库存数量
|
||||
*/
|
||||
@NotNull(message = "库存数量不能为空")
|
||||
private Integer quantity;
|
||||
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
package cn.iocoder.mall.promotion.api.rpc.banner;
|
||||
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.common.framework.vo.PageResult;
|
||||
import cn.iocoder.mall.promotion.api.rpc.banner.dto.*;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Title:
|
||||
* Description:
|
||||
*
|
||||
* @author zhuyang
|
||||
* @version 1.0 2021/10/9
|
||||
*/
|
||||
@FeignClient("promotion-service")
|
||||
public interface BannerFeign {
|
||||
|
||||
@PostMapping("/promotion/banner/createBanner")
|
||||
public CommonResult<Integer> createBanner(@RequestBody BannerCreateReqDTO createDTO) ;
|
||||
@PostMapping("/promotion/banner/updateBanner")
|
||||
public CommonResult<Boolean> updateBanner(@RequestBody BannerUpdateReqDTO updateDTO) ;
|
||||
|
||||
@PostMapping("/promotion/banner/deleteBanner")
|
||||
public CommonResult<Boolean> deleteBanner(@RequestBody Integer bannerId) ;
|
||||
|
||||
@PostMapping("/promotion/banner/listBanners")
|
||||
public CommonResult<List<BannerRespDTO>> listBanners(@RequestBody BannerListReqDTO listDTO) ;
|
||||
|
||||
@PostMapping("/promotion/banner/pageBanner")
|
||||
public CommonResult<PageResult<BannerRespDTO>> pageBanner(@RequestBody BannerPageReqDTO pageDTO);
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
package cn.iocoder.mall.promotion.api.rpc.banner.dto;
|
||||
|
||||
import cn.iocoder.common.framework.enums.CommonStatusEnum;
|
||||
import cn.iocoder.common.framework.validator.InEnum;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
import org.hibernate.validator.constraints.URL;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Banner 创建 Request DTO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class BannerCreateReqDTO implements Serializable {
|
||||
|
||||
/**
|
||||
* 标题
|
||||
*/
|
||||
@NotEmpty(message = "标题不能为空")
|
||||
@Length(min = 2, max = 32, message = "标题长度为 2-32 位")
|
||||
private String title;
|
||||
/**
|
||||
* 跳转链接
|
||||
*/
|
||||
@NotEmpty(message = "跳转链接不能为空")
|
||||
@URL(message = "跳转链接格式不正确")
|
||||
@Length(max = 255, message = "跳转链接最大长度为 255 位")
|
||||
private String url;
|
||||
/**
|
||||
* 图片链接
|
||||
*/
|
||||
@NotEmpty(message = "图片链接不能为空")
|
||||
@URL(message = "图片链接格式不正确")
|
||||
@Length(max = 255, message = "图片链接最大长度为 255 位")
|
||||
private String picUrl;
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
@NotNull(message = "排序不能为空")
|
||||
private Integer sort;
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
@NotNull(message = "状态不能为空")
|
||||
@InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}")
|
||||
private Integer status;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
@Length(max = 255, message = "备注最大长度为 255 位")
|
||||
private String memo;
|
||||
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
package cn.iocoder.mall.promotion.api.rpc.banner.dto;
|
||||
|
||||
import cn.iocoder.common.framework.enums.CommonStatusEnum;
|
||||
import cn.iocoder.common.framework.validator.InEnum;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Banner 列表 Request DTO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class BannerListReqDTO implements Serializable {
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
@InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}")
|
||||
private Integer status;
|
||||
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
package cn.iocoder.mall.promotion.api.rpc.banner.dto;
|
||||
|
||||
import cn.iocoder.common.framework.vo.PageParam;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* Banner 分页 Request DTO
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Accessors(chain = true)
|
||||
public class BannerPageReqDTO extends PageParam {
|
||||
|
||||
/**
|
||||
* 标题,模糊匹配
|
||||
*/
|
||||
private String title;
|
||||
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
package cn.iocoder.mall.promotion.api.rpc.banner.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Banner Response DTO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class BannerRespDTO implements Serializable {
|
||||
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
private Integer id;
|
||||
/**
|
||||
* 标题
|
||||
*/
|
||||
private String title;
|
||||
/**
|
||||
* 跳转链接
|
||||
*/
|
||||
private String url;
|
||||
/**
|
||||
* 图片链接
|
||||
*/
|
||||
private String picUrl;
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
private Integer sort;
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String memo;
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createTime;
|
||||
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
package cn.iocoder.mall.promotion.api.rpc.banner.dto;
|
||||
|
||||
import cn.iocoder.common.framework.enums.CommonStatusEnum;
|
||||
import cn.iocoder.common.framework.validator.InEnum;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
import org.hibernate.validator.constraints.URL;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Banner 更新 Request DTO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class BannerUpdateReqDTO implements Serializable {
|
||||
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
@NotNull(message = "编号不能为空")
|
||||
private Integer id;
|
||||
/**
|
||||
* 标题
|
||||
*/
|
||||
@NotEmpty(message = "标题不能为空")
|
||||
@Length(min = 2, max = 32, message = "标题长度为 2-32 位")
|
||||
private String title;
|
||||
/**
|
||||
* 跳转链接
|
||||
*/
|
||||
@NotEmpty(message = "跳转链接不能为空")
|
||||
@URL(message = "跳转链接格式不正确")
|
||||
@Length(max = 255, message = "跳转链接最大长度为 255 位")
|
||||
private String url;
|
||||
/**
|
||||
* 图片链接
|
||||
*/
|
||||
@NotEmpty(message = "图片链接不能为空")
|
||||
@URL(message = "图片链接格式不正确")
|
||||
@Length(max = 255, message = "图片链接最大长度为 255 位")
|
||||
private String picUrl;
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
@NotNull(message = "排序不能为空")
|
||||
private Integer sort;
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
@NotNull(message = "状态不能为空")
|
||||
@InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}")
|
||||
private Integer status;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
@Length(max = 255, message = "备注最大长度为 255 位")
|
||||
private String memo;
|
||||
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
package cn.iocoder.mall.promotionservice.controller;
|
||||
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.common.framework.vo.PageResult;
|
||||
import cn.iocoder.mall.promotion.api.rpc.banner.dto.*;
|
||||
import cn.iocoder.mall.promotionservice.manager.banner.BannerManager;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.common.framework.vo.CommonResult.success;
|
||||
|
||||
/**
|
||||
* Title:
|
||||
* Description:
|
||||
*
|
||||
* @author zhuyang
|
||||
* @version 1.0 2021/10/9
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/promotion/banner")
|
||||
public class BannerController {
|
||||
|
||||
@Autowired
|
||||
private BannerManager bannerManager;
|
||||
|
||||
@PostMapping("createBanner")
|
||||
public CommonResult<Integer> createBanner(@RequestBody BannerCreateReqDTO createDTO) {
|
||||
return success(bannerManager.createBanner(createDTO));
|
||||
}
|
||||
|
||||
@PostMapping("updateBanner")
|
||||
public CommonResult<Boolean> updateBanner(@RequestBody BannerUpdateReqDTO updateDTO) {
|
||||
bannerManager.updateBanner(updateDTO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PostMapping("deleteBanner")
|
||||
public CommonResult<Boolean> deleteBanner(@RequestBody Integer bannerId) {
|
||||
bannerManager.deleteBanner(bannerId);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PostMapping("listBanners")
|
||||
public CommonResult<List<BannerRespDTO>> listBanners(@RequestBody BannerListReqDTO listDTO) {
|
||||
return success(bannerManager.listBanners(listDTO));
|
||||
}
|
||||
|
||||
@PostMapping("pageBanner")
|
||||
public CommonResult<PageResult<BannerRespDTO>> pageBanner(@RequestBody BannerPageReqDTO pageDTO) {
|
||||
return success(bannerManager.pageBanner(pageDTO));
|
||||
}
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
package cn.iocoder.mall.promotionservice.convert.banner;
|
||||
|
||||
import cn.iocoder.common.framework.vo.PageResult;
|
||||
import cn.iocoder.mall.promotion.api.rpc.banner.dto.BannerCreateReqDTO;
|
||||
import cn.iocoder.mall.promotion.api.rpc.banner.dto.BannerRespDTO;
|
||||
import cn.iocoder.mall.promotion.api.rpc.banner.dto.BannerUpdateReqDTO;
|
||||
import cn.iocoder.mall.promotionservice.dal.mysql.dataobject.banner.BannerDO;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface BannerConvert {
|
||||
|
||||
BannerConvert INSTANCE = Mappers.getMapper(BannerConvert.class);
|
||||
|
||||
BannerDO convert(BannerCreateReqDTO bean);
|
||||
|
||||
BannerDO convert(BannerUpdateReqDTO bean);
|
||||
|
||||
@Mapping(source = "records", target = "list")
|
||||
PageResult<BannerRespDTO> convertPage(IPage<BannerDO> page);
|
||||
|
||||
List<BannerRespDTO> convertList(List<BannerDO> list);
|
||||
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
package cn.iocoder.mall.promotionservice.manager.banner;
|
||||
|
||||
import cn.iocoder.common.framework.vo.PageResult;
|
||||
import cn.iocoder.mall.promotion.api.rpc.banner.dto.*;
|
||||
import cn.iocoder.mall.promotionservice.service.banner.BannerService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Banner Manager
|
||||
*/
|
||||
@Service
|
||||
@Valid
|
||||
public class BannerManager {
|
||||
|
||||
@Autowired
|
||||
private BannerService bannerService;
|
||||
|
||||
public Integer createBanner(BannerCreateReqDTO createDTO) {
|
||||
return bannerService.createBanner(createDTO);
|
||||
}
|
||||
|
||||
public void updateBanner(BannerUpdateReqDTO updateDTO) {
|
||||
bannerService.updateBanner(updateDTO);
|
||||
}
|
||||
|
||||
public void deleteBanner(Integer bannerId) {
|
||||
bannerService.deleteBanner(bannerId);
|
||||
}
|
||||
|
||||
public List<BannerRespDTO> listBanners(BannerListReqDTO listDTO) {
|
||||
return bannerService.listBanners(listDTO);
|
||||
}
|
||||
|
||||
public PageResult<BannerRespDTO> pageBanner(BannerPageReqDTO pageDTO) {
|
||||
return bannerService.pageBanner(pageDTO);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,137 +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>onemall</artifactId>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>shop-web-app</artifactId>
|
||||
<description>商城,用于用户购物</description>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<!-- onemall 基础 bom 文件 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>mall-dependencies</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<!-- Web 相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>mall-spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>mall-spring-boot-starter-swagger</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>mall-spring-boot-starter-security-user</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- RPC 相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>mall-spring-boot-starter-dubbo</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<!-- 用户服务 -->
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>user-service-api</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<!-- 商品服务 -->
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>product-service-api</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<!-- 搜索服务 -->
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>search-service-api</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<!-- 订单服务 -->
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>trade-service-api</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<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>pay-service-api</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Registry 和 Config 相关 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 监控相关 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 工具类相关 -->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct</artifactId> <!-- use mapstruct-jdk8 for Java 8 or higher -->
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct-jdk8</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<!-- 设置构建的 jar 包名 -->
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
<!-- 使用 spring-boot-maven-plugin 插件打包 -->
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
|
@ -1,19 +0,0 @@
|
|||
package cn.iocoder.mall.shopweb;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableDiscoveryClient
|
||||
@EnableFeignClients(basePackages = {"cn.iocoder.mall.productservice.rpc","cn.iocoder.mall.searchservice.rpc",
|
||||
"cn.iocoder.mall.tradeservice.rpc","cn.iocoder.mall.payservice.rpc","cn.iocoder.mall.promotion.api.rpc",
|
||||
"cn.iocoder.mall.systemservice.rpc","cn.iocoder.mall.userservice.rpc"})
|
||||
public class ShopWebApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(ShopWebApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
package cn.iocoder.mall.shopweb.client.user;
|
||||
|
||||
import cn.iocoder.mall.userservice.rpc.address.UserAddressFeign;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class UserAddressClient {
|
||||
@Autowired
|
||||
private UserAddressFeign userAddressFeign;
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
package cn.iocoder.mall.shopweb.controller.product.vo.category;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@ApiModel("商品分类 Response VO")
|
||||
@Data
|
||||
public class ProductCategoryRespVO {
|
||||
|
||||
@ApiModelProperty(value = "分类编号", required = true, example = "1")
|
||||
private Integer id;
|
||||
@ApiModelProperty(value = "分类名称", required = true, example = "手机")
|
||||
private String name;
|
||||
@ApiModelProperty(value = "分类图片", notes = "一般情况下,只有根分类才有图片", example = "http://www.iocoder.cn/xx.jpg")
|
||||
private String picUrl;
|
||||
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
package cn.iocoder.mall.shopweb.controller.product.vo.product;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ApiModel("商品 SPU Response VO")
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ProductSpuRespVO {
|
||||
|
||||
@ApiModelProperty(value = "SPU 编号", required = true, example = "1")
|
||||
private Integer id;
|
||||
|
||||
// ========== 基本信息 =========
|
||||
@ApiModelProperty(value = "SPU 名字", required = true, example = "芋艿")
|
||||
private String name;
|
||||
@ApiModelProperty(value = "卖点", required = true, example = "好吃好玩")
|
||||
private String sellPoint;
|
||||
@ApiModelProperty(value = "描述", required = true, example = "我是哈哈哈")
|
||||
private String description;
|
||||
@ApiModelProperty(value = "分类编号", required = true, example = "1")
|
||||
private Integer cid;
|
||||
@ApiModelProperty(value = "分类名字", required = true, example = "蔬菜")
|
||||
private String categoryName;
|
||||
@ApiModelProperty(value = "商品主图地址", required = true, example = "http://www.iocoder.cn/xxx.jpg", notes = "多个之间,使用逗号分隔")
|
||||
private List<String> picUrls;
|
||||
|
||||
// ========== 其他信息 =========
|
||||
@ApiModelProperty(value = "是否上架商品", required = true, example = "true")
|
||||
private Boolean visible;
|
||||
@ApiModelProperty(value = "排序字段", required = true, example = "1024")
|
||||
private Integer sort;
|
||||
|
||||
// ========== Sku 相关字段 =========
|
||||
@ApiModelProperty(value = "原始价格,单位:分", required = true, example = "233", notes = "该价格为商品的原始价格")
|
||||
private Integer originalPrice;
|
||||
@ApiModelProperty(value = "购买价格,单位:分", required = true, example = "233", notes = "该价格为商品经过优惠计算后的价格")
|
||||
private Integer buyPrice;
|
||||
@ApiModelProperty(value = "库存数量", required = true, example = "1024")
|
||||
private Integer quantity;
|
||||
|
||||
// ========== 促销活动相关字段 ========= TODO 芋艿:等做到促销在处理
|
||||
// 目前只促销单体商品促销,目前仅限制折扣。
|
||||
/**
|
||||
* 促销活动编号
|
||||
*/
|
||||
private Integer promotionActivityId;
|
||||
/**
|
||||
* 促销活动标题
|
||||
*/
|
||||
private String promotionActivityTitle;
|
||||
/**
|
||||
* 促销活动类型
|
||||
*/
|
||||
private Integer promotionActivityType;
|
||||
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
### /passport/login-by-sms 成功
|
||||
POST {{shop-api-base-url}}/passport/login-by-sms
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
|
||||
mobile=15601691300&code=9999
|
||||
|
||||
### /passport/send-sms-code 成功
|
||||
POST {{shop-api-base-url}}/passport/send-sms-code
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
|
||||
mobile=15601691300&scene=1
|
||||
|
||||
### /passport/refresh-token
|
||||
POST {{shop-api-base-url}}/passport/refresh-token
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
|
||||
refreshToken=77abd74e84e34cfc8aba9625317a14a3
|
||||
|
||||
###
|
|
@ -1,56 +0,0 @@
|
|||
package cn.iocoder.mall.shopweb.controller.user;
|
||||
|
||||
import cn.iocoder.common.framework.util.HttpUtil;
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.mall.shopweb.controller.user.vo.passport.PassportAccessTokenRespVO;
|
||||
import cn.iocoder.mall.shopweb.controller.user.vo.passport.PassportLoginBySmsReqVO;
|
||||
import cn.iocoder.mall.shopweb.controller.user.vo.passport.PassportSendSmsRespVO;
|
||||
import cn.iocoder.mall.shopweb.service.user.PassportManager;
|
||||
import cn.iocoder.security.annotations.RequiresNone;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import static cn.iocoder.common.framework.vo.CommonResult.success;
|
||||
|
||||
@Api(tags = "用户 Passport API")
|
||||
@RestController
|
||||
@RequestMapping("/passport")
|
||||
public class PassportController {
|
||||
|
||||
@Autowired
|
||||
private PassportManager passportManager;
|
||||
|
||||
@PostMapping("/login-by-sms")
|
||||
@ApiOperation("手机验证码登陆")
|
||||
@RequiresNone
|
||||
public CommonResult<PassportAccessTokenRespVO> loginBySms(PassportLoginBySmsReqVO loginBySmsDTO,
|
||||
HttpServletRequest request) {
|
||||
return success(passportManager.loginBySms(loginBySmsDTO, HttpUtil.getIp(request)));
|
||||
}
|
||||
|
||||
@PostMapping("/send-sms-code")
|
||||
@ApiOperation("发送手机验证码")
|
||||
@RequiresNone
|
||||
public CommonResult<Boolean> sendSmsCode(PassportSendSmsRespVO sendSmsCodeDTO,
|
||||
HttpServletRequest request) {
|
||||
passportManager.sendSmsCode(sendSmsCodeDTO, HttpUtil.getIp(request));
|
||||
// 返回成功
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PostMapping("/refresh-token")
|
||||
@ApiOperation("刷新令牌")
|
||||
@RequiresNone
|
||||
public CommonResult<PassportAccessTokenRespVO> refreshToken(@RequestParam("refreshToken") String refreshToken,
|
||||
HttpServletRequest request) {
|
||||
return success(passportManager.refreshToken(refreshToken, HttpUtil.getIp(request)));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
### /user-address/get-default 成功
|
||||
GET {{shop-api-base-url}}/user-address/get-default
|
||||
Authorization: Bearer {{user-access-token}}
|
||||
dubbo-tag: {{dubboTag}}
|
||||
|
||||
###
|
|
@ -1,80 +0,0 @@
|
|||
package cn.iocoder.mall.shopweb.controller.user;
|
||||
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.mall.security.user.core.context.UserSecurityContextHolder;
|
||||
import cn.iocoder.mall.shopweb.controller.user.vo.address.UserAddressCreateReqVO;
|
||||
import cn.iocoder.mall.shopweb.controller.user.vo.address.UserAddressRespVO;
|
||||
import cn.iocoder.mall.shopweb.controller.user.vo.address.UserAddressUpdateReqVO;
|
||||
import cn.iocoder.mall.shopweb.service.user.UserAddressManager;
|
||||
import cn.iocoder.security.annotations.RequiresPermissions;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.common.framework.vo.CommonResult.success;
|
||||
|
||||
/**
|
||||
* 用户收件地址 Controller
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/user-address")
|
||||
@Api(tags = "用户收件地址")
|
||||
@Validated
|
||||
public class UserAddressController {
|
||||
|
||||
@Autowired
|
||||
private UserAddressManager userAddressManager;
|
||||
|
||||
@PostMapping("/create")
|
||||
@ApiOperation("创建用户收件地址")
|
||||
@RequiresPermissions
|
||||
public CommonResult<Integer> createUserAddress(@Valid UserAddressCreateReqVO createVO) {
|
||||
return success(userAddressManager.createUserAddress(UserSecurityContextHolder.getUserId(), createVO));
|
||||
}
|
||||
|
||||
@PostMapping("/update")
|
||||
@ApiOperation("更新用户收件地址")
|
||||
@RequiresPermissions
|
||||
public CommonResult<Boolean> updateUserAddress(@Valid UserAddressUpdateReqVO updateVO) {
|
||||
userAddressManager.updateUserAddress(UserSecurityContextHolder.getUserId(), updateVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PostMapping("/delete")
|
||||
@ApiOperation("删除用户收件地址")
|
||||
@ApiImplicitParam(name = "userAddressId", value = "用户收件地址编号", required = true)
|
||||
@RequiresPermissions
|
||||
public CommonResult<Boolean> deleteUserAddress(@RequestParam("userAddressId") Integer userAddressId) {
|
||||
userAddressManager.deleteUserAddress(UserSecurityContextHolder.getUserId(), userAddressId);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@ApiOperation("获得用户收件地址")
|
||||
@ApiImplicitParam(name = "userAddressId", value = "用户收件地址编号", required = true)
|
||||
@RequiresPermissions
|
||||
public CommonResult<UserAddressRespVO> getUserAddress(@RequestParam("userAddressId") Integer userAddressId) {
|
||||
return success(userAddressManager.getUserAddress(UserSecurityContextHolder.getUserId(), userAddressId));
|
||||
}
|
||||
|
||||
@GetMapping("/get-default")
|
||||
@ApiOperation("获得默认的用户收件地址")
|
||||
@RequiresPermissions
|
||||
public CommonResult<UserAddressRespVO> getDefaultUserAddress() {
|
||||
return success(userAddressManager.getDefaultUserAddress(UserSecurityContextHolder.getUserId()));
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
@ApiOperation("获得用户收件地址列表")
|
||||
@RequiresPermissions
|
||||
public CommonResult<List<UserAddressRespVO>> listUserAddresses() {
|
||||
return success(userAddressManager.listUserAddresses(UserSecurityContextHolder.getUserId()));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
package cn.iocoder.mall.shopweb.controller.user;
|
||||
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.mall.security.user.core.context.UserSecurityContextHolder;
|
||||
import cn.iocoder.mall.shopweb.controller.user.vo.user.UserRespVO;
|
||||
import cn.iocoder.mall.shopweb.service.user.UserManager;
|
||||
import cn.iocoder.security.annotations.RequiresAuthenticate;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import static cn.iocoder.common.framework.vo.CommonResult.success;
|
||||
|
||||
@Api(tags = "用户信息 API")
|
||||
@RestController
|
||||
@RequestMapping("/user")
|
||||
public class UserController {
|
||||
|
||||
@Autowired
|
||||
private UserManager userManager;
|
||||
|
||||
@ApiOperation(value = "用户信息")
|
||||
@GetMapping("/info")
|
||||
@RequiresAuthenticate
|
||||
public CommonResult<UserRespVO> getUserInfo() {
|
||||
UserRespVO user = userManager.getUser(UserSecurityContextHolder.getUserId());
|
||||
return success(user);
|
||||
}
|
||||
|
||||
@PostMapping("/update-avatar")
|
||||
@RequiresAuthenticate
|
||||
@ApiOperation(value = "更新头像")
|
||||
@ApiImplicitParam(name = "avatar", value = "头像", required = true, example = "http://www.iocoder.cn/xxx.png")
|
||||
public CommonResult<Boolean> updateUserAvatar(@RequestParam("avatar") String avatar) {
|
||||
userManager.updateUserAvatar(UserSecurityContextHolder.getUserId(), avatar);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PostMapping("/update-nickname")
|
||||
@RequiresAuthenticate
|
||||
@ApiOperation(value = "更新昵称")
|
||||
@ApiImplicitParam(name = "nickname", value = "昵称", required = true, example = "蠢艿艿")
|
||||
public CommonResult<Boolean> updateUserNickname(@RequestParam("nickname") String nickname) {
|
||||
userManager.updateUserNickname(UserSecurityContextHolder.getUserId(), nickname);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
package cn.iocoder.mall.shopweb.controller.user.vo.address;
|
||||
|
||||
import cn.iocoder.common.framework.validator.InEnum;
|
||||
import cn.iocoder.mall.userservice.enums.address.UserAddressType;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@ApiModel("用户收件地址创建 Request VO")
|
||||
@Data
|
||||
public class UserAddressCreateReqVO {
|
||||
|
||||
@ApiModelProperty(value = "收件人名称", required = true, example = "帅艿艿")
|
||||
@NotEmpty(message = "收件人名称不能为空")
|
||||
private String name;
|
||||
@ApiModelProperty(value = "手机号", required = true, example = "15601691300")
|
||||
@NotEmpty(message = "手机号不能为空")
|
||||
private String mobile;
|
||||
@ApiModelProperty(value = "区域编号", required = true, example = "610632")
|
||||
@NotNull(message = "地区编码不能为空")
|
||||
private Integer areaCode;
|
||||
@ApiModelProperty(value = "收件详细地址", required = true, example = "芋道源码 233 号 666 室")
|
||||
@NotEmpty(message = "收件详细地址不能为空")
|
||||
private String detailAddress;
|
||||
@ApiModelProperty(value = "地址类型", required = true, example = "1", notes = "参见 UserAddressType 枚举类")
|
||||
@NotNull(message = "地址类型不能为空")
|
||||
@InEnum(value = UserAddressType.class, message = "地址类型必须是 {value}")
|
||||
private Integer type;
|
||||
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
package cn.iocoder.mall.shopweb.controller.user.vo.address;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@ApiModel("用户收件地址 Response VO")
|
||||
@Data
|
||||
public class UserAddressRespVO {
|
||||
|
||||
@ApiModelProperty(value = "收件地址编号", required = true, example = "1024")
|
||||
private Integer id;
|
||||
@ApiModelProperty(value = "用户编号", required = true, example = "2048")
|
||||
private Integer userId;
|
||||
@ApiModelProperty(value = "收件人名称", required = true, example = "帅艿艿")
|
||||
private String name;
|
||||
@ApiModelProperty(value = "手机号", required = true, example = "15601691300")
|
||||
private String mobile;
|
||||
@ApiModelProperty(value = "区域编号", required = true, example = "610632")
|
||||
private Integer areaCode;
|
||||
@ApiModelProperty(value = "收件详细地址", required = true, example = "芋道源码 233 号 666 室")
|
||||
private String detailAddress;
|
||||
@ApiModelProperty(value = "地址类型", required = true, example = "1", notes = "参见 UserAddressType 枚举类")
|
||||
private Integer type;
|
||||
@ApiModelProperty(value = "创建时间", required = true)
|
||||
private Date createTime;
|
||||
|
||||
}
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
package cn.iocoder.mall.shopweb.controller.user.vo.address;
|
||||
|
||||
import cn.iocoder.common.framework.validator.InEnum;
|
||||
import cn.iocoder.mall.userservice.enums.address.UserAddressType;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@ApiModel("用户收件地址更新 Request VO")
|
||||
@Data
|
||||
public class UserAddressUpdateReqVO {
|
||||
|
||||
@ApiModelProperty(value = "收件地址编号", required = true, example = "1024")
|
||||
@NotNull(message = "收件地址编号不能为空")
|
||||
private Integer id;
|
||||
@ApiModelProperty(value = "收件人名称", required = true, example = "帅艿艿")
|
||||
@NotEmpty(message = "收件人名称不能为空")
|
||||
private String name;
|
||||
@ApiModelProperty(value = "手机号", required = true, example = "15601691300")
|
||||
@NotEmpty(message = "手机号不能为空")
|
||||
private String mobile;
|
||||
@ApiModelProperty(value = "区域编号", required = true, example = "610632")
|
||||
@NotNull(message = "地区编码不能为空")
|
||||
private Integer areaCode;
|
||||
@ApiModelProperty(value = "收件详细地址", required = true, example = "芋道源码 233 号 666 室")
|
||||
@NotEmpty(message = "收件详细地址不能为空")
|
||||
private String detailAddress;
|
||||
@ApiModelProperty(value = "地址类型", required = true, example = "1", notes = "参见 UserAddressType 枚举类")
|
||||
@NotNull(message = "地址类型不能为空")
|
||||
@InEnum(value = UserAddressType.class, message = "地址类型必须是 {value}")
|
||||
private Integer type;
|
||||
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
package cn.iocoder.mall.shopweb.controller.user.vo.passport;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@ApiModel("访问令牌信息 Response VO")
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class PassportAccessTokenRespVO {
|
||||
|
||||
@ApiModelProperty(value = "访问令牌", required = true, example = "001e8f49b20e47f7b3a2de774497cd50")
|
||||
private String accessToken;
|
||||
@ApiModelProperty(value = "刷新令牌", required = true, example = "001e8f49b20e47f7b3a2de774497cd50")
|
||||
private String refreshToken;
|
||||
@ApiModelProperty(value = "过期时间", required = true)
|
||||
private Date expiresTime;
|
||||
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
package cn.iocoder.mall.shopweb.controller.user.vo.passport;
|
||||
|
||||
import cn.iocoder.common.framework.validator.Mobile;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.Pattern;
|
||||
import java.io.Serializable;
|
||||
|
||||
@ApiModel("用户短信验证码登陆 Request VO")
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class PassportLoginBySmsReqVO implements Serializable {
|
||||
|
||||
@ApiModelProperty(value = "手机号", required = true, example = "15601691300")
|
||||
@NotEmpty(message = "手机号不能为空")
|
||||
@Mobile
|
||||
private String mobile;
|
||||
|
||||
@ApiModelProperty(value = "手机验证码", required = true, example = "1024")
|
||||
@NotEmpty(message = "手机验证码不能为空")
|
||||
@Length(min = 4, max = 6, message = "手机验证码长度为 4-6 位")
|
||||
@Pattern(regexp = "^[0-9]+$", message = "手机验证码必须都是数字")
|
||||
private String code;
|
||||
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
package cn.iocoder.mall.shopweb.controller.user.vo.passport;
|
||||
|
||||
import cn.iocoder.common.framework.validator.Mobile;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@ApiModel("发送手机验证码 Response VO")
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class PassportSendSmsRespVO {
|
||||
|
||||
@ApiModelProperty(value = "手机号", example = "15601691234")
|
||||
@Mobile
|
||||
private String mobile;
|
||||
@ApiModelProperty(value = "发送场景", example = "1", notes = "对应 UserSmsSceneEnum 枚举")
|
||||
@NotNull(message = "发送场景不能为空")
|
||||
private Integer scene;
|
||||
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
package cn.iocoder.mall.shopweb.controller.user.vo.user;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@ApiModel("用户信息 VO")
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class UserRespVO {
|
||||
|
||||
@ApiModelProperty(value = "用户编号", required = true, example = "123")
|
||||
private Integer id;
|
||||
@ApiModelProperty(value = "手机号", required = true, example = "15601691300")
|
||||
private String mobile;
|
||||
@ApiModelProperty(value = "昵称", required = true, example = "小王")
|
||||
private String nickname;
|
||||
@ApiModelProperty(value = "头像", required = true, example = "http://www.iocoder.cn/xxx.jpg")
|
||||
private String avatar;
|
||||
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
package cn.iocoder.mall.shopweb.convert.product;
|
||||
|
||||
import cn.iocoder.mall.productservice.rpc.category.dto.ProductCategoryRespDTO;
|
||||
import cn.iocoder.mall.shopweb.controller.product.vo.category.ProductCategoryRespVO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface ProductCategoryConvert {
|
||||
|
||||
ProductCategoryConvert INSTANCE = Mappers.getMapper(ProductCategoryConvert.class);
|
||||
|
||||
List<ProductCategoryRespVO> convertList(List<ProductCategoryRespDTO> list);
|
||||
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
package cn.iocoder.mall.shopweb.convert.promotion;
|
||||
|
||||
import cn.iocoder.mall.promotion.api.rpc.banner.dto.BannerRespDTO;
|
||||
import cn.iocoder.mall.shopweb.controller.promotion.vo.brand.BannerRespVO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface BannerConvert {
|
||||
|
||||
BannerConvert INSTANCE = Mappers.getMapper(BannerConvert.class);
|
||||
|
||||
List<BannerRespVO> convertList(List<BannerRespDTO> list);
|
||||
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
package cn.iocoder.mall.shopweb.convert.user;
|
||||
|
||||
import cn.iocoder.mall.shopweb.controller.user.vo.passport.PassportAccessTokenRespVO;
|
||||
import cn.iocoder.mall.shopweb.controller.user.vo.passport.PassportLoginBySmsReqVO;
|
||||
import cn.iocoder.mall.shopweb.controller.user.vo.passport.PassportSendSmsRespVO;
|
||||
import cn.iocoder.mall.systemservice.rpc.oauth.dto.OAuth2AccessTokenRespDTO;
|
||||
import cn.iocoder.mall.userservice.rpc.sms.dto.UserSendSmsCodeReqDTO;
|
||||
import cn.iocoder.mall.userservice.rpc.sms.dto.UserVerifySmsCodeReqDTO;
|
||||
import cn.iocoder.mall.userservice.rpc.user.dto.UserCreateReqDTO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
@Mapper
|
||||
public interface PassportConvert {
|
||||
|
||||
PassportConvert INSTANCE = Mappers.getMapper(PassportConvert.class);
|
||||
|
||||
UserVerifySmsCodeReqDTO convert(PassportLoginBySmsReqVO bean);
|
||||
UserCreateReqDTO convert02(PassportLoginBySmsReqVO bean);
|
||||
|
||||
UserSendSmsCodeReqDTO convert(PassportSendSmsRespVO bean);
|
||||
|
||||
PassportAccessTokenRespVO convert(OAuth2AccessTokenRespDTO bean);
|
||||
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
package cn.iocoder.mall.shopweb.convert.user;
|
||||
|
||||
import cn.iocoder.mall.shopweb.controller.user.vo.address.UserAddressCreateReqVO;
|
||||
import cn.iocoder.mall.shopweb.controller.user.vo.address.UserAddressRespVO;
|
||||
import cn.iocoder.mall.shopweb.controller.user.vo.address.UserAddressUpdateReqVO;
|
||||
import cn.iocoder.mall.userservice.rpc.address.dto.UserAddressCreateReqDTO;
|
||||
import cn.iocoder.mall.userservice.rpc.address.dto.UserAddressRespDTO;
|
||||
import cn.iocoder.mall.userservice.rpc.address.dto.UserAddressUpdateReqDTO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface UserAddressConvert {
|
||||
|
||||
UserAddressConvert INSTANCE = Mappers.getMapper(UserAddressConvert.class);
|
||||
|
||||
UserAddressUpdateReqDTO convert(UserAddressUpdateReqVO bean);
|
||||
|
||||
UserAddressRespVO convert(UserAddressRespDTO bean);
|
||||
|
||||
List<UserAddressRespVO> convertList(List<UserAddressRespDTO> list);
|
||||
|
||||
UserAddressCreateReqDTO convert(UserAddressCreateReqVO bean);
|
||||
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
package cn.iocoder.mall.shopweb.convert.user;
|
||||
|
||||
import cn.iocoder.mall.shopweb.controller.user.vo.user.UserRespVO;
|
||||
import cn.iocoder.mall.userservice.rpc.user.dto.UserRespDTO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
@Mapper
|
||||
public interface UserConvert {
|
||||
|
||||
UserConvert INSTANCE = Mappers.getMapper(UserConvert.class);
|
||||
|
||||
UserRespVO convert(UserRespDTO bean);
|
||||
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
package cn.iocoder.mall.shopweb.service.promotion;
|
||||
|
||||
import cn.iocoder.common.framework.enums.CommonStatusEnum;
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.mall.promotion.api.rpc.banner.BannerFeign;
|
||||
import cn.iocoder.mall.promotion.api.rpc.banner.dto.BannerListReqDTO;
|
||||
import cn.iocoder.mall.promotion.api.rpc.banner.dto.BannerRespDTO;
|
||||
import cn.iocoder.mall.shopweb.controller.promotion.vo.brand.BannerRespVO;
|
||||
import cn.iocoder.mall.shopweb.convert.promotion.BannerConvert;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Banner Manager
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class BannerManager {
|
||||
@Autowired
|
||||
private BannerFeign bannerFeign;
|
||||
public List<BannerRespVO> listBanners() {
|
||||
// 获取 Banner 列表
|
||||
CommonResult<List<BannerRespDTO>> listBannersResult = bannerFeign.listBanners(
|
||||
new BannerListReqDTO().setStatus(CommonStatusEnum.ENABLE.getValue()));
|
||||
listBannersResult.checkError();
|
||||
// 排序返回
|
||||
listBannersResult.getData().sort(Comparator.comparing(BannerRespDTO::getSort));
|
||||
return BannerConvert.INSTANCE.convertList(listBannersResult.getData());
|
||||
}
|
||||
|
||||
}
|
|
@ -28,68 +28,6 @@ import java.util.stream.Collectors;
|
|||
@Service
|
||||
public class CartManager {
|
||||
|
||||
@Autowired
|
||||
private CartFeign cartFeign;
|
||||
@Autowired
|
||||
private PriceFeign priceFeign;
|
||||
|
||||
@Autowired
|
||||
private PromotionActivityFeign promotionActivityFeign;
|
||||
|
||||
@Autowired
|
||||
private ProductSkuFeign productSkuFeign;
|
||||
|
||||
/**
|
||||
* 添加商品到购物车
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @param skuId 商品 SKU 编号
|
||||
* @param quantity 增加数量
|
||||
*/
|
||||
public void addCartItem(Integer userId, Integer skuId, Integer quantity) {
|
||||
CommonResult<Boolean> addCartItemResult = cartFeign.addCartItem(new CartItemAddReqDTO().setUserId(userId)
|
||||
.setSkuId(skuId).setQuantity(quantity));
|
||||
addCartItemResult.checkError();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用户在购物车中的商品数量
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @return 商品数量
|
||||
*/
|
||||
public Integer sumCartItemQuantity(Integer userId) {
|
||||
CommonResult<Integer> sumCartItemQuantityResult = cartFeign.sumCartItemQuantity(userId);
|
||||
sumCartItemQuantityResult.checkError();
|
||||
return sumCartItemQuantityResult.getData();
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新购物车商品数量
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @param skuId 商品 SKU 编号
|
||||
* @param quantity 数量
|
||||
*/
|
||||
public void updateCartItemQuantity(Integer userId, Integer skuId, Integer quantity) {
|
||||
CommonResult<Boolean> updateCartItemQuantityResult = cartFeign.updateCartItemQuantity(new CartItemUpdateQuantityReqDTO()
|
||||
.setUserId(userId).setSkuId(skuId).setQuantity(quantity));
|
||||
updateCartItemQuantityResult.checkError();
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新购物车商品是否选中
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @param skuIds 商品 SKU 编号数组
|
||||
* @param selected 是否选中
|
||||
*/
|
||||
public void updateCartItemSelected(Integer userId, Set<Integer> skuIds, Boolean selected) {
|
||||
CommonResult<Boolean> updateCartItemSelectedResult = cartFeign.updateCartItemSelected(new CartItemUpdateSelectedReqDTO()
|
||||
.setUserId(userId).setSkuIds(skuIds).setSelected(selected));
|
||||
updateCartItemSelectedResult.checkError();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用户的购物车的商品列表
|
||||
*
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
package cn.iocoder.mall.shopweb.service.user;
|
||||
|
||||
import cn.iocoder.common.framework.enums.UserTypeEnum;
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.mall.shopweb.controller.user.vo.passport.PassportAccessTokenRespVO;
|
||||
import cn.iocoder.mall.shopweb.controller.user.vo.passport.PassportLoginBySmsReqVO;
|
||||
import cn.iocoder.mall.shopweb.controller.user.vo.passport.PassportSendSmsRespVO;
|
||||
import cn.iocoder.mall.shopweb.convert.user.PassportConvert;
|
||||
import cn.iocoder.mall.systemservice.rpc.oauth.OAuthFeign;
|
||||
import cn.iocoder.mall.systemservice.rpc.oauth.dto.OAuth2AccessTokenRespDTO;
|
||||
import cn.iocoder.mall.systemservice.rpc.oauth.dto.OAuth2CreateAccessTokenReqDTO;
|
||||
import cn.iocoder.mall.systemservice.rpc.oauth.dto.OAuth2RefreshAccessTokenReqDTO;
|
||||
import cn.iocoder.mall.userservice.enums.sms.UserSmsSceneEnum;
|
||||
import cn.iocoder.mall.userservice.rpc.sms.UserSmsCodeFeign;
|
||||
import cn.iocoder.mall.userservice.rpc.user.UserFeign;
|
||||
import cn.iocoder.mall.userservice.rpc.user.dto.UserRespDTO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class PassportManager {
|
||||
|
||||
private UserSmsCodeFeign userSmsCodeFeign;
|
||||
private UserFeign userFeign;
|
||||
|
||||
@Autowired
|
||||
private OAuthFeign oAuthFeign;
|
||||
|
||||
public PassportAccessTokenRespVO loginBySms(PassportLoginBySmsReqVO loginBySmsDTO, String ip) {
|
||||
// 校验验证码
|
||||
CommonResult<Boolean> verifySmsCodeResult = userSmsCodeFeign.verifySmsCode(
|
||||
PassportConvert.INSTANCE.convert(loginBySmsDTO).setScene(UserSmsSceneEnum.LOGIN_BY_SMS.getValue()).setIp(ip));
|
||||
verifySmsCodeResult.checkError();
|
||||
// 获得用户
|
||||
CommonResult<UserRespDTO> createUserResult = userFeign.createUserIfAbsent(
|
||||
PassportConvert.INSTANCE.convert02(loginBySmsDTO).setIp(ip));
|
||||
createUserResult.checkError();
|
||||
// 创建访问令牌
|
||||
CommonResult<OAuth2AccessTokenRespDTO> createAccessTokenResult = oAuthFeign.createAccessToken(
|
||||
new OAuth2CreateAccessTokenReqDTO().setUserId(createUserResult.getData().getId())
|
||||
.setUserType(UserTypeEnum.USER.getValue()).setCreateIp(ip));
|
||||
createAccessTokenResult.checkError();
|
||||
// 返回
|
||||
return PassportConvert.INSTANCE.convert(createAccessTokenResult.getData());
|
||||
}
|
||||
|
||||
public void sendSmsCode(PassportSendSmsRespVO sendSmsCodeDTO, String ip) {
|
||||
CommonResult<Boolean> sendSmsCodeResult = userSmsCodeFeign.sendSmsCode(
|
||||
PassportConvert.INSTANCE.convert(sendSmsCodeDTO).setIp(ip));
|
||||
sendSmsCodeResult.checkError();
|
||||
}
|
||||
|
||||
public PassportAccessTokenRespVO refreshToken(String refreshToken, String ip) {
|
||||
CommonResult<OAuth2AccessTokenRespDTO> refreshAccessTokenResult = oAuthFeign.refreshAccessToken(
|
||||
new OAuth2RefreshAccessTokenReqDTO().setRefreshToken(refreshToken).setCreateIp(ip));
|
||||
refreshAccessTokenResult.checkError();
|
||||
return PassportConvert.INSTANCE.convert(refreshAccessTokenResult.getData());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,129 +0,0 @@
|
|||
package cn.iocoder.mall.shopweb.service.user;
|
||||
|
||||
import cn.iocoder.common.framework.exception.GlobalException;
|
||||
import cn.iocoder.common.framework.util.CollectionUtils;
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.mall.shopweb.controller.user.vo.address.UserAddressCreateReqVO;
|
||||
import cn.iocoder.mall.shopweb.controller.user.vo.address.UserAddressRespVO;
|
||||
import cn.iocoder.mall.shopweb.controller.user.vo.address.UserAddressUpdateReqVO;
|
||||
import cn.iocoder.mall.shopweb.convert.user.UserAddressConvert;
|
||||
import cn.iocoder.mall.userservice.enums.address.UserAddressType;
|
||||
import cn.iocoder.mall.userservice.rpc.address.UserAddressFeign;
|
||||
import cn.iocoder.mall.userservice.rpc.address.dto.UserAddressRespDTO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.common.framework.exception.enums.GlobalErrorCodeConstants.FORBIDDEN;
|
||||
|
||||
/**
|
||||
* 用户收件地址 Manager
|
||||
*/
|
||||
@Service
|
||||
public class UserAddressManager {
|
||||
|
||||
@Autowired
|
||||
private UserAddressFeign userAddressFeign;
|
||||
/**
|
||||
* 创建用户收件地址
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @param createVO 创建用户收件地址 VO
|
||||
* @return 用户收件地址
|
||||
*/
|
||||
public Integer createUserAddress(Integer userId, UserAddressCreateReqVO createVO) {
|
||||
CommonResult<Integer> createUserAddressResult = userAddressFeign.createUserAddress(
|
||||
UserAddressConvert.INSTANCE.convert(createVO).setUserId(userId));
|
||||
createUserAddressResult.checkError();
|
||||
return createUserAddressResult.getData();
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新用户收件地址
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @param updateVO 更新用户收件地址 VO
|
||||
*/
|
||||
public void updateUserAddress(Integer userId, UserAddressUpdateReqVO updateVO) {
|
||||
// 校验是否能够操作
|
||||
check(userId, updateVO.getId());
|
||||
// 执行更新
|
||||
CommonResult<Boolean> updateUserAddressResult = userAddressFeign.updateUserAddress(UserAddressConvert.INSTANCE.convert(updateVO)
|
||||
.setUserId(userId));
|
||||
updateUserAddressResult.checkError();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除用户收件地址
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @param userAddressId 用户收件地址编号
|
||||
*/
|
||||
public void deleteUserAddress(Integer userId, Integer userAddressId) {
|
||||
// 校验是否能够操作
|
||||
check(userId, userAddressId);
|
||||
// 执行删除
|
||||
CommonResult<Boolean> deleteUserAddressResult = userAddressFeign.deleteUserAddress(userAddressId);
|
||||
deleteUserAddressResult.checkError();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得用户收件地址
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @param userAddressId 用户收件地址编号
|
||||
* @return 用户收件地址
|
||||
*/
|
||||
public UserAddressRespVO getUserAddress(Integer userId, Integer userAddressId) {
|
||||
CommonResult<UserAddressRespDTO> getUserAddressResult = userAddressFeign.getUserAddress(userAddressId);
|
||||
getUserAddressResult.checkError();
|
||||
// 校验是否能够操作
|
||||
this.check(userId, userAddressId);
|
||||
return UserAddressConvert.INSTANCE.convert(getUserAddressResult.getData());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得用户收件地址列表
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @return 用户收件地址列表
|
||||
*/
|
||||
public List<UserAddressRespVO> listUserAddresses(Integer userId) {
|
||||
CommonResult<List<UserAddressRespDTO>> listUserAddressResult = userAddressFeign.listUserAddresses(userId, null);
|
||||
listUserAddressResult.checkError();
|
||||
return UserAddressConvert.INSTANCE.convertList(listUserAddressResult.getData());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得用户的默认收件地址
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @return 用户收件地址
|
||||
*/
|
||||
public UserAddressRespVO getDefaultUserAddress(Integer userId) {
|
||||
CommonResult<List<UserAddressRespDTO>> listUserAddressResult = userAddressFeign.listUserAddresses(userId, UserAddressType.DEFAULT.getType());
|
||||
listUserAddressResult.checkError();
|
||||
return !CollectionUtils.isEmpty(listUserAddressResult.getData()) ?
|
||||
UserAddressConvert.INSTANCE.convert(listUserAddressResult.getData().get(0)) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验用户收件地址是不是属于该用户
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @param userAddressId 用户收件地址
|
||||
*/
|
||||
private void check(Integer userId, Integer userAddressId) {
|
||||
CommonResult<UserAddressRespDTO> getUserAddressResult = userAddressFeign.getUserAddress(userAddressId);
|
||||
getUserAddressResult.checkError();
|
||||
this.check(userId, getUserAddressResult.getData());
|
||||
}
|
||||
|
||||
private void check(Integer userId, UserAddressRespDTO userAddressRespDTO) {
|
||||
if (!userAddressRespDTO.getUserId().equals(userId)) {
|
||||
throw new GlobalException(FORBIDDEN);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
package cn.iocoder.mall.shopweb.service.user;
|
||||
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.mall.shopweb.controller.user.vo.user.UserRespVO;
|
||||
import cn.iocoder.mall.shopweb.convert.user.UserConvert;
|
||||
import cn.iocoder.mall.userservice.rpc.user.UserFeign;
|
||||
import cn.iocoder.mall.userservice.rpc.user.dto.UserRespDTO;
|
||||
import cn.iocoder.mall.userservice.rpc.user.dto.UserUpdateReqDTO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class UserManager {
|
||||
|
||||
@Autowired
|
||||
private UserFeign userFeign;
|
||||
public UserRespVO getUser(Integer id) {
|
||||
CommonResult<UserRespDTO> userResult = userFeign.getUser(id);
|
||||
userResult.checkError();
|
||||
return UserConvert.INSTANCE.convert(userResult.getData());
|
||||
}
|
||||
|
||||
public void updateUserAvatar(Integer userId, String avatar) {
|
||||
CommonResult<Boolean> updateUserResult = userFeign.updateUser(new UserUpdateReqDTO().setId(userId).setAvatar(avatar));
|
||||
updateUserResult.checkError();
|
||||
}
|
||||
|
||||
public void updateUserNickname(Integer userId, String nickname) {
|
||||
CommonResult<Boolean> updateUserResult = userFeign.updateUser(new UserUpdateReqDTO().setId(userId).setNickname(nickname));
|
||||
updateUserResult.checkError();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
spring:
|
||||
# Spring Cloud 配置项
|
||||
cloud:
|
||||
nacos:
|
||||
# Spring Cloud Nacos Discovery 配置项
|
||||
discovery:
|
||||
server-addr: localhost:8848 # Nacos 服务器地址
|
||||
namespace: dev # Nacos 命名空间
|
||||
|
||||
# Dubbo 配置项
|
||||
dubbo:
|
||||
# Dubbo 注册中心
|
||||
registry:
|
||||
# address: spring-cloud://localhost:8848 # 指定 Dubbo 服务注册中心的地址
|
||||
address: nacos://localhost:8848?namespace=dev # 指定 Dubbo 服务注册中心的地址
|
|
@ -1,18 +0,0 @@
|
|||
spring:
|
||||
# Spring Cloud 配置项
|
||||
cloud:
|
||||
nacos:
|
||||
# Spring Cloud Nacos Discovery 配置项
|
||||
discovery:
|
||||
server-addr: localhost:8848 # Nacos 服务器地址
|
||||
namespace: dev # Nacos 命名空间
|
||||
# Spring 主应用配置
|
||||
main:
|
||||
lazy-initialization: true # 开启延迟加载,保证本地开发的性能
|
||||
|
||||
# Dubbo 配置项
|
||||
dubbo:
|
||||
# Dubbo 注册中心
|
||||
registry:
|
||||
# address: spring-cloud://localhost:8848 # 指定 Dubbo 服务注册中心的地址
|
||||
address: nacos://localhost:8848?namespace=dev # 指定 Dubbo 服务注册中心的地址
|
|
@ -1,75 +0,0 @@
|
|||
# 服务器的配置项
|
||||
server:
|
||||
port: 18084
|
||||
servlet:
|
||||
context-path: /shop-api/
|
||||
|
||||
spring:
|
||||
# Application 的配置项
|
||||
application:
|
||||
name: shop-web
|
||||
# Profile 的配置项
|
||||
profiles:
|
||||
active: local
|
||||
# SpringMVC 配置项
|
||||
mvc:
|
||||
throw-exception-if-no-handler-found: true # 匹配不到路径时,抛出 NoHandlerFoundException 异常
|
||||
static-path-pattern: /doc.html # 静态资源的路径
|
||||
|
||||
# Dubbo 配置项
|
||||
dubbo:
|
||||
# Spring Cloud Alibaba Dubbo 专属配置
|
||||
cloud:
|
||||
subscribed-services: 'user-service,system-service' # 设置订阅的应用列表,默认为 * 订阅所有应用
|
||||
# Dubbo 服务消费者的配置
|
||||
consumer:
|
||||
timeout: 10000
|
||||
validation: true # 开启 Consumer 的参数校验
|
||||
UserRpc:
|
||||
version: 1.0.0
|
||||
OAuth2Rpc:
|
||||
version: 1.0.0
|
||||
SystemAccessLogRpc:
|
||||
version: 1.0.0
|
||||
SystemExceptionLogRpc:
|
||||
version: 1.0.0
|
||||
ProductCategoryRpc:
|
||||
version: 1.0.0
|
||||
ProductSpuRpc:
|
||||
version: 1.0.0
|
||||
ProductSkuRpc:
|
||||
version: 1.0.0
|
||||
SearchProductRpc:
|
||||
version: 1.0.0
|
||||
PriceRpc:
|
||||
version: 1.0.0
|
||||
PromotionActivityRpc:
|
||||
version: 1.0.0
|
||||
CouponCardRpc:
|
||||
version: 1.0.0
|
||||
CouponTemplateRpc:
|
||||
version: 1.0.0
|
||||
BannerRpc:
|
||||
version: 1.0.0
|
||||
ProductRecommendRpc:
|
||||
version: 1.0.0
|
||||
TradeOrderRpc:
|
||||
version: 1.0.0
|
||||
PayTransactionRpc:
|
||||
version: 1.0.0
|
||||
UserSmsCodeRpc:
|
||||
version: 1.0.0
|
||||
UserAddressRpc:
|
||||
version: 1.0.0
|
||||
|
||||
# Swagger 配置项
|
||||
swagger:
|
||||
title: 商城中心
|
||||
description: 提供用户商城购物流程中的 API
|
||||
version: 1.0.0
|
||||
base-package: cn.iocoder.mall.shopweb.controller
|
||||
|
||||
# Actuator 监控配置项
|
||||
management:
|
||||
server.port: 38088 # 独立端口,避免被暴露出去
|
||||
endpoints.web.exposure.include: '*' # 暴露所有监控端点
|
|
@ -1,36 +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>trade-service-project</artifactId>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>trade-service-api</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>common-framework</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 工具类相关 -->
|
||||
<dependency>
|
||||
<groupId>javax.validation</groupId>
|
||||
<artifactId>validation-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-openfeign-core</artifactId>
|
||||
<version>RELEASE</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -39,11 +39,6 @@ public interface OrderErrorCodeConstants {
|
|||
ErrorCode ORDER_RETURN_NOT_EXISTENT = new ErrorCode(1008000401, "退货订单不存在");
|
||||
ErrorCode ORDER_RETURN_REFUND_FAILED = new ErrorCode(1008000402, "退款失败");
|
||||
|
||||
// ========== 购物车 ==========
|
||||
ErrorCode CARD_ITEM_NOT_FOUND = new ErrorCode(1008003000, "购物车项不存在");
|
||||
ErrorCode CARD_ITEM_SKU_NOT_FOUND = new ErrorCode(1008003001, "商品不存在");
|
||||
ErrorCode CARD_ITEM_SKU_QUANTITY_NOT_ENOUGH = new ErrorCode(1008003002, "商品库存不足");
|
||||
|
||||
// 工具类服务 1008004000
|
||||
ErrorCode DICT_SERVER_INVOKING_FAIL = new ErrorCode(1008004000, "字典服务调用失败!");
|
||||
ErrorCode ORDER_LOGISTICS_INVOKING_FAIL = new ErrorCode(1008004001, "订单物流调用失败!");
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
package cn.iocoder.mall.tradeservice.rpc.cart;
|
||||
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.mall.tradeservice.rpc.cart.dto.*;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Title:
|
||||
* Description:
|
||||
*
|
||||
* @author zhuyang
|
||||
* @version 1.0 2021/10/9
|
||||
*/
|
||||
@FeignClient(value = "trade-service")
|
||||
public interface CartFeign {
|
||||
/**
|
||||
* 添加商品到购物车
|
||||
*
|
||||
* @param addReqDTO 添加商品信息
|
||||
* @return 成功
|
||||
*/
|
||||
@PostMapping("/trade/cart/addCartItem")
|
||||
CommonResult<Boolean> addCartItem(@RequestBody CartItemAddReqDTO addReqDTO);
|
||||
|
||||
/**
|
||||
* 更新购物车商品数量
|
||||
*
|
||||
* @param updateQuantityReqDTO 更新商品数量 DTO
|
||||
* @return 成功
|
||||
*/
|
||||
@PostMapping("/trade/cart/updateCartItemQuantity")
|
||||
CommonResult<Boolean> updateCartItemQuantity(@RequestBody CartItemUpdateQuantityReqDTO updateQuantityReqDTO);
|
||||
|
||||
/**
|
||||
* 更新购物车商品是否选中
|
||||
*
|
||||
* @param updateSelectedReqDTO 更新商品是否选中 DTO
|
||||
* @return 成功
|
||||
*/
|
||||
@PostMapping("/trade/cart/updateCartItemSelected")
|
||||
CommonResult<Boolean> updateCartItemSelected(@RequestBody CartItemUpdateSelectedReqDTO updateSelectedReqDTO);
|
||||
|
||||
/**
|
||||
* 删除购物车商品列表
|
||||
*
|
||||
* @param deleteListReqDTO 删除商品列表 DTO
|
||||
* @return 成功
|
||||
*/
|
||||
@PostMapping("/trade/cart/deleteCartItems")
|
||||
CommonResult<Boolean> deleteCartItems(@RequestBody CartItemDeleteListReqDTO deleteListReqDTO);
|
||||
@GetMapping("/sumCartItemQuantity")
|
||||
public CommonResult<Integer> sumCartItemQuantity(@RequestParam("userId") Integer userId) ;
|
||||
@PostMapping("/trade/cart/listCartItems")
|
||||
public CommonResult<List<CartItemRespDTO>> listCartItems(@RequestBody CartItemListReqDTO listReqDTO) ;
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
package cn.iocoder.mall.tradeservice.rpc.cart.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 购物车添加购物项 Request DTO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class CartItemAddReqDTO implements Serializable {
|
||||
|
||||
/**
|
||||
* 用户编号
|
||||
*/
|
||||
@NotNull(message = "用户编号不能为空")
|
||||
private Integer userId;
|
||||
/**
|
||||
* 商品 SKU 编号
|
||||
*/
|
||||
@NotNull(message = "商品 SKU 编号不能为空")
|
||||
private Integer skuId;
|
||||
/**
|
||||
* 数量
|
||||
*/
|
||||
@NotNull(message = "数量不能为空")
|
||||
@Min(message = "数量必须大于 0", value = 1L)
|
||||
private Integer quantity;
|
||||
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
package cn.iocoder.mall.tradeservice.rpc.cart.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 购物车删除商品列表 Request DTO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class CartItemDeleteListReqDTO implements Serializable {
|
||||
|
||||
/**
|
||||
* 用户编号
|
||||
*/
|
||||
@NotNull(message = "用户编号不能为空")
|
||||
private Integer userId;
|
||||
/**
|
||||
* 商品 SKU 编号列表
|
||||
*/
|
||||
@NotNull(message = "商品 SKU 编号列表不能为空")
|
||||
private List<Integer> skuIds;
|
||||
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
package cn.iocoder.mall.tradeservice.rpc.cart.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 购物车的商品信息查询 BO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class CartItemListReqDTO implements Serializable {
|
||||
|
||||
/**
|
||||
* 用户编号
|
||||
*/
|
||||
@NotNull(message = "用户编号不能为空")
|
||||
private Integer userId;
|
||||
/**
|
||||
* 是否选中
|
||||
*/
|
||||
private Boolean selected;
|
||||
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
package cn.iocoder.mall.tradeservice.rpc.cart.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 购物车的商品信息 Response DTO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class CartItemRespDTO implements Serializable {
|
||||
|
||||
// ========= 基础字段 BEGIN =========
|
||||
|
||||
/**
|
||||
* 编号,唯一自增。
|
||||
*/
|
||||
private Integer id;
|
||||
/**
|
||||
* 是否选中
|
||||
*/
|
||||
private Boolean selected;
|
||||
|
||||
// ========= 基础字段 END =========
|
||||
|
||||
// ========= 买家信息 BEGIN =========
|
||||
|
||||
/**
|
||||
* 用户编号
|
||||
*/
|
||||
private Integer userId;
|
||||
|
||||
// ========= 买家信息 END =========
|
||||
|
||||
// ========= 商品信息 BEGIN =========
|
||||
|
||||
/**
|
||||
* 商品 SPU 编号
|
||||
*/
|
||||
private Integer spuId;
|
||||
/**
|
||||
* 商品 SKU 编号
|
||||
*/
|
||||
private Integer skuId;
|
||||
/**
|
||||
* 商品购买数量
|
||||
*/
|
||||
private Integer quantity;
|
||||
|
||||
// ========= 商品信息 END =========
|
||||
|
||||
// ========= 优惠信息 BEGIN =========
|
||||
|
||||
// /**
|
||||
// * 商品营销活动编号
|
||||
// */
|
||||
// private Integer activityId;
|
||||
// /**
|
||||
// * 商品营销活动类型
|
||||
// */
|
||||
// private Integer activityType;
|
||||
|
||||
// ========= 优惠信息 END =========
|
||||
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
package cn.iocoder.mall.tradeservice.rpc.cart.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 购物车更新数量 Request DTO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class CartItemUpdateQuantityReqDTO implements Serializable {
|
||||
|
||||
/**
|
||||
* 用户编号
|
||||
*/
|
||||
@NotNull(message = "用户编号不能为空")
|
||||
private Integer userId;
|
||||
/**
|
||||
* 商品 SKU 编号
|
||||
*/
|
||||
@NotNull(message = "商品 SKU 编号不能为空")
|
||||
private Integer skuId;
|
||||
/**
|
||||
* 数量
|
||||
*/
|
||||
@NotNull(message = "数量不能为空")
|
||||
@Min(message = "数量必须大于 0", value = 1L)
|
||||
private Integer quantity;
|
||||
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
package cn.iocoder.mall.tradeservice.rpc.cart.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* 购物车更新是否选中 Request DTO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class CartItemUpdateSelectedReqDTO implements Serializable {
|
||||
|
||||
/**
|
||||
* 用户编号
|
||||
*/
|
||||
@NotNull(message = "用户编号不能为空")
|
||||
private Integer userId;
|
||||
/**
|
||||
* 商品 SKU 编号列表
|
||||
*/
|
||||
@NotNull(message = "商品 SKU 编号列表不能为空")
|
||||
private Collection<Integer> skuIds;
|
||||
/**
|
||||
* 是否选中
|
||||
*/
|
||||
@NotNull(message = "是否选中不能为空")
|
||||
private Boolean selected;
|
||||
|
||||
}
|
|
@ -1,147 +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>trade-service-project</artifactId>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>trade-service-app</artifactId>
|
||||
<dependencies>
|
||||
<!-- RPC 相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>mall-spring-boot-starter-dubbo</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<!-- 订单服务 -->
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>trade-service-api</artifactId>
|
||||
</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>user-service-api</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<!-- 商品服务 -->
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>product-service-api</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<!-- 支付服务 -->
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>pay-service-api</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<!-- 营销服务 -->
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>promotion-service-api</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Web 相关 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId> <!-- 需要开启 Web 容器,因为 Actuator 需要使用到 -->
|
||||
</dependency>
|
||||
|
||||
<!-- MQ 相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>mall-spring-boot-starter-rocketmq</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Registry 和 Config 相关 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- DB 相关 -->
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>mall-spring-boot-starter-mybatis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 监控相关 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 工具类相关 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct</artifactId> <!-- use mapstruct-jdk8 for Java 8 or higher -->
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct-jdk8</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjweaver</artifactId>
|
||||
<version>1.9.6</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Test 相关 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<!-- 设置构建的 jar 包名 -->
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
<!-- 使用 spring-boot-maven-plugin 插件打包 -->
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -1,17 +0,0 @@
|
|||
package cn.iocoder.mall.tradeservice;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableDiscoveryClient
|
||||
@EnableFeignClients(basePackages = {"cn.iocoder.mall.productservice.rpc","cn.iocoder.mall.promotion.api.rpc","cn.iocoder.mall.userservice.rpc"})
|
||||
public class TradeServiceApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(TradeServiceApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
package cn.iocoder.mall.tradeservice.client.user;
|
||||
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.mall.userservice.rpc.address.UserAddressFeign;
|
||||
import cn.iocoder.mall.userservice.rpc.address.dto.UserAddressRespDTO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@Service
|
||||
public class UserAddressClient {
|
||||
|
||||
@Autowired
|
||||
private UserAddressFeign userAddressFeign;
|
||||
public UserAddressRespDTO getUserAddress(Integer userAddressId, Integer userId) {
|
||||
CommonResult<UserAddressRespDTO> getUserAddressResult = userAddressFeign.getUserAddress(userAddressId);
|
||||
getUserAddressResult.checkError();
|
||||
if (getUserAddressResult.getData() == null) {
|
||||
return null;
|
||||
}
|
||||
// 如果用户编号不匹配,则返回 null
|
||||
return Objects.equals(getUserAddressResult.getData().getUserId(), userId) ?
|
||||
getUserAddressResult.getData() : null;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
package cn.iocoder.mall.tradeservice.config;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.EnableAspectJAutoProxy;
|
||||
|
||||
/**
|
||||
* Spring Aop 配置类
|
||||
*/
|
||||
@Configuration
|
||||
@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
|
||||
public class AopConfiguration {
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
package cn.iocoder.mall.tradeservice.config;
|
||||
|
||||
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
|
||||
import com.baomidou.mybatisplus.core.injector.ISqlInjector;
|
||||
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
|
||||
@Configuration
|
||||
@MapperScan("cn.iocoder.mall.tradeservice.dal.mysql.mapper") // 扫描对应的 Mapper 接口
|
||||
@EnableTransactionManagement(proxyTargetClass = true) // 启动事务管理。
|
||||
public class DatabaseConfiguration {
|
||||
|
||||
// 数据库连接池 Druid
|
||||
|
||||
@Bean
|
||||
public ISqlInjector sqlInjector() {
|
||||
return new DefaultSqlInjector(); // MyBatis Plus 逻辑删除
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PaginationInterceptor paginationInterceptor() {
|
||||
return new PaginationInterceptor(); // MyBatis Plus 分页插件
|
||||
}
|
||||
|
||||
}
|
|
@ -1,74 +0,0 @@
|
|||
package cn.iocoder.mall.tradeservice.controller;
|
||||
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.mall.tradeservice.rpc.cart.dto.*;
|
||||
import cn.iocoder.mall.tradeservice.service.cart.CartManager;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.common.framework.vo.CommonResult.success;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/trade/cart")
|
||||
public class CartController {
|
||||
@Autowired
|
||||
private CartManager cartManager;
|
||||
|
||||
/**
|
||||
* 添加商品到购物车
|
||||
*
|
||||
* @param addReqDTO 添加商品信息
|
||||
* @return 成功
|
||||
*/
|
||||
@PostMapping("addCartItem")
|
||||
CommonResult<Boolean> addCartItem(@RequestBody CartItemAddReqDTO addReqDTO){
|
||||
cartManager.addCartItem(addReqDTO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新购物车商品数量
|
||||
*
|
||||
* @param updateQuantityReqDTO 更新商品数量 DTO
|
||||
* @return 成功
|
||||
*/
|
||||
@PostMapping("updateCartItemQuantity")
|
||||
CommonResult<Boolean> updateCartItemQuantity(@RequestBody CartItemUpdateQuantityReqDTO updateQuantityReqDTO){
|
||||
cartManager.updateCartItemSelected(updateQuantityReqDTO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新购物车商品是否选中
|
||||
*
|
||||
* @param updateSelectedReqDTO 更新商品是否选中 DTO
|
||||
* @return 成功
|
||||
*/
|
||||
@PostMapping("updateCartItemSelected")
|
||||
CommonResult<Boolean> updateCartItemSelected(@RequestBody CartItemUpdateSelectedReqDTO updateSelectedReqDTO){
|
||||
cartManager.updateCartItemSelected(updateSelectedReqDTO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除购物车商品列表
|
||||
*
|
||||
* @param deleteListReqDTO 删除商品列表 DTO
|
||||
* @return 成功
|
||||
*/
|
||||
@PostMapping("deleteCartItems")
|
||||
CommonResult<Boolean> deleteCartItems(@RequestBody CartItemDeleteListReqDTO deleteListReqDTO){
|
||||
cartManager.deleteCartItems(deleteListReqDTO);
|
||||
return success(true);
|
||||
}
|
||||
@GetMapping("/sumCartItemQuantity")
|
||||
public CommonResult<Integer> sumCartItemQuantity(@RequestParam("userId") Integer userId) {
|
||||
return success(cartManager.sumCartItemQuantity(userId));
|
||||
}
|
||||
@PostMapping("/listCartItems")
|
||||
public CommonResult<List<CartItemRespDTO>> listCartItems(@RequestBody CartItemListReqDTO listReqDTO) {
|
||||
return success(cartManager.listCartItems(listReqDTO));
|
||||
}
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
package cn.iocoder.mall.tradeservice.convert.cart;
|
||||
|
||||
import cn.iocoder.mall.tradeservice.dal.mysql.dataobject.cart.CartItemDO;
|
||||
import cn.iocoder.mall.tradeservice.rpc.cart.dto.CartItemAddReqDTO;
|
||||
import cn.iocoder.mall.tradeservice.rpc.cart.dto.CartItemListReqDTO;
|
||||
import cn.iocoder.mall.tradeservice.rpc.cart.dto.CartItemRespDTO;
|
||||
import cn.iocoder.mall.tradeservice.service.cart.bo.CartItemAddBO;
|
||||
import cn.iocoder.mall.tradeservice.service.cart.bo.CartItemBO;
|
||||
import cn.iocoder.mall.tradeservice.service.cart.bo.CartItemListQueryBO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface CartConvert {
|
||||
|
||||
CartConvert INSTANCE = Mappers.getMapper(CartConvert.class);
|
||||
|
||||
CartItemDO convert(CartItemAddBO bean);
|
||||
|
||||
CartItemAddBO convert(CartItemAddReqDTO bean);
|
||||
|
||||
List<CartItemBO> convertList(List<CartItemDO> list);
|
||||
|
||||
CartItemListQueryBO convert(CartItemListReqDTO bean);
|
||||
|
||||
List<CartItemRespDTO> convertList02(List<CartItemBO> list);
|
||||
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
package cn.iocoder.mall.tradeservice.convert.order;
|
||||
|
||||
import cn.iocoder.common.framework.vo.PageResult;
|
||||
import cn.iocoder.mall.tradeservice.dal.mysql.dataobject.order.TradeOrderDO;
|
||||
import cn.iocoder.mall.tradeservice.dal.mysql.dataobject.order.TradeOrderItemDO;
|
||||
import cn.iocoder.mall.tradeservice.rpc.order.dto.TradeOrderItemRespDTO;
|
||||
import cn.iocoder.mall.tradeservice.rpc.order.dto.TradeOrderRespDTO;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface TradeOrderConvert {
|
||||
|
||||
TradeOrderConvert INSTANCE = Mappers.getMapper(TradeOrderConvert.class);
|
||||
|
||||
TradeOrderRespDTO convert(TradeOrderDO bean);
|
||||
|
||||
@Mapping(source = "records", target = "list")
|
||||
PageResult<TradeOrderRespDTO> convertPage(IPage<TradeOrderDO> page);
|
||||
|
||||
List<TradeOrderItemRespDTO> convertList(List<TradeOrderItemDO> list);
|
||||
|
||||
TradeOrderItemRespDTO convert(TradeOrderItemDO bean);
|
||||
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
package cn.iocoder.mall.tradeservice.dal.mysql.dataobject.cart;
|
||||
|
||||
import cn.iocoder.mall.mybatis.core.dataobject.DeletableDO;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 购物车的商品信息 DO
|
||||
*/
|
||||
@TableName("cart_item")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Accessors(chain = true)
|
||||
public class CartItemDO extends DeletableDO {
|
||||
|
||||
// ========= 基础字段 BEGIN =========
|
||||
|
||||
/**
|
||||
* 编号,唯一自增。
|
||||
*/
|
||||
private Integer id;
|
||||
/**
|
||||
* 是否选中
|
||||
*/
|
||||
private Boolean selected;
|
||||
|
||||
// ========= 基础字段 END =========
|
||||
|
||||
// ========= 买家信息 BEGIN =========
|
||||
|
||||
/**
|
||||
* 用户编号
|
||||
*/
|
||||
private Integer userId;
|
||||
|
||||
// ========= 买家信息 END =========
|
||||
|
||||
// ========= 商品信息 BEGIN =========
|
||||
|
||||
/**
|
||||
* 商品 SPU 编号
|
||||
*/
|
||||
private Integer spuId;
|
||||
/**
|
||||
* 商品 SKU 编号
|
||||
*/
|
||||
private Integer skuId;
|
||||
/**
|
||||
* 商品购买数量
|
||||
*/
|
||||
private Integer quantity;
|
||||
|
||||
// TODO 冗余字段
|
||||
|
||||
|
||||
// ========= 商品信息 END =========
|
||||
|
||||
// ========= 优惠信息 BEGIN =========
|
||||
|
||||
// /**
|
||||
// * 商品营销活动编号
|
||||
// */
|
||||
// private Integer activityId;
|
||||
// /**
|
||||
// * 商品营销活动类型
|
||||
// */
|
||||
// private Integer activityType;
|
||||
|
||||
// ========= 优惠信息 END =========
|
||||
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
package cn.iocoder.mall.tradeservice.dal.mysql.mapper.cart;
|
||||
|
||||
import cn.iocoder.mall.mybatis.core.query.QueryWrapperX;
|
||||
import cn.iocoder.mall.tradeservice.dal.mysql.dataobject.cart.CartItemDO;
|
||||
import cn.iocoder.mall.tradeservice.service.cart.bo.CartItemListQueryBO;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@Repository
|
||||
public interface CartItemMapper extends BaseMapper<CartItemDO> {
|
||||
|
||||
default CartItemDO selectByUserIdAndSkuId(Integer userId, Integer skuId) {
|
||||
return selectOne(new QueryWrapper<CartItemDO>().eq("user_id", userId)
|
||||
.eq("sku_id", skuId));
|
||||
}
|
||||
|
||||
default List<CartItemDO> selectListByUserIdAndSkuIds(Integer userId, Collection<Integer> skuIds) {
|
||||
return selectList(new QueryWrapperX<CartItemDO>().eq("user_id", userId)
|
||||
.inIfPresent("sku_id", skuIds));
|
||||
}
|
||||
|
||||
default void updateByIds(@Param("ids") Set<Integer> ids, @Param("updateObject") CartItemDO updateObject) {
|
||||
// TODO 芋艿:batch update ,在 mybatis plus 做拓展,这里先临时处理
|
||||
ids.forEach(id -> updateById(updateObject.setId(id)));
|
||||
}
|
||||
|
||||
default Integer selectSumQuantityByUserId(Integer userId) {
|
||||
// SQL sum 查询
|
||||
List<Map<String, Object>> result = selectMaps(new QueryWrapper<CartItemDO>()
|
||||
.select("SUM(quantity) AS sumQuantity")
|
||||
.eq("user_id", userId));
|
||||
// 获得数量
|
||||
return ((BigDecimal) result.get(0).get("sumQuantity")).intValue();
|
||||
}
|
||||
|
||||
default List<CartItemDO> selectList(CartItemListQueryBO queryBO) {
|
||||
return selectList(new QueryWrapperX<CartItemDO>().eq("user_id", queryBO.getUserId())
|
||||
.eqIfPresent("selected", queryBO.getSelected()));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,114 +0,0 @@
|
|||
package cn.iocoder.mall.tradeservice.service.cart;
|
||||
|
||||
import cn.iocoder.common.framework.enums.CommonStatusEnum;
|
||||
import cn.iocoder.common.framework.exception.util.ServiceExceptionUtil;
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.mall.productservice.rpc.sku.ProductSkuFeign;
|
||||
import cn.iocoder.mall.productservice.rpc.sku.dto.ProductSkuRespDTO;
|
||||
import cn.iocoder.mall.tradeservice.convert.cart.CartConvert;
|
||||
import cn.iocoder.mall.tradeservice.rpc.cart.dto.*;
|
||||
import cn.iocoder.mall.tradeservice.service.cart.bo.CartItemBO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.mall.tradeservice.enums.OrderErrorCodeConstants.CARD_ITEM_SKU_NOT_FOUND;
|
||||
|
||||
/**
|
||||
* 购物车 Manager
|
||||
*/
|
||||
@Service
|
||||
public class CartManager {
|
||||
|
||||
@Autowired
|
||||
private ProductSkuFeign productSkuFeign;
|
||||
|
||||
@Autowired
|
||||
private CartService cartService;
|
||||
|
||||
/**
|
||||
* 添加商品到购物车
|
||||
*
|
||||
* @param addReqDTO 添加商品信息
|
||||
*/
|
||||
public void addCartItem(CartItemAddReqDTO addReqDTO) {
|
||||
// 校验商品 SKU 是否合法
|
||||
ProductSkuRespDTO skuDTO = this.checkProductSku(addReqDTO.getSkuId());
|
||||
// 添加购物车项
|
||||
cartService.addCartItem(CartConvert.INSTANCE.convert(addReqDTO).setSpuId(skuDTO.getSpuId()), skuDTO.getQuantity());
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新购物车商品数量
|
||||
*
|
||||
* @param updateQuantityReqDTO 更新商品数量
|
||||
*/
|
||||
public void updateCartItemSelected(CartItemUpdateQuantityReqDTO updateQuantityReqDTO) {
|
||||
// 校验商品 SKU 是否合法
|
||||
ProductSkuRespDTO skuDTO = this.checkProductSku(updateQuantityReqDTO.getSkuId());
|
||||
// 更新购物车商品数量
|
||||
cartService.updateCartItemQuantity(updateQuantityReqDTO.getUserId(), updateQuantityReqDTO.getSkuId(),
|
||||
updateQuantityReqDTO.getQuantity(), skuDTO.getQuantity());
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新购物车商品是否选中
|
||||
*
|
||||
* @param updateSelectedReqDTO 更新商品是否选中 DTO
|
||||
*/
|
||||
public void updateCartItemSelected(CartItemUpdateSelectedReqDTO updateSelectedReqDTO) {
|
||||
cartService.updateCartItemSelected(updateSelectedReqDTO.getUserId(),
|
||||
updateSelectedReqDTO.getSkuIds(), updateSelectedReqDTO.getSelected());
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除购物车商品列表
|
||||
*
|
||||
* @param deleteListReqDTO 删除商品列表 DTO
|
||||
*/
|
||||
public void deleteCartItems(CartItemDeleteListReqDTO deleteListReqDTO) {
|
||||
cartService.deleteCartItems(deleteListReqDTO.getUserId(),
|
||||
deleteListReqDTO.getSkuIds());
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用户在购物车中的商品数量
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @return 商品数量
|
||||
*/
|
||||
public Integer sumCartItemQuantity(Integer userId) {
|
||||
return cartService.sumCartItemQuantity(userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用户在购物车种的商品列表
|
||||
*
|
||||
* @param listReqDTO 查询条件 DTO
|
||||
* @return 购物车中商品列表信息
|
||||
*/
|
||||
public List<CartItemRespDTO> listCartItems(CartItemListReqDTO listReqDTO) {
|
||||
List<CartItemBO> cartItemBOs = cartService.listCartItems(CartConvert.INSTANCE.convert(listReqDTO));
|
||||
return CartConvert.INSTANCE.convertList02(cartItemBOs);
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验商品 SKU 是否合法
|
||||
* 1. 是否存在
|
||||
* 2. 是否下架
|
||||
*
|
||||
* @param skuId 商品 SKU 编号
|
||||
* @return 商品 SKU 信息
|
||||
*/
|
||||
private ProductSkuRespDTO checkProductSku(Integer skuId) {
|
||||
CommonResult<ProductSkuRespDTO> getProductSkuResult = productSkuFeign.getProductSku(skuId);
|
||||
getProductSkuResult.checkError();
|
||||
ProductSkuRespDTO skuDTO = getProductSkuResult.getData();
|
||||
if (skuDTO == null || CommonStatusEnum.DISABLE.getValue().equals(skuDTO.getStatus())) {
|
||||
throw ServiceExceptionUtil.exception(CARD_ITEM_SKU_NOT_FOUND);
|
||||
}
|
||||
return skuDTO;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,136 +0,0 @@
|
|||
package cn.iocoder.mall.tradeservice.service.cart;
|
||||
|
||||
import cn.iocoder.common.framework.exception.util.ServiceExceptionUtil;
|
||||
import cn.iocoder.common.framework.util.CollectionUtils;
|
||||
import cn.iocoder.mall.tradeservice.convert.cart.CartConvert;
|
||||
import cn.iocoder.mall.tradeservice.dal.mysql.dataobject.cart.CartItemDO;
|
||||
import cn.iocoder.mall.tradeservice.dal.mysql.mapper.cart.CartItemMapper;
|
||||
import cn.iocoder.mall.tradeservice.service.cart.bo.CartItemAddBO;
|
||||
import cn.iocoder.mall.tradeservice.service.cart.bo.CartItemBO;
|
||||
import cn.iocoder.mall.tradeservice.service.cart.bo.CartItemListQueryBO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.mall.tradeservice.enums.OrderErrorCodeConstants.CARD_ITEM_NOT_FOUND;
|
||||
import static cn.iocoder.mall.tradeservice.enums.OrderErrorCodeConstants.CARD_ITEM_SKU_QUANTITY_NOT_ENOUGH;
|
||||
|
||||
/**
|
||||
* 购物车 Service
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class CartService {
|
||||
|
||||
@Autowired
|
||||
private CartItemMapper cartItemMapper;
|
||||
|
||||
/**
|
||||
* 添加商品到购物车
|
||||
*
|
||||
* @param addBO 添加商品信息
|
||||
* @param skuQuantity 商品 SKU 的库存,主要用于库存校验
|
||||
*/
|
||||
public void addCartItem(@Valid CartItemAddBO addBO, Integer skuQuantity) {
|
||||
// 查询 CartItemDO
|
||||
CartItemDO itemDO = cartItemMapper.selectByUserIdAndSkuId(addBO.getUserId(), addBO.getSkuId());
|
||||
// 存在,则进行数量更新
|
||||
if (itemDO != null) {
|
||||
if (addBO.getQuantity() + itemDO.getQuantity() > skuQuantity) {
|
||||
// 校验库存
|
||||
throw ServiceExceptionUtil.exception(CARD_ITEM_SKU_QUANTITY_NOT_ENOUGH);
|
||||
}
|
||||
cartItemMapper.updateById(new CartItemDO().setId(itemDO.getId()).setSelected(true)
|
||||
.setQuantity(addBO.getQuantity() + itemDO.getQuantity()));
|
||||
return;
|
||||
}
|
||||
// 不存在,则进行插入
|
||||
if (addBO.getQuantity() > skuQuantity) {
|
||||
// 校验库存
|
||||
throw ServiceExceptionUtil.exception(CARD_ITEM_SKU_QUANTITY_NOT_ENOUGH);
|
||||
}
|
||||
cartItemMapper.insert(CartConvert.INSTANCE.convert(addBO).setSelected(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新购物车商品数量
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @param skuId 商品 SKU 编号
|
||||
* @param quantity 数量
|
||||
* @param skuQuantity 商品 SKU 的库存,主要用于库存校验
|
||||
*/
|
||||
public void updateCartItemQuantity(Integer userId, Integer skuId, Integer quantity, Integer skuQuantity) {
|
||||
if (quantity > skuQuantity) {
|
||||
// 校验库存
|
||||
throw ServiceExceptionUtil.exception(CARD_ITEM_SKU_QUANTITY_NOT_ENOUGH);
|
||||
}
|
||||
// 查询 CartItemDO
|
||||
CartItemDO itemDO = cartItemMapper.selectByUserIdAndSkuId(userId, skuId);
|
||||
if (itemDO == null) {
|
||||
throw ServiceExceptionUtil.exception(CARD_ITEM_NOT_FOUND);
|
||||
}
|
||||
// 更新数量
|
||||
cartItemMapper.updateById(new CartItemDO().setId(itemDO.getId()).setQuantity(quantity));
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新购物车商品是否选中
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @param skuIds 商品 SKU 编号数组
|
||||
* @param selected 是否选中
|
||||
*/
|
||||
public void updateCartItemSelected(Integer userId, Collection<Integer> skuIds, Boolean selected) {
|
||||
// 查询 CartItemDO 列表
|
||||
List<CartItemDO> itemDOs = cartItemMapper.selectListByUserIdAndSkuIds(userId, skuIds);
|
||||
if (skuIds.size() != itemDOs.size()) {
|
||||
throw ServiceExceptionUtil.exception(CARD_ITEM_NOT_FOUND);
|
||||
}
|
||||
// 更新选中
|
||||
cartItemMapper.updateByIds(CollectionUtils.convertSet(itemDOs, CartItemDO::getId),
|
||||
new CartItemDO().setSelected(selected));
|
||||
}
|
||||
|
||||
/**
|
||||
* 购物车删除商品
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @param skuIds 商品 SKU 编号的数组
|
||||
*/
|
||||
public void deleteCartItems(Integer userId, List<Integer> skuIds) {
|
||||
// 查询 CartItemDO 列表
|
||||
List<CartItemDO> itemDOs = cartItemMapper.selectListByUserIdAndSkuIds(userId, skuIds);
|
||||
if (CollectionUtils.isEmpty(itemDOs)) {
|
||||
return;
|
||||
}
|
||||
// 批量标记删除
|
||||
cartItemMapper.deleteBatchIds(CollectionUtils.convertSet(itemDOs, CartItemDO::getId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用户在购物车中的商品数量
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @return 商品数量
|
||||
*/
|
||||
public Integer sumCartItemQuantity(Integer userId) {
|
||||
return cartItemMapper.selectSumQuantityByUserId(userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用户在购物车种的商品列表
|
||||
*
|
||||
* @param queryBO 查询条件 BO
|
||||
* @return 购物车中商品列表信息
|
||||
*/
|
||||
public List<CartItemBO> listCartItems(CartItemListQueryBO queryBO) {
|
||||
List<CartItemDO> cartItemDOs = cartItemMapper.selectList(queryBO);
|
||||
return CartConvert.INSTANCE.convertList(cartItemDOs);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
package cn.iocoder.mall.tradeservice.service.cart.bo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 购物车添加购物项 Request DTO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class CartItemAddBO {
|
||||
|
||||
/**
|
||||
* 用户编号
|
||||
*/
|
||||
@NotNull(message = "用户编号不能为空")
|
||||
private Integer userId;
|
||||
/**
|
||||
* 商品 SPU 编号
|
||||
*/
|
||||
@NotNull(message = "商品 SPU 编号不能为空")
|
||||
private Integer spuId;
|
||||
/**
|
||||
* 商品 SKU 编号
|
||||
*/
|
||||
@NotNull(message = "商品 SKU 编号不能为空")
|
||||
private Integer skuId;
|
||||
/**
|
||||
* 数量
|
||||
*/
|
||||
@NotNull(message = "数量不能为空")
|
||||
@Min(message = "数量必须大于 0", value = 1L)
|
||||
private Integer quantity;
|
||||
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
package cn.iocoder.mall.tradeservice.service.cart.bo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 购物车的商品信息 BO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class CartItemBO {
|
||||
|
||||
// ========= 基础字段 BEGIN =========
|
||||
|
||||
/**
|
||||
* 编号,唯一自增。
|
||||
*/
|
||||
private Integer id;
|
||||
/**
|
||||
* 是否选中
|
||||
*/
|
||||
private Boolean selected;
|
||||
|
||||
// ========= 基础字段 END =========
|
||||
|
||||
// ========= 买家信息 BEGIN =========
|
||||
|
||||
/**
|
||||
* 用户编号
|
||||
*/
|
||||
private Integer userId;
|
||||
|
||||
// ========= 买家信息 END =========
|
||||
|
||||
// ========= 商品信息 BEGIN =========
|
||||
|
||||
/**
|
||||
* 商品 SPU 编号
|
||||
*/
|
||||
private Integer spuId;
|
||||
/**
|
||||
* 商品 SKU 编号
|
||||
*/
|
||||
private Integer skuId;
|
||||
/**
|
||||
* 商品购买数量
|
||||
*/
|
||||
private Integer quantity;
|
||||
|
||||
// ========= 商品信息 END =========
|
||||
|
||||
// ========= 优惠信息 BEGIN =========
|
||||
|
||||
// /**
|
||||
// * 商品营销活动编号
|
||||
// */
|
||||
// private Integer activityId;
|
||||
// /**
|
||||
// * 商品营销活动类型
|
||||
// */
|
||||
// private Integer activityType;
|
||||
|
||||
// ========= 优惠信息 END =========
|
||||
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
package cn.iocoder.mall.tradeservice.service.cart.bo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 购物车的商品信息查询 BO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class CartItemListQueryBO {
|
||||
|
||||
/**
|
||||
* 用户编号
|
||||
*/
|
||||
@NotNull(message = "用户编号不能为空")
|
||||
private Integer userId;
|
||||
/**
|
||||
* 是否选中
|
||||
*/
|
||||
private Boolean selected;
|
||||
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
package cn.iocoder.mall.tradeservice.service.order;
|
||||
|
||||
import cn.iocoder.common.framework.vo.PageResult;
|
||||
import cn.iocoder.mall.tradeservice.rpc.order.dto.TradeOrderCreateReqDTO;
|
||||
import cn.iocoder.mall.tradeservice.rpc.order.dto.TradeOrderPageReqDTO;
|
||||
import cn.iocoder.mall.tradeservice.rpc.order.dto.TradeOrderRespDTO;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* 交易订单 Service 接口
|
||||
*/
|
||||
public interface TradeOrderService {
|
||||
|
||||
/**
|
||||
* 创建交易订单
|
||||
*
|
||||
* @param createReqDTO 订单信息
|
||||
* @return 订单编号
|
||||
*/
|
||||
Integer createTradeOrder(TradeOrderCreateReqDTO createReqDTO);
|
||||
|
||||
/**
|
||||
* 获得订单交易
|
||||
*
|
||||
* @param tradeOrderId 订单交易编号
|
||||
* @param fields 额外返回字段,可见 {@link cn.iocoder.mall.tradeservice.enums.order.TradeOrderDetailFieldEnum}
|
||||
* @return 订单交易
|
||||
*/
|
||||
TradeOrderRespDTO getTradeOrder(Integer tradeOrderId, Collection<String> fields);
|
||||
|
||||
/**
|
||||
* 获得订单交易分页
|
||||
*
|
||||
* @param pageReqDTO 订单交易分页查询
|
||||
* @return 订单交易分页结果
|
||||
*/
|
||||
PageResult<TradeOrderRespDTO> pageTradeOrder(TradeOrderPageReqDTO pageReqDTO);
|
||||
|
||||
/**
|
||||
* 更新交易订单支付成功
|
||||
*
|
||||
* @param tradeOrderId 交易订单编号
|
||||
* @param payAmount 支付金额
|
||||
*/
|
||||
void updateTradeOrderPaySuccess(Integer tradeOrderId, Integer payAmount);
|
||||
|
||||
}
|
|
@ -1,279 +0,0 @@
|
|||
package cn.iocoder.mall.tradeservice.service.order.impl;
|
||||
|
||||
import cn.iocoder.common.framework.exception.util.ServiceExceptionUtil;
|
||||
import cn.iocoder.common.framework.util.CollectionUtils;
|
||||
import cn.iocoder.common.framework.util.DateUtil;
|
||||
import cn.iocoder.common.framework.util.MathUtil;
|
||||
import cn.iocoder.common.framework.vo.PageResult;
|
||||
import cn.iocoder.mall.payservice.rpc.transaction.dto.PayTransactionCreateReqDTO;
|
||||
import cn.iocoder.mall.productservice.enums.sku.ProductSkuDetailFieldEnum;
|
||||
import cn.iocoder.mall.productservice.rpc.sku.dto.ProductSkuRespDTO;
|
||||
import cn.iocoder.mall.promotion.api.rpc.price.dto.PriceProductCalcReqDTO;
|
||||
import cn.iocoder.mall.promotion.api.rpc.price.dto.PriceProductCalcRespDTO;
|
||||
import cn.iocoder.mall.tradeservice.client.pay.PayTransactionClient;
|
||||
import cn.iocoder.mall.tradeservice.client.product.ProductSkuClient;
|
||||
import cn.iocoder.mall.tradeservice.client.promotion.CouponCardClient;
|
||||
import cn.iocoder.mall.tradeservice.client.promotion.PriceClient;
|
||||
import cn.iocoder.mall.tradeservice.client.user.UserAddressClient;
|
||||
import cn.iocoder.mall.tradeservice.config.TradeBizProperties;
|
||||
import cn.iocoder.mall.tradeservice.convert.order.TradeOrderConvert;
|
||||
import cn.iocoder.mall.tradeservice.dal.mysql.dataobject.order.TradeOrderDO;
|
||||
import cn.iocoder.mall.tradeservice.dal.mysql.dataobject.order.TradeOrderItemDO;
|
||||
import cn.iocoder.mall.tradeservice.dal.mysql.mapper.order.TradeOrderItemMapper;
|
||||
import cn.iocoder.mall.tradeservice.dal.mysql.mapper.order.TradeOrderMapper;
|
||||
import cn.iocoder.mall.tradeservice.enums.logistics.LogisticsDeliveryTypeEnum;
|
||||
import cn.iocoder.mall.tradeservice.enums.order.TradeOrderAfterSaleStatusEnum;
|
||||
import cn.iocoder.mall.tradeservice.enums.order.TradeOrderDetailFieldEnum;
|
||||
import cn.iocoder.mall.tradeservice.enums.order.TradeOrderStatusEnum;
|
||||
import cn.iocoder.mall.tradeservice.rpc.order.dto.TradeOrderCreateReqDTO;
|
||||
import cn.iocoder.mall.tradeservice.rpc.order.dto.TradeOrderPageReqDTO;
|
||||
import cn.iocoder.mall.tradeservice.rpc.order.dto.TradeOrderRespDTO;
|
||||
import cn.iocoder.mall.tradeservice.service.order.TradeOrderService;
|
||||
import cn.iocoder.mall.userservice.rpc.address.dto.UserAddressRespDTO;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.iocoder.common.framework.util.CollectionUtils.convertSet;
|
||||
import static cn.iocoder.mall.tradeservice.enums.OrderErrorCodeConstants.*;
|
||||
import static cn.iocoder.mall.userservice.enums.UserErrorCodeConstants.USER_ADDRESS_NOT_FOUND;
|
||||
|
||||
/**
|
||||
* 交易订单 Service 实现
|
||||
*/
|
||||
@Service
|
||||
public class TradeOrderServiceImpl implements TradeOrderService {
|
||||
|
||||
@Autowired
|
||||
private TradeOrderMapper tradeOrderMapper;
|
||||
@Autowired
|
||||
private TradeOrderItemMapper tradeOrderItemMapper;
|
||||
|
||||
@Autowired // 注入自己,用于调用事务方法
|
||||
private TradeOrderServiceImpl self;
|
||||
|
||||
@Autowired
|
||||
private UserAddressClient userAddressClient;
|
||||
@Autowired
|
||||
private ProductSkuClient productSkuClient;
|
||||
@Autowired
|
||||
private PriceClient priceClient;
|
||||
@Autowired
|
||||
private CouponCardClient couponCardClient;
|
||||
@Autowired
|
||||
private PayTransactionClient payTransactionClient;
|
||||
|
||||
@Autowired
|
||||
private TradeBizProperties tradeBizProperties;
|
||||
|
||||
@Override
|
||||
// @GlobalTransactional TODO 芋艿,使用 seata 实现分布式事务
|
||||
public Integer createTradeOrder(TradeOrderCreateReqDTO createReqDTO) {
|
||||
// 获得收件地址
|
||||
UserAddressRespDTO userAddressRespDTO = userAddressClient.getUserAddress(createReqDTO.getUserAddressId(),
|
||||
createReqDTO.getUserId());
|
||||
if (userAddressRespDTO == null) {
|
||||
throw ServiceExceptionUtil.exception(USER_ADDRESS_NOT_FOUND);
|
||||
}
|
||||
// 获得商品信息
|
||||
List<ProductSkuRespDTO> listProductSkus = productSkuClient.listProductSkus(
|
||||
convertSet(createReqDTO.getOrderItems(), TradeOrderCreateReqDTO.OrderItem::getSkuId),
|
||||
ProductSkuDetailFieldEnum.SPU.getField());
|
||||
if (listProductSkus.size() != createReqDTO.getOrderItems().size()) { // 校验获得的数量,是否匹配
|
||||
throw ServiceExceptionUtil.exception(ORDER_GET_GOODS_INFO_INCORRECT);
|
||||
}
|
||||
// 价格计算
|
||||
PriceProductCalcRespDTO priceProductCalcRespDTO = priceClient.calcProductPrice(createReqDTO.getUserId(),
|
||||
createReqDTO.getOrderItems().stream().map(orderItem -> new PriceProductCalcReqDTO.Item().setSkuId(orderItem.getSkuId())
|
||||
.setQuantity(orderItem.getQuantity()).setSelected(true)).collect(Collectors.toList()),
|
||||
createReqDTO.getCouponCardId());
|
||||
|
||||
// TODO 芋艿,扣除库存
|
||||
|
||||
// 标记优惠劵已使用
|
||||
if (createReqDTO.getCouponCardId() != null) {
|
||||
couponCardClient.useCouponCard(createReqDTO.getUserId(), createReqDTO.getCouponCardId());
|
||||
}
|
||||
|
||||
// 创建交易订单(本地事务)
|
||||
TradeOrderDO tradeOrderDO = self.createTradeOrder0(createReqDTO, listProductSkus, priceProductCalcRespDTO, userAddressRespDTO);
|
||||
|
||||
// 创建支付订单,对接支付服务
|
||||
createPayTransaction(tradeOrderDO, createReqDTO, listProductSkus);
|
||||
return tradeOrderDO.getId();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public TradeOrderDO createTradeOrder0(TradeOrderCreateReqDTO createReqDTO, List<ProductSkuRespDTO> listProductSkus,
|
||||
PriceProductCalcRespDTO priceProductCalcRespDTO, UserAddressRespDTO userAddressRespDTO) {
|
||||
// 构建 TradeOrderDO 对象,并进行保存
|
||||
TradeOrderDO tradeOrderDO = new TradeOrderDO();
|
||||
// 1. 基本信息
|
||||
tradeOrderDO.setUserId(createReqDTO.getUserId()).setOrderNo(generateTradeOrderNo())
|
||||
.setOrderStatus(TradeOrderStatusEnum.WAITING_PAYMENT.getValue()).setRemark(createReqDTO.getRemark());
|
||||
// 2. 价格 + 支付基本信息
|
||||
tradeOrderDO.setBuyPrice(priceProductCalcRespDTO.getFee().getBuyTotal())
|
||||
.setDiscountPrice(priceProductCalcRespDTO.getFee().getDiscountTotal())
|
||||
.setLogisticsPrice(priceProductCalcRespDTO.getFee().getPostageTotal())
|
||||
.setPresentPrice(priceProductCalcRespDTO.getFee().getPresentTotal())
|
||||
.setPayPrice(0).setRefundPrice(0);
|
||||
// 3. 收件 + 物流基本信息
|
||||
tradeOrderDO.setDeliveryType(LogisticsDeliveryTypeEnum.EXPRESS.getDeliveryType())
|
||||
.setReceiverName(userAddressRespDTO.getName()).setReceiverMobile(userAddressRespDTO.getMobile())
|
||||
.setReceiverAreaCode(userAddressRespDTO.getAreaCode()).setReceiverDetailAddress(userAddressRespDTO.getDetailAddress());
|
||||
// 4. 售后基本信息
|
||||
tradeOrderDO.setAfterSaleStatus(TradeOrderAfterSaleStatusEnum.NULL.getStatus());
|
||||
// 5. 营销基本信息
|
||||
tradeOrderDO.setCouponCardId(createReqDTO.getCouponCardId());
|
||||
// 最终保存
|
||||
tradeOrderMapper.insert(tradeOrderDO);
|
||||
|
||||
// 创建 TradeOrderItemDO 数组,并进行保存
|
||||
List<TradeOrderItemDO> tradeOrderItemDOs = new ArrayList<>(listProductSkus.size());
|
||||
Map<Integer, ProductSkuRespDTO> listProductSkuMap = CollectionUtils.convertMap(listProductSkus, ProductSkuRespDTO::getId);
|
||||
Map<Integer, PriceProductCalcRespDTO.Item> priceItemMap = new HashMap<>(); // 商品 SKU 价格的映射
|
||||
priceProductCalcRespDTO.getItemGroups().forEach(itemGroup ->
|
||||
itemGroup.getItems().forEach(item -> priceItemMap.put(item.getSkuId(), item)));
|
||||
for (TradeOrderCreateReqDTO.OrderItem orderItem : createReqDTO.getOrderItems()) {
|
||||
TradeOrderItemDO tradeOrderItemDO = new TradeOrderItemDO();
|
||||
tradeOrderItemDOs.add(tradeOrderItemDO);
|
||||
// 1. 基本信息
|
||||
tradeOrderItemDO.setOrderId(tradeOrderDO.getId()).setStatus(tradeOrderDO.getOrderStatus());
|
||||
// 2. 商品基本信息
|
||||
ProductSkuRespDTO productSkuRespDTO = listProductSkuMap.get(orderItem.getSkuId());
|
||||
tradeOrderItemDO.setSpuId(productSkuRespDTO.getSpuId()).setSkuId(productSkuRespDTO.getId())
|
||||
.setSkuName(productSkuRespDTO.getSpu().getName())
|
||||
.setSkuImage(CollectionUtils.getFirst(productSkuRespDTO.getSpu().getPicUrls()))
|
||||
.setQuantity(orderItem.getQuantity());
|
||||
// 3. 价格 + 支付基本信息
|
||||
PriceProductCalcRespDTO.Item priceItem = priceItemMap.get(orderItem.getSkuId());
|
||||
tradeOrderItemDO.setOriginPrice(priceItem.getOriginPrice()).setBuyPrice(priceItem.getBuyPrice())
|
||||
.setPresentPrice(priceItem.getPresentPrice()).setBuyTotal(priceItem.getBuyTotal())
|
||||
.setDiscountTotal(priceItem.getDiscountTotal()).setPresentTotal(priceItem.getPresentTotal())
|
||||
.setRefundTotal(0);
|
||||
// 4. 物流基本信息
|
||||
// 5. 售后基本信息
|
||||
tradeOrderItemDO.setAfterSaleStatus(TradeOrderAfterSaleStatusEnum.NULL.getStatus());
|
||||
}
|
||||
// 最终保存
|
||||
tradeOrderItemMapper.insertList(tradeOrderItemDOs);
|
||||
|
||||
return tradeOrderDO;
|
||||
}
|
||||
|
||||
private void createPayTransaction(TradeOrderDO tradeOrderDO, TradeOrderCreateReqDTO createReqDTO,
|
||||
List<ProductSkuRespDTO> listProductSkus) {
|
||||
// 创建支付单
|
||||
String orderSubject = listProductSkus.get(0).getSpu().getName();
|
||||
Date expireTime = DateUtil.addDate(Calendar.MINUTE, tradeBizProperties.getPayExpireTime());
|
||||
Integer payTransactionId = payTransactionClient.createPayTransaction(
|
||||
new PayTransactionCreateReqDTO().setUserId(createReqDTO.getUserId())
|
||||
.setCreateIp(createReqDTO.getIp()).setAppId(tradeBizProperties.getPayAppId())
|
||||
.setOrderId(tradeOrderDO.getId().toString()).setExpireTime(expireTime)
|
||||
.setPrice(tradeOrderDO.getPresentPrice()).setOrderSubject(orderSubject)
|
||||
.setOrderMemo("测试备注") // TODO 芋艿,后面补充
|
||||
.setOrderDescription("测试描述") // TODO 芋艿,后面补充
|
||||
);
|
||||
|
||||
// 更新
|
||||
tradeOrderMapper.updateById(new TradeOrderDO().setId(tradeOrderDO.getId()).setPayTransactionId(payTransactionId));
|
||||
}
|
||||
|
||||
private String generateTradeOrderNo() {
|
||||
// wx
|
||||
// 2014
|
||||
// 10
|
||||
// 27
|
||||
// 20
|
||||
// 09
|
||||
// 39
|
||||
// 5522657
|
||||
// a690389285100
|
||||
// 目前的算法
|
||||
// 时间序列,年月日时分秒 14 位
|
||||
// 纯随机,6 位 TODO 此处估计是会有问题的,后续在调整
|
||||
return DateUtil.format(new Date(), "yyyyMMddHHmmss") + // 时间序列
|
||||
MathUtil.random(100000, 999999) // 随机。为什么是这个范围,因为偷懒
|
||||
;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TradeOrderRespDTO getTradeOrder(Integer tradeOrderId, Collection<String> fields) {
|
||||
// 查询交易订单
|
||||
TradeOrderDO tradeOrderDO = tradeOrderMapper.selectById(tradeOrderId);
|
||||
if (tradeOrderDO == null) {
|
||||
return null;
|
||||
}
|
||||
TradeOrderRespDTO tradeOrderRespDTO = TradeOrderConvert.INSTANCE.convert(tradeOrderDO);
|
||||
// 查询交易订单项
|
||||
if (fields.contains(TradeOrderDetailFieldEnum.ITEM.getField())) {
|
||||
List<TradeOrderItemDO> tradeOrderItemDOs = tradeOrderItemMapper.selectListByOrderIds(
|
||||
Collections.singleton(tradeOrderDO.getId()));
|
||||
tradeOrderRespDTO.setOrderItems(TradeOrderConvert.INSTANCE.convertList(tradeOrderItemDOs));
|
||||
}
|
||||
// 返回
|
||||
return tradeOrderRespDTO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<TradeOrderRespDTO> pageTradeOrder(TradeOrderPageReqDTO pageReqDTO) {
|
||||
// 查询交易订单分页
|
||||
IPage<TradeOrderDO> tradeOrderDOPage = tradeOrderMapper.selectPage(pageReqDTO);
|
||||
PageResult<TradeOrderRespDTO> pageResult = TradeOrderConvert.INSTANCE.convertPage(tradeOrderDOPage);
|
||||
if (CollectionUtils.isEmpty(pageResult.getList())) {
|
||||
return pageResult;
|
||||
}
|
||||
// 查询交易订单项们
|
||||
if (pageReqDTO.getFields().contains(TradeOrderDetailFieldEnum.ITEM.getField())) {
|
||||
List<TradeOrderItemDO> tradeOrderItemDOs = tradeOrderItemMapper.selectListByOrderIds(
|
||||
convertSet(tradeOrderDOPage.getRecords(), TradeOrderDO::getId));
|
||||
Map<Integer, List<TradeOrderItemDO>> tradeOrderItemDOMultiMap = CollectionUtils.convertMultiMap(
|
||||
tradeOrderItemDOs, TradeOrderItemDO::getOrderId);
|
||||
pageResult.getList().forEach(tradeOrderRespDTO -> tradeOrderRespDTO.setOrderItems(
|
||||
TradeOrderConvert.INSTANCE.convertList(tradeOrderItemDOMultiMap.get(tradeOrderRespDTO.getId()))));
|
||||
}
|
||||
// 返回
|
||||
return pageResult;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void updateTradeOrderPaySuccess(Integer tradeOrderId, Integer payAmount) {
|
||||
// if (true) {
|
||||
// throw new IllegalArgumentException("测试失败的情况");
|
||||
// }
|
||||
// 校验交易订单,是否可以
|
||||
TradeOrderDO tradeOrderDO = tradeOrderMapper.selectById(tradeOrderId);
|
||||
if (tradeOrderDO == null) { // 订单不存在
|
||||
throw ServiceExceptionUtil.exception(ORDER_NOT_EXISTENT);
|
||||
}
|
||||
if (!tradeOrderDO.getOrderStatus().equals(TradeOrderStatusEnum.WAITING_PAYMENT.getValue())) { // 状态不处于等待支付
|
||||
throw ServiceExceptionUtil.exception(ORDER_STATUS_NOT_WAITING_PAYMENT);
|
||||
}
|
||||
if (!tradeOrderDO.getPresentPrice().equals(payAmount)) { // 支付金额不正确
|
||||
throw ServiceExceptionUtil.exception(ORDER_PAY_AMOUNT_ERROR);
|
||||
}
|
||||
|
||||
// 更新 TradeOrderDO 状态为已支付,等待发货
|
||||
TradeOrderDO updateOrderObj = new TradeOrderDO().setId(tradeOrderId)
|
||||
.setOrderStatus(TradeOrderStatusEnum.WAIT_SHIPMENT.getValue())
|
||||
.setPayPrice(payAmount)
|
||||
.setPayTime(new Date());
|
||||
int updateCount = tradeOrderMapper.update(updateOrderObj, TradeOrderStatusEnum.WAITING_PAYMENT.getValue());
|
||||
if (updateCount <= 0) {
|
||||
throw ServiceExceptionUtil.exception(ORDER_STATUS_NOT_WAITING_PAYMENT);
|
||||
}
|
||||
|
||||
// 更新 TradeOrderItemDO 状态为已支付,等待发货
|
||||
TradeOrderItemDO updateOrderItemObj = new TradeOrderItemDO()
|
||||
.setStatus(TradeOrderStatusEnum.WAIT_SHIPMENT.getValue());
|
||||
tradeOrderItemMapper.updateListByOrderId(updateOrderItemObj, tradeOrderId,
|
||||
TradeOrderStatusEnum.WAITING_PAYMENT.getValue());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
spring:
|
||||
# 数据源配置项
|
||||
datasource:
|
||||
url: jdbc:mysql://localhost:3306/mall_trade?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT
|
||||
driver-class-name: com.mysql.jdbc.Driver
|
||||
username: root
|
||||
password: zhuyang
|
||||
# Spring Cloud 配置项
|
||||
cloud:
|
||||
nacos:
|
||||
# Spring Cloud Nacos Discovery 配置项
|
||||
discovery:
|
||||
server-addr: localhost:8848 # Nacos 服务器地址
|
||||
namespace: dev # Nacos 命名空间
|
||||
|
||||
# Dubbo 配置项
|
||||
dubbo:
|
||||
# Dubbo 注册中心
|
||||
registry:
|
||||
# address: spring-cloud://localhost:8848 # 指定 Dubbo 服务注册中心的地址
|
||||
address: nacos://localhost:8848?namespace=dev # 指定 Dubbo 服务注册中心的地址
|
|
@ -1,32 +0,0 @@
|
|||
spring:
|
||||
# 数据源配置项
|
||||
datasource:
|
||||
url: jdbc:mysql://localhost:3306/mall_trade?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT
|
||||
driver-class-name: com.mysql.jdbc.Driver
|
||||
username: root
|
||||
password: zhuyang
|
||||
# Spring Cloud 配置项
|
||||
cloud:
|
||||
nacos:
|
||||
# Spring Cloud Nacos Discovery 配置项
|
||||
discovery:
|
||||
server-addr: localhost:8848 # Nacos 服务器地址
|
||||
namespace: dev # Nacos 命名空间
|
||||
# # Spring 主应用配置
|
||||
# main:
|
||||
# lazy-initialization: true # 开启延迟加载,保证本地开发的性能
|
||||
|
||||
# Dubbo 配置项
|
||||
dubbo:
|
||||
# Dubbo 注册中心
|
||||
registry:
|
||||
# address: spring-cloud://localhost:8848 # 指定 Dubbo 服务注册中心的地址
|
||||
address: nacos://localhost:8848?namespace=dev # 指定 Dubbo 服务注册中心的地址
|
||||
# Dubbo 服务提供者的配置
|
||||
provider:
|
||||
tag: ${DUBBO_TAG} # Dubbo 路由分组
|
||||
|
||||
# MyBatis Plus 配置
|
||||
mybatis-plus:
|
||||
configuration:
|
||||
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 本地开发环境下,多打印 SQL 到控制台
|
|
@ -1,75 +0,0 @@
|
|||
spring:
|
||||
# Application 的配置项
|
||||
application:
|
||||
name: trade-service
|
||||
# Profile 的配置项
|
||||
profiles:
|
||||
active: local
|
||||
|
||||
# MyBatis Plus 配置项
|
||||
mybatis-plus:
|
||||
configuration:
|
||||
map-underscore-to-camel-case: true # 虽然默认为 true ,但是还是显示去指定下。
|
||||
global-config:
|
||||
db-config:
|
||||
id-type: auto
|
||||
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
|
||||
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
|
||||
mapper-locations: classpath*:mapper/*.xml
|
||||
type-aliases-package: cn.iocoder.mall.tradeservice.dal.mysql.dataobject
|
||||
|
||||
# Dubbo 配置项
|
||||
dubbo:
|
||||
# Spring Cloud Alibaba Dubbo 专属配置
|
||||
cloud:
|
||||
subscribed-services: '' # 设置订阅的应用列表,默认为 * 订阅所有应用
|
||||
# Dubbo 提供者的协议
|
||||
protocol:
|
||||
name: dubbo
|
||||
port: -1
|
||||
# Dubbo 提供服务的扫描基础包
|
||||
scan:
|
||||
base-packages: cn.iocoder.mall.tradeservice.rpc
|
||||
# Dubbo 服务提供者的配置
|
||||
provider:
|
||||
filter: -exception
|
||||
validation: true # 开启 Provider 参数校验
|
||||
version: 1.0.0 # 服务的版本号
|
||||
# Dubbo 服务消费者的配置
|
||||
consumer:
|
||||
ErrorCodeRpc:
|
||||
version: 1.0.0
|
||||
ProductSkuRpc:
|
||||
version: 1.0.0
|
||||
UserAddressRpc:
|
||||
version: 1.0.0
|
||||
PriceRpc:
|
||||
version: 1.0.0
|
||||
CouponCardRpc:
|
||||
version: 1.0.0
|
||||
PayTransactionRpc:
|
||||
version: 1.0.0
|
||||
|
||||
# RocketMQ 配置项
|
||||
rocketmq:
|
||||
name-server: localhost:9876
|
||||
producer:
|
||||
group: ${spring.application.name}-producer-group
|
||||
|
||||
# Actuator 监控配置项
|
||||
management:
|
||||
server.port: 38084 # 独立端口,避免被暴露出去
|
||||
endpoints.web.exposure.include: '*' # 暴露所有监控端点
|
||||
server.port: ${management.server.port} # 设置使用 Actuator 的服务器端口,因为 RPC 服务不需要 Web 端口
|
||||
|
||||
# Mall 配置项
|
||||
mall:
|
||||
# 错误码配置项对应 ErrorCodeProperties 配置类
|
||||
error-code:
|
||||
group: ${spring.application.name}
|
||||
constants-class: cn.iocoder.mall.tradeservice.enums.OrderErrorCodeConstants
|
||||
|
||||
# 业务配置
|
||||
biz:
|
||||
pay-app-id: POd4RC6a
|
||||
pay-expire-time: 120
|
|
@ -1,52 +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>onemall</artifactId>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>user-service-project</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<description>用户服务</description>
|
||||
<modules>
|
||||
<module>user-service-api</module>
|
||||
<module>user-service-app</module>
|
||||
</modules>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<!-- onemall 基础 bom 文件 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>mall-dependencies</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>common-framework</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>user-service-api</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
</project>
|
|
@ -1,37 +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>user-service-project</artifactId>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>user-service-api</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>common-framework</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 工具类相关 -->
|
||||
<dependency>
|
||||
<groupId>javax.validation</groupId>
|
||||
<artifactId>validation-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-openfeign-core</artifactId>
|
||||
<version>RELEASE</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -1,16 +0,0 @@
|
|||
package cn.iocoder.mall.userservice.enums;
|
||||
|
||||
import cn.iocoder.common.framework.exception.ErrorCode;
|
||||
|
||||
/**
|
||||
* 错误码枚举类
|
||||
*
|
||||
* user-service 服务,使用 1-002-000-000 段
|
||||
*/
|
||||
public interface UserErrorCodeConstants {
|
||||
|
||||
// ========== 用户地址 ==========
|
||||
ErrorCode USER_ADDRESS_NOT_FOUND = new ErrorCode(1001004000, "用户地址不存在!");
|
||||
ErrorCode USER_GET_ADDRESS_NOT_EXISTS = new ErrorCode(1001004001, "获取的地址不存在!");
|
||||
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
package cn.iocoder.mall.userservice.rpc.user;
|
||||
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.common.framework.vo.PageResult;
|
||||
import cn.iocoder.mall.userservice.rpc.user.dto.UserCreateReqDTO;
|
||||
import cn.iocoder.mall.userservice.rpc.user.dto.UserPageReqDTO;
|
||||
import cn.iocoder.mall.userservice.rpc.user.dto.UserRespDTO;
|
||||
import cn.iocoder.mall.userservice.rpc.user.dto.UserUpdateReqDTO;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用户短信验证码 Rpc 接口
|
||||
*/
|
||||
@FeignClient("user-service")
|
||||
public interface UserFeign {
|
||||
@GetMapping("/user/manage/getUser")
|
||||
public CommonResult<UserRespDTO> getUser(@RequestParam("id") Integer id) ;
|
||||
|
||||
@GetMapping("/user/manage/listUsers")
|
||||
public CommonResult<List<UserRespDTO>> listUsers(@RequestParam("userIds") List<Integer> userIds) ;
|
||||
|
||||
@PostMapping("/user/manage/createUserIfAbsent")
|
||||
public CommonResult<UserRespDTO> createUserIfAbsent(@RequestBody UserCreateReqDTO createDTO);
|
||||
@PostMapping("/user/manage/updateUser")
|
||||
public CommonResult<Boolean> updateUser(@RequestBody UserUpdateReqDTO updateDTO);
|
||||
|
||||
@PostMapping("/user/manage/pageUser")
|
||||
public CommonResult<PageResult<UserRespDTO>> pageUser(@RequestBody UserPageReqDTO pageDTO);
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
package cn.iocoder.mall.userservice.rpc.user.dto;
|
||||
|
||||
import cn.iocoder.common.framework.validator.Mobile;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 用户创建 Request DTO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class UserCreateReqDTO implements Serializable {
|
||||
|
||||
/**
|
||||
* 手机号
|
||||
*/
|
||||
@NotNull(message = "手机号不能为空")
|
||||
@Mobile(message = "手机格式不正确")
|
||||
private String mobile;
|
||||
/**
|
||||
* 密码
|
||||
*
|
||||
* 允许为空,自动生成
|
||||
*/
|
||||
private String password;
|
||||
/**
|
||||
* IP
|
||||
*/
|
||||
@NotNull(message = "IP 不能为空")
|
||||
private String ip;
|
||||
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
package cn.iocoder.mall.userservice.rpc.user.dto;
|
||||
|
||||
import cn.iocoder.common.framework.enums.CommonStatusEnum;
|
||||
import cn.iocoder.common.framework.validator.InEnum;
|
||||
import cn.iocoder.common.framework.vo.PageParam;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 用户分页 Request DTO
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Accessors(chain = true)
|
||||
public class UserPageReqDTO extends PageParam {
|
||||
|
||||
/**
|
||||
* 昵称,模糊匹配
|
||||
*/
|
||||
private String nickname;
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
@InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}")
|
||||
private Integer status;
|
||||
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
package cn.iocoder.mall.userservice.rpc.user.dto;
|
||||
|
||||
import cn.iocoder.common.framework.enums.CommonStatusEnum;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 用户信息 Response DTO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class UserRespDTO implements Serializable {
|
||||
|
||||
/**
|
||||
* 用户编号
|
||||
*/
|
||||
private Integer id;
|
||||
/**
|
||||
* 手机号
|
||||
*/
|
||||
private String mobile;
|
||||
/**
|
||||
* 昵称
|
||||
*/
|
||||
private String nickname;
|
||||
/**
|
||||
* 头像
|
||||
*/
|
||||
private String avatar;
|
||||
/**
|
||||
* 用户状态
|
||||
*
|
||||
* 枚举 {@link CommonStatusEnum}
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 注册时间
|
||||
*/
|
||||
private Date createTime;
|
||||
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
package cn.iocoder.mall.userservice.rpc.user.dto;
|
||||
|
||||
import cn.iocoder.common.framework.enums.CommonStatusEnum;
|
||||
import cn.iocoder.common.framework.validator.InEnum;
|
||||
import cn.iocoder.common.framework.validator.Mobile;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 用户更新 Request DTO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class UserUpdateReqDTO implements Serializable {
|
||||
|
||||
/**
|
||||
* 用户编号
|
||||
*/
|
||||
@NotNull(message = "用户编号不能为空")
|
||||
private Integer id;
|
||||
/**
|
||||
* 昵称
|
||||
*/
|
||||
private String nickname;
|
||||
/**
|
||||
* 头像
|
||||
*/
|
||||
private String avatar;
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
@InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}")
|
||||
private Integer status;
|
||||
/**
|
||||
* 手机号
|
||||
*/
|
||||
@Mobile
|
||||
private String mobile;
|
||||
/**
|
||||
* 加密后的密码
|
||||
*/
|
||||
private String password;
|
||||
|
||||
}
|
|
@ -1,108 +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>user-service-project</artifactId>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>user-service-app</artifactId>
|
||||
<dependencies>
|
||||
<!-- RPC 相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>mall-spring-boot-starter-dubbo</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<!-- 系统服务 -->
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>system-service-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<!-- 用户服务 -->
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>user-service-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Web 相关 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId> <!-- 需要开启 Web 容器,因为 Actuator 需要使用到 -->
|
||||
</dependency>
|
||||
|
||||
<!-- Registry 和 Config 相关 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</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>cn.iocoder.mall</groupId>
|
||||
<artifactId>mall-spring-boot-starter-mybatis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 监控相关 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 工具类相关 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct</artifactId> <!-- use mapstruct-jdk8 for Java 8 or higher -->
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct-jdk8</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<!-- 设置构建的 jar 包名 -->
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
<!-- 使用 spring-boot-maven-plugin 插件打包 -->
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -1,17 +0,0 @@
|
|||
package cn.iocoder.mall.userservice;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableFeignClients(basePackages = {"cn.iocoder.mall.systemservice.rpc"})
|
||||
@EnableDiscoveryClient
|
||||
public class UserServiceApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(UserServiceApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
package cn.iocoder.mall.userservice.controller;
|
||||
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.common.framework.vo.PageResult;
|
||||
import cn.iocoder.mall.userservice.manager.user.UserManager;
|
||||
import cn.iocoder.mall.userservice.rpc.user.dto.UserCreateReqDTO;
|
||||
import cn.iocoder.mall.userservice.rpc.user.dto.UserPageReqDTO;
|
||||
import cn.iocoder.mall.userservice.rpc.user.dto.UserRespDTO;
|
||||
import cn.iocoder.mall.userservice.rpc.user.dto.UserUpdateReqDTO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.common.framework.vo.CommonResult.success;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/user/manage")
|
||||
public class UserManageController {
|
||||
|
||||
@Autowired
|
||||
private UserManager userManager;
|
||||
|
||||
@GetMapping("getUser")
|
||||
public CommonResult<UserRespDTO> getUser(@RequestParam("id") Integer id) {
|
||||
return success(userManager.getUser(id));
|
||||
}
|
||||
|
||||
@GetMapping("listUsers")
|
||||
public CommonResult<List<UserRespDTO>> listUsers(@RequestParam("userIds") List<Integer> userIds) {
|
||||
return success(userManager.listUsers(userIds));
|
||||
}
|
||||
|
||||
@PostMapping("createUserIfAbsent")
|
||||
public CommonResult<UserRespDTO> createUserIfAbsent(@RequestBody UserCreateReqDTO createDTO) {
|
||||
return success(userManager.createUserIfAbsent(createDTO));
|
||||
}
|
||||
|
||||
@PostMapping("updateUser")
|
||||
public CommonResult<Boolean> updateUser(@RequestBody UserUpdateReqDTO updateDTO) {
|
||||
userManager.updateUser(updateDTO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PostMapping("pageUser")
|
||||
public CommonResult<PageResult<UserRespDTO>> pageUser(@RequestBody UserPageReqDTO pageDTO) {
|
||||
return success(userManager.pageUser(pageDTO));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
package cn.iocoder.mall.userservice.dal.mysql.dataobject.sms;
|
||||
|
||||
import cn.iocoder.mall.mybatis.core.dataobject.BaseDO;
|
||||
import cn.iocoder.mall.userservice.enums.sms.UserSmsSceneEnum;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 手机验证码 DO
|
||||
*
|
||||
* idx_mobile 索引:基于 {@link #mobile} 字段
|
||||
*/
|
||||
@TableName("user_sms_code")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Accessors(chain = true)
|
||||
public class UserSmsCodeDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
private Integer id;
|
||||
/**
|
||||
* 手机号
|
||||
*/
|
||||
private String mobile;
|
||||
/**
|
||||
* 验证码
|
||||
*/
|
||||
private String code;
|
||||
/**
|
||||
* 发送场景
|
||||
*
|
||||
* 外键 {@link UserSmsSceneEnum}
|
||||
*/
|
||||
private Integer scene;
|
||||
/**
|
||||
* 创建 IP
|
||||
*/
|
||||
private String createIp;
|
||||
/**
|
||||
* 今日发送的第几条
|
||||
*/
|
||||
private Integer todayIndex;
|
||||
/**
|
||||
* 是否使用
|
||||
*/
|
||||
private Boolean used;
|
||||
/**
|
||||
* 使用时间
|
||||
*/
|
||||
private Date usedTime;
|
||||
/**
|
||||
* 使用 IP
|
||||
*/
|
||||
private String usedIp;
|
||||
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
package cn.iocoder.mall.userservice.dal.mysql.dataobject.user;
|
||||
|
||||
import cn.iocoder.common.framework.enums.CommonStatusEnum;
|
||||
import cn.iocoder.mall.mybatis.core.dataobject.BaseDO;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 用户实体
|
||||
*
|
||||
* uk_mobile 索引:基于 {@link #mobile} 字段
|
||||
*/
|
||||
@TableName(value = "users")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Accessors(chain = true)
|
||||
public class UserDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 用户编号
|
||||
*/
|
||||
private Integer id;
|
||||
/**
|
||||
* 昵称
|
||||
*/
|
||||
private String nickname;
|
||||
/**
|
||||
* 头像
|
||||
*/
|
||||
private String avatar;
|
||||
/**
|
||||
* 用户状态
|
||||
*
|
||||
* 枚举 {@link CommonStatusEnum}
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 手机
|
||||
*/
|
||||
private String mobile;
|
||||
/**
|
||||
* 经过加密的密码串
|
||||
*/
|
||||
private String password;
|
||||
/**
|
||||
* {@link #password} 的盐
|
||||
*/
|
||||
private String passwordSalt;
|
||||
/**
|
||||
* 注册 IP
|
||||
*/
|
||||
private String createIp;
|
||||
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
package cn.iocoder.mall.userservice.dal.mysql.dataobject.user;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 用户三方开放平台授权,例如:QQ / 微博 / 微信等等。
|
||||
*
|
||||
* TODO 优化点:需要在改改
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class UserThirdAuthDO {
|
||||
|
||||
/**
|
||||
* 用户编号
|
||||
*
|
||||
* 外键 {@link UserDO#uid}
|
||||
*/
|
||||
private Long uid;
|
||||
|
||||
// ========== 授权相关字段
|
||||
|
||||
/**
|
||||
* 用户的唯一标识
|
||||
*/
|
||||
private String openid;
|
||||
/**
|
||||
* 开放平台
|
||||
*
|
||||
* @see cn.iocoder.mall.user.api.constant.ThirdPlatformConstant
|
||||
*/
|
||||
private Integer platform;
|
||||
/**
|
||||
* 访问令牌
|
||||
*/
|
||||
private Date accessToken;
|
||||
/**
|
||||
* 过期时间
|
||||
*/
|
||||
private Date expireTime;
|
||||
/**
|
||||
* 刷新令牌
|
||||
*/
|
||||
private Date refreshToken;
|
||||
/**
|
||||
* 授权范围。一般情况下,使用逗号分隔
|
||||
*/
|
||||
private String scopes;
|
||||
|
||||
// ========== 基础信息
|
||||
/**
|
||||
* 用户昵称
|
||||
*/
|
||||
private String nickname;
|
||||
/**
|
||||
* 性别
|
||||
*
|
||||
* TODO 芋艿,找地方统一枚举。0-未知,1-男,2-女
|
||||
*/
|
||||
private Integer gender;
|
||||
// TODO https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842
|
||||
// TODO 芋艿,其他字段,国家/省份/城市/地区等
|
||||
// TODO 芋艿,头像
|
||||
// TODO 芋艿,微信独有 unionid
|
||||
/**
|
||||
* 统一存储基础信息,使用 JSON 格式化,避免未有效解析的情况。
|
||||
*/
|
||||
private String extras;
|
||||
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
package cn.iocoder.mall.userservice.dal.mysql.mapper.address;
|
||||
|
||||
import cn.iocoder.mall.mybatis.core.query.QueryWrapperX;
|
||||
import cn.iocoder.mall.userservice.dal.mysql.dataobject.address.UserAddressDO;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface UserAddressMapper extends BaseMapper<UserAddressDO> {
|
||||
|
||||
default List<UserAddressDO> selectListByUserIdAndType(Integer userId, @Nullable Integer type) {
|
||||
return selectList(new QueryWrapperX<UserAddressDO>().eq("user_id", userId)
|
||||
.eqIfPresent("type", type));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
package cn.iocoder.mall.userservice.dal.mysql.mapper.sms;
|
||||
|
||||
import cn.iocoder.mall.mybatis.core.query.QueryWrapperX;
|
||||
import cn.iocoder.mall.userservice.dal.mysql.dataobject.sms.UserSmsCodeDO;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface UserSmsCodeMapper extends BaseMapper<UserSmsCodeDO> {
|
||||
|
||||
/**
|
||||
* 获得手机号的最后一个手机验证码
|
||||
*
|
||||
* @param mobile 手机号
|
||||
* @param scene 发送场景,选填
|
||||
* @return 手机验证码
|
||||
*/
|
||||
default UserSmsCodeDO selectLastByMobile(String mobile, Integer scene) {
|
||||
QueryWrapperX<UserSmsCodeDO> query = new QueryWrapperX<UserSmsCodeDO>()
|
||||
.eq("mobile", mobile)
|
||||
.eqIfPresent("scene", scene)
|
||||
.orderByDesc("id")
|
||||
.last("limit 1");
|
||||
return selectOne(query);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
package cn.iocoder.mall.userservice.dal.mysql.mapper.user;
|
||||
|
||||
import cn.iocoder.mall.mybatis.core.query.QueryWrapperX;
|
||||
import cn.iocoder.mall.userservice.dal.mysql.dataobject.user.UserDO;
|
||||
import cn.iocoder.mall.userservice.service.user.bo.UserPageBO;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface UserMapper extends BaseMapper<UserDO> {
|
||||
|
||||
default UserDO selectByMobile(String mobile) {
|
||||
return selectOne(new QueryWrapper<UserDO>()
|
||||
.eq("mobile", mobile)
|
||||
);
|
||||
}
|
||||
|
||||
default IPage<UserDO> selectPage(UserPageBO pageBO) {
|
||||
return selectPage(new Page<>(pageBO.getPageNo(), pageBO.getPageSize()),
|
||||
new QueryWrapperX<UserDO>().likeIfPresent("nickname", pageBO.getNickname())
|
||||
.eqIfPresent("status", pageBO.getStatus()));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
package cn.iocoder.mall.userservice.manager.sms;
|
||||
|
||||
import cn.iocoder.mall.userservice.rpc.sms.dto.UserSendSmsCodeReqDTO;
|
||||
import cn.iocoder.mall.userservice.rpc.sms.dto.UserVerifySmsCodeReqDTO;
|
||||
import cn.iocoder.mall.userservice.service.sms.UserSmsCodeService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class UserSmsCodeManager {
|
||||
|
||||
@Autowired
|
||||
private UserSmsCodeService userSmsCodeService;
|
||||
|
||||
public void sendSmsCode(UserSendSmsCodeReqDTO sendSmsCodeDTO) {
|
||||
// 生成短信验证码
|
||||
String smsCode = userSmsCodeService.createSmsCode(sendSmsCodeDTO.getMobile(),
|
||||
sendSmsCodeDTO.getScene(), sendSmsCodeDTO.getIp());
|
||||
// TODO 调用发送验证码
|
||||
}
|
||||
|
||||
public void verifySmsCode(UserVerifySmsCodeReqDTO verifySmsCodeDTO) {
|
||||
userSmsCodeService.verifySmsCode(verifySmsCodeDTO.getMobile(), verifySmsCodeDTO.getCode(),
|
||||
verifySmsCodeDTO.getScene(), verifySmsCodeDTO.getIp());
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue