Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
有来技术
youlai-mall
提交
b7b21b6a
Y
youlai-mall
项目概览
有来技术
/
youlai-mall
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
Y
youlai-mall
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
b7b21b6a
编写于
8月 13, 2021
作者:
有
有来技术
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
refactor:商品优化
上级
a4f985a7
变更
32
隐藏空白更改
内联
并排
Showing
32 changed file
with
666 addition
and
501 deletion
+666
-501
mall-oms/oms-api/src/main/java/com/youlai/mall/oms/pojo/dto/CartItemDTO.java
...c/main/java/com/youlai/mall/oms/pojo/dto/CartItemDTO.java
+56
-0
mall-oms/oms-api/src/main/java/com/youlai/mall/oms/pojo/vo/CartVO.java
...api/src/main/java/com/youlai/mall/oms/pojo/vo/CartVO.java
+0
-44
mall-oms/oms-boot/src/main/java/com/youlai/mall/oms/constant/OmsConstants.java
.../main/java/com/youlai/mall/oms/constant/OmsConstants.java
+0
-5
mall-oms/oms-boot/src/main/java/com/youlai/mall/oms/controller/app/CartController.java
...va/com/youlai/mall/oms/controller/app/CartController.java
+8
-4
mall-oms/oms-boot/src/main/java/com/youlai/mall/oms/controller/app/OrderController.java
...a/com/youlai/mall/oms/controller/app/OrderController.java
+7
-18
mall-oms/oms-boot/src/main/java/com/youlai/mall/oms/service/ICartService.java
...c/main/java/com/youlai/mall/oms/service/ICartService.java
+3
-4
mall-oms/oms-boot/src/main/java/com/youlai/mall/oms/service/impl/CartServiceImpl.java
...ava/com/youlai/mall/oms/service/impl/CartServiceImpl.java
+13
-26
mall-oms/oms-boot/src/main/java/com/youlai/mall/oms/service/impl/OrderServiceImpl.java
...va/com/youlai/mall/oms/service/impl/OrderServiceImpl.java
+39
-44
mall-pms/pms-api/src/main/java/com/youlai/mall/pms/api/GoodsFeignClient.java
...c/main/java/com/youlai/mall/pms/api/GoodsFeignClient.java
+2
-2
mall-pms/pms-api/src/main/java/com/youlai/mall/pms/api/StockFeignClient.java
...c/main/java/com/youlai/mall/pms/api/StockFeignClient.java
+3
-4
mall-pms/pms-api/src/main/java/com/youlai/mall/pms/pojo/dto/app/LockStockDTO.java
...n/java/com/youlai/mall/pms/pojo/dto/app/LockStockDTO.java
+1
-1
mall-pms/pms-api/src/main/java/com/youlai/mall/pms/pojo/dto/app/SkuDTO.java
...rc/main/java/com/youlai/mall/pms/pojo/dto/app/SkuDTO.java
+3
-3
mall-pms/pms-api/src/main/java/com/youlai/mall/pms/pojo/vo/app/GoodsDetailVO.java
...n/java/com/youlai/mall/pms/pojo/vo/app/GoodsDetailVO.java
+114
-0
mall-pms/pms-api/src/main/java/com/youlai/mall/pms/pojo/vo/app/GoodsVO.java
...rc/main/java/com/youlai/mall/pms/pojo/vo/app/GoodsVO.java
+18
-0
mall-pms/pms-boot/src/main/java/com/youlai/mall/pms/PmsApplication.java
...oot/src/main/java/com/youlai/mall/pms/PmsApplication.java
+3
-0
mall-pms/pms-boot/src/main/java/com/youlai/mall/pms/config/BloomFilterConfig.java
...in/java/com/youlai/mall/pms/config/BloomFilterConfig.java
+5
-7
mall-pms/pms-boot/src/main/java/com/youlai/mall/pms/controller/app/CategoryController.java
...om/youlai/mall/pms/controller/app/CategoryController.java
+1
-1
mall-pms/pms-boot/src/main/java/com/youlai/mall/pms/controller/app/GoodsController.java
...a/com/youlai/mall/pms/controller/app/GoodsController.java
+44
-42
mall-pms/pms-boot/src/main/java/com/youlai/mall/pms/controller/app/ProductController.java
...com/youlai/mall/pms/controller/app/ProductController.java
+0
-71
mall-pms/pms-boot/src/main/java/com/youlai/mall/pms/controller/app/StockController.java
...a/com/youlai/mall/pms/controller/app/StockController.java
+58
-0
mall-pms/pms-boot/src/main/java/com/youlai/mall/pms/mapper/PmsSkuMapper.java
...rc/main/java/com/youlai/mall/pms/mapper/PmsSkuMapper.java
+1
-5
mall-pms/pms-boot/src/main/java/com/youlai/mall/pms/service/IPmsAttributeService.java
...ava/com/youlai/mall/pms/service/IPmsAttributeService.java
+0
-1
mall-pms/pms-boot/src/main/java/com/youlai/mall/pms/service/IPmsSkuService.java
...main/java/com/youlai/mall/pms/service/IPmsSkuService.java
+2
-2
mall-pms/pms-boot/src/main/java/com/youlai/mall/pms/service/IProductService.java
...ain/java/com/youlai/mall/pms/service/IProductService.java
+0
-11
mall-pms/pms-boot/src/main/java/com/youlai/mall/pms/service/impl/PmsSkuServiceImpl.java
...a/com/youlai/mall/pms/service/impl/PmsSkuServiceImpl.java
+9
-9
mall-pms/pms-boot/src/main/java/com/youlai/mall/pms/service/impl/PmsSpuServiceImpl.java
...a/com/youlai/mall/pms/service/impl/PmsSpuServiceImpl.java
+88
-56
mall-pms/pms-boot/src/main/java/com/youlai/mall/pms/service/impl/ProductServiceImpl.java
.../com/youlai/mall/pms/service/impl/ProductServiceImpl.java
+0
-109
mall-pms/pms-boot/src/main/java/com/youlai/mall/pms/serviceapp/IGoodsService.java
...in/java/com/youlai/mall/pms/serviceapp/IGoodsService.java
+13
-0
mall-pms/pms-boot/src/main/java/com/youlai/mall/pms/serviceapp/impl/GoodsServiceImpl.java
...com/youlai/mall/pms/serviceapp/impl/GoodsServiceImpl.java
+115
-0
mall-pms/pms-boot/src/main/resources/mapper/PmsSkuMapper.xml
mall-pms/pms-boot/src/main/resources/mapper/PmsSkuMapper.xml
+21
-12
mall-pms/pms-boot/src/main/resources/mapper/PmsSpuMapper.xml
mall-pms/pms-boot/src/main/resources/mapper/PmsSpuMapper.xml
+38
-19
youlai-common/common-web/src/main/java/com/youlai/common/web/exception/GlobalExceptionHandler.java
...m/youlai/common/web/exception/GlobalExceptionHandler.java
+1
-1
未找到文件。
mall-oms/oms-api/src/main/java/com/youlai/mall/oms/pojo/dto/CartItemDTO.java
0 → 100644
浏览文件 @
b7b21b6a
package
com.youlai.mall.oms.pojo.dto
;
import
lombok.*
;
import
java.io.Serializable
;
/**
* 购物车商品传输层实体
*/
@NoArgsConstructor
@AllArgsConstructor
@ToString
@Builder
@Data
public
class
CartItemDTO
implements
Serializable
{
private
Long
skuId
;
/**
* 商品库存单元名称
*/
private
String
skuName
;
/**
* 商品库存单元编码
*/
private
String
skuSn
;
/**
* 商品库存单元图片
*/
private
String
picUrl
;
private
Integer
count
;
// 商品数量
/**
* 加入购物车价格,因会变动,不能作为订单计算因子,订单验价时需重新获取商品价格即可
*/
private
Long
price
;
private
Long
coupon
;
private
Boolean
checked
;
/**
* 商品库存数量,页面控制能选择最大数量
*/
private
Integer
stock
;
/**
* 商品名称
*/
private
String
goodsName
;
}
mall-oms/oms-api/src/main/java/com/youlai/mall/oms/pojo/vo/CartVO.java
已删除
100644 → 0
浏览文件 @
a4f985a7
package
com.youlai.mall.oms.pojo.vo
;
import
lombok.*
;
import
java.io.Serializable
;
import
java.util.List
;
/**
* 购物车实体类
*/
@NoArgsConstructor
@AllArgsConstructor
@ToString
@Builder
@Data
public
class
CartVO
implements
Serializable
{
private
List
<
CartItem
>
items
;
@Data
public
static
class
CartItem
{
private
Long
skuId
;
private
String
skuName
;
// 标题
private
String
skuCode
;
private
String
pic
;
private
Integer
count
;
// 商品数量
private
Long
price
;
// 加入购物车价格,因会变动,不能作为订单计算因子,订单验价时需重新获取商品价格即可
private
Long
coupon
;
private
Boolean
checked
;
private
Integer
stock
;
// 商品库存数量,页面控制能选择最大数量
private
String
spuName
;
}
}
mall-oms/oms-boot/src/main/java/com/youlai/mall/oms/constant/OmsConstants.java
浏览文件 @
b7b21b6a
...
...
@@ -15,10 +15,5 @@ public interface OmsConstants {
*/
String
RELEASE_LOCK_LUA_SCRIPT
=
"if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end"
;
/**
* 释放锁成功返回值
*/
Long
RELEASE_LOCK_SUCCESS_RESULT
=
1L
;
}
mall-oms/oms-boot/src/main/java/com/youlai/mall/oms/controller/app/CartController.java
浏览文件 @
b7b21b6a
...
...
@@ -2,7 +2,8 @@ package com.youlai.mall.oms.controller.app;
import
com.github.xiaoymin.knife4j.annotations.ApiOperationSupport
;
import
com.youlai.common.result.Result
;
import
com.youlai.mall.oms.pojo.vo.CartVO
;
import
com.youlai.common.web.util.JwtUtils
;
import
com.youlai.mall.oms.pojo.dto.CartItemDTO
;
import
com.youlai.mall.oms.service.ICartService
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiImplicitParam
;
...
...
@@ -11,6 +12,8 @@ import lombok.AllArgsConstructor;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.web.bind.annotation.*
;
import
java.util.List
;
/**
* @author huawei
* @email huawei_code@163.com
...
...
@@ -30,8 +33,9 @@ public class CartController {
@GetMapping
@ApiOperationSupport
(
order
=
1
)
public
Result
getCart
()
{
CartVO
cart
=
cartService
.
getCart
();
return
Result
.
success
(
cart
);
Long
memberId
=
JwtUtils
.
getUserId
();
List
<
CartItemDTO
>
result
=
cartService
.
listCartItemByMemberId
(
memberId
);
return
Result
.
success
(
result
);
}
@ApiOperation
(
value
=
"删除购物车"
)
...
...
@@ -54,7 +58,7 @@ public class CartController {
@ApiOperation
(
value
=
"更新购物车商品"
)
@PutMapping
(
"/skuId/{skuId}"
)
@ApiOperationSupport
(
order
=
4
)
public
Result
updateCartItem
(
@PathVariable
Long
skuId
,
@RequestBody
Cart
VO
.
CartItem
cartItem
)
{
public
Result
updateCartItem
(
@PathVariable
Long
skuId
,
@RequestBody
Cart
ItemDTO
cartItem
)
{
cartItem
.
setSkuId
(
skuId
);
boolean
result
=
cartService
.
updateCartItem
(
cartItem
);
return
Result
.
judge
(
result
);
...
...
mall-oms/oms-boot/src/main/java/com/youlai/mall/oms/controller/app/OrderController.java
浏览文件 @
b7b21b6a
...
...
@@ -5,14 +5,15 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import
com.youlai.common.result.Result
;
import
com.youlai.common.web.util.JwtUtils
;
import
com.youlai.mall.oms.enums.PayTypeEnum
;
import
com.youlai.mall.oms.pojo.entity.OmsOrder
;
import
com.youlai.mall.oms.pojo.dto.OrderConfirmDTO
;
import
com.youlai.mall.oms.pojo.dto.OrderSubmitDTO
;
import
com.youlai.mall.oms.pojo.entity.OmsOrder
;
import
com.youlai.mall.oms.pojo.vo.OrderConfirmVO
;
import
com.youlai.mall.oms.pojo.vo.OrderSubmitVO
;
import
com.youlai.mall.oms.pojo.dto.OrderSubmitDTO
;
import
com.youlai.mall.oms.service.IOrderService
;
import
io.swagger.annotations.*
;
import
lombok.AllArgsConstructor
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiOperation
;
import
lombok.RequiredArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.web.bind.annotation.*
;
...
...
@@ -28,18 +29,13 @@ import javax.validation.Valid;
@RestController
@RequestMapping
(
"/app-api/v1/orders"
)
@Slf4j
@
All
ArgsConstructor
@
Required
ArgsConstructor
public
class
OrderController
{
private
IOrderService
orderService
;
final
IOrderService
orderService
;
@ApiOperation
(
"订单列表"
)
@GetMapping
@ApiImplicitParams
({
@ApiImplicitParam
(
name
=
"page"
,
defaultValue
=
"1"
,
value
=
"页码"
,
paramType
=
"query"
,
dataType
=
"Long"
),
@ApiImplicitParam
(
name
=
"limit"
,
defaultValue
=
"10"
,
value
=
"每页数量"
,
paramType
=
"query"
,
dataType
=
"Long"
),
@ApiImplicitParam
(
name
=
"status"
,
value
=
"订单状态"
,
paramType
=
"query"
,
dataType
=
"Integer"
)
})
public
Result
list
(
@RequestParam
(
defaultValue
=
"1"
)
Long
page
,
@RequestParam
(
defaultValue
=
"10"
)
Long
limit
,
...
...
@@ -53,7 +49,6 @@ public class OrderController {
}
@ApiOperation
(
"订单确认"
)
@ApiImplicitParam
(
name
=
"orderConfirm"
,
value
=
"确认订单信息"
,
required
=
true
,
paramType
=
"body"
,
dataType
=
"OrderConfirmDTO"
)
@PostMapping
(
"/_confirm"
)
public
Result
<
OrderConfirmVO
>
confirm
(
@RequestBody
OrderConfirmDTO
orderConfirm
)
{
OrderConfirmVO
result
=
orderService
.
confirm
(
orderConfirm
);
...
...
@@ -61,7 +56,6 @@ public class OrderController {
}
@ApiOperation
(
"订单提交"
)
@ApiImplicitParam
(
name
=
"orderSubmitDTO"
,
value
=
"提交订单信息"
,
required
=
true
,
paramType
=
"body"
,
dataType
=
"orderSubmitDTO"
)
@PostMapping
(
"/_submit"
)
public
Result
submit
(
@Valid
@RequestBody
OrderSubmitDTO
orderSubmitDTO
)
{
OrderSubmitVO
result
=
orderService
.
submit
(
orderSubmitDTO
);
...
...
@@ -70,10 +64,6 @@ public class OrderController {
@ApiOperation
(
"订单支付"
)
@PostMapping
(
"/{orderId}/_pay"
)
@ApiImplicitParams
({
@ApiImplicitParam
(
name
=
"orderId"
,
value
=
"订单ID"
,
paramType
=
"path"
,
dataType
=
"Long"
),
@ApiImplicitParam
(
name
=
"payType"
,
value
=
"支付方式"
,
paramType
=
"query"
,
dataType
=
"Integer"
)
})
public
Result
pay
(
@PathVariable
Long
orderId
,
Integer
payType
)
{
PayTypeEnum
payTypeEnum
=
PayTypeEnum
.
getByCode
(
payType
);
switch
(
payTypeEnum
)
{
...
...
@@ -88,7 +78,6 @@ public class OrderController {
@ApiOperation
(
"订单删除"
)
@PostMapping
(
"/{orderId}"
)
@ApiImplicitParam
(
name
=
"orderId"
,
value
=
"订单ID"
,
paramType
=
"path"
,
dataType
=
"Long"
)
public
Result
deleteOrder
(
@PathVariable
Long
orderId
)
{
boolean
result
=
orderService
.
deleteOrder
(
orderId
);
return
Result
.
judge
(
result
);
...
...
mall-oms/oms-boot/src/main/java/com/youlai/mall/oms/service/ICartService.java
浏览文件 @
b7b21b6a
package
com.youlai.mall.oms.service
;
import
com.youlai.mall.oms.pojo.
vo.CartV
O
;
import
com.youlai.mall.oms.pojo.
dto.CartItemDT
O
;
import
java.util.List
;
...
...
@@ -10,15 +10,14 @@ import java.util.List;
public
interface
ICartService
{
CartVO
getCart
();
List
<
Cart
VO
.
CartItem
>
getCartItems
(
Long
memberId
);
List
<
Cart
ItemDTO
>
listCartItemByMemberId
(
Long
memberId
);
boolean
deleteCart
();
boolean
addCartItem
(
Long
skuId
);
boolean
updateCartItem
(
Cart
VO
.
CartItem
cartItem
);
boolean
updateCartItem
(
Cart
ItemDTO
cartItem
);
boolean
removeCartItem
(
Long
skuId
);
...
...
mall-oms/oms-boot/src/main/java/com/youlai/mall/oms/service/impl/CartServiceImpl.java
浏览文件 @
b7b21b6a
...
...
@@ -2,7 +2,7 @@ package com.youlai.mall.oms.service.impl;
import
com.youlai.common.web.util.JwtUtils
;
import
com.youlai.mall.oms.constant.OmsConstants
;
import
com.youlai.mall.oms.pojo.
vo.CartV
O
;
import
com.youlai.mall.oms.pojo.
dto.CartItemDT
O
;
import
com.youlai.mall.oms.service.ICartService
;
import
com.youlai.mall.pms.api.GoodsFeignClient
;
import
com.youlai.mall.pms.pojo.dto.app.SkuDTO
;
...
...
@@ -34,23 +34,10 @@ public class CartServiceImpl implements ICartService {
private
RedisTemplate
redisTemplate
;
private
GoodsFeignClient
skuFeignService
;
/**
* 获取用户购物车
*/
@Override
public
CartVO
getCart
()
{
CartVO
cart
=
new
CartVO
();
Long
memberId
=
JwtUtils
.
getUserId
();
BoundHashOperations
cartHashOperations
=
getCartHashOperations
(
memberId
);
List
<
CartVO
.
CartItem
>
cartItems
=
cartHashOperations
.
values
();
cart
.
setItems
(
cartItems
);
return
cart
;
}
@Override
public
List
<
Cart
VO
.
CartItem
>
getCartItems
(
Long
memberId
)
{
public
List
<
Cart
ItemDTO
>
listCartItemByMemberId
(
Long
memberId
)
{
BoundHashOperations
cartHashOperations
=
getCartHashOperations
(
memberId
);
List
<
Cart
VO
.
CartItem
>
cartItems
=
cartHashOperations
.
values
();
List
<
Cart
ItemDTO
>
cartItems
=
cartHashOperations
.
values
();
return
cartItems
;
}
...
...
@@ -73,28 +60,28 @@ public class CartServiceImpl implements ICartService {
BoundHashOperations
cartHashOperations
=
getCartHashOperations
(
memberId
);
String
hKey
=
skuId
+
""
;
Cart
VO
.
CartItem
cartItem
;
Cart
ItemDTO
cartItem
;
// 购物车已存在该商品,更新商品数量
if
(
cartHashOperations
.
get
(
hKey
)
!=
null
)
{
cartItem
=
(
Cart
VO
.
CartItem
)
cartHashOperations
.
get
(
hKey
);
cartItem
=
(
Cart
ItemDTO
)
cartHashOperations
.
get
(
hKey
);
cartItem
.
setCount
(
cartItem
.
getCount
()
+
1
);
// 点击一次“加入购物车”,数量+1
cartItem
.
setChecked
(
true
);
cartHashOperations
.
put
(
hKey
,
cartItem
);
return
true
;
}
// 购物车不存在该商品,添加商品至购物车
cartItem
=
new
Cart
VO
.
CartItem
();
cartItem
=
new
Cart
ItemDTO
();
CompletableFuture
<
Void
>
cartItemCompletableFuture
=
CompletableFuture
.
runAsync
(()
->
{
SkuDTO
sku
=
skuFeignService
.
getSkuById
(
skuId
).
getData
();
if
(
sku
!=
null
)
{
cartItem
.
setSkuId
(
sku
.
getId
());
cartItem
.
setCount
(
1
);
cartItem
.
setPrice
(
sku
.
getPrice
());
cartItem
.
setPic
(
sku
.
getPic
());
cartItem
.
setPic
Url
(
sku
.
getPicUrl
());
cartItem
.
setSkuName
(
sku
.
getName
());
cartItem
.
setStock
(
sku
.
getStock
());
cartItem
.
setSku
Code
(
sku
.
getCode
());
cartItem
.
set
SpuName
(
sku
.
getSpu
Name
());
cartItem
.
setSku
Sn
(
sku
.
getSn
());
cartItem
.
set
GoodsName
(
sku
.
getGoods
Name
());
cartItem
.
setChecked
(
true
);
}
});
...
...
@@ -107,12 +94,12 @@ public class CartServiceImpl implements ICartService {
* 更新购物车总商品数量、选中状态
*/
@Override
public
boolean
updateCartItem
(
Cart
VO
.
CartItem
cartItem
)
{
public
boolean
updateCartItem
(
Cart
ItemDTO
cartItem
)
{
Long
memberId
=
JwtUtils
.
getUserId
();
BoundHashOperations
cartHashOperations
=
getCartHashOperations
(
memberId
);
String
hKey
=
cartItem
.
getSkuId
()
+
""
;
if
(
cartHashOperations
.
get
(
hKey
)
!=
null
)
{
Cart
VO
.
CartItem
cacheCartItem
=
(
CartVO
.
CartItem
)
cartHashOperations
.
get
(
hKey
);
Cart
ItemDTO
cacheCartItem
=
(
CartItemDTO
)
cartHashOperations
.
get
(
hKey
);
if
(
cartItem
.
getChecked
()!=
null
){
cacheCartItem
.
setChecked
(
cartItem
.
getChecked
());
}
...
...
@@ -145,7 +132,7 @@ public class CartServiceImpl implements ICartService {
Long
memberId
=
JwtUtils
.
getUserId
();
BoundHashOperations
cartHashOperations
=
getCartHashOperations
(
memberId
);
for
(
Object
value
:
cartHashOperations
.
values
())
{
Cart
VO
.
CartItem
cartItem
=
(
CartVO
.
CartItem
)
value
;
Cart
ItemDTO
cartItem
=
(
CartItemDTO
)
value
;
cartItem
.
setChecked
(
checked
);
String
hKey
=
cartItem
.
getSkuId
()
+
""
;
cartHashOperations
.
put
(
hKey
,
cartItem
);
...
...
@@ -163,7 +150,7 @@ public class CartServiceImpl implements ICartService {
Long
memberId
=
JwtUtils
.
getUserId
();
BoundHashOperations
cartHashOperations
=
getCartHashOperations
(
memberId
);
for
(
Object
value
:
cartHashOperations
.
values
())
{
Cart
VO
.
CartItem
cartItem
=
(
CartVO
.
CartItem
)
value
;
Cart
ItemDTO
cartItem
=
(
CartItemDTO
)
value
;
if
(
cartItem
.
getChecked
())
{
cartHashOperations
.
delete
(
cartItem
.
getSkuId
()+
""
);
}
...
...
mall-oms/oms-boot/src/main/java/com/youlai/mall/oms/service/impl/OrderServiceImpl.java
浏览文件 @
b7b21b6a
package
com.youlai.mall.oms.service.impl
;
import
cn.hutool.core.collection.CollectionUtil
;
import
cn.hutool.core.lang.Assert
;
import
cn.hutool.core.util.ObjectUtil
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
...
...
@@ -20,20 +21,21 @@ import com.youlai.mall.oms.pojo.entity.OmsOrderItem;
import
com.youlai.mall.oms.pojo.dto.OrderConfirmDTO
;
import
com.youlai.mall.oms.pojo.dto.OrderItemDTO
;
import
com.youlai.mall.oms.pojo.dto.OrderSubmitDTO
;
import
com.youlai.mall.oms.pojo.
vo.CartV
O
;
import
com.youlai.mall.oms.pojo.
dto.CartItemDT
O
;
import
com.youlai.mall.oms.pojo.vo.OrderConfirmVO
;
import
com.youlai.mall.oms.pojo.vo.OrderSubmitVO
;
import
com.youlai.mall.oms.service.ICartService
;
import
com.youlai.mall.oms.service.IOrderItemService
;
import
com.youlai.mall.oms.service.IOrderService
;
import
com.youlai.mall.pms.api.GoodsFeignClient
;
import
com.youlai.mall.pms.api.StockFeignClient
;
import
com.youlai.mall.pms.pojo.dto.app.SkuDTO
;
import
com.youlai.mall.pms.pojo.dto.app.
SkuL
ockDTO
;
import
com.youlai.mall.pms.pojo.dto.app.
LockSt
ockDTO
;
import
com.youlai.mall.ums.api.MemberAddressFeignClient
;
import
com.youlai.mall.ums.api.MemberFeignClient
;
import
com.youlai.mall.ums.pojo.entity.UmsAddress
;
import
io.seata.spring.annotation.GlobalTransactional
;
import
lombok.
All
ArgsConstructor
;
import
lombok.
Required
ArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.amqp.rabbit.core.RabbitTemplate
;
import
org.springframework.data.redis.core.StringRedisTemplate
;
...
...
@@ -51,21 +53,23 @@ import java.util.stream.Collectors;
import
static
com
.
youlai
.
mall
.
oms
.
constant
.
OmsConstants
.*;
@
All
ArgsConstructor
@
Required
ArgsConstructor
@Slf4j
@Service
public
class
OrderServiceImpl
extends
ServiceImpl
<
OrderMapper
,
OmsOrder
>
implements
IOrderService
{
private
ICartService
cartService
;
private
GoodsFeignClient
skuFeignService
;
private
MemberAddressFeignClient
addressFeignService
;
private
IOrderItemService
orderItemService
;
private
RabbitTemplate
rabbitTemplate
;
private
StringRedisTemplate
redisTemplate
;
private
ThreadPoolExecutor
threadPoolExecutor
;
private
MemberFeignClient
memberFeignClient
;
final
ICartService
cartService
;
final
MemberAddressFeignClient
addressFeignService
;
final
IOrderItemService
orderItemService
;
final
RabbitTemplate
rabbitTemplate
;
final
StringRedisTemplate
redisTemplate
;
final
ThreadPoolExecutor
threadPoolExecutor
;
final
MemberFeignClient
memberFeignClient
;
final
BusinessNoGenerator
businessNoGenerator
;
private
BusinessNoGenerator
businessNoGenerator
;
final
GoodsFeignClient
goodsFeignClient
;
final
StockFeignClient
stockFeignClient
;
/**
* 订单确认
...
...
@@ -83,25 +87,25 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, OmsOrder> impleme
.
skuId
(
orderConfirmDTO
.
getSkuId
())
.
count
(
orderConfirmDTO
.
getCount
())
.
build
();
SkuDTO
sku
=
skuFeignService
.
getSkuById
(
orderConfirmDTO
.
getSkuId
()).
getData
();
SkuDTO
sku
=
goodsFeignClient
.
getSkuById
(
orderConfirmDTO
.
getSkuId
()).
getData
();
orderItemDTO
.
setPrice
(
sku
.
getPrice
());
orderItemDTO
.
setPic
(
sku
.
getPic
());
orderItemDTO
.
setPic
(
sku
.
getPic
Url
());
orderItemDTO
.
setSkuName
(
sku
.
getName
());
orderItemDTO
.
setSkuCode
(
sku
.
get
Code
());
orderItemDTO
.
setSpuName
(
sku
.
get
Spu
Name
());
orderItemDTO
.
setSkuCode
(
sku
.
get
Sn
());
orderItemDTO
.
setSpuName
(
sku
.
get
Goods
Name
());
orderItems
.
add
(
orderItemDTO
);
}
else
{
// 购物车中商品结算
List
<
Cart
VO
.
CartItem
>
cartItems
=
cartService
.
getCartItems
(
memberId
);
List
<
Cart
ItemDTO
>
cartItems
=
cartService
.
listCartItemByMemberId
(
memberId
);
List
<
OrderItemDTO
>
items
=
cartItems
.
stream
()
.
filter
(
Cart
VO
.
CartItem
::
getChecked
)
.
filter
(
Cart
ItemDTO
:
:
getChecked
)
.
map
(
cartItem
->
OrderItemDTO
.
builder
()
.
skuId
(
cartItem
.
getSkuId
())
.
count
(
cartItem
.
getCount
())
.
price
(
cartItem
.
getPrice
())
.
skuName
(
cartItem
.
getSkuName
())
.
skuCode
(
cartItem
.
getSku
Code
())
.
spuName
(
cartItem
.
get
Spu
Name
())
.
pic
(
cartItem
.
getPic
())
.
skuCode
(
cartItem
.
getSku
Sn
())
.
spuName
(
cartItem
.
get
Goods
Name
())
.
pic
(
cartItem
.
getPic
Url
())
.
build
())
.
collect
(
Collectors
.
toList
());
orderItems
.
addAll
(
items
);
...
...
@@ -124,7 +128,7 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, OmsOrder> impleme
},
threadPoolExecutor
);
CompletableFuture
.
allOf
(
orderItemsCompletableFuture
,
addressesCompletableFuture
,
orderTokenCompletableFuture
).
join
();
log
.
info
(
"订单确认响应:{}"
,
orderConfirmVO
.
toString
()
);
log
.
info
(
"订单确认响应:{}"
,
orderConfirmVO
);
return
orderConfirmVO
;
}
...
...
@@ -138,43 +142,34 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, OmsOrder> impleme
// 订单重复提交校验
String
orderToken
=
submitDTO
.
getOrderToken
();
DefaultRedisScript
<
Long
>
redisScript
=
new
DefaultRedisScript
<>(
RELEASE_LOCK_LUA_SCRIPT
,
Long
.
class
);
Long
result
=
this
.
redisTemplate
.
execute
(
redisScript
,
Collections
.
singletonList
(
ORDER_TOKEN_PREFIX
+
orderToken
),
orderToken
);
if
(!
ObjectUtil
.
equals
(
result
,
RELEASE_LOCK_SUCCESS_RESULT
))
{
throw
new
BizException
(
"订单不可重复提交"
);
}
Long
execute
=
this
.
redisTemplate
.
execute
(
redisScript
,
Collections
.
singletonList
(
ORDER_TOKEN_PREFIX
+
orderToken
),
orderToken
);
Assert
.
isTrue
(
execute
.
equals
(
1
l
),
"订单不可重复提交"
);
List
<
OrderItemDTO
>
orderItems
=
submitDTO
.
getOrderItems
();
if
(
CollectionUtil
.
isEmpty
(
orderItems
))
{
throw
new
BizException
(
"订单没有商品,请选择商品后提交"
);
}
Assert
.
isTrue
(
CollectionUtil
.
isNotEmpty
(
orderItems
),
"订单商品为空"
);
// 订单验价
Long
currentTotalPrice
=
orderItems
.
stream
().
map
(
item
->
{
SkuDTO
sku
=
skuFeignService
.
getSkuById
(
item
.
getSkuId
()).
getData
();
SkuDTO
sku
=
goodsFeignClient
.
getSkuById
(
item
.
getSkuId
()).
getData
();
if
(
sku
!=
null
)
{
return
sku
.
getPrice
()
*
item
.
getCount
();
}
return
0
l
;
}).
reduce
(
0
l
,
Long:
:
sum
);
if
(
currentTotalPrice
.
compareTo
(
submitDTO
.
getTotalPrice
())
!=
0
)
{
throw
new
BizException
(
"页面已过期,请重新刷新页面再提交"
);
}
Assert
.
isTrue
(
currentTotalPrice
.
compareTo
(
submitDTO
.
getTotalPrice
())
==
0
,
"当前页面已过期,请重新刷新页面再提交"
);
// 校验库存是否足够和锁库存
List
<
SkuL
ockDTO
>
skuLockList
=
orderItems
.
stream
()
.
map
(
item
->
SkuL
ockDTO
.
builder
().
skuId
(
item
.
getSkuId
())
List
<
LockSt
ockDTO
>
skuLockList
=
orderItems
.
stream
()
.
map
(
item
->
LockSt
ockDTO
.
builder
().
skuId
(
item
.
getSkuId
())
.
count
(
item
.
getCount
())
.
orderToken
(
orderToken
)
.
build
())
.
collect
(
Collectors
.
toList
());
Result
lockResult
=
s
kuFeignService
.
lockStock
(
skuLockList
);
Result
lockResult
=
s
tockFeignClient
.
lockStock
(
skuLockList
);
if
(!
Result
.
success
().
getCode
().
equals
(
lockResult
.
getCode
()))
{
throw
new
BizException
(
Result
.
failed
().
getMsg
());
}
Assert
.
isTrue
(
Result
.
success
().
getCode
().
equals
(
lockResult
.
getCode
()),
"锁定商品库存失败:{}"
,
lockResult
.
getMsg
());
// 创建订单(状态:待支付)
OmsOrder
order
=
new
OmsOrder
();
...
...
@@ -209,7 +204,7 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, OmsOrder> impleme
OrderSubmitVO
submitVO
=
new
OrderSubmitVO
();
submitVO
.
setOrderId
(
order
.
getId
());
submitVO
.
setOrderSn
(
order
.
getOrderSn
());
log
.
info
(
"订单提交响应:{}"
,
submitVO
.
toString
()
);
log
.
info
(
"订单提交响应:{}"
,
submitVO
);
return
submitVO
;
}
...
...
@@ -238,7 +233,7 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, OmsOrder> impleme
}
// 扣减库存
Result
deductStockResult
=
s
kuFeignService
.
deductStock
(
order
.
getOrderSn
());
Result
deductStockResult
=
s
tockFeignClient
.
deductStock
(
order
.
getOrderSn
());
if
(!
Result
.
isSuccess
(
deductStockResult
))
{
throw
new
BizException
(
"扣减商品库存失败"
);
}
...
...
@@ -279,7 +274,7 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, OmsOrder> impleme
boolean
result
=
this
.
updateById
(
order
);
if
(
result
)
{
// 释放被锁定的库存
Result
unlockResult
=
s
kuFeignService
.
unlockStock
(
order
.
getOrderSn
());
Result
unlockResult
=
s
tockFeignClient
.
unlockStock
(
order
.
getOrderSn
());
if
(!
Result
.
isSuccess
(
unlockResult
))
{
throw
new
BizException
(
unlockResult
.
getMsg
());
}
...
...
mall-pms/pms-api/src/main/java/com/youlai/mall/pms/api/GoodsFeignClient.java
浏览文件 @
b7b21b6a
...
...
@@ -6,12 +6,12 @@ import org.springframework.cloud.openfeign.FeignClient;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.PathVariable
;
@FeignClient
(
value
=
"mall-pms"
)
@FeignClient
(
value
=
"mall-pms"
,
contextId
=
"goods"
)
public
interface
GoodsFeignClient
{
/**
* 获取商品信息
*/
@GetMapping
(
"/app-api/v1/
good
s/{id}"
)
@GetMapping
(
"/app-api/v1/
stock
s/{id}"
)
Result
<
SkuDTO
>
getSkuById
(
@PathVariable
Long
id
);
}
mall-pms/pms-api/src/main/java/com/youlai/mall/pms/api/StockFeignClient.java
浏览文件 @
b7b21b6a
package
com.youlai.mall.pms.api
;
import
com.youlai.common.result.Result
;
import
com.youlai.mall.pms.pojo.dto.app.
SkuL
ockDTO
;
import
com.youlai.mall.pms.pojo.dto.app.
LockSt
ockDTO
;
import
org.springframework.cloud.openfeign.FeignClient
;
import
org.springframework.web.bind.annotation.*
;
import
java.util.List
;
@FeignClient
(
value
=
"mall-pms"
)
@FeignClient
(
value
=
"mall-pms"
,
contextId
=
"stock"
)
public
interface
StockFeignClient
{
/**
* 锁定库存
*/
@PutMapping
(
"/app-api/v1/stocks/_lock"
)
Result
lockStock
(
@RequestBody
List
<
SkuL
ockDTO
>
list
);
Result
lockStock
(
@RequestBody
List
<
LockSt
ockDTO
>
list
);
/**
* 解锁库存
...
...
mall-pms/pms-api/src/main/java/com/youlai/mall/pms/pojo/dto/app/
SkuL
ockDTO.java
→
mall-pms/pms-api/src/main/java/com/youlai/mall/pms/pojo/dto/app/
LockSt
ockDTO.java
浏览文件 @
b7b21b6a
...
...
@@ -14,7 +14,7 @@ import lombok.NoArgsConstructor;
@Builder
@NoArgsConstructor
@AllArgsConstructor
public
class
SkuL
ockDTO
{
public
class
LockSt
ockDTO
{
private
Long
skuId
;
...
...
mall-pms/pms-api/src/main/java/com/youlai/mall/pms/pojo/dto/app/SkuDTO.java
浏览文件 @
b7b21b6a
...
...
@@ -12,12 +12,12 @@ import lombok.Data;
public
class
SkuDTO
{
private
Long
id
;
private
String
code
;
private
String
sn
;
private
String
name
;
private
String
pic
;
private
String
pic
Url
;
private
Long
price
;
private
Integer
stock
;
private
String
spu
Name
;
private
String
goods
Name
;
}
mall-pms/pms-api/src/main/java/com/youlai/mall/pms/pojo/vo/app/GoodsDetailVO.java
0 → 100644
浏览文件 @
b7b21b6a
package
com.youlai.mall.pms.pojo.vo.app
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
lombok.Data
;
import
java.util.List
;
/**
* 商品详情页-商品详细信息
*
* @author <a href="mailto:xianrui0365@163.com">xianrui</a>
* @date 2021/8/8
*/
@Data
@ApiModel
(
"商品详情"
)
public
class
GoodsDetailVO
{
@ApiModelProperty
(
"商品基本信息"
)
private
GoodsInfo
goodsInfo
;
@ApiModelProperty
(
"商品属性列表"
)
private
List
<
Attribute
>
attributeList
;
@ApiModelProperty
(
"商品规格列表"
)
private
List
<
Specification
>
specList
;
@ApiModelProperty
(
"商品库存单元列表"
)
private
List
<
Sku
>
skuList
;
@Data
@ApiModel
(
"商品信息"
)
public
static
class
GoodsInfo
{
@ApiModelProperty
(
"商品ID"
)
private
Long
id
;
@ApiModelProperty
(
"商品名称"
)
private
String
name
;
@ApiModelProperty
(
"商品原价(单位:分)"
)
private
Long
originPrice
;
@ApiModelProperty
(
"商品零售价(单位:分)"
)
private
Long
price
;
@ApiModelProperty
(
"销量"
)
private
Integer
sales
;
@ApiModelProperty
(
"商品图册"
)
private
List
<
String
>
album
;
@ApiModelProperty
(
"商品详情"
)
private
String
detail
;
}
@Data
@ApiModel
(
"属性信息"
)
public
static
class
Attribute
{
@ApiModelProperty
(
"属性ID"
)
private
Long
id
;
@ApiModelProperty
(
"属性名称"
)
private
String
name
;
@ApiModelProperty
(
"属性值"
)
private
String
value
;
}
@Data
@ApiModel
(
"规格信息"
)
public
static
class
Specification
{
@ApiModelProperty
(
value
=
"规格名称"
,
example
=
"颜色"
)
private
String
name
;
@ApiModelProperty
(
value
=
"规格项列表"
,
example
=
"[黑,白]"
)
private
List
<
Value
>
values
;
@Data
@ApiModel
(
"规格项"
)
public
static
class
Value
{
@ApiModelProperty
(
"规格项ID"
)
private
Long
id
;
@ApiModelProperty
(
"规格项值"
)
private
String
value
;
}
}
@Data
@ApiModel
(
"商品库存单元"
)
public
static
class
Sku
{
@ApiModelProperty
(
"库存单元ID"
)
private
Long
id
;
@ApiModelProperty
(
"库存单元名称"
)
private
String
name
;
@ApiModelProperty
(
"库存单元规格值ID集合,以英文逗号拼接"
)
private
String
specIds
;
@ApiModelProperty
(
"价格"
)
private
Long
price
;
@ApiModelProperty
(
"库存"
)
private
Integer
stock
;
@ApiModelProperty
(
"商品图片URL"
)
private
String
picUrl
;
}
}
mall-pms/pms-api/src/main/java/com/youlai/mall/pms/pojo/vo/app/GoodsVO.java
0 → 100644
浏览文件 @
b7b21b6a
package
com.youlai.mall.pms.pojo.vo.app
;
import
lombok.Data
;
/**
* 商品列表页-商品基础信息
*
* @author <a href="mailto:xianrui0365@163.com">xianrui</a>
* @date 2021/8/8
*/
@Data
public
class
GoodsVO
{
private
Long
id
;
private
String
name
;
private
Long
price
;
private
Integer
sales
;
private
String
picUrl
;
}
mall-pms/pms-boot/src/main/java/com/youlai/mall/pms/PmsApplication.java
浏览文件 @
b7b21b6a
...
...
@@ -4,8 +4,11 @@ import org.springframework.boot.SpringApplication;
import
org.springframework.boot.autoconfigure.SpringBootApplication
;
import
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
;
import
org.springframework.cloud.client.discovery.EnableDiscoveryClient
;
import
org.springframework.context.ConfigurableApplicationContext
;
import
org.springframework.transaction.annotation.EnableTransactionManagement
;
import
java.util.Arrays
;
@SpringBootApplication
(
exclude
=
DataSourceAutoConfiguration
.
class
)
@EnableDiscoveryClient
@EnableTransactionManagement
...
...
mall-pms/pms-boot/src/main/java/com/youlai/mall/pms/config/BloomFilterConfig.java
浏览文件 @
b7b21b6a
...
...
@@ -2,9 +2,10 @@ package com.youlai.mall.pms.config;
import
com.google.common.base.Charsets
;
import
com.google.common.hash.Funnel
;
import
com.youlai.mall.pms.common.constant.PmsConstants
;
import
com.youlai.mall.pms.component.BloomRedisService
;
import
com.youlai.mall.pms.pojo.entity.PmsSpu
;
import
com.youlai.mall.pms.service
.IProduct
Service
;
import
com.youlai.mall.pms.service
app.IGoods
Service
;
import
com.youlai.mall.pms.utils.BloomFilterUtils
;
import
lombok.AllArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
...
...
@@ -13,11 +14,8 @@ import org.springframework.context.annotation.Bean;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.data.redis.core.RedisTemplate
;
import
org.springframework.util.CollectionUtils
;
import
java.util.List
;
import
static
com
.
youlai
.
mall
.
pms
.
common
.
constant
.
PmsConstants
.
PRODUCT_REDIS_BLOOM_FILTER
;
/**
* @Author DaniR
* @Description
...
...
@@ -28,7 +26,7 @@ import static com.youlai.mall.pms.common.constant.PmsConstants.PRODUCT_REDIS_BLO
@AllArgsConstructor
public
class
BloomFilterConfig
implements
InitializingBean
{
private
final
I
ProductService
iProduct
Service
;
private
final
I
GoodsService
goods
Service
;
private
final
RedisTemplate
redisTemplate
;
@Bean
...
...
@@ -48,11 +46,11 @@ public class BloomFilterConfig implements InitializingBean {
@Override
public
void
afterPropertiesSet
()
throws
Exception
{
List
<
PmsSpu
>
list
=
iProduct
Service
.
list
();
List
<
PmsSpu
>
list
=
goods
Service
.
list
();
log
.
info
(
"加载产品到布隆过滤器当中,size:{}"
,
list
.
size
());
if
(!
CollectionUtils
.
isEmpty
(
list
))
{
list
.
stream
().
filter
(
item
->
item
.
getId
()
>
0
).
forEach
(
item
->
{
bloomRedisService
().
addByBloomFilter
(
PRODUCT_REDIS_BLOOM_FILTER
,
item
.
getId
()
+
""
);
bloomRedisService
().
addByBloomFilter
(
P
msConstants
.
P
RODUCT_REDIS_BLOOM_FILTER
,
item
.
getId
()
+
""
);
});
}
}
...
...
mall-pms/pms-boot/src/main/java/com/youlai/mall/pms/controller/app/CategoryController.java
浏览文件 @
b7b21b6a
...
...
@@ -17,7 +17,7 @@ import java.util.List;
/**
* @author <a href="mailto:xianrui0365@163.com">xianrui</a>
*/
@Api
(
tags
=
"移动端-
分类信息
"
)
@Api
(
tags
=
"移动端-
商品分类
"
)
@RestController
(
"appCategoryController"
)
@RequestMapping
(
"/app-api/v1/categories"
)
@Slf4j
...
...
mall-pms/pms-boot/src/main/java/com/youlai/mall/pms/controller/app/GoodsController.java
浏览文件 @
b7b21b6a
package
com.youlai.mall.pms.controller.app
;
import
cn.hutool.core.bean.BeanUtil
;
import
cn.hutool.core.util.StrUtil
;
import
com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
;
import
com.baomidou.mybatisplus.extension.plugins.pagination.Page
;
import
com.youlai.common.result.Result
;
import
com.youlai.mall.pms.pojo.dto.app.SkuDTO
;
import
com.youlai.mall.pms.pojo.dto.app.SkuLockDTO
;
import
com.youlai.mall.pms.service.IPmsSkuService
;
import
com.youlai.mall.pms.pojo.entity.PmsSpu
;
import
com.youlai.mall.pms.pojo.vo.app.GoodsDetailVO
;
import
com.youlai.mall.pms.pojo.vo.app.GoodsVO
;
import
com.youlai.mall.pms.serviceapp.IGoodsService
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiImplicitParam
;
import
io.swagger.annotations.ApiImplicitParams
;
import
io.swagger.annotations.ApiOperation
;
import
jodd.util.StringUtil
;
import
lombok.AllArgsConstructor
;
import
org.springframework.web.bind.annotation.*
;
import
java.util.List
;
import
java.util.stream.Collectors
;
@Api
(
tags
=
"移动端-商品"
)
@RestController
(
"appGoodsController"
)
@Api
(
tags
=
"移动端-商品
信息
"
)
@RestController
(
value
=
"appGoodsController"
)
@RequestMapping
(
"/app-api/v1/goods"
)
@AllArgsConstructor
public
class
GoodsController
{
private
I
PmsSkuService
iPmsSku
Service
;
private
I
GoodsService
goods
Service
;
@ApiOperation
(
value
=
"商品详情"
)
@ApiImplicitParam
(
name
=
"id"
,
value
=
"商品ID"
,
required
=
true
,
paramType
=
"path"
,
dataType
=
"Long"
)
@GetMapping
(
"/{id}"
)
public
Result
detail
(
@PathVariable
Long
id
)
{
SkuDTO
sku
=
iPmsSkuService
.
getSkuById
(
id
);
return
Result
.
success
(
sku
);
}
@ApiOperation
(
value
=
"商品分页列表"
)
@ApiImplicitParams
({
@ApiImplicitParam
(
name
=
"page"
,
value
=
"页码"
,
example
=
"1"
,
paramType
=
"query"
,
dataType
=
"Long"
),
@ApiImplicitParam
(
name
=
"limit"
,
value
=
"每页数量"
,
example
=
"10"
,
paramType
=
"query"
,
dataType
=
"Long"
),
@ApiImplicitParam
(
name
=
"name"
,
value
=
"商品名称"
,
example
=
"华为P50"
,
paramType
=
"query"
,
dataType
=
"String"
),
@ApiImplicitParam
(
name
=
"categoryId"
,
value
=
"商品类目"
,
example
=
"1"
,
paramType
=
"query"
,
dataType
=
"Long"
),
@ApiImplicitParam
(
name
=
"orderBy"
,
value
=
"排序字段"
,
example
=
"price"
,
paramType
=
"query"
,
dataType
=
"Long"
),
@ApiImplicitParam
(
name
=
"isAsc"
,
value
=
"是否升序"
,
example
=
"false"
,
paramType
=
"query"
,
dataType
=
"Boolean"
)
})
@GetMapping
public
Result
list
(
Integer
page
,
Integer
limit
,
String
name
,
Long
categoryId
,
String
orderBy
,
Boolean
isAsc
)
{
Page
<
PmsSpu
>
pageResult
=
goodsService
.
page
(
new
Page
<>(
page
,
limit
),
new
QueryWrapper
<
PmsSpu
>()
.
eq
(
categoryId
!=
null
,
"category_id"
,
categoryId
)
.
like
(
StrUtil
.
isNotBlank
(
name
),
"name"
,
name
)
.
select
(
"id"
,
"name"
,
"pic_url"
,
"price"
,
"sales"
)
.
orderBy
(
StringUtil
.
isNotBlank
(
orderBy
),
isAsc
,
StrUtil
.
toUnderlineCase
(
orderBy
))
);
@ApiOperation
(
"获取商品的库存数量"
)
@ApiImplicitParam
(
name
=
"id"
,
value
=
"商品ID"
,
required
=
true
,
paramType
=
"path"
,
dataType
=
"Long"
)
@GetMapping
(
"/{id}/stock"
)
public
Result
<
Integer
>
getStockById
(
@PathVariable
Long
id
)
{
Integer
stock
=
iPmsSkuService
.
getStockById
(
id
);
return
Result
.
success
(
stock
);
List
<
GoodsVO
>
list
=
pageResult
.
getRecords
().
stream
()
.
map
(
item
->
{
GoodsVO
goodsVO
=
new
GoodsVO
();
BeanUtil
.
copyProperties
(
item
,
goodsVO
);
return
goodsVO
;
}).
collect
(
Collectors
.
toList
());
return
Result
.
success
(
list
,
pageResult
.
getTotal
());
}
@ApiOperation
(
value
=
"锁定库存"
)
@ApiImplicitParam
(
name
=
"list"
,
value
=
"商品列表"
,
required
=
true
,
paramType
=
"body"
,
dataType
=
"SkuLockDTO"
)
@PutMapping
(
"/stocks/_lock"
)
public
Result
<
Boolean
>
lockStock
(
@RequestBody
List
<
SkuLockDTO
>
list
)
{
boolean
result
=
iPmsSkuService
.
lockStock
(
list
);
return
Result
.
judge
(
result
);
}
@ApiOperation
(
value
=
"解锁库存"
)
@ApiImplicitParam
(
name
=
"orderToken"
,
value
=
"订单令牌"
,
required
=
true
,
paramType
=
"body"
,
dataType
=
"String"
)
@PutMapping
(
"/stocks/_unlock"
)
public
Result
<
Boolean
>
unlockStock
(
String
orderToken
)
{
boolean
result
=
iPmsSkuService
.
unlockStock
(
orderToken
);
return
Result
.
judge
(
result
);
}
@ApiOperation
(
value
=
"扣减库存"
)
@ApiImplicitParam
(
name
=
"orderToken"
,
value
=
"订单令牌"
,
required
=
true
,
paramType
=
"body"
,
dataType
=
"String"
)
@PutMapping
(
"/stocks/_deduct"
)
public
Result
<
Boolean
>
deductStock
(
String
orderToken
)
{
boolean
result
=
iPmsSkuService
.
deductStock
(
orderToken
);
return
Result
.
judge
(
result
);
@ApiOperation
(
value
=
"商品详情"
)
@ApiImplicitParam
(
name
=
"id"
,
value
=
"商品ID"
,
required
=
true
,
paramType
=
"path"
,
dataType
=
"Long"
)
@GetMapping
(
"/{id}"
)
public
Result
<
GoodsDetailVO
>
detail
(
@PathVariable
Long
id
)
{
GoodsDetailVO
goodsDetailVO
=
goodsService
.
getGoodsById
(
id
);
return
Result
.
success
(
goodsDetailVO
);
}
}
mall-pms/pms-boot/src/main/java/com/youlai/mall/pms/controller/app/ProductController.java
已删除
100644 → 0
浏览文件 @
a4f985a7
package
com.youlai.mall.pms.controller.app
;
import
cn.hutool.core.util.StrUtil
;
import
cn.hutool.json.JSONUtil
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.baomidou.mybatisplus.extension.plugins.pagination.Page
;
import
com.youlai.common.result.Result
;
import
com.youlai.mall.pms.pojo.dto.app.ProductFormDTO
;
import
com.youlai.mall.pms.pojo.entity.PmsSpu
;
import
com.youlai.mall.pms.pojo.dto.app.ProductDTO
;
import
com.youlai.mall.pms.service.IPmsSpuService
;
import
com.youlai.mall.pms.service.IProductService
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiImplicitParam
;
import
io.swagger.annotations.ApiImplicitParams
;
import
io.swagger.annotations.ApiOperation
;
import
lombok.AllArgsConstructor
;
import
org.springframework.web.bind.annotation.*
;
import
java.util.List
;
import
java.util.stream.Collectors
;
@Api
(
tags
=
"移动端-产品"
)
@RestController
(
"appSpuController"
)
@RequestMapping
(
"/app-api/v1/products"
)
@AllArgsConstructor
public
class
ProductController
{
private
IPmsSpuService
iPmsSpuService
;
private
IProductService
iProductService
;
@ApiOperation
(
value
=
"列表分页"
)
@ApiImplicitParams
({
@ApiImplicitParam
(
name
=
"page"
,
value
=
"页码"
,
defaultValue
=
"1"
,
paramType
=
"query"
,
dataType
=
"Long"
),
@ApiImplicitParam
(
name
=
"limit"
,
value
=
"每页数量"
,
defaultValue
=
"10"
,
paramType
=
"query"
,
dataType
=
"Long"
),
@ApiImplicitParam
(
name
=
"name"
,
value
=
"商品名称"
,
paramType
=
"query"
,
dataType
=
"String"
),
@ApiImplicitParam
(
name
=
"categoryId"
,
value
=
"商品类目"
,
paramType
=
"query"
,
dataType
=
"Long"
)
})
@GetMapping
public
Result
list
(
Integer
page
,
Integer
limit
,
String
name
,
Long
categoryId
)
{
Page
<
PmsSpu
>
result
=
iPmsSpuService
.
page
(
new
Page
<>(
page
,
limit
),
new
LambdaQueryWrapper
<
PmsSpu
>()
.
eq
(
categoryId
!=
null
,
PmsSpu:
:
getCategoryId
,
categoryId
)
.
like
(
StrUtil
.
isNotBlank
(
name
),
PmsSpu:
:
getName
,
name
)
.
select
(
PmsSpu:
:
getId
,
PmsSpu:
:
getName
,
PmsSpu:
:
getPicUrl
,
PmsSpu:
:
getPrice
,
PmsSpu:
:
getSales
)
);
List
<
ProductDTO
>
list
=
result
.
getRecords
().
stream
()
.
map
(
item
->
JSONUtil
.
toBean
(
JSONUtil
.
toJsonStr
(
item
),
ProductDTO
.
class
))
.
collect
(
Collectors
.
toList
());
return
Result
.
success
(
list
,
result
.
getTotal
());
}
@ApiOperation
(
value
=
"商品详情"
)
@ApiImplicitParam
(
name
=
"id"
,
value
=
"商品ID"
,
required
=
true
,
paramType
=
"path"
,
dataType
=
"Long"
)
@GetMapping
(
"/{id}"
)
public
Result
detail
(
@PathVariable
Long
id
)
{
ProductFormDTO
product
=
iProductService
.
getProductById
(
id
);
return
Result
.
success
(
product
);
}
}
mall-pms/pms-boot/src/main/java/com/youlai/mall/pms/controller/app/StockController.java
0 → 100644
浏览文件 @
b7b21b6a
package
com.youlai.mall.pms.controller.app
;
import
com.youlai.common.result.Result
;
import
com.youlai.mall.pms.pojo.dto.app.SkuDTO
;
import
com.youlai.mall.pms.pojo.dto.app.LockStockDTO
;
import
com.youlai.mall.pms.service.IPmsSkuService
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiOperation
;
import
lombok.AllArgsConstructor
;
import
org.springframework.web.bind.annotation.*
;
import
java.util.List
;
@Api
(
tags
=
"移动端-商品库存"
)
@RestController
(
value
=
"appStockController"
)
@RequestMapping
(
"/app-api/v1/stocks"
)
@AllArgsConstructor
public
class
StockController
{
private
IPmsSkuService
iPmsSkuService
;
@ApiOperation
(
value
=
"商品库存单元详情"
)
@GetMapping
(
"/{skuId}"
)
public
Result
detail
(
@PathVariable
Long
skuId
)
{
SkuDTO
sku
=
iPmsSkuService
.
getSkuById
(
skuId
);
return
Result
.
success
(
sku
);
}
@ApiOperation
(
"获取商品的库存数量"
)
@GetMapping
(
"/{skuId}/stock"
)
public
Result
<
Integer
>
getStockById
(
@PathVariable
Long
skuId
)
{
Integer
stock
=
iPmsSkuService
.
getStockById
(
skuId
);
return
Result
.
success
(
stock
);
}
@ApiOperation
(
value
=
"锁定库存"
)
@PutMapping
(
"/_lock"
)
public
Result
<
Boolean
>
lockStock
(
@RequestBody
List
<
LockStockDTO
>
list
)
{
boolean
result
=
iPmsSkuService
.
lockStock
(
list
);
return
Result
.
judge
(
result
);
}
@ApiOperation
(
value
=
"解锁库存"
)
@PutMapping
(
"/_unlock"
)
public
Result
<
Boolean
>
unlockStock
(
String
orderToken
)
{
boolean
result
=
iPmsSkuService
.
unlockStock
(
orderToken
);
return
Result
.
judge
(
result
);
}
@ApiOperation
(
value
=
"扣减库存"
)
@PutMapping
(
"/_deduct"
)
public
Result
<
Boolean
>
deductStock
(
String
orderToken
)
{
boolean
result
=
iPmsSkuService
.
deductStock
(
orderToken
);
return
Result
.
judge
(
result
);
}
}
mall-pms/pms-boot/src/main/java/com/youlai/mall/pms/mapper/PmsSkuMapper.java
浏览文件 @
b7b21b6a
...
...
@@ -17,10 +17,6 @@ public interface PmsSkuMapper extends BaseMapper<PmsSku> {
List
<
PmsSku
>
listBySpuId
(
Long
spuId
);
@Select
(
"<script>"
+
" select t1.id,t1.code,t1.name,t1.pic,t1.price,(t1.stock-t1.locked_stock) as stock,t2.name as spu_name from pms_sku t1"
+
" left join pms_spu t2 on t1.spu_id=t2.id"
+
" where t1.id=#{id}"
+
"</script>"
)
SkuDTO
getSkuById
(
Long
id
);
}
mall-pms/pms-boot/src/main/java/com/youlai/mall/pms/service/IPmsAttributeService.java
浏览文件 @
b7b21b6a
...
...
@@ -6,6 +6,5 @@ import com.youlai.mall.pms.pojo.entity.PmsAttribute;
public
interface
IPmsAttributeService
extends
IService
<
PmsAttribute
>
{
boolean
saveBatch
(
AttributeFormDTO
attributeForm
);
}
mall-pms/pms-boot/src/main/java/com/youlai/mall/pms/service/IPmsSkuService.java
浏览文件 @
b7b21b6a
...
...
@@ -3,7 +3,7 @@ package com.youlai.mall.pms.service;
import
com.baomidou.mybatisplus.extension.service.IService
;
import
com.youlai.mall.pms.pojo.entity.PmsSku
;
import
com.youlai.mall.pms.pojo.dto.app.SkuDTO
;
import
com.youlai.mall.pms.pojo.dto.app.
SkuL
ockDTO
;
import
com.youlai.mall.pms.pojo.dto.app.
LockSt
ockDTO
;
import
java.util.List
;
...
...
@@ -12,7 +12,7 @@ public interface IPmsSkuService extends IService<PmsSku> {
/**
* 锁定库存
*/
boolean
lockStock
(
List
<
SkuL
ockDTO
>
list
);
boolean
lockStock
(
List
<
LockSt
ockDTO
>
list
);
/**
* 解锁库存
...
...
mall-pms/pms-boot/src/main/java/com/youlai/mall/pms/service/IProductService.java
已删除
100644 → 0
浏览文件 @
a4f985a7
package
com.youlai.mall.pms.service
;
import
com.baomidou.mybatisplus.extension.service.IService
;
import
com.youlai.mall.pms.pojo.dto.app.ProductFormDTO
;
import
com.youlai.mall.pms.pojo.entity.PmsSpu
;
public
interface
IProductService
extends
IService
<
PmsSpu
>
{
ProductFormDTO
getProductById
(
Long
id
);
}
mall-pms/pms-boot/src/main/java/com/youlai/mall/pms/service/impl/PmsSkuServiceImpl.java
浏览文件 @
b7b21b6a
...
...
@@ -11,7 +11,7 @@ import com.youlai.common.web.exception.BizException;
import
com.youlai.mall.pms.mapper.PmsSkuMapper
;
import
com.youlai.mall.pms.pojo.entity.PmsSku
;
import
com.youlai.mall.pms.pojo.dto.app.SkuDTO
;
import
com.youlai.mall.pms.pojo.dto.app.
SkuL
ockDTO
;
import
com.youlai.mall.pms.pojo.dto.app.
LockSt
ockDTO
;
import
com.youlai.mall.pms.service.IPmsSkuService
;
import
lombok.AllArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
...
...
@@ -39,7 +39,7 @@ public class PmsSkuServiceImpl extends ServiceImpl<PmsSkuMapper, PmsSku> impleme
* 创建订单时锁定库存
*/
@Override
public
boolean
lockStock
(
List
<
SkuL
ockDTO
>
skuLockList
)
{
public
boolean
lockStock
(
List
<
LockSt
ockDTO
>
skuLockList
)
{
log
.
info
(
"=======================创建订单,开始锁定商品库存======================="
);
log
.
info
(
"锁定商品信息:{}"
,
skuLockList
.
toString
());
if
(
CollectionUtil
.
isEmpty
(
skuLockList
))
{
...
...
@@ -64,17 +64,17 @@ public class PmsSkuServiceImpl extends ServiceImpl<PmsSkuMapper, PmsSku> impleme
});
// 锁定失败的商品集合
List
<
SkuL
ockDTO
>
unlockSkuList
=
skuLockList
.
stream
().
filter
(
item
->
!
item
.
getLocked
()).
collect
(
Collectors
.
toList
());
List
<
LockSt
ockDTO
>
unlockSkuList
=
skuLockList
.
stream
().
filter
(
item
->
!
item
.
getLocked
()).
collect
(
Collectors
.
toList
());
if
(
CollectionUtil
.
isNotEmpty
(
unlockSkuList
))
{
// 恢复已被锁定的库存
List
<
SkuLockDTO
>
lockSkuList
=
skuLockList
.
stream
().
filter
(
SkuL
ockDTO:
:
getLocked
).
collect
(
Collectors
.
toList
());
List
<
LockStockDTO
>
lockSkuList
=
skuLockList
.
stream
().
filter
(
LockSt
ockDTO:
:
getLocked
).
collect
(
Collectors
.
toList
());
lockSkuList
.
forEach
(
item
->
this
.
update
(
new
LambdaUpdateWrapper
<
PmsSku
>()
.
eq
(
PmsSku:
:
getId
,
item
.
getSkuId
())
.
setSql
(
"locked_stock = locked_stock - "
+
item
.
getCount
()))
);
// 提示订单哪些商品库存不足
List
<
Long
>
ids
=
unlockSkuList
.
stream
().
map
(
SkuL
ockDTO:
:
getSkuId
).
collect
(
Collectors
.
toList
());
List
<
Long
>
ids
=
unlockSkuList
.
stream
().
map
(
LockSt
ockDTO:
:
getSkuId
).
collect
(
Collectors
.
toList
());
throw
new
BizException
(
"商品"
+
ids
.
toString
()
+
"库存不足"
);
}
...
...
@@ -96,7 +96,7 @@ public class PmsSkuServiceImpl extends ServiceImpl<PmsSkuMapper, PmsSku> impleme
return
true
;
}
List
<
SkuLockDTO
>
skuLockList
=
JSONUtil
.
toList
(
json
,
SkuL
ockDTO
.
class
);
List
<
LockStockDTO
>
skuLockList
=
JSONUtil
.
toList
(
json
,
LockSt
ockDTO
.
class
);
skuLockList
.
forEach
(
item
->
this
.
update
(
new
LambdaUpdateWrapper
<
PmsSku
>()
...
...
@@ -121,13 +121,13 @@ public class PmsSkuServiceImpl extends ServiceImpl<PmsSkuMapper, PmsSku> impleme
return
true
;
}
List
<
SkuLockDTO
>
skuLockList
=
JSONUtil
.
toList
(
json
,
SkuL
ockDTO
.
class
);
List
<
LockStockDTO
>
skuLockList
=
JSONUtil
.
toList
(
json
,
LockSt
ockDTO
.
class
);
skuLockList
.
forEach
(
item
->
{
boolean
result
=
this
.
update
(
new
LambdaUpdateWrapper
<
PmsSku
>()
.
eq
(
PmsSku:
:
getId
,
item
.
getSkuId
())
.
setSql
(
"
inventory = inventory
- "
+
item
.
getCount
())
// 扣减库存
.
setSql
(
"locked_
inventory = locked_inventory
- "
+
item
.
getCount
())
.
setSql
(
"
stock = stock
- "
+
item
.
getCount
())
// 扣减库存
.
setSql
(
"locked_
stock = locked_stock
- "
+
item
.
getCount
())
);
if
(!
result
)
{
throw
new
BizException
(
"扣减库存失败,商品"
+
item
.
getSkuId
()
+
"库存不足"
);
...
...
mall-pms/pms-boot/src/main/java/com/youlai/mall/pms/service/impl/PmsSpuServiceImpl.java
浏览文件 @
b7b21b6a
...
...
@@ -32,6 +32,7 @@ import java.util.stream.Collectors;
/**
* @author <a href="mailto:xianrui0365@163.com">xianrui</a>
* @date 2021/08/08
*/
@Service
@RequiredArgsConstructor
...
...
@@ -40,6 +41,14 @@ public class PmsSpuServiceImpl extends ServiceImpl<PmsSpuMapper, PmsSpu> impleme
private
final
IPmsSpuAttributeValueService
iPmsSpuAttributeValueService
;
private
final
BloomRedisService
bloomRedisService
;
/**
* 商品分页列表
*
* @param page
* @param name
* @param categoryId
* @return
*/
@Override
public
IPage
<
PmsSpu
>
list
(
Page
<
PmsSpu
>
page
,
String
name
,
Long
categoryId
)
{
List
<
PmsSpu
>
list
=
this
.
baseMapper
.
list
(
page
,
name
,
categoryId
);
...
...
@@ -47,6 +56,12 @@ public class PmsSpuServiceImpl extends ServiceImpl<PmsSpuMapper, PmsSpu> impleme
return
page
;
}
/**
* 添加商品
*
* @param goods
* @return
*/
@Override
@Transactional
public
boolean
addGoods
(
GoodsFormDTO
goods
)
{
...
...
@@ -63,6 +78,12 @@ public class PmsSpuServiceImpl extends ServiceImpl<PmsSpuMapper, PmsSpu> impleme
}
/**
* 修改商品
*
* @param goods
* @return
*/
@Transactional
@Override
public
boolean
updateGoods
(
GoodsFormDTO
goods
)
{
...
...
@@ -85,6 +106,73 @@ public class PmsSpuServiceImpl extends ServiceImpl<PmsSpuMapper, PmsSpu> impleme
return
saveResult
;
}
/**
* 获取商品(SPU)详情
*
* @param id 商品(SPU)ID
* @return
*/
@Override
public
GoodsDetailVO
getGoodsById
(
Long
id
)
{
GoodsDetailVO
goodsDetailVO
=
new
GoodsDetailVO
();
PmsSpu
spu
=
this
.
getById
(
id
);
Assert
.
isTrue
(
spu
!=
null
,
"商品不存在"
);
BeanUtil
.
copyProperties
(
spu
,
goodsDetailVO
);
// 商品图册JSON字符串转集合
String
album
=
spu
.
getAlbum
();
if
(
StrUtil
.
isNotBlank
(
album
))
{
List
<
String
>
picUrls
=
JSONUtil
.
toList
(
album
,
String
.
class
);
goodsDetailVO
.
setSubPicUrls
(
picUrls
);
}
// 商品属性列表
List
<
PmsSpuAttributeValue
>
attrList
=
iPmsSpuAttributeValueService
.
list
(
new
LambdaQueryWrapper
<
PmsSpuAttributeValue
>()
.
eq
(
PmsSpuAttributeValue:
:
getSpuId
,
id
)
.
eq
(
PmsSpuAttributeValue:
:
getType
,
AttributeTypeEnum
.
ATTRIBUTE
.
getValue
())
);
goodsDetailVO
.
setAttrList
(
attrList
);
// 商品规格列表
List
<
PmsSpuAttributeValue
>
specList
=
iPmsSpuAttributeValueService
.
list
(
new
LambdaQueryWrapper
<
PmsSpuAttributeValue
>()
.
eq
(
PmsSpuAttributeValue:
:
getSpuId
,
id
)
.
eq
(
PmsSpuAttributeValue:
:
getType
,
AttributeTypeEnum
.
SPECIFICATION
.
getValue
())
);
goodsDetailVO
.
setSpecList
(
specList
);
// 商品SKU列表
List
<
PmsSku
>
skuList
=
iPmsSkuService
.
list
(
new
LambdaQueryWrapper
<
PmsSku
>().
eq
(
PmsSku:
:
getSpuId
,
id
));
goodsDetailVO
.
setSkuList
(
skuList
);
return
goodsDetailVO
;
}
/**
* 批量删除商品(SPU)
*
* @param goodsIds
* @return
*/
@Override
@Transactional
public
boolean
removeByGoodsIds
(
List
<
Long
>
goodsIds
)
{
boolean
result
=
true
;
for
(
Long
goodsId
:
goodsIds
)
{
// sku
iPmsSkuService
.
remove
(
new
LambdaQueryWrapper
<
PmsSku
>().
eq
(
PmsSku:
:
getSpuId
,
goodsId
));
// 规格
iPmsSpuAttributeValueService
.
remove
(
new
LambdaQueryWrapper
<
PmsSpuAttributeValue
>().
eq
(
PmsSpuAttributeValue:
:
getId
,
goodsId
));
// 属性
iPmsSpuAttributeValueService
.
remove
(
new
LambdaQueryWrapper
<
PmsSpuAttributeValue
>().
eq
(
PmsSpuAttributeValue:
:
getSpuId
,
goodsId
));
// spu
result
=
this
.
removeById
(
goodsId
);
}
return
result
;
}
/**
* 保存商品
*
...
...
@@ -234,60 +322,4 @@ public class PmsSpuServiceImpl extends ServiceImpl<PmsSpuMapper, PmsSpu> impleme
}
return
tempIdIdMap
;
}
@Override
public
GoodsDetailVO
getGoodsById
(
Long
id
)
{
GoodsDetailVO
goodsDetailVO
=
new
GoodsDetailVO
();
PmsSpu
spu
=
this
.
getById
(
id
);
Assert
.
isTrue
(
spu
!=
null
,
"商品不存在"
);
BeanUtil
.
copyProperties
(
spu
,
goodsDetailVO
);
// 商品图册JSON字符串转JSON
String
album
=
spu
.
getAlbum
();
if
(
StrUtil
.
isNotBlank
(
album
))
{
List
<
String
>
picUrls
=
JSONUtil
.
toList
(
album
,
String
.
class
);
goodsDetailVO
.
setSubPicUrls
(
picUrls
);
}
// 商品属性列表
List
<
PmsSpuAttributeValue
>
attrList
=
iPmsSpuAttributeValueService
.
list
(
new
LambdaQueryWrapper
<
PmsSpuAttributeValue
>()
.
eq
(
PmsSpuAttributeValue:
:
getSpuId
,
id
)
.
eq
(
PmsSpuAttributeValue:
:
getType
,
AttributeTypeEnum
.
ATTRIBUTE
.
getValue
())
);
goodsDetailVO
.
setAttrList
(
attrList
);
// 商品规格列表
List
<
PmsSpuAttributeValue
>
specList
=
iPmsSpuAttributeValueService
.
list
(
new
LambdaQueryWrapper
<
PmsSpuAttributeValue
>()
.
eq
(
PmsSpuAttributeValue:
:
getSpuId
,
id
)
.
eq
(
PmsSpuAttributeValue:
:
getType
,
AttributeTypeEnum
.
SPECIFICATION
.
getValue
())
);
goodsDetailVO
.
setSpecList
(
specList
);
// 商品SKU列表
List
<
PmsSku
>
skuList
=
iPmsSkuService
.
list
(
new
LambdaQueryWrapper
<
PmsSku
>().
eq
(
PmsSku:
:
getSpuId
,
id
));
goodsDetailVO
.
setSkuList
(
skuList
);
return
goodsDetailVO
;
}
@Override
public
boolean
removeByGoodsIds
(
List
<
Long
>
goodsIds
)
{
boolean
result
=
true
;
for
(
Long
goodsId
:
goodsIds
)
{
// sku
iPmsSkuService
.
remove
(
new
LambdaQueryWrapper
<
PmsSku
>().
eq
(
PmsSku:
:
getSpuId
,
goodsId
));
// 规格
iPmsSpuAttributeValueService
.
remove
(
new
LambdaQueryWrapper
<
PmsSpuAttributeValue
>().
eq
(
PmsSpuAttributeValue:
:
getId
,
goodsId
));
// 属性
iPmsSpuAttributeValueService
.
remove
(
new
LambdaQueryWrapper
<
PmsSpuAttributeValue
>().
eq
(
PmsSpuAttributeValue:
:
getSpuId
,
goodsId
));
// spu
result
=
this
.
removeById
(
goodsId
);
}
return
result
;
}
}
mall-pms/pms-boot/src/main/java/com/youlai/mall/pms/service/impl/ProductServiceImpl.java
已删除
100644 → 0
浏览文件 @
a4f985a7
package
com.youlai.mall.pms.service.impl
;
import
cn.hutool.core.bean.BeanUtil
;
import
cn.hutool.core.util.StrUtil
;
import
cn.hutool.json.JSONUtil
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
com.youlai.common.redis.utils.RedisUtils
;
import
com.youlai.mall.pms.config.ProductLocalCache
;
import
com.youlai.mall.pms.mapper.PmsSpuMapper
;
import
com.youlai.mall.pms.pojo.dto.app.ProductFormDTO
;
import
com.youlai.mall.pms.pojo.entity.PmsAttribute
;
import
com.youlai.mall.pms.pojo.entity.PmsSku
;
import
com.youlai.mall.pms.pojo.entity.PmsSpu
;
import
com.youlai.mall.pms.pojo.entity.PmsSpuAttributeValue
;
import
com.youlai.mall.pms.service.IPmsAttributeService
;
import
com.youlai.mall.pms.service.IPmsSkuService
;
import
com.youlai.mall.pms.service.IPmsSpuAttributeValueService
;
import
com.youlai.mall.pms.service.IProductService
;
import
lombok.AllArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
org.redisson.api.RLock
;
import
org.redisson.api.RedissonClient
;
import
org.springframework.stereotype.Service
;
import
java.util.List
;
import
static
com
.
youlai
.
mall
.
pms
.
common
.
constant
.
PmsConstants
.
LOCK_PRODUCT_DETAIL
;
import
static
com
.
youlai
.
mall
.
pms
.
common
.
constant
.
PmsConstants
.
PRODUCT_DETAIL_CACHE
;
/**
* @author haoxr
* @date 2020-11-06
*/
@Service
@Slf4j
@AllArgsConstructor
public
class
ProductServiceImpl
extends
ServiceImpl
<
PmsSpuMapper
,
PmsSpu
>
implements
IProductService
{
private
final
IPmsSkuService
iPmsSkuService
;
private
final
IPmsSpuAttributeValueService
iPmsSpuAttributeValueService
;
private
final
IPmsAttributeService
iPmsSpecService
;
private
final
RedisUtils
redisUtils
;
private
final
RedissonClient
redissonClient
;
private
final
ProductLocalCache
productLocalCache
;
@Override
public
ProductFormDTO
getProductById
(
Long
spuId
)
{
//1、一级本地缓存设置
ProductFormDTO
product
=
productLocalCache
.
get
(
PRODUCT_DETAIL_CACHE
+
spuId
);
/* if (null != product) {
log.info("get LocalCache product:" + product);
return product;
}
//2、二级缓存设置,Redis中获取商品详情信息
product = (ProductFormDTO) redisUtils.get(PRODUCT_DETAIL_CACHE + spuId);
if (null != product) {
log.info("get redis product:" + product);
return product;
}
//3、分布式锁,保证原子操作
RLock lock = redissonClient.getLock(LOCK_PRODUCT_DETAIL + spuId);
try {
if (lock.tryLock()) {
// spu
PmsSpu spu = this.getById(spuId);
SpuDTO SpuDTO = new SpuDTO();
BeanUtil.copyProperties(spu, SpuDTO);
if (StrUtil.isNotBlank(spu.getAlbum())) {
// spu专辑图片转换处理 json字符串 -> List
List<String> pics = JSONUtil.toList(JSONUtil.parseArray(spu.getAlbum()), String.class);
SpuDTO.setPics(pics);
}
// 属性
List<PmsSpuAttributeValue> attrs = iPmsSpuAttributeValueService.list(
new LambdaQueryWrapper<PmsSpuAttributeValue>(
).eq(PmsSpuAttributeValue::getSpuId, spuId)
);
// 规格
// List<PmsSpec> specs = iPmsSpecService.listBySpuId(spuId);
List<PmsAttribute> specs=null;
// sku
List<PmsSku> skuList = iPmsSkuService.list(new LambdaQueryWrapper<PmsSku>().eq(PmsSku::getSpuId, spuId));
// product = new ProductFormDTO(SpuDTO, attrs, specs, skuList);
product = new ProductFormDTO();
//TODO 4、需要判断商品是否是秒杀商品,根据秒杀信息更新商品秒杀相关信息
log.info("get db product:" + product);
redisUtils.set(PRODUCT_DETAIL_CACHE + spuId, product, 3600);
productLocalCache.setLocalCache(PRODUCT_DETAIL_CACHE + spuId,product);
} else {
log.info("get redis2 product:" + product);
product = (ProductFormDTO) redisUtils.get(PRODUCT_DETAIL_CACHE + spuId);
if (null!=product) {
productLocalCache.setLocalCache(PRODUCT_DETAIL_CACHE + spuId, product);
}
}
} finally {
if (lock.isLocked()) {
if (lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
}*/
return
product
;
}
}
mall-pms/pms-boot/src/main/java/com/youlai/mall/pms/serviceapp/IGoodsService.java
0 → 100644
浏览文件 @
b7b21b6a
package
com.youlai.mall.pms.serviceapp
;
import
com.baomidou.mybatisplus.extension.service.IService
;
import
com.youlai.mall.pms.pojo.entity.PmsSpu
;
import
com.youlai.mall.pms.pojo.vo.app.GoodsDetailVO
;
/**
* @author <a href="mailto:xianrui0365@163.com">xianrui</a>
* @date 2021/8/8
*/
public
interface
IGoodsService
extends
IService
<
PmsSpu
>
{
GoodsDetailVO
getGoodsById
(
Long
id
);
}
mall-pms/pms-boot/src/main/java/com/youlai/mall/pms/serviceapp/impl/GoodsServiceImpl.java
0 → 100644
浏览文件 @
b7b21b6a
package
com.youlai.mall.pms.serviceapp.impl
;
import
cn.hutool.core.bean.BeanUtil
;
import
cn.hutool.core.collection.CollectionUtil
;
import
cn.hutool.core.lang.Assert
;
import
cn.hutool.core.util.StrUtil
;
import
cn.hutool.json.JSONUtil
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
com.youlai.mall.pms.common.enums.AttributeTypeEnum
;
import
com.youlai.mall.pms.mapper.PmsSpuMapper
;
import
com.youlai.mall.pms.pojo.entity.PmsSku
;
import
com.youlai.mall.pms.pojo.entity.PmsSpu
;
import
com.youlai.mall.pms.pojo.entity.PmsSpuAttributeValue
;
import
com.youlai.mall.pms.pojo.vo.app.GoodsDetailVO
;
import
com.youlai.mall.pms.service.IPmsSkuService
;
import
com.youlai.mall.pms.service.IPmsSpuAttributeValueService
;
import
com.youlai.mall.pms.serviceapp.IGoodsService
;
import
lombok.RequiredArgsConstructor
;
import
org.springframework.stereotype.Service
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.stream.Collectors
;
/**
* @author <a href="mailto:xianrui0365@163.com">xianrui</a>
* @date 2021/8/8
*/
@Service
@RequiredArgsConstructor
public
class
GoodsServiceImpl
extends
ServiceImpl
<
PmsSpuMapper
,
PmsSpu
>
implements
IGoodsService
{
final
IPmsSpuAttributeValueService
spuAttributeValueService
;
final
IPmsSkuService
skuService
;
@Override
public
GoodsDetailVO
getGoodsById
(
Long
goodsId
)
{
GoodsDetailVO
goodsDetailVO
=
new
GoodsDetailVO
();
PmsSpu
pmsSpu
=
this
.
baseMapper
.
selectById
(
goodsId
);
Assert
.
isTrue
(
pmsSpu
!=
null
,
"商品不存在"
);
// 商品基本信息
GoodsDetailVO
.
GoodsInfo
goodsInfo
=
new
GoodsDetailVO
.
GoodsInfo
();
BeanUtil
.
copyProperties
(
pmsSpu
,
goodsInfo
,
"album"
);
List
<
String
>
album
=
new
ArrayList
<>();
if
(
StrUtil
.
isNotBlank
(
pmsSpu
.
getPicUrl
()))
{
album
.
add
(
pmsSpu
.
getPicUrl
());
}
if
(
StrUtil
.
isNotBlank
(
pmsSpu
.
getAlbum
()))
{
album
.
addAll
(
JSONUtil
.
parseArray
(
pmsSpu
.
getAlbum
()).
toList
(
String
.
class
));
goodsInfo
.
setAlbum
(
album
);
}
goodsDetailVO
.
setGoodsInfo
(
goodsInfo
);
// 商品属性列表
List
<
GoodsDetailVO
.
Attribute
>
attributeList
=
spuAttributeValueService
.
list
(
new
LambdaQueryWrapper
<
PmsSpuAttributeValue
>()
.
eq
(
PmsSpuAttributeValue:
:
getType
,
AttributeTypeEnum
.
ATTRIBUTE
.
getValue
())
.
eq
(
PmsSpuAttributeValue:
:
getSpuId
,
goodsId
)
.
select
(
PmsSpuAttributeValue:
:
getId
,
PmsSpuAttributeValue:
:
getName
,
PmsSpuAttributeValue:
:
getValue
)
).
stream
().
map
(
item
->
{
GoodsDetailVO
.
Attribute
attribute
=
new
GoodsDetailVO
.
Attribute
();
BeanUtil
.
copyProperties
(
item
,
attribute
);
return
attribute
;
}).
collect
(
Collectors
.
toList
());
goodsDetailVO
.
setAttributeList
(
attributeList
);
// 商品规格列表
List
<
PmsSpuAttributeValue
>
specSourceList
=
spuAttributeValueService
.
list
(
new
LambdaQueryWrapper
<
PmsSpuAttributeValue
>()
.
eq
(
PmsSpuAttributeValue:
:
getType
,
AttributeTypeEnum
.
SPECIFICATION
.
getValue
())
.
eq
(
PmsSpuAttributeValue:
:
getSpuId
,
goodsId
)
.
select
(
PmsSpuAttributeValue:
:
getId
,
PmsSpuAttributeValue:
:
getName
,
PmsSpuAttributeValue:
:
getValue
)
);
List
<
GoodsDetailVO
.
Specification
>
specList
=
new
ArrayList
<>();
// 规格Map [key:"颜色",value:[{id:1,value:"黑"},{id:2,value:"白"}]]
Map
<
String
,
List
<
PmsSpuAttributeValue
>>
specValueMap
=
specSourceList
.
stream
()
.
collect
(
Collectors
.
groupingBy
(
item
->
item
.
getName
()));
for
(
Map
.
Entry
<
String
,
List
<
PmsSpuAttributeValue
>>
entry
:
specValueMap
.
entrySet
())
{
String
specName
=
entry
.
getKey
();
List
<
PmsSpuAttributeValue
>
specValueSourceList
=
entry
.
getValue
();
// 规格映射处理
GoodsDetailVO
.
Specification
spec
=
new
GoodsDetailVO
.
Specification
();
spec
.
setName
(
specName
);
if
(
CollectionUtil
.
isNotEmpty
(
specValueSourceList
))
{
List
<
GoodsDetailVO
.
Specification
.
Value
>
specValueList
=
specValueSourceList
.
stream
().
map
(
item
->
{
GoodsDetailVO
.
Specification
.
Value
specValue
=
new
GoodsDetailVO
.
Specification
.
Value
();
specValue
.
setId
(
item
.
getId
());
specValue
.
setValue
(
item
.
getValue
());
return
specValue
;
}).
collect
(
Collectors
.
toList
());
spec
.
setValues
(
specValueList
);
specList
.
add
(
spec
);
}
}
goodsDetailVO
.
setSpecList
(
specList
);
// 商品SKU列表
List
<
PmsSku
>
skuSourceList
=
skuService
.
list
(
new
LambdaQueryWrapper
<
PmsSku
>().
eq
(
PmsSku:
:
getSpuId
,
goodsId
));
if
(
CollectionUtil
.
isNotEmpty
(
skuSourceList
))
{
List
<
GoodsDetailVO
.
Sku
>
skuList
=
skuSourceList
.
stream
().
map
(
item
->
{
GoodsDetailVO
.
Sku
sku
=
new
GoodsDetailVO
.
Sku
();
BeanUtil
.
copyProperties
(
item
,
sku
);
return
sku
;
}).
collect
(
Collectors
.
toList
());
goodsDetailVO
.
setSkuList
(
skuList
);
}
return
goodsDetailVO
;
}
}
mall-pms/pms-boot/src/main/resources/mapper/PmsSkuMapper.xml
浏览文件 @
b7b21b6a
...
...
@@ -5,23 +5,32 @@
<mapper
namespace=
"com.youlai.mall.pms.mapper.PmsSkuMapper"
>
<resultMap
id=
"BaseResultMap"
type=
"com.youlai.mall.pms.pojo.entity.PmsSku"
>
<id
property=
"id"
column=
"id"
jdbcType=
"BIGINT"
/>
<result
property=
"spuId"
column=
"spu_id"
jdbcType=
"BIGINT"
/>
<result
property=
"name"
column=
"name"
jdbcType=
"VARCHAR"
/>
<result
property=
"sn"
column=
"sn"
jdbcType=
"VARCHAR"
/>
<result
property=
"picUrl"
column=
"pic_url"
jdbcType=
"VARCHAR"
/>
<result
property=
"specIds"
column=
"specs"
jdbcType=
"VARCHAR"
/>
<result
property=
"price"
column=
"price"
jdbcType=
"BIGINT"
/>
<result
property=
"stock"
column=
"stock"
jdbcType=
"INTEGER"
/>
<result
property=
"lockedStock"
column=
"locked_stock"
jdbcType=
"INTEGER"
/>
<result
property=
"gmtCreate"
column=
"gmt_create"
jdbcType=
"TIMESTAMP"
/>
<result
property=
"gmtModified"
column=
"gmt_modified"
jdbcType=
"TIMESTAMP"
/>
<id
property=
"id"
column=
"id"
jdbcType=
"BIGINT"
/>
<result
property=
"spuId"
column=
"spu_id"
jdbcType=
"BIGINT"
/>
<result
property=
"name"
column=
"name"
jdbcType=
"VARCHAR"
/>
<result
property=
"sn"
column=
"sn"
jdbcType=
"VARCHAR"
/>
<result
property=
"picUrl"
column=
"pic_url"
jdbcType=
"VARCHAR"
/>
<result
property=
"specIds"
column=
"specs"
jdbcType=
"VARCHAR"
/>
<result
property=
"price"
column=
"price"
jdbcType=
"BIGINT"
/>
<result
property=
"stock"
column=
"stock"
jdbcType=
"INTEGER"
/>
<result
property=
"lockedStock"
column=
"locked_stock"
jdbcType=
"INTEGER"
/>
<result
property=
"gmtCreate"
column=
"gmt_create"
jdbcType=
"TIMESTAMP"
/>
<result
property=
"gmtModified"
column=
"gmt_modified"
jdbcType=
"TIMESTAMP"
/>
</resultMap>
<sql
id=
"Base_Column_List"
>
id,spu_id,name,
id
,spu_id,name,
sn,pic_url,specs,
origin_price,price,stock,
locked_stock,gmt_create,gmt_modified
</sql>
<select
id=
"getSkuById"
resultType=
"com.youlai.mall.pms.pojo.dto.app.SkuDTO"
>
select t1.id, t1.sn, t1.name, t1.pic_url, t1.price, (t1.stock - t1.locked_stock) as stock, t2.name as goodsName
from pms_sku t1
left join pms_spu t2 on t1.spu_id = t2.id
where t1.id = #{id}
</select>
</mapper>
mall-pms/pms-boot/src/main/resources/mapper/PmsSpuMapper.xml
浏览文件 @
b7b21b6a
...
...
@@ -32,9 +32,16 @@
<result property="stock" column="stock" jdbcType="INTEGER"/>
<result property="lockedStock" column="locked_stock" jdbcType="INTEGER"/>
</collection>-->
<collection
property=
"skuList"
column=
"id"
select=
"getSkuListBySpuId"
>
<id
property=
"id"
column=
"id"
jdbcType=
"BIGINT"
/>
<result
property=
"name"
column=
"name"
jdbcType=
"VARCHAR"
/>
<result
property=
"sn"
column=
"sn"
jdbcType=
"VARCHAR"
/>
<result
property=
"picUrl"
column=
"pic_url"
jdbcType=
"VARCHAR"
/>
<result
property=
"specIds"
column=
"spec_ids"
jdbcType=
"VARCHAR"
/>
<result
property=
"price"
column=
"price"
jdbcType=
"BIGINT"
/>
<result
property=
"stock"
column=
"stock"
jdbcType=
"INTEGER"
/>
<result
property=
"lockedStock"
column=
"locked_stock"
jdbcType=
"INTEGER"
/>
</collection>
</resultMap>
<sql
id=
"Base_Column_List"
>
...
...
@@ -46,28 +53,40 @@
status,gmt_create,gmt_modified
</sql>
<select
id=
"list"
resultMap=
"BaseResultMap"
>
SELECT
t1.name,
t1.pic_url
,
t3.NAME categoryName
,
t4.NAME brandNam
e,
t2.id skuId
,
t2.NAME skuName
,
t2.sn
,
t2.pic_url skuPicUr
l,
t2.spec_ids
,
t2.price skuPric
e,
t2.stock
SELECT
t1.id
,
t1.name,
t1.pic_url
,
t1.origin_pric
e,
t1.price
,
t1.sales
,
t1.unit
,
t1.detai
l,
t1.description
,
t3.NAME categoryNam
e,
t4.NAME brandName
FROM pms_spu t1
LEFT JOIN pms_sku t2 ON t1.id = t2.spu_id
LEFT JOIN pms_category t3 ON t1.category_id = t3.id
LEFT JOIN pms_brand t4 ON t1.brand_id = t4.id
LEFT JOIN pms_category t3 ON t1.category_id = t3.id
LEFT JOIN pms_brand t4 ON t1.brand_id = t4.id
WHERE 1 = 1
<if
test=
"categoryId!=null"
>
AND t1.category_id =#{categoryId}
</if>
<if
test=
'name!=null and name neq ""'
>
AND t1.
category_id =#{categoryId}
AND t1.
name like concat('%',#{name},'%')
</if>
</select>
<select
id=
"getSkuListBySpuId"
resultType=
"com.youlai.mall.pms.pojo.entity.PmsSku"
>
SELECT id ,
NAME ,
sn,
pic_url ,
spec_ids,
price ,
stock
FROM pms_sku
WHERE spu_id = #{id}
</select>
</mapper>
youlai-common/common-web/src/main/java/com/youlai/common/web/exception/GlobalExceptionHandler.java
浏览文件 @
b7b21b6a
...
...
@@ -18,7 +18,7 @@ public class GlobalExceptionHandler {
@ExceptionHandler
(
IllegalArgumentException
.
class
)
public
Result
handleIllegalArgumentException
(
IllegalArgumentException
e
)
{
log
.
error
(
"
非法参数异常,异常原因
:{}"
,
e
.
getMessage
(),
e
);
log
.
error
(
"
业务异常
:{}"
,
e
.
getMessage
(),
e
);
return
Result
.
failed
(
e
.
getMessage
());
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录