Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
Y
yudao-cloud
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
hblj
yudao-cloud
Commits
cb07eb3f
提交
cb07eb3f
authored
4月 19, 2019
作者:
YunaiV
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
前端:订单确认页,接入优惠劵列表(不包括计算)
后端:增加优惠劵的计算逻辑
上级
ea4593ad
隐藏空白字符变更
内嵌
并排
正在显示
12 个修改的文件
包含
339 行增加
和
33 行删除
+339
-33
order.vue
mobile-web/src/page/shipping/order.vue
+4
-3
UsersCartController.java
...der/application/controller/users/UsersCartController.java
+7
-5
UsersOrderController.java
...er/application/controller/users/UsersOrderController.java
+5
-2
UsersOrderConfirmCreateVO.java
.../mall/order/application/vo/UsersOrderConfirmCreateVO.java
+0
-1
CalcOrderPriceBO.java
...n/java/cn/iocoder/mall/order/api/bo/CalcOrderPriceBO.java
+11
-0
CalcOrderPriceDTO.java
...java/cn/iocoder/mall/order/api/dto/CalcOrderPriceDTO.java
+6
-1
CartServiceImpl.java
...va/cn/iocoder/mall/order/biz/service/CartServiceImpl.java
+101
-3
CouponService.java
...ain/java/cn/iocoder/mall/promotion/api/CouponService.java
+10
-0
CouponCardDetailBO.java
.../cn/iocoder/mall/promotion/api/bo/CouponCardDetailBO.java
+142
-0
PromotionErrorCodeEnum.java
...r/mall/promotion/api/constant/PromotionErrorCodeEnum.java
+13
-7
CouponCardConvert.java
...iocoder/mall/promotion/biz/convert/CouponCardConvert.java
+4
-0
CouponServiceImpl.java
...iocoder/mall/promotion/biz/service/CouponServiceImpl.java
+36
-11
没有找到文件。
mobile-web/src/page/shipping/order.vue
浏览文件 @
cb07eb3f
...
...
@@ -124,8 +124,9 @@
};
},
methods
:
{
onCouponChange
(
a
,
b
,
c
)
{
debugger
;
onCouponChange
(
index
)
{
this
.
chosenCoupon
=
index
;
this
.
showCouponPopup
=
false
;
},
onCouponExchange
(
a
,
b
,
c
)
{
Dialog
.
alert
({
...
...
@@ -204,7 +205,7 @@
endAt
:
card
.
validEndTime
/
1000
,
// description: '述信息,优惠券可用时展示',
reason
:
card
.
unavailableReason
,
value
:
card
.
preferentialType
===
1
?
card
.
priceOff
:
card
.
percentOff
,
value
:
0
,
// TODO ,需要服务端算
valueDesc
:
card
.
preferentialType
===
1
?
card
.
priceOff
/
100
:
card
.
percentOff
/
10.0
,
unitDesc
:
card
.
preferentialType
===
1
?
'元'
:
'折'
})
...
...
order/order-application/src/main/java/cn/iocoder/mall/order/application/controller/users/UsersCartController.java
浏览文件 @
cb07eb3f
...
...
@@ -96,7 +96,7 @@ public class UsersCartController {
return
CommonResult
.
success
(
result
);
}
// 计算商品价格
CommonResult
<
CalcOrderPriceBO
>
calcOrderPriceResult
=
list0
(
cartItems
);
CommonResult
<
CalcOrderPriceBO
>
calcOrderPriceResult
=
list0
(
cartItems
,
null
);
if
(
calcOrderPriceResult
.
isError
())
{
return
CommonResult
.
error
(
calcOrderPriceResult
);
}
...
...
@@ -105,7 +105,7 @@ public class UsersCartController {
}
@GetMapping
(
"/confirm_create_order"
)
public
CommonResult
<
UsersOrderConfirmCreateVO
>
getConfirmCreateOrder
()
{
public
CommonResult
<
UsersOrderConfirmCreateVO
>
getConfirmCreateOrder
(
@RequestParam
(
"couponCardId"
)
Integer
couponCardId
)
{
Integer
userId
=
UserSecurityContextHolder
.
getContext
().
getUserId
();
// 获得购物车中选中的
List
<
CartItemBO
>
cartItems
=
cartService
.
list
(
userId
,
true
).
getData
();
...
...
@@ -117,7 +117,7 @@ public class UsersCartController {
return
CommonResult
.
success
(
result
);
}
// 计算商品价格
CommonResult
<
CalcOrderPriceBO
>
calcOrderPriceResult
=
list0
(
cartItems
);
CommonResult
<
CalcOrderPriceBO
>
calcOrderPriceResult
=
list0
(
cartItems
,
couponCardId
);
if
(
calcOrderPriceResult
.
isError
())
{
return
CommonResult
.
error
(
calcOrderPriceResult
);
}
...
...
@@ -130,10 +130,12 @@ public class UsersCartController {
.
setCouponCards
(
couponCards
));
}
private
CommonResult
<
CalcOrderPriceBO
>
list0
(
List
<
CartItemBO
>
cartItems
)
{
private
CommonResult
<
CalcOrderPriceBO
>
list0
(
List
<
CartItemBO
>
cartItems
,
Integer
couponCardId
)
{
// 创建计算的 DTO
CalcOrderPriceDTO
calcOrderPriceDTO
=
new
CalcOrderPriceDTO
()
.
setItems
(
new
ArrayList
<>(
cartItems
.
size
()));
.
setUserId
(
UserSecurityContextHolder
.
getContext
().
getUserId
())
.
setItems
(
new
ArrayList
<>(
cartItems
.
size
()))
.
setCouponCardId
(
couponCardId
);
for
(
CartItemBO
item
:
cartItems
)
{
calcOrderPriceDTO
.
getItems
().
add
(
new
CalcOrderPriceDTO
.
Item
(
item
.
getSkuId
(),
item
.
getQuantity
(),
item
.
getSelected
()));
}
...
...
order/order-application/src/main/java/cn/iocoder/mall/order/application/controller/users/UsersOrderController.java
浏览文件 @
cb07eb3f
...
...
@@ -93,10 +93,13 @@ public class UsersOrderController {
@GetMapping
(
"confirm_create_order"
)
@ApiOperation
(
"确认创建订单"
)
public
CommonResult
<
UsersOrderConfirmCreateVO
>
getConfirmCreateOrder
(
@RequestParam
(
"skuId"
)
Integer
skuId
,
@RequestParam
(
"quantity"
)
Integer
quantity
)
{
@RequestParam
(
"quantity"
)
Integer
quantity
,
@RequestParam
(
"couponCardId"
)
Integer
couponCardId
)
{
// 创建 CalcOrderPriceDTO 对象,并执行价格计算
CalcOrderPriceDTO
calcOrderPriceDTO
=
new
CalcOrderPriceDTO
()
.
setItems
(
Collections
.
singletonList
(
new
CalcOrderPriceDTO
.
Item
(
skuId
,
quantity
,
true
)));
.
setUserId
(
UserSecurityContextHolder
.
getContext
().
getUserId
())
.
setItems
(
Collections
.
singletonList
(
new
CalcOrderPriceDTO
.
Item
(
skuId
,
quantity
,
true
)))
.
setCouponCardId
(
couponCardId
);
CommonResult
<
CalcOrderPriceBO
>
calcOrderPriceResult
=
cartService
.
calcOrderPrice
(
calcOrderPriceDTO
);
if
(
calcOrderPriceResult
.
isError
())
{
return
CommonResult
.
error
(
calcOrderPriceResult
);
...
...
order/order-application/src/main/java/cn/iocoder/mall/order/application/vo/UsersOrderConfirmCreateVO.java
浏览文件 @
cb07eb3f
...
...
@@ -24,7 +24,6 @@ public class UsersOrderConfirmCreateVO {
* 优惠劵列表 TODO 芋艿,后续改改
*/
private
List
<
CouponCardAvailableBO
>
couponCards
;
/**
* 商品分组
*
...
...
order/order-service-api/src/main/java/cn/iocoder/mall/order/api/bo/CalcOrderPriceBO.java
浏览文件 @
cb07eb3f
...
...
@@ -18,6 +18,17 @@ public class CalcOrderPriceBO {
* 商品分组数组
*/
private
List
<
ItemGroup
>
itemGroups
;
/**
* 优惠劵编号
*/
private
Integer
couponCardId
;
/**
* 优惠劵减少的金额
*
* 1. 若未使用优惠劵,返回 null
* 2. 该金额,已经分摊到每个 Item 的 discountTotal ,需要注意。
*/
private
Integer
couponCardDiscountTotal
;
/**
* 邮费信息
*
...
...
order/order-service-api/src/main/java/cn/iocoder/mall/order/api/dto/CalcOrderPriceDTO.java
浏览文件 @
cb07eb3f
...
...
@@ -3,6 +3,7 @@ package cn.iocoder.mall.order.api.dto;
import
lombok.Data
;
import
lombok.experimental.Accessors
;
import
javax.validation.constraints.NotNull
;
import
java.util.List
;
/**
...
...
@@ -12,9 +13,13 @@ import java.util.List;
@Accessors
(
chain
=
true
)
public
class
CalcOrderPriceDTO
{
@NotNull
(
message
=
"用户编号不能为空"
)
private
Integer
userId
;
/**
*
商品数组
*
优惠劵编号
*/
private
Integer
couponCardId
;
@NotNull
(
message
=
"商品数组不能为空"
)
private
List
<
Item
>
items
;
@Data
...
...
order/order-service-impl/src/main/java/cn/iocoder/mall/order/biz/service/CartServiceImpl.java
浏览文件 @
cb07eb3f
...
...
@@ -16,7 +16,9 @@ import cn.iocoder.mall.order.biz.dataobject.CartItemDO;
import
cn.iocoder.mall.product.api.ProductSpuService
;
import
cn.iocoder.mall.product.api.bo.ProductSkuBO
;
import
cn.iocoder.mall.product.api.bo.ProductSkuDetailBO
;
import
cn.iocoder.mall.promotion.api.CouponService
;
import
cn.iocoder.mall.promotion.api.PromotionActivityService
;
import
cn.iocoder.mall.promotion.api.bo.CouponCardDetailBO
;
import
cn.iocoder.mall.promotion.api.bo.PromotionActivityBO
;
import
cn.iocoder.mall.promotion.api.constant.*
;
import
com.alibaba.dubbo.config.annotation.Reference
;
...
...
@@ -38,6 +40,8 @@ public class CartServiceImpl implements CartService {
private
ProductSpuService
productSpuService
;
@Reference
(
validation
=
"true"
)
private
PromotionActivityService
promotionActivityService
;
@Reference
(
validation
=
"true"
)
private
CouponService
couponService
;
@Autowired
private
CartMapper
cartMapper
;
...
...
@@ -152,6 +156,7 @@ public class CartServiceImpl implements CartService {
@Override
public
CommonResult
<
CalcOrderPriceBO
>
calcOrderPrice
(
CalcOrderPriceDTO
calcOrderPriceDTO
)
{
// TODO 芋艿,补充一些表单校验。例如说,需要传入用户编号。
// 校验商品都存在
Map
<
Integer
,
CalcOrderPriceDTO
.
Item
>
calcOrderItemMap
=
calcOrderPriceDTO
.
getItems
().
stream
()
.
collect
(
Collectors
.
toMap
(
CalcOrderPriceDTO
.
Item
::
getSkuId
,
item
->
item
));
// KEY:skuId
...
...
@@ -177,7 +182,15 @@ public class CartServiceImpl implements CartService {
// 3. 计算【满减送】促销
List
<
CalcOrderPriceBO
.
ItemGroup
>
itemGroups
=
groupByFullPrivilege
(
items
,
activityList
);
calcOrderPriceBO
.
setItemGroups
(
itemGroups
);
// 4. 计算最终的价格
// 4. 计算优惠劵
if
(
calcOrderPriceDTO
.
getCouponCardId
()
!=
null
)
{
CommonResult
<
Integer
>
result
=
modifyPriceByCouponCard
(
calcOrderPriceDTO
.
getUserId
(),
calcOrderPriceDTO
.
getCouponCardId
(),
itemGroups
);
if
(
result
.
isError
())
{
return
CommonResult
.
error
(
result
);
}
calcOrderPriceBO
.
setCouponCardDiscountTotal
(
result
.
getData
());
}
// 5. 计算最终的价格
int
buyTotal
=
0
;
int
discountTotal
=
0
;
int
presentTotal
=
0
;
...
...
@@ -314,6 +327,72 @@ public class CartServiceImpl implements CartService {
return
itemGroups
;
}
private
CommonResult
<
Integer
>
modifyPriceByCouponCard
(
Integer
userId
,
Integer
couponCardId
,
List
<
CalcOrderPriceBO
.
ItemGroup
>
itemGroups
)
{
Assert
.
isTrue
(
couponCardId
!=
null
,
"优惠劵编号不能为空"
);
// 查询优惠劵
CommonResult
<
CouponCardDetailBO
>
couponCardResult
=
couponService
.
getCouponCardDetail
(
userId
,
couponCardId
);
if
(
couponCardResult
.
isError
())
{
return
CommonResult
.
error
(
couponCardResult
);
}
CouponCardDetailBO
couponCard
=
couponCardResult
.
getData
();
// 获得匹配的商品
List
<
CalcOrderPriceBO
.
Item
>
items
=
new
ArrayList
<>();
if
(
RangeTypeEnum
.
ALL
.
getValue
().
equals
(
couponCard
.
getRangeType
()))
{
// totalPrice = spus.stream().mapToInt(spu -> spu.getPrice() * spu.getQuantity()).sum();
itemGroups
.
forEach
(
itemGroup
->
items
.
addAll
(
itemGroup
.
getItems
()));
}
else
if
(
RangeTypeEnum
.
PRODUCT_INCLUDE_PART
.
getValue
().
equals
(
couponCard
.
getRangeType
()))
{
itemGroups
.
forEach
(
itemGroup
->
items
.
forEach
(
item
->
{
if
(
couponCard
.
getRangeValues
().
contains
(
item
.
getSpu
().
getId
()))
{
items
.
add
(
item
);
}
}));
}
else
if
(
RangeTypeEnum
.
PRODUCT_EXCLUDE_PART
.
getValue
().
equals
(
couponCard
.
getRangeType
()))
{
itemGroups
.
forEach
(
itemGroup
->
items
.
forEach
(
item
->
{
if
(!
couponCard
.
getRangeValues
().
contains
(
item
.
getSpu
().
getId
()))
{
items
.
add
(
item
);
}
}));
}
else
if
(
RangeTypeEnum
.
CATEGORY_INCLUDE_PART
.
getValue
().
equals
(
couponCard
.
getRangeType
()))
{
itemGroups
.
forEach
(
itemGroup
->
items
.
forEach
(
item
->
{
if
(
couponCard
.
getRangeValues
().
contains
(
item
.
getSpu
().
getCid
()))
{
items
.
add
(
item
);
}
}));
}
else
if
(
RangeTypeEnum
.
CATEGORY_EXCLUDE_PART
.
getValue
().
equals
(
couponCard
.
getRangeType
()))
{
itemGroups
.
forEach
(
itemGroup
->
items
.
forEach
(
item
->
{
if
(!
couponCard
.
getRangeValues
().
contains
(
item
.
getSpu
().
getCid
()))
{
items
.
add
(
item
);
}
}));
}
// 判断是否符合条件
int
originalTotal
=
items
.
stream
().
mapToInt
(
CalcOrderPriceBO
.
Item
::
getPresentTotal
).
sum
();
// 此处,指的是以优惠劵视角的原价
if
(
originalTotal
==
0
||
originalTotal
<
couponCard
.
getPriceAvailable
())
{
return
ServiceExceptionUtil
.
error
(
PromotionErrorCodeEnum
.
COUPON_CARD_NOT_MATCH
.
getCode
());
// TODO 芋艿,这种情况,会出现错误码的提示,无法格式化出来。另外,这块的最佳实践,找人讨论下。
}
// 计算价格
// 获得到优惠信息,进行价格计算
int
presentTotal
;
if
(
PreferentialTypeEnum
.
PRICE
.
getValue
().
equals
(
couponCard
.
getPreferentialType
()))
{
// 减价
// 计算循环次数。这样,后续优惠的金额就是相乘了
presentTotal
=
originalTotal
-
couponCard
.
getPriceOff
();
Assert
.
isTrue
(
presentTotal
>
0
,
"计算后,价格为负数:"
+
presentTotal
);
}
else
if
(
PreferentialTypeEnum
.
DISCOUNT
.
getValue
().
equals
(
couponCard
.
getPreferentialType
()))
{
// 打折
presentTotal
=
originalTotal
*
couponCard
.
getPercentOff
()
/
100
;
if
(
originalTotal
-
presentTotal
>
couponCard
.
getDiscountPriceLimit
())
{
presentTotal
=
originalTotal
-
couponCard
.
getDiscountPriceLimit
();
}
}
else
{
throw
new
IllegalArgumentException
(
String
.
format
(
"优惠劵(%s) 的优惠类型不正确"
,
couponCard
.
toString
()));
}
int
discountTotal
=
originalTotal
-
presentTotal
;
Assert
.
isTrue
(
discountTotal
>
0
,
"计算后,不产生优惠:"
+
discountTotal
);
// 按比例,拆分 presentTotal
splitDiscountPriceToItems
(
items
,
discountTotal
,
presentTotal
);
// 返回优惠金额
return
CommonResult
.
success
(
originalTotal
-
presentTotal
);
}
/**
* 计算指定 SKU 在限时折扣下的价格
*
...
...
@@ -393,11 +472,31 @@ public class CartServiceImpl implements CartService {
}
else
{
throw
new
IllegalArgumentException
(
String
.
format
(
"满减送促销(%s) 的优惠类型不正确"
,
activity
.
toString
()));
}
Integer
discountTotal
=
originalTotal
-
presentTotal
;
int
discountTotal
=
originalTotal
-
presentTotal
;
if
(
discountTotal
==
0
)
{
return
null
;
}
// 按比例,拆分 presentTotal
// for (int i = 0; i < items.size(); i++) {
// CalcOrderPriceBO.Item item = items.get(i);
// Integer discountPart;
// if (i < items.size() - 1) { // 减一的原因,是因为拆分时,如果按照比例,可能会出现.所以最后一个,使用反减
// discountPart = (int) (discountTotal * (1.0D * item.getPresentTotal() / presentTotal));
// discountTotal -= discountPart;
// } else {
// discountPart = discountTotal;
// }
// Assert.isTrue(discountPart > 0, "优惠金额必须大于 0");
// item.setDiscountTotal(item.getDiscountTotal() + discountPart);
// item.setPresentTotal(item.getBuyTotal() - item.getDiscountTotal());
// item.setPresentPrice(item.getPresentTotal() / item.getBuyQuantity());
// }
splitDiscountPriceToItems
(
items
,
discountTotal
,
presentTotal
);
// 返回优惠金额
return
originalTotal
-
presentTotal
;
}
private
void
splitDiscountPriceToItems
(
List
<
CalcOrderPriceBO
.
Item
>
items
,
Integer
discountTotal
,
Integer
presentTotal
)
{
for
(
int
i
=
0
;
i
<
items
.
size
();
i
++)
{
CalcOrderPriceBO
.
Item
item
=
items
.
get
(
i
);
Integer
discountPart
;
...
...
@@ -412,7 +511,6 @@ public class CartServiceImpl implements CartService {
item
.
setPresentTotal
(
item
.
getBuyTotal
()
-
item
.
getDiscountTotal
());
item
.
setPresentPrice
(
item
.
getPresentTotal
()
/
item
.
getBuyQuantity
());
}
return
originalTotal
-
presentTotal
;
}
private
PromotionActivityBO
findPromotionActivityByType
(
List
<
PromotionActivityBO
>
activityList
,
PromotionActivityTypeEnum
type
)
{
...
...
promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/CouponService.java
浏览文件 @
cb07eb3f
...
...
@@ -92,6 +92,15 @@ public interface CouponService {
*/
CommonResult
<
Boolean
>
cancelUseCouponCard
(
Integer
userId
,
Integer
couponCardId
);
/**
* 获得指定优惠劵
*
* @param userId 用户编号
* @param couponCardId 优惠劵编号
* @return 优惠劵
*/
CommonResult
<
CouponCardDetailBO
>
getCouponCardDetail
(
Integer
userId
,
Integer
couponCardId
);
/**
* 获得用户所有优惠劵,并标明是否可用
*
...
...
@@ -103,6 +112,7 @@ public interface CouponService {
*/
CommonResult
<
List
<
CouponCardAvailableBO
>>
getCouponCardList
(
Integer
userId
,
List
<
CouponCardSpuDTO
>
spus
);
// ========== 优惠码 ==========
/**
...
...
promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/bo/CouponCardDetailBO.java
0 → 100644
浏览文件 @
cb07eb3f
package
cn
.
iocoder
.
mall
.
promotion
.
api
.
bo
;
import
lombok.Data
;
import
lombok.experimental.Accessors
;
import
java.util.Date
;
import
java.util.List
;
/**
* 优惠劵明细 BO 。
*
* 主要是,会带上 {@link CouponTemplateBO} 的信息
*/
@Data
@Accessors
(
chain
=
true
)
public
class
CouponCardDetailBO
{
// ========== 基本信息 BEGIN ==========
/**
* 优惠劵编号
*/
private
Integer
id
;
/**
* 优惠劵(码)分组编号
*/
private
Integer
templateId
;
/**
* 优惠劵名
*/
private
String
title
;
// /**
// * 核销码
// */
// private String verifyCode;
/**
* 优惠码状态
*
* 1-未使用
* 2-已使用
* 3-已失效
*/
private
Integer
status
;
// ========== 基本信息 END ==========
// ========== 领取情况 BEGIN ==========
/**
* 用户编号
*/
private
Integer
userId
;
/**
* 领取类型
*
* 1 - 用户主动领取
* 2 - 后台自动发放
*/
private
Integer
takeType
;
// ========== 领取情况 END ==========
// ========== 使用规则 BEGIN ==========
/**
* 是否设置满多少金额可用,单位:分
*/
private
Integer
priceAvailable
;
/**
* 生效开始时间
*/
private
Date
validStartTime
;
/**
* 生效结束时间
*/
private
Date
validEndTime
;
// ========== 使用规则 END ==========
// ========== 使用效果 BEGIN ==========
/**
* 优惠类型
*
* 1-代金卷
* 2-折扣卷
*/
private
Integer
preferentialType
;
/**
* 折扣
*/
private
Integer
percentOff
;
/**
* 优惠金额,单位:分。
*/
private
Integer
priceOff
;
/**
* 折扣上限,仅在 {@link #preferentialType} 等于 2 时生效。
*
* 例如,折扣上限为 20 元,当使用 8 折优惠券,订单金额为 1000 元时,最高只可折扣 20 元,而非 80 元。
*/
private
Integer
discountPriceLimit
;
// ========== 使用效果 END ==========
// ========== 使用情况 BEGIN ==========
/**
* 是否使用
*/
private
Boolean
used
;
/**
* 使用订单号
*/
private
Integer
usedOrderId
;
/**
* 订单中优惠面值,单位:分
*/
private
Integer
usedPrice
;
/**
* 使用时间
*/
private
Date
usedTime
;
// TODO 芋艿,后续要加优惠劵的使用日志,因为下单后,可能会取消。
// ========== 使用情况 END ==========
/**
* 创建时间
*/
private
Date
createTime
;
// ========== FROM template 使用规则 BEGIN ==========
/**
* 可用范围的类型
*
* 10-全部(ALL):所有可用
* 20-部分(PART):部分商品可用,或指定商品可用
* 21-部分(PART):部分商品不可用,或指定商品可用
* 30-部分(PART):部分分类可用,或指定商品可用
* 31-部分(PART):部分分类不可用,或指定商品可用
*/
private
Integer
rangeType
;
/**
* 指定商品 / 分类列表,使用逗号分隔商品编号
*/
private
List
<
Integer
>
rangeValues
;
}
promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/constant/PromotionErrorCodeEnum.java
浏览文件 @
cb07eb3f
...
...
@@ -17,15 +17,21 @@ public enum PromotionErrorCodeEnum {
// ========== COUPON TEMPLATE 模块 ==========
PRODUCT_TEMPLATE_NOT_EXISTS
(
1006002000
,
"优惠劵模板(码)不存在"
),
PRODUCT_TEMPLATE_NOT_CARD
(
1006002001
,
"不是优惠劵模板"
),
PRODUCT_TEMPLATE_NOT_CODE
(
1006002002
,
"不是优惠码模板"
),
PRODUCT_TEMPLATE_TOTAL_CAN_NOT_REDUCE
(
1006002003
,
"优惠劵(码)模板的发放数量不能减小"
),
PRODUCT_TEMPLATE_STATUS_NOT_ENABLE
(
1006002004
,
"优惠劵模板(码)未开启"
),
PRODUCT_TEMPLATE_TOTAL_NOT_ENOUGH
(
1006002005
,
"优惠劵(码)模板的发放量不足"
),
PRODUCT_TEMPLATE_CARD_ADD_EXCEED_QUOTA
(
1006002006
,
"优惠劵领取到达上限"
),
COUPON_TEMPLATE_NOT_EXISTS
(
1006002000
,
"优惠劵模板(码)不存在"
),
COUPON_TEMPLATE_NOT_CARD
(
1006002001
,
"不是优惠劵模板"
),
COUPON_TEMPLATE_NOT_CODE
(
1006002002
,
"不是优惠码模板"
),
COUPON_TEMPLATE_TOTAL_CAN_NOT_REDUCE
(
1006002003
,
"优惠劵(码)模板的发放数量不能减小"
),
COUPON_TEMPLATE_STATUS_NOT_ENABLE
(
1006002004
,
"优惠劵模板(码)未开启"
),
COUPON_TEMPLATE_TOTAL_NOT_ENOUGH
(
1006002005
,
"优惠劵(码)模板的发放量不足"
),
COUPON_TEMPLATE_CARD_ADD_EXCEED_QUOTA
(
1006002006
,
"优惠劵领取到达上限"
),
// ========== COUPON CARD 模块 ==========
COUPON_CARD_NOT_EXISTS
(
1006003000
,
"优惠劵不存在"
),
COUPON_CARD_ERROR_USER
(
1006003001
,
"优惠劵不属于当前用户"
),
COUPON_CARD_NOT_MATCH
(
1006003002
,
"优惠劵不匹配,无法使用"
),
;
private
final
int
code
;
private
final
String
message
;
...
...
promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/convert/CouponCardConvert.java
浏览文件 @
cb07eb3f
...
...
@@ -2,6 +2,7 @@ package cn.iocoder.mall.promotion.biz.convert;
import
cn.iocoder.mall.promotion.api.bo.CouponCardAvailableBO
;
import
cn.iocoder.mall.promotion.api.bo.CouponCardBO
;
import
cn.iocoder.mall.promotion.api.bo.CouponCardDetailBO
;
import
cn.iocoder.mall.promotion.biz.dataobject.CouponCardDO
;
import
org.mapstruct.Mapper
;
import
org.mapstruct.Mappings
;
...
...
@@ -23,6 +24,9 @@ public interface CouponCardConvert {
@Mappings
({})
CouponCardBO
convert
(
CouponCardDO
card
);
@Mappings
({})
CouponCardDetailBO
convert2
(
CouponCardDO
card
);
@Mappings
({})
CouponCardAvailableBO
convert2
(
CouponCardDO
card
,
boolean
x
);
// TODO 芋艿,临时用来解决 mapstruct 无法正确匹配方法的问题
...
...
promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/service/CouponServiceImpl.java
浏览文件 @
cb07eb3f
...
...
@@ -20,7 +20,10 @@ import org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
java.util.*
;
import
java.util.Calendar
;
import
java.util.Date
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.stream.Collectors
;
@Service
// 实际上不用添加。添加的原因是,必须 Spring 报错提示
...
...
@@ -99,15 +102,15 @@ public class CouponServiceImpl implements CouponService {
// 校验 CouponCardTemplate 存在
CouponTemplateDO
template
=
couponTemplateMapper
.
selectById
(
couponCardTemplateUpdateDTO
.
getId
());
if
(
template
==
null
)
{
return
ServiceExceptionUtil
.
error
(
PromotionErrorCodeEnum
.
PRODUCT
_TEMPLATE_NOT_EXISTS
.
getCode
());
return
ServiceExceptionUtil
.
error
(
PromotionErrorCodeEnum
.
COUPON
_TEMPLATE_NOT_EXISTS
.
getCode
());
}
// 校验 CouponCardTemplate 是 CARD
if
(!
CouponTemplateTypeEnum
.
CARD
.
getValue
().
equals
(
template
.
getType
()))
{
return
ServiceExceptionUtil
.
error
(
PromotionErrorCodeEnum
.
PRODUCT
_TEMPLATE_NOT_CARD
.
getCode
());
return
ServiceExceptionUtil
.
error
(
PromotionErrorCodeEnum
.
COUPON
_TEMPLATE_NOT_CARD
.
getCode
());
}
// 校验发放数量不能减少
if
(
couponCardTemplateUpdateDTO
.
getTotal
()
<
template
.
getTotal
())
{
return
ServiceExceptionUtil
.
error
(
PromotionErrorCodeEnum
.
PRODUCT
_TEMPLATE_TOTAL_CAN_NOT_REDUCE
.
getCode
());
return
ServiceExceptionUtil
.
error
(
PromotionErrorCodeEnum
.
COUPON
_TEMPLATE_TOTAL_CAN_NOT_REDUCE
.
getCode
());
}
// 更新优惠劵模板到数据库
CouponTemplateDO
updateTemplateDO
=
CouponTemplateConvert
.
INSTANCE
.
convert
(
couponCardTemplateUpdateDTO
);
...
...
@@ -121,7 +124,7 @@ public class CouponServiceImpl implements CouponService {
// 校验 CouponCardTemplate 存在
CouponTemplateDO
template
=
couponTemplateMapper
.
selectById
(
couponTemplateId
);
if
(
template
==
null
)
{
return
ServiceExceptionUtil
.
error
(
PromotionErrorCodeEnum
.
PRODUCT
_TEMPLATE_NOT_EXISTS
.
getCode
());
return
ServiceExceptionUtil
.
error
(
PromotionErrorCodeEnum
.
COUPON
_TEMPLATE_NOT_EXISTS
.
getCode
());
}
// 更新到数据库
CouponTemplateDO
updateTemplateDO
=
new
CouponTemplateDO
().
setId
(
couponTemplateId
).
setStatus
(
status
);
...
...
@@ -195,28 +198,28 @@ public class CouponServiceImpl implements CouponService {
// 校验 CouponCardTemplate 存在
CouponTemplateDO
template
=
couponTemplateMapper
.
selectById
(
couponTemplateId
);
if
(
template
==
null
)
{
return
ServiceExceptionUtil
.
error
(
PromotionErrorCodeEnum
.
PRODUCT
_TEMPLATE_NOT_EXISTS
.
getCode
());
return
ServiceExceptionUtil
.
error
(
PromotionErrorCodeEnum
.
COUPON
_TEMPLATE_NOT_EXISTS
.
getCode
());
}
// 校验 CouponCardTemplate 是 CARD
if
(!
CouponTemplateTypeEnum
.
CARD
.
getValue
().
equals
(
template
.
getType
()))
{
return
ServiceExceptionUtil
.
error
(
PromotionErrorCodeEnum
.
PRODUCT
_TEMPLATE_NOT_CARD
.
getCode
());
return
ServiceExceptionUtil
.
error
(
PromotionErrorCodeEnum
.
COUPON
_TEMPLATE_NOT_CARD
.
getCode
());
}
// 校验 CouponCardTemplate 状态是否开启
if
(!
CouponTemplateStatusEnum
.
ENABLE
.
getValue
().
equals
(
template
.
getStatus
()))
{
return
ServiceExceptionUtil
.
error
(
PromotionErrorCodeEnum
.
PRODUCT
_TEMPLATE_STATUS_NOT_ENABLE
.
getCode
());
return
ServiceExceptionUtil
.
error
(
PromotionErrorCodeEnum
.
COUPON
_TEMPLATE_STATUS_NOT_ENABLE
.
getCode
());
}
// 校验 CouponCardTemplate 是否到达可领取的上限
if
(
template
.
getStatFetchNum
()
>
template
.
getTotal
())
{
return
ServiceExceptionUtil
.
error
(
PromotionErrorCodeEnum
.
PRODUCT
_TEMPLATE_TOTAL_NOT_ENOUGH
.
getCode
());
return
ServiceExceptionUtil
.
error
(
PromotionErrorCodeEnum
.
COUPON
_TEMPLATE_TOTAL_NOT_ENOUGH
.
getCode
());
}
// 校验单人可领取优惠劵是否到达上限
if
(
couponCardMapper
.
selectCountByUserIdAndTemplateId
(
userId
,
couponTemplateId
)
>
template
.
getQuota
())
{
return
ServiceExceptionUtil
.
error
(
PromotionErrorCodeEnum
.
PRODUCT
_TEMPLATE_CARD_ADD_EXCEED_QUOTA
.
getCode
());
return
ServiceExceptionUtil
.
error
(
PromotionErrorCodeEnum
.
COUPON
_TEMPLATE_CARD_ADD_EXCEED_QUOTA
.
getCode
());
}
// 增加优惠劵已领取量
int
updateTemplateCount
=
couponTemplateMapper
.
updateStatFetchNumIncr
(
couponTemplateId
);
if
(
updateTemplateCount
==
0
)
{
// 超过 CouponCardTemplate 发放量
return
ServiceExceptionUtil
.
error
(
PromotionErrorCodeEnum
.
PRODUCT
_TEMPLATE_CARD_ADD_EXCEED_QUOTA
.
getCode
());
return
ServiceExceptionUtil
.
error
(
PromotionErrorCodeEnum
.
COUPON
_TEMPLATE_CARD_ADD_EXCEED_QUOTA
.
getCode
());
}
// 创建优惠劵
// 1. 基本信息 + 领取情况
...
...
@@ -250,6 +253,28 @@ public class CouponServiceImpl implements CouponService {
return
null
;
}
@Override
public
CommonResult
<
CouponCardDetailBO
>
getCouponCardDetail
(
Integer
userId
,
Integer
couponCardId
)
{
// 查询优惠劵
CouponCardDO
card
=
couponCardMapper
.
selectById
(
couponCardId
);
if
(
card
==
null
)
{
return
ServiceExceptionUtil
.
error
(
PromotionErrorCodeEnum
.
COUPON_CARD_NOT_EXISTS
.
getCode
());
}
if
(!
userId
.
equals
(
card
.
getUserId
()))
{
return
ServiceExceptionUtil
.
error
(
PromotionErrorCodeEnum
.
COUPON_CARD_ERROR_USER
.
getCode
());
}
// 查询优惠劵模板
CouponTemplateDO
template
=
couponTemplateMapper
.
selectById
(
card
.
getTemplateId
());
if
(
template
==
null
)
{
return
ServiceExceptionUtil
.
error
(
PromotionErrorCodeEnum
.
COUPON_TEMPLATE_NOT_EXISTS
.
getCode
());
}
// 拼接结果
CouponCardDetailBO
detail
=
CouponCardConvert
.
INSTANCE
.
convert2
(
card
);
detail
.
setRangeType
(
template
.
getRangeType
());
detail
.
setRangeValues
(
StringUtil
.
splitToInt
(
template
.
getRangeValues
(),
","
));
return
CommonResult
.
success
(
detail
);
}
@Override
public
CommonResult
<
List
<
CouponCardAvailableBO
>>
getCouponCardList
(
Integer
userId
,
List
<
CouponCardSpuDTO
>
spus
)
{
// 查询用户未使用的优惠劵列表
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论