Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
Y
yudao-cloud
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
hblj
yudao-cloud
Commits
0e6d9487
提交
0e6d9487
authored
10月 30, 2022
作者:
YunaiV
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
清理价格计算相关的逻辑
上级
c54b330c
隐藏空白字符变更
内嵌
并排
正在显示
4 个修改的文件
包含
0 行增加
和
569 行删除
+0
-569
PromotionServiceApplication.java
...er/mall/promotionservice/PromotionServiceApplication.java
+0
-18
CouponCardDO.java
...tionservice/dal/mysql/dataobject/coupon/CouponCardDO.java
+0
-123
PriceManager.java
...der/mall/promotionservice/manager/price/PriceManager.java
+0
-336
BannerService.java
...r/mall/promotionservice/service/banner/BannerService.java
+0
-92
没有找到文件。
归档/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/PromotionServiceApplication.java
deleted
100644 → 0
浏览文件 @
c54b330c
package
cn
.
iocoder
.
mall
.
promotionservice
;
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"
})
public
class
PromotionServiceApplication
{
public
static
void
main
(
String
[]
args
)
{
SpringApplication
.
run
(
PromotionServiceApplication
.
class
,
args
);
}
}
归档/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/dal/mysql/dataobject/coupon/CouponCardDO.java
deleted
100644 → 0
浏览文件 @
c54b330c
package
cn
.
iocoder
.
mall
.
promotionservice
.
dal
.
mysql
.
dataobject
.
coupon
;
import
cn.iocoder.mall.mybatis.core.dataobject.BaseDO
;
import
com.baomidou.mybatisplus.annotation.TableName
;
import
lombok.Data
;
import
lombok.EqualsAndHashCode
;
import
lombok.experimental.Accessors
;
import
java.util.Date
;
/**
* 优惠劵 DO
*/
@TableName
(
"coupon_card"
)
@Data
@EqualsAndHashCode
(
callSuper
=
true
)
@Accessors
(
chain
=
true
)
public
class
CouponCardDO
extends
BaseDO
{
// ========== 基本信息 BEGIN ==========
/**
* 优惠劵编号
*/
private
Integer
id
;
/**
* 优惠劵(码)分组编号,{@link CouponTemplateDO} 的 id
*/
private
Integer
templateId
;
/**
* 优惠劵名
*
* 冗余自 {@link CouponTemplateDO} 的 title
*
* TODO 芋艿,暂时不考虑冗余的更新
*/
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 Integer usedOrderId; // TODO 芋艿,暂时不考虑这个字段
// /**
// * 订单中优惠面值,单位:分
// */
// private Integer usedPrice; // TODO 芋艿,暂时不考虑这个字段
/**
* 使用时间
*/
private
Date
usedTime
;
// TODO 芋艿,后续要加优惠劵的使用日志,因为下单后,可能会取消。
// ========== 使用情况 END ==========
}
归档/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/manager/price/PriceManager.java
deleted
100644 → 0
浏览文件 @
c54b330c
package
cn
.
iocoder
.
mall
.
promotionservice
.
manager
.
price
;
import
cn.iocoder.common.framework.exception.util.ServiceExceptionUtil
;
import
cn.iocoder.common.framework.util.CollectionUtils
;
import
cn.iocoder.common.framework.vo.CommonResult
;
import
cn.iocoder.mall.productservice.rpc.sku.ProductSkuFeign
;
import
cn.iocoder.mall.productservice.rpc.sku.dto.ProductSkuListQueryReqDTO
;
import
cn.iocoder.mall.productservice.rpc.sku.dto.ProductSkuRespDTO
;
import
cn.iocoder.mall.productservice.rpc.spu.ProductSpuFeign
;
import
cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuRespDTO
;
import
cn.iocoder.mall.promotion.api.enums.MeetTypeEnum
;
import
cn.iocoder.mall.promotion.api.enums.PreferentialTypeEnum
;
import
cn.iocoder.mall.promotion.api.enums.RangeTypeEnum
;
import
cn.iocoder.mall.promotion.api.enums.activity.PromotionActivityStatusEnum
;
import
cn.iocoder.mall.promotion.api.enums.activity.PromotionActivityTypeEnum
;
import
cn.iocoder.mall.promotion.api.rpc.activity.dto.PromotionActivityRespDTO
;
import
cn.iocoder.mall.promotion.api.rpc.coupon.dto.card.CouponCardRespDTO
;
import
cn.iocoder.mall.promotion.api.rpc.coupon.dto.template.CouponTemplateRespDTO
;
import
cn.iocoder.mall.promotion.api.rpc.price.dto.PriceProductCalcReqDTO
;
import
cn.iocoder.mall.promotion.api.rpc.price.dto.PriceProductCalcRespDTO
;
import
cn.iocoder.mall.promotionservice.service.activity.PromotionActivityService
;
import
cn.iocoder.mall.promotionservice.service.coupon.CouponCardService
;
import
cn.iocoder.mall.promotionservice.service.coupon.CouponTemplateService
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
org.springframework.util.Assert
;
import
org.springframework.validation.annotation.Validated
;
import
java.util.*
;
import
java.util.stream.Collectors
;
import
static
cn
.
iocoder
.
mall
.
promotion
.
api
.
enums
.
PromotionErrorCodeConstants
.*;
@Service
@Validated
public
class
PriceManager
{
@Autowired
private
ProductSkuFeign
productSkuFeign
;
@Autowired
private
ProductSpuFeign
productSpuFeign
;
@Autowired
private
PromotionActivityService
promotionActivityService
;
@Autowired
private
CouponCardService
couponCardService
;
@Autowired
private
CouponTemplateService
couponTemplateService
;
public
PriceProductCalcRespDTO
calcProductPrice
(
PriceProductCalcReqDTO
calcReqDTO
)
{
// 拼装结果(主要是计算价格)
PriceProductCalcRespDTO
calcRespDTO
=
new
PriceProductCalcRespDTO
();
List
<
PromotionActivityRespDTO
>
activityRespDTOs
=
promotionActivityService
.
listPromotionActivitiesBySpuIds
(
CollectionUtils
.
convertSet
(
listProductSkusResult
.
getData
(),
ProductSkuRespDTO:
:
getSpuId
),
Collections
.
singleton
(
PromotionActivityStatusEnum
.
RUN
.
getValue
()));
// 2. 计算【限时折扣】促销
this
.
modifyPriceByTimeLimitDiscount
(
calcItemRespDTOs
,
activityRespDTOs
);
// 3. 计算【满减送】促销
List
<
PriceProductCalcRespDTO
.
ItemGroup
>
itemGroups
=
this
.
groupByFullPrivilege
(
calcItemRespDTOs
,
activityRespDTOs
);
calcRespDTO
.
setItemGroups
(
itemGroups
);
// 4. 计算优惠劵 TODO 芋艿:未详细测试;
if
(
calcReqDTO
.
getCouponCardId
()
!=
null
)
{
Integer
result
=
this
.
modifyPriceByCouponCard
(
calcReqDTO
.
getUserId
(),
calcReqDTO
.
getCouponCardId
(),
itemGroups
);
calcRespDTO
.
setCouponCardDiscountTotal
(
result
);
}
// 5. 计算最终的价格
int
buyTotal
=
0
;
int
discountTotal
=
0
;
int
presentTotal
=
0
;
for
(
PriceProductCalcRespDTO
.
ItemGroup
itemGroup
:
calcRespDTO
.
getItemGroups
())
{
buyTotal
+=
itemGroup
.
getItems
().
stream
().
mapToInt
(
item
->
item
.
getSelected
()
?
item
.
getBuyTotal
()
:
0
).
sum
();
discountTotal
+=
itemGroup
.
getItems
().
stream
().
mapToInt
(
item
->
item
.
getSelected
()
?
item
.
getDiscountTotal
()
:
0
).
sum
();
presentTotal
+=
itemGroup
.
getItems
().
stream
().
mapToInt
(
item
->
item
.
getSelected
()
?
item
.
getPresentTotal
()
:
0
).
sum
();
}
Assert
.
isTrue
(
buyTotal
-
discountTotal
==
presentTotal
,
String
.
format
(
"价格合计( %d - %d == %d )不正确"
,
buyTotal
,
discountTotal
,
presentTotal
));
calcRespDTO
.
setFee
(
new
PriceProductCalcRespDTO
.
Fee
(
buyTotal
,
discountTotal
,
0
,
presentTotal
));
return
calcRespDTO
;
}
private
void
modifyPriceByTimeLimitDiscount
(
List
<
PriceProductCalcRespDTO
.
Item
>
items
,
List
<
PromotionActivityRespDTO
>
activityList
)
{
for
(
PriceProductCalcRespDTO
.
Item
item
:
items
)
{
// 获得符合条件的限时折扣
PromotionActivityRespDTO
timeLimitedDiscount
=
activityList
.
stream
()
.
filter
(
activity
->
PromotionActivityTypeEnum
.
TIME_LIMITED_DISCOUNT
.
getValue
().
equals
(
activity
.
getActivityType
())
&&
activity
.
getTimeLimitedDiscount
().
getItems
().
stream
().
anyMatch
(
item0
->
item0
.
getSpuId
().
equals
(
item
.
getSpuId
())))
.
findFirst
().
orElse
(
null
);
if
(
timeLimitedDiscount
==
null
)
{
continue
;
}
// 计算价格
Integer
newBuyPrice
=
calcSkuPriceByTimeLimitDiscount
(
item
,
timeLimitedDiscount
);
if
(
newBuyPrice
.
equals
(
item
.
getBuyPrice
()))
{
// 未优惠
continue
;
}
// 设置优惠
item
.
setActivityId
(
timeLimitedDiscount
.
getId
());
// 设置价格
item
.
setBuyPrice
(
newBuyPrice
);
item
.
setBuyTotal
(
newBuyPrice
*
item
.
getBuyQuantity
());
item
.
setPresentTotal
(
item
.
getBuyTotal
()
-
item
.
getDiscountTotal
());
item
.
setPresentPrice
(
item
.
getPresentTotal
()
/
item
.
getBuyQuantity
());
}
}
/**
* 计算指定 SKU 在限时折扣下的价格
*
* @param sku SKU
* @param timeLimitedDiscount 限时折扣促销。
* 传入的该活动,要保证该 SKU 在该促销下一定有优惠。
* @return 计算后的价格
*/
private
Integer
calcSkuPriceByTimeLimitDiscount
(
PriceProductCalcRespDTO
.
Item
sku
,
PromotionActivityRespDTO
timeLimitedDiscount
)
{
if
(
timeLimitedDiscount
==
null
)
{
return
sku
.
getBuyPrice
();
}
// 获得对应的优惠项
PromotionActivityRespDTO
.
TimeLimitedDiscount
.
Item
item
=
timeLimitedDiscount
.
getTimeLimitedDiscount
().
getItems
().
stream
()
.
filter
(
item0
->
item0
.
getSpuId
().
equals
(
sku
.
getSpuId
()))
.
findFirst
().
orElse
(
null
);
if
(
item
==
null
)
{
throw
new
IllegalArgumentException
(
String
.
format
(
"折扣活动(%s) 不存在商品(%s) 的优惠配置"
,
timeLimitedDiscount
.
toString
(),
sku
.
toString
()));
}
// 计算价格
if
(
PreferentialTypeEnum
.
PRICE
.
getValue
().
equals
(
item
.
getPreferentialType
()))
{
// 减价
int
presentPrice
=
sku
.
getBuyPrice
()
-
item
.
getPreferentialValue
();
return
presentPrice
>=
0
?
presentPrice
:
sku
.
getBuyPrice
();
// 如果计算优惠价格小于 0 ,则说明无法使用优惠。
}
if
(
PreferentialTypeEnum
.
DISCOUNT
.
getValue
().
equals
(
item
.
getPreferentialType
()))
{
// 打折
return
sku
.
getBuyPrice
()
*
item
.
getPreferentialValue
()
/
100
;
}
throw
new
IllegalArgumentException
(
String
.
format
(
"折扣活动(%s) 的优惠类型不正确"
,
timeLimitedDiscount
.
toString
()));
}
private
List
<
PriceProductCalcRespDTO
.
ItemGroup
>
groupByFullPrivilege
(
List
<
PriceProductCalcRespDTO
.
Item
>
items
,
List
<
PromotionActivityRespDTO
>
activityList
)
{
List
<
PriceProductCalcRespDTO
.
ItemGroup
>
itemGroups
=
new
ArrayList
<>();
// 获得所有满减送促销
List
<
PromotionActivityRespDTO
>
fullPrivileges
=
activityList
.
stream
()
.
filter
(
activity
->
PromotionActivityTypeEnum
.
FULL_PRIVILEGE
.
getValue
().
equals
(
activity
.
getActivityType
()))
.
collect
(
Collectors
.
toList
());
// 基于满减送促销,进行分组
if
(!
fullPrivileges
.
isEmpty
())
{
items
=
new
ArrayList
<>(
items
);
// 因为下面会修改数组,进行浅拷贝,避免影响传入的 items 。
for
(
PromotionActivityRespDTO
fullPrivilege
:
fullPrivileges
)
{
// 创建 fullPrivilege 对应的分组
PriceProductCalcRespDTO
.
ItemGroup
itemGroup
=
new
PriceProductCalcRespDTO
.
ItemGroup
()
.
setActivityId
(
fullPrivilege
.
getId
())
.
setItems
(
new
ArrayList
<>());
// 筛选商品到分组中
for
(
Iterator
<
PriceProductCalcRespDTO
.
Item
>
iterator
=
items
.
iterator
();
iterator
.
hasNext
();
)
{
PriceProductCalcRespDTO
.
Item
item
=
iterator
.
next
();
if
(!
isSpuMatchFullPrivilege
(
item
.
getSpuId
(),
fullPrivilege
))
{
continue
;
}
itemGroup
.
getItems
().
add
(
item
);
iterator
.
remove
();
}
// 如果匹配到,则添加到 itemGroups 中
if
(!
itemGroup
.
getItems
().
isEmpty
())
{
itemGroups
.
add
(
itemGroup
);
}
}
}
// 处理未参加活动的商品,形成一个分组
if
(!
items
.
isEmpty
())
{
itemGroups
.
add
(
new
PriceProductCalcRespDTO
.
ItemGroup
().
setItems
(
items
));
}
// 计算每个分组的价格
Map
<
Integer
,
PromotionActivityRespDTO
>
activityMap
=
CollectionUtils
.
convertMap
(
activityList
,
PromotionActivityRespDTO:
:
getId
);
for
(
PriceProductCalcRespDTO
.
ItemGroup
itemGroup
:
itemGroups
)
{
itemGroup
.
setActivityDiscountTotal
(
calcSkuPriceByFullPrivilege
(
itemGroup
,
activityMap
.
get
(
itemGroup
.
getActivityId
())));
}
// 返回结果
return
itemGroups
;
}
private
boolean
isSpuMatchFullPrivilege
(
Integer
spuId
,
PromotionActivityRespDTO
activity
)
{
Assert
.
isTrue
(
PromotionActivityTypeEnum
.
FULL_PRIVILEGE
.
getValue
().
equals
(
activity
.
getActivityType
()),
"传入的必须的促销活动必须是满减送"
);
PromotionActivityRespDTO
.
FullPrivilege
fullPrivilege
=
activity
.
getFullPrivilege
();
if
(
RangeTypeEnum
.
ALL
.
getValue
().
equals
(
fullPrivilege
.
getRangeType
()))
{
return
true
;
}
else
if
(
RangeTypeEnum
.
PRODUCT_INCLUDE_PART
.
getValue
().
equals
(
fullPrivilege
.
getRangeType
()))
{
return
fullPrivilege
.
getRangeValues
().
contains
(
spuId
);
}
throw
new
IllegalArgumentException
(
String
.
format
(
"促销活动(%s) 可用范围的类型是不正确"
,
activity
.
toString
()));
}
private
Integer
calcSkuPriceByFullPrivilege
(
PriceProductCalcRespDTO
.
ItemGroup
itemGroup
,
PromotionActivityRespDTO
activity
)
{
if
(
itemGroup
.
getActivityId
()
==
null
)
{
return
null
;
}
Assert
.
isTrue
(
PromotionActivityTypeEnum
.
FULL_PRIVILEGE
.
getValue
().
equals
(
activity
.
getActivityType
()),
"传入的必须的满减送活动必须是满减送"
);
// 获得优惠信息
List
<
PriceProductCalcRespDTO
.
Item
>
items
=
itemGroup
.
getItems
().
stream
().
filter
(
PriceProductCalcRespDTO
.
Item
::
getSelected
)
.
collect
(
Collectors
.
toList
());
Integer
itemCnt
=
items
.
stream
().
mapToInt
(
PriceProductCalcRespDTO
.
Item
::
getBuyQuantity
).
sum
();
Integer
originalTotal
=
items
.
stream
().
mapToInt
(
PriceProductCalcRespDTO
.
Item
::
getPresentTotal
).
sum
();
List
<
PromotionActivityRespDTO
.
FullPrivilege
.
Privilege
>
privileges
=
activity
.
getFullPrivilege
().
getPrivileges
().
stream
()
.
filter
(
privilege
->
{
if
(
MeetTypeEnum
.
PRICE
.
getValue
().
equals
(
privilege
.
getMeetType
()))
{
return
originalTotal
>=
privilege
.
getMeetValue
();
}
if
(
MeetTypeEnum
.
QUANTITY
.
getValue
().
equals
(
privilege
.
getMeetType
()))
{
return
itemCnt
>=
privilege
.
getMeetValue
();
}
throw
new
IllegalArgumentException
(
String
.
format
(
"满减送活动(%s) 的匹配(%s)不正确"
,
activity
.
toString
(),
privilege
.
toString
()));
}).
collect
(
Collectors
.
toList
());
// 获得不到优惠信息,返回原始价格
if
(
privileges
.
isEmpty
())
{
return
null
;
}
// 获得到优惠信息,进行价格计算
PromotionActivityRespDTO
.
FullPrivilege
.
Privilege
privilege
=
privileges
.
get
(
privileges
.
size
()
-
1
);
Integer
presentTotal
;
if
(
PreferentialTypeEnum
.
PRICE
.
getValue
().
equals
(
privilege
.
getPreferentialType
()))
{
// 减价
// 计算循环次数。这样,后续优惠的金额就是相乘了
Integer
cycleCount
=
1
;
if
(
activity
.
getFullPrivilege
().
getCycled
())
{
if
(
MeetTypeEnum
.
PRICE
.
getValue
().
equals
(
privilege
.
getMeetType
()))
{
cycleCount
=
originalTotal
/
privilege
.
getMeetValue
();
}
else
if
(
MeetTypeEnum
.
QUANTITY
.
getValue
().
equals
(
privilege
.
getMeetType
()))
{
cycleCount
=
itemCnt
/
privilege
.
getMeetValue
();
}
}
presentTotal
=
originalTotal
-
cycleCount
*
privilege
.
getMeetValue
();
if
(
presentTotal
<
0
)
{
// 如果计算优惠价格小于 0 ,则说明无法使用优惠。
presentTotal
=
originalTotal
;
}
}
else
if
(
PreferentialTypeEnum
.
DISCOUNT
.
getValue
().
equals
(
privilege
.
getPreferentialType
()))
{
// 打折
presentTotal
=
originalTotal
*
privilege
.
getPreferentialValue
()
/
100
;
}
else
{
throw
new
IllegalArgumentException
(
String
.
format
(
"满减送促销(%s) 的优惠类型不正确"
,
activity
.
toString
()));
}
int
discountTotal
=
originalTotal
-
presentTotal
;
if
(
discountTotal
==
0
)
{
return
null
;
}
// 按比例,拆分 presentTotal
splitDiscountPriceToItems
(
items
,
discountTotal
,
presentTotal
);
// 返回优惠金额
return
originalTotal
-
presentTotal
;
}
private
Integer
modifyPriceByCouponCard
(
Integer
userId
,
Integer
couponCardId
,
List
<
PriceProductCalcRespDTO
.
ItemGroup
>
itemGroups
)
{
Assert
.
isTrue
(
couponCardId
!=
null
,
"优惠劵编号不能为空"
);
// 查询优惠劵
CouponCardRespDTO
couponCard
=
couponCardService
.
getCouponCard
(
userId
,
couponCardId
);
if
(
couponCard
==
null
)
{
throw
ServiceExceptionUtil
.
exception
(
COUPON_CARD_NOT_EXISTS
);
}
CouponTemplateRespDTO
couponTemplate
=
couponTemplateService
.
getCouponTemplate
(
couponCardId
);
if
(
couponTemplate
==
null
)
{
throw
ServiceExceptionUtil
.
exception
(
COUPON_TEMPLATE_NOT_EXISTS
);
}
// 获得匹配的商品
List
<
PriceProductCalcRespDTO
.
Item
>
items
=
new
ArrayList
<>();
if
(
RangeTypeEnum
.
ALL
.
getValue
().
equals
(
couponTemplate
.
getRangeType
()))
{
itemGroups
.
forEach
(
itemGroup
->
items
.
addAll
(
itemGroup
.
getItems
()));
}
else
if
(
RangeTypeEnum
.
PRODUCT_INCLUDE_PART
.
getValue
().
equals
(
couponTemplate
.
getRangeType
()))
{
itemGroups
.
forEach
(
itemGroup
->
items
.
forEach
(
item
->
{
if
(
couponTemplate
.
getRangeValues
().
contains
(
item
.
getSpuId
()))
{
items
.
add
(
item
);
}
}));
}
else
if
(
RangeTypeEnum
.
PRODUCT_EXCLUDE_PART
.
getValue
().
equals
(
couponTemplate
.
getRangeType
()))
{
itemGroups
.
forEach
(
itemGroup
->
items
.
forEach
(
item
->
{
if
(!
couponTemplate
.
getRangeValues
().
contains
(
item
.
getSpuId
()))
{
items
.
add
(
item
);
}
}));
}
else
if
(
RangeTypeEnum
.
CATEGORY_INCLUDE_PART
.
getValue
().
equals
(
couponTemplate
.
getRangeType
()))
{
itemGroups
.
forEach
(
itemGroup
->
items
.
forEach
(
item
->
{
if
(
couponTemplate
.
getRangeValues
().
contains
(
item
.
getCid
()))
{
items
.
add
(
item
);
}
}));
}
else
if
(
RangeTypeEnum
.
CATEGORY_EXCLUDE_PART
.
getValue
().
equals
(
couponTemplate
.
getRangeType
()))
{
itemGroups
.
forEach
(
itemGroup
->
items
.
forEach
(
item
->
{
if
(!
couponTemplate
.
getRangeValues
().
contains
(
item
.
getCid
()))
{
items
.
add
(
item
);
}
}));
}
// 判断是否符合条件
int
originalTotal
=
items
.
stream
().
mapToInt
(
PriceProductCalcRespDTO
.
Item
::
getPresentTotal
).
sum
();
// 此处,指的是以优惠劵视角的原价
if
(
originalTotal
==
0
||
originalTotal
<
couponCard
.
getPriceAvailable
())
{
throw
ServiceExceptionUtil
.
exception
(
COUPON_CARD_NOT_MATCH
);
// 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
(
couponCard
.
getDiscountPriceLimit
()
!=
null
// 空,代表不限制优惠上限
&&
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
originalTotal
-
presentTotal
;
}
private
void
splitDiscountPriceToItems
(
List
<
PriceProductCalcRespDTO
.
Item
>
items
,
Integer
discountTotal
,
Integer
presentTotal
)
{
for
(
int
i
=
0
;
i
<
items
.
size
();
i
++)
{
PriceProductCalcRespDTO
.
Item
item
=
items
.
get
(
i
);
Integer
discountPart
;
if
(
i
<
items
.
size
()
-
1
)
{
// 减一的原因,是因为拆分时,如果按照比例,可能会出现.所以最后一个,使用反减
discountPart
=
(
int
)
(
discountTotal
*
(
1.0
D
*
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
());
}
}
}
归档/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/service/banner/BannerService.java
deleted
100644 → 0
浏览文件 @
c54b330c
package
cn
.
iocoder
.
mall
.
promotionservice
.
service
.
banner
;
import
cn.iocoder.common.framework.exception.util.ServiceExceptionUtil
;
import
cn.iocoder.common.framework.vo.PageResult
;
import
cn.iocoder.mall.promotion.api.rpc.banner.dto.*
;
import
cn.iocoder.mall.promotionservice.convert.banner.BannerConvert
;
import
cn.iocoder.mall.promotionservice.dal.mysql.dataobject.banner.BannerDO
;
import
cn.iocoder.mall.promotionservice.dal.mysql.mapper.banner.BannerMapper
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
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.List
;
import
static
cn
.
iocoder
.
mall
.
promotion
.
api
.
enums
.
PromotionErrorCodeConstants
.
BANNER_NOT_EXISTS
;
@Service
@Validated
public
class
BannerService
{
@Autowired
private
BannerMapper
bannerMapper
;
/**
* 获得 Banner 列表
*
* @param listReqDTO Banner 列表查询
* @return Banner 列表
*/
public
List
<
BannerRespDTO
>
listBanners
(
BannerListReqDTO
listReqDTO
)
{
List
<
BannerDO
>
banners
=
bannerMapper
.
selectList
(
listReqDTO
);
return
BannerConvert
.
INSTANCE
.
convertList
(
banners
);
}
/**
* 获得 Banner 分页
*
* @param bannerPageDTO Banner 分页查询
* @return Banner 分页结果
*/
public
PageResult
<
BannerRespDTO
>
pageBanner
(
BannerPageReqDTO
bannerPageDTO
)
{
IPage
<
BannerDO
>
bannerPage
=
bannerMapper
.
selectPage
(
bannerPageDTO
);
return
BannerConvert
.
INSTANCE
.
convertPage
(
bannerPage
);
}
/**
* 创建 Banner
*
* @param createReqDTO 创建 Banner 信息
* @return banner
*/
public
Integer
createBanner
(
@Valid
BannerCreateReqDTO
createReqDTO
)
{
// 插入到数据库
BannerDO
bannerDO
=
BannerConvert
.
INSTANCE
.
convert
(
createReqDTO
);
bannerMapper
.
insert
(
bannerDO
);
// 返回
return
bannerDO
.
getId
();
}
/**
* 更新 Banner
*
* @param updateReqDTO 更新 Banner 信息
*/
public
void
updateBanner
(
@Valid
BannerUpdateReqDTO
updateReqDTO
)
{
// 校验更新的 Banner 是否存在
if
(
bannerMapper
.
selectById
(
updateReqDTO
.
getId
())
==
null
)
{
throw
ServiceExceptionUtil
.
exception
(
BANNER_NOT_EXISTS
);
}
// 更新到数据库
BannerDO
updateObject
=
BannerConvert
.
INSTANCE
.
convert
(
updateReqDTO
);
bannerMapper
.
updateById
(
updateObject
);
}
/**
* 删除 Banner
*
* @param bannerId Banner 编号
*/
public
void
deleteBanner
(
Integer
bannerId
)
{
// 校验 Banner 存在
if
(
bannerMapper
.
selectById
(
bannerId
)
==
null
)
{
throw
ServiceExceptionUtil
.
exception
(
BANNER_NOT_EXISTS
);
}
// 更新到数据库
bannerMapper
.
deleteById
(
bannerId
);
}
}
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论