From 5698a1d5979a9405a73ca37812d952536edb8cb3 Mon Sep 17 00:00:00 2001 From: zhangsan <646228430@qq.com> Date: Thu, 22 May 2025 16:32:45 +0800 Subject: [PATCH] =?UTF-8?q?5.22=20=E6=8B=86=E5=88=86=E4=BA=A4=E6=98=93?= =?UTF-8?q?=E3=80=81=E6=94=AF=E4=BB=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hmall/cart/controller/CartController.java | 1 + .../src/main/resources/application.yaml | 2 +- .../java/com/hmall/api/client/CartClient.java | 13 ++ .../java/com/hmall/api/client/ItemClient.java | 5 + .../com/hmall/api/client/TradeClient.java | 11 ++ .../java/com/hmall/api/client/UserClient.java | 11 ++ .../com/hmall/api}/dto/OrderDetailDTO.java | 2 +- .../src/main/resources/application.yaml | 2 +- item-service/pom.xml | 5 + .../hmall/item/controller/ItemController.java | 4 +- .../com/hmall/item/domain/dto/ItemDTO.java | 34 ----- .../com/hmall/item/service/IItemService.java | 4 +- .../item/service/impl/ItemServiceImpl.java | 4 +- .../src/main/resources/application.yaml | 2 +- pay-service/pom.xml | 67 +++++++++ .../java/com/hmall/pay/PayApplication.java | 16 +++ .../hmall/pay/controller/PayController.java | 49 +++++++ .../com/hmall/pay/domain/dto/PayApplyDTO.java | 30 ++++ .../hmall/pay/domain/dto/PayOrderFormDTO.java | 20 +++ .../com/hmall/pay/domain/po/PayOrder.java | 123 ++++++++++++++++ .../com/hmall/pay/domain/po/po/Address.java | 77 ++++++++++ .../java/com/hmall/pay/domain/po/po/Cart.java | 81 +++++++++++ .../java/com/hmall/pay/domain/po/po/Item.java | 113 +++++++++++++++ .../com/hmall/pay/domain/po/po/Order.java | 91 ++++++++++++ .../hmall/pay/domain/po/po/OrderDetail.java | 81 +++++++++++ .../pay/domain/po/po/OrderLogistics.java | 86 ++++++++++++ .../java/com/hmall/pay/domain/po/po/User.java | 66 +++++++++ .../com/hmall/pay/domain/vo/PayOrderVO.java | 49 +++++++ .../java/com/hmall/pay/enums/PayChannel.java | 25 ++++ .../java/com/hmall/pay/enums/PayStatus.java | 27 ++++ .../java/com/hmall/pay/enums/PayType.java | 27 ++++ .../com/hmall/pay/mapper/PayOrderMapper.java | 17 +++ .../hmall/pay/service/IPayOrderService.java | 22 +++ .../pay/service/impl/PayOrderServiceImpl.java | 131 ++++++++++++++++++ .../src/main/resources/application-dev.yaml | 4 + .../src/main/resources/application-local.yaml | 4 + .../src/main/resources/application.yaml | 51 +++++++ pom.xml | 2 + trade-service/pom.xml | 67 +++++++++ .../com/hmall/trade/TradeApplication.java | 16 +++ .../trade/controller/OrderController.java | 40 ++++++ .../hmall/trade/domain/dto/OrderFormDTO.java | 19 +++ .../java/com/hmall/trade/domain/po/Order.java | 91 ++++++++++++ .../hmall/trade/domain/po/OrderDetail.java | 81 +++++++++++ .../hmall/trade/domain/po/OrderLogistics.java | 86 ++++++++++++ .../com/hmall/trade/domain/vo/OrderVO.java | 34 +++++ .../hmall/trade/mapper/OrderDetailMapper.java | 17 +++ .../trade/mapper/OrderLogisticsMapper.java | 17 +++ .../com/hmall/trade/mapper/OrderMapper.java | 17 +++ .../trade/service/IOrderDetailService.java | 17 +++ .../trade/service/IOrderLogisticsService.java | 17 +++ .../hmall/trade/service/IOrderService.java | 21 +++ .../service/impl/OrderDetailServiceImpl.java | 21 +++ .../impl/OrderLogisticsServiceImpl.java | 21 +++ .../trade/service/impl/OrderServiceImpl.java | 114 +++++++++++++++ .../src/main/resources/application-dev.yaml | 4 + .../src/main/resources/application-local.yaml | 4 + .../src/main/resources/application.yaml | 51 +++++++ .../src/main/resources/application.yaml | 2 +- 59 files changed, 2071 insertions(+), 45 deletions(-) create mode 100644 hm-api/src/main/java/com/hmall/api/client/CartClient.java create mode 100644 hm-api/src/main/java/com/hmall/api/client/TradeClient.java create mode 100644 hm-api/src/main/java/com/hmall/api/client/UserClient.java rename {item-service/src/main/java/com/hmall/item/domain => hm-api/src/main/java/com/hmall/api}/dto/OrderDetailDTO.java (91%) delete mode 100644 item-service/src/main/java/com/hmall/item/domain/dto/ItemDTO.java create mode 100644 pay-service/pom.xml create mode 100644 pay-service/src/main/java/com/hmall/pay/PayApplication.java create mode 100644 pay-service/src/main/java/com/hmall/pay/controller/PayController.java create mode 100644 pay-service/src/main/java/com/hmall/pay/domain/dto/PayApplyDTO.java create mode 100644 pay-service/src/main/java/com/hmall/pay/domain/dto/PayOrderFormDTO.java create mode 100644 pay-service/src/main/java/com/hmall/pay/domain/po/PayOrder.java create mode 100644 pay-service/src/main/java/com/hmall/pay/domain/po/po/Address.java create mode 100644 pay-service/src/main/java/com/hmall/pay/domain/po/po/Cart.java create mode 100644 pay-service/src/main/java/com/hmall/pay/domain/po/po/Item.java create mode 100644 pay-service/src/main/java/com/hmall/pay/domain/po/po/Order.java create mode 100644 pay-service/src/main/java/com/hmall/pay/domain/po/po/OrderDetail.java create mode 100644 pay-service/src/main/java/com/hmall/pay/domain/po/po/OrderLogistics.java create mode 100644 pay-service/src/main/java/com/hmall/pay/domain/po/po/User.java create mode 100644 pay-service/src/main/java/com/hmall/pay/domain/vo/PayOrderVO.java create mode 100644 pay-service/src/main/java/com/hmall/pay/enums/PayChannel.java create mode 100644 pay-service/src/main/java/com/hmall/pay/enums/PayStatus.java create mode 100644 pay-service/src/main/java/com/hmall/pay/enums/PayType.java create mode 100644 pay-service/src/main/java/com/hmall/pay/mapper/PayOrderMapper.java create mode 100644 pay-service/src/main/java/com/hmall/pay/service/IPayOrderService.java create mode 100644 pay-service/src/main/java/com/hmall/pay/service/impl/PayOrderServiceImpl.java create mode 100644 pay-service/src/main/resources/application-dev.yaml create mode 100644 pay-service/src/main/resources/application-local.yaml create mode 100644 pay-service/src/main/resources/application.yaml create mode 100644 trade-service/pom.xml create mode 100644 trade-service/src/main/java/com/hmall/trade/TradeApplication.java create mode 100644 trade-service/src/main/java/com/hmall/trade/controller/OrderController.java create mode 100644 trade-service/src/main/java/com/hmall/trade/domain/dto/OrderFormDTO.java create mode 100644 trade-service/src/main/java/com/hmall/trade/domain/po/Order.java create mode 100644 trade-service/src/main/java/com/hmall/trade/domain/po/OrderDetail.java create mode 100644 trade-service/src/main/java/com/hmall/trade/domain/po/OrderLogistics.java create mode 100644 trade-service/src/main/java/com/hmall/trade/domain/vo/OrderVO.java create mode 100644 trade-service/src/main/java/com/hmall/trade/mapper/OrderDetailMapper.java create mode 100644 trade-service/src/main/java/com/hmall/trade/mapper/OrderLogisticsMapper.java create mode 100644 trade-service/src/main/java/com/hmall/trade/mapper/OrderMapper.java create mode 100644 trade-service/src/main/java/com/hmall/trade/service/IOrderDetailService.java create mode 100644 trade-service/src/main/java/com/hmall/trade/service/IOrderLogisticsService.java create mode 100644 trade-service/src/main/java/com/hmall/trade/service/IOrderService.java create mode 100644 trade-service/src/main/java/com/hmall/trade/service/impl/OrderDetailServiceImpl.java create mode 100644 trade-service/src/main/java/com/hmall/trade/service/impl/OrderLogisticsServiceImpl.java create mode 100644 trade-service/src/main/java/com/hmall/trade/service/impl/OrderServiceImpl.java create mode 100644 trade-service/src/main/resources/application-dev.yaml create mode 100644 trade-service/src/main/resources/application-local.yaml create mode 100644 trade-service/src/main/resources/application.yaml diff --git a/cart-service/src/main/java/com/hmall/cart/controller/CartController.java b/cart-service/src/main/java/com/hmall/cart/controller/CartController.java index bf8be0d..b7a1f0d 100644 --- a/cart-service/src/main/java/com/hmall/cart/controller/CartController.java +++ b/cart-service/src/main/java/com/hmall/cart/controller/CartController.java @@ -44,6 +44,7 @@ public class CartController { public List queryMyCarts(){ return cartService.queryMyCarts(); } + @ApiOperation("批量删除购物车中商品") @ApiImplicitParam(name = "ids", value = "购物车条目id集合") @DeleteMapping diff --git a/cart-service/src/main/resources/application.yaml b/cart-service/src/main/resources/application.yaml index b8320b9..3aae4ff 100644 --- a/cart-service/src/main/resources/application.yaml +++ b/cart-service/src/main/resources/application.yaml @@ -6,7 +6,7 @@ spring: profiles: active: local datasource: - url: jdbc:mysql://${hm.db.host}:3306/hm-cart?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai + url: jdbc:mysql://${hm.db.host}:3307/hm-cart?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai driver-class-name: com.mysql.cj.jdbc.Driver username: root password: ${hm.db.pw} diff --git a/hm-api/src/main/java/com/hmall/api/client/CartClient.java b/hm-api/src/main/java/com/hmall/api/client/CartClient.java new file mode 100644 index 0000000..0b51c6e --- /dev/null +++ b/hm-api/src/main/java/com/hmall/api/client/CartClient.java @@ -0,0 +1,13 @@ +package com.hmall.api.client; + +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.RequestParam; + +import java.util.Collection; + +@FeignClient("cart-service") +public interface CartClient { + @DeleteMapping("/carts") + void deleteCartItemByIds(@RequestParam("ids") Collection ids); +} \ No newline at end of file diff --git a/hm-api/src/main/java/com/hmall/api/client/ItemClient.java b/hm-api/src/main/java/com/hmall/api/client/ItemClient.java index c4369f4..04feaed 100644 --- a/hm-api/src/main/java/com/hmall/api/client/ItemClient.java +++ b/hm-api/src/main/java/com/hmall/api/client/ItemClient.java @@ -1,8 +1,11 @@ package com.hmall.api.client; import com.hmall.api.dto.ItemDTO; +import com.hmall.api.dto.OrderDetailDTO; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; import java.util.Collection; @@ -13,4 +16,6 @@ public interface ItemClient { @GetMapping("/items") List queryItemByIds(@RequestParam("ids") Collection ids); + @PutMapping("/items/stock/deduct") + void deductStock(@RequestBody List items); } diff --git a/hm-api/src/main/java/com/hmall/api/client/TradeClient.java b/hm-api/src/main/java/com/hmall/api/client/TradeClient.java new file mode 100644 index 0000000..a3ce9ea --- /dev/null +++ b/hm-api/src/main/java/com/hmall/api/client/TradeClient.java @@ -0,0 +1,11 @@ +package com.hmall.api.client; + +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PutMapping; + +@FeignClient("trade-service") +public interface TradeClient { + @PutMapping("/orders/{orderId}") + void markOrderPaySuccess(@PathVariable("orderId") Long orderId); +} \ No newline at end of file diff --git a/hm-api/src/main/java/com/hmall/api/client/UserClient.java b/hm-api/src/main/java/com/hmall/api/client/UserClient.java new file mode 100644 index 0000000..ac3c97e --- /dev/null +++ b/hm-api/src/main/java/com/hmall/api/client/UserClient.java @@ -0,0 +1,11 @@ +package com.hmall.api.client; + +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestParam; + +@FeignClient("user-service") +public interface UserClient { + @PutMapping("/users/money/deduct") + void deductMoney(@RequestParam("pw") String pw,@RequestParam("amount") Integer amount); +} \ No newline at end of file diff --git a/item-service/src/main/java/com/hmall/item/domain/dto/OrderDetailDTO.java b/hm-api/src/main/java/com/hmall/api/dto/OrderDetailDTO.java similarity index 91% rename from item-service/src/main/java/com/hmall/item/domain/dto/OrderDetailDTO.java rename to hm-api/src/main/java/com/hmall/api/dto/OrderDetailDTO.java index 6d2088b..556c649 100644 --- a/item-service/src/main/java/com/hmall/item/domain/dto/OrderDetailDTO.java +++ b/hm-api/src/main/java/com/hmall/api/dto/OrderDetailDTO.java @@ -1,4 +1,4 @@ -package com.hmall.item.domain.dto; +package com.hmall.api.dto; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; diff --git a/hm-service/src/main/resources/application.yaml b/hm-service/src/main/resources/application.yaml index cac3313..6d701b4 100644 --- a/hm-service/src/main/resources/application.yaml +++ b/hm-service/src/main/resources/application.yaml @@ -6,7 +6,7 @@ spring: profiles: active: local datasource: - url: jdbc:mysql://${hm.db.host}:3306/hmall?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai + url: jdbc:mysql://${hm.db.host}:3307/hmall?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai driver-class-name: com.mysql.cj.jdbc.Driver username: root password: ${hm.db.pw} diff --git a/item-service/pom.xml b/item-service/pom.xml index 2ce3832..fc9045e 100644 --- a/item-service/pom.xml +++ b/item-service/pom.xml @@ -16,6 +16,11 @@ 17 + + com.heima + hm-api + 1.0.0 + com.heima diff --git a/item-service/src/main/java/com/hmall/item/controller/ItemController.java b/item-service/src/main/java/com/hmall/item/controller/ItemController.java index f1d3c4a..08949b4 100644 --- a/item-service/src/main/java/com/hmall/item/controller/ItemController.java +++ b/item-service/src/main/java/com/hmall/item/controller/ItemController.java @@ -1,10 +1,10 @@ package com.hmall.item.controller; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.hmall.api.dto.ItemDTO; +import com.hmall.api.dto.OrderDetailDTO; import com.hmall.common.domain.PageDTO; import com.hmall.common.domain.PageQuery; import com.hmall.common.utils.BeanUtils; -import com.hmall.item.domain.dto.ItemDTO; -import com.hmall.item.domain.dto.OrderDetailDTO; import com.hmall.item.domain.po.Item; import com.hmall.item.service.IItemService; import io.swagger.annotations.Api; diff --git a/item-service/src/main/java/com/hmall/item/domain/dto/ItemDTO.java b/item-service/src/main/java/com/hmall/item/domain/dto/ItemDTO.java deleted file mode 100644 index 457f16d..0000000 --- a/item-service/src/main/java/com/hmall/item/domain/dto/ItemDTO.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.hmall.item.domain.dto; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -@Data -@ApiModel(description = "商品实体") -public class ItemDTO { - @ApiModelProperty("商品id") - private Long id; - @ApiModelProperty("SKU名称") - private String name; - @ApiModelProperty("价格(分)") - private Integer price; - @ApiModelProperty("库存数量") - private Integer stock; - @ApiModelProperty("商品图片") - private String image; - @ApiModelProperty("类目名称") - private String category; - @ApiModelProperty("品牌名称") - private String brand; - @ApiModelProperty("规格") - private String spec; - @ApiModelProperty("销量") - private Integer sold; - @ApiModelProperty("评论数") - private Integer commentCount; - @ApiModelProperty("是否是推广广告,true/false") - private Boolean isAD; - @ApiModelProperty("商品状态 1-正常,2-下架,3-删除") - private Integer status; -} diff --git a/item-service/src/main/java/com/hmall/item/service/IItemService.java b/item-service/src/main/java/com/hmall/item/service/IItemService.java index dfe6a9e..646f4e8 100644 --- a/item-service/src/main/java/com/hmall/item/service/IItemService.java +++ b/item-service/src/main/java/com/hmall/item/service/IItemService.java @@ -1,8 +1,8 @@ package com.hmall.item.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.hmall.item.domain.dto.ItemDTO; -import com.hmall.item.domain.dto.OrderDetailDTO; +import com.hmall.api.dto.ItemDTO; +import com.hmall.api.dto.OrderDetailDTO; import com.hmall.item.domain.po.Item; import java.util.Collection; diff --git a/item-service/src/main/java/com/hmall/item/service/impl/ItemServiceImpl.java b/item-service/src/main/java/com/hmall/item/service/impl/ItemServiceImpl.java index f7fcc1d..739bd77 100644 --- a/item-service/src/main/java/com/hmall/item/service/impl/ItemServiceImpl.java +++ b/item-service/src/main/java/com/hmall/item/service/impl/ItemServiceImpl.java @@ -2,11 +2,11 @@ package com.hmall.item.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.hmall.api.dto.ItemDTO; +import com.hmall.api.dto.OrderDetailDTO; import com.hmall.common.exception.BizIllegalException; import com.hmall.common.utils.BeanUtils; -import com.hmall.item.domain.dto.ItemDTO; -import com.hmall.item.domain.dto.OrderDetailDTO; import com.hmall.item.domain.po.Item; import com.hmall.item.mapper.ItemMapper; import com.hmall.item.service.IItemService; diff --git a/item-service/src/main/resources/application.yaml b/item-service/src/main/resources/application.yaml index 73ef548..d3de1a3 100644 --- a/item-service/src/main/resources/application.yaml +++ b/item-service/src/main/resources/application.yaml @@ -10,7 +10,7 @@ spring: profiles: active: local datasource: - url: jdbc:mysql://${hm.db.host}:3306/hm-item?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai + url: jdbc:mysql://${hm.db.host}:3307/hm-item?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai driver-class-name: com.mysql.cj.jdbc.Driver username: root password: ${hm.db.pw} diff --git a/pay-service/pom.xml b/pay-service/pom.xml new file mode 100644 index 0000000..18d43ed --- /dev/null +++ b/pay-service/pom.xml @@ -0,0 +1,67 @@ + + + + hmall + com.heima + 1.0.0 + + 4.0.0 + + pay-service + + + 17 + 17 + + + + com.heima + hm-api + 1.0.0 + + + + com.heima + hm-common + 1.0.0 + + + + org.springframework.boot + spring-boot-starter-web + + + + + mysql + mysql-connector-java + + + + com.baomidou + mybatis-plus-boot-starter + + + com.heima + hm-service + 1.0.0 + compile + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + + \ No newline at end of file diff --git a/pay-service/src/main/java/com/hmall/pay/PayApplication.java b/pay-service/src/main/java/com/hmall/pay/PayApplication.java new file mode 100644 index 0000000..0216fa6 --- /dev/null +++ b/pay-service/src/main/java/com/hmall/pay/PayApplication.java @@ -0,0 +1,16 @@ +package com.hmall.pay; + +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.openfeign.EnableFeignClients; + +@MapperScan("com.hmall.pay.mapper") +@EnableFeignClients(basePackages= "com.hmall.api.client") +@SpringBootApplication +public class PayApplication { + public static void main(String[] args) { + + SpringApplication.run(PayApplication.class, args); + } +} \ No newline at end of file diff --git a/pay-service/src/main/java/com/hmall/pay/controller/PayController.java b/pay-service/src/main/java/com/hmall/pay/controller/PayController.java new file mode 100644 index 0000000..6fad8fa --- /dev/null +++ b/pay-service/src/main/java/com/hmall/pay/controller/PayController.java @@ -0,0 +1,49 @@ +package com.hmall.pay.controller; + +import com.hmall.common.exception.BizIllegalException; + +import com.hmall.common.utils.BeanUtils; +import com.hmall.pay.domain.dto.PayApplyDTO; +import com.hmall.pay.domain.dto.PayOrderFormDTO; +import com.hmall.pay.domain.vo.PayOrderVO; +import com.hmall.pay.enums.PayType; +import com.hmall.pay.service.IPayOrderService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@Api(tags = "支付相关接口") +@RestController +@RequestMapping("pay-orders") +@RequiredArgsConstructor +public class PayController { + + private final IPayOrderService payOrderService; + + @ApiOperation("生成支付单") + @PostMapping + public String applyPayOrder(@RequestBody PayApplyDTO applyDTO){ + if(!PayType.BALANCE.equalsValue(applyDTO.getPayType())){ + // 目前只支持余额支付 + throw new BizIllegalException("抱歉,目前只支持余额支付"); + } + return payOrderService.applyPayOrder(applyDTO); + } + @ApiOperation("查询支付单") + @GetMapping + public List queryPayOrders(){ + return BeanUtils.copyList(payOrderService.list(), PayOrderVO.class); + } + + @ApiOperation("尝试基于用户余额支付") + @ApiImplicitParam(value = "支付单id", name = "id") + @PostMapping("{id}") + public void tryPayOrderByBalance(@PathVariable("id") Long id, @RequestBody PayOrderFormDTO payOrderFormDTO){ + payOrderFormDTO.setId(id); + payOrderService.tryPayOrderByBalance(payOrderFormDTO); + } +} diff --git a/pay-service/src/main/java/com/hmall/pay/domain/dto/PayApplyDTO.java b/pay-service/src/main/java/com/hmall/pay/domain/dto/PayApplyDTO.java new file mode 100644 index 0000000..49c24df --- /dev/null +++ b/pay-service/src/main/java/com/hmall/pay/domain/dto/PayApplyDTO.java @@ -0,0 +1,30 @@ +package com.hmall.pay.domain.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Builder; +import lombok.Data; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + +@Data +@Builder +@ApiModel(description = "支付下单表单实体") +public class PayApplyDTO { + @ApiModelProperty("业务订单id不能为空") + @NotNull(message = "业务订单id不能为空") + private Long bizOrderNo; + @ApiModelProperty("支付金额必须为正数") + @Min(value = 1, message = "支付金额必须为正数") + private Integer amount; + @ApiModelProperty("支付渠道编码不能为空") + @NotNull(message = "支付渠道编码不能为空") + private String payChannelCode; + @ApiModelProperty("支付方式不能为空") + @NotNull(message = "支付方式不能为空") + private Integer payType; + @ApiModelProperty("订单中的商品信息不能为空") + @NotNull(message = "订单中的商品信息不能为空") + private String orderInfo; +} \ No newline at end of file diff --git a/pay-service/src/main/java/com/hmall/pay/domain/dto/PayOrderFormDTO.java b/pay-service/src/main/java/com/hmall/pay/domain/dto/PayOrderFormDTO.java new file mode 100644 index 0000000..214b797 --- /dev/null +++ b/pay-service/src/main/java/com/hmall/pay/domain/dto/PayOrderFormDTO.java @@ -0,0 +1,20 @@ +package com.hmall.pay.domain.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Builder; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +@Data +@Builder +@ApiModel(description = "支付确认表单实体") +public class PayOrderFormDTO { + @ApiModelProperty("支付订单id不能为空") + @NotNull(message = "支付订单id不能为空") + private Long id; + @ApiModelProperty("支付密码") + @NotNull(message = "支付密码") + private String pw; +} \ No newline at end of file diff --git a/pay-service/src/main/java/com/hmall/pay/domain/po/PayOrder.java b/pay-service/src/main/java/com/hmall/pay/domain/po/PayOrder.java new file mode 100644 index 0000000..b79960a --- /dev/null +++ b/pay-service/src/main/java/com/hmall/pay/domain/po/PayOrder.java @@ -0,0 +1,123 @@ +package com.hmall.pay.domain.po; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 支付订单 + *

+ */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("pay_order") +public class PayOrder implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * id + */ + @TableId(value = "id", type = IdType.ASSIGN_ID) + private Long id; + + /** + * 业务订单号 + */ + private Long bizOrderNo; + + /** + * 支付单号 + */ + private Long payOrderNo; + + /** + * 支付用户id + */ + private Long bizUserId; + + /** + * 支付渠道编码 + */ + private String payChannelCode; + + /** + * 支付金额,单位分 + */ + private Integer amount; + + /** + * 支付类型,1:h5,2:小程序,3:公众号,4:扫码,5:余额支付 + */ + private Integer payType; + + /** + * 支付状态,0:待提交,1:待支付,2:支付超时或取消,3:支付成功 + */ + private Integer status; + + /** + * 拓展字段,用于传递不同渠道单独处理的字段 + */ + private String expandJson; + + /** + * 第三方返回业务码 + */ + private String resultCode; + + /** + * 第三方返回提示信息 + */ + private String resultMsg; + + /** + * 支付成功时间 + */ + private LocalDateTime paySuccessTime; + + /** + * 支付超时时间 + */ + private LocalDateTime payOverTime; + + /** + * 支付二维码链接 + */ + private String qrCodeUrl; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + /** + * 创建人 + */ + private Long creater; + + /** + * 更新人 + */ + private Long updater; + + /** + * 逻辑删除 + */ + private Boolean isDelete; + + +} diff --git a/pay-service/src/main/java/com/hmall/pay/domain/po/po/Address.java b/pay-service/src/main/java/com/hmall/pay/domain/po/po/Address.java new file mode 100644 index 0000000..f4dd497 --- /dev/null +++ b/pay-service/src/main/java/com/hmall/pay/domain/po/po/Address.java @@ -0,0 +1,77 @@ +package com.hmall.pay.domain.po.po; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +/** + *

+ * + *

+ * + * @author 虎哥 + * @since 2023-05-05 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("address") +public class Address implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * 用户ID + */ + private Long userId; + + /** + * 省 + */ + private String province; + + /** + * 市 + */ + private String city; + + /** + * 县/区 + */ + private String town; + + /** + * 手机 + */ + private String mobile; + + /** + * 详细地址 + */ + private String street; + + /** + * 联系人 + */ + private String contact; + + /** + * 是否是默认 1默认 0否 + */ + private Integer isDefault; + + /** + * 备注 + */ + private String notes; + + +} diff --git a/pay-service/src/main/java/com/hmall/pay/domain/po/po/Cart.java b/pay-service/src/main/java/com/hmall/pay/domain/po/po/Cart.java new file mode 100644 index 0000000..e44e6b6 --- /dev/null +++ b/pay-service/src/main/java/com/hmall/pay/domain/po/po/Cart.java @@ -0,0 +1,81 @@ +package com.hmall.pay.domain.po.po; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 订单详情表 + *

+ * + * @author 虎哥 + * @since 2023-05-05 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("cart") +public class Cart implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 购物车条目id + */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * 用户id + */ + private Long userId; + + /** + * sku商品id + */ + private Long itemId; + + /** + * 购买数量 + */ + private Integer num; + + /** + * 商品标题 + */ + private String name; + + /** + * 商品动态属性键值集 + */ + private String spec; + + /** + * 价格,单位:分 + */ + private Integer price; + + /** + * 商品图片 + */ + private String image; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + +} diff --git a/pay-service/src/main/java/com/hmall/pay/domain/po/po/Item.java b/pay-service/src/main/java/com/hmall/pay/domain/po/po/Item.java new file mode 100644 index 0000000..eca750c --- /dev/null +++ b/pay-service/src/main/java/com/hmall/pay/domain/po/po/Item.java @@ -0,0 +1,113 @@ +package com.hmall.pay.domain.po.po; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 商品表 + *

+ * + * @author 虎哥 + * @since 2023-05-05 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("item") +public class Item implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 商品id + */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * SKU名称 + */ + private String name; + + /** + * 价格(分) + */ + private Integer price; + + /** + * 库存数量 + */ + private Integer stock; + + /** + * 商品图片 + */ + private String image; + + /** + * 类目名称 + */ + private String category; + + /** + * 品牌名称 + */ + private String brand; + + /** + * 规格 + */ + private String spec; + + /** + * 销量 + */ + private Integer sold; + + /** + * 评论数 + */ + private Integer commentCount; + + /** + * 是否是推广广告,true/false + */ + @TableField("isAD") + private Boolean isAD; + + /** + * 商品状态 1-正常,2-下架,3-删除 + */ + private Integer status; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + /** + * 创建人 + */ + private Long creater; + + /** + * 修改人 + */ + private Long updater; + + +} diff --git a/pay-service/src/main/java/com/hmall/pay/domain/po/po/Order.java b/pay-service/src/main/java/com/hmall/pay/domain/po/po/Order.java new file mode 100644 index 0000000..4f95df2 --- /dev/null +++ b/pay-service/src/main/java/com/hmall/pay/domain/po/po/Order.java @@ -0,0 +1,91 @@ +package com.hmall.pay.domain.po.po; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * + *

+ * + * @author 虎哥 + * @since 2023-05-05 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("`order`") +public class Order implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 订单id + */ + @TableId(value = "id", type = IdType.ASSIGN_ID) + private Long id; + + /** + * 总金额,单位为分 + */ + private Integer totalFee; + + /** + * 支付类型,1、支付宝,2、微信,3、扣减余额 + */ + private Integer paymentType; + + /** + * 用户id + */ + private Long userId; + + /** + * 订单的状态,1、未付款 2、已付款,未发货 3、已发货,未确认 4、确认收货,交易成功 5、交易取消,订单关闭 6、交易结束,已评价 + */ + private Integer status; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 支付时间 + */ + private LocalDateTime payTime; + + /** + * 发货时间 + */ + private LocalDateTime consignTime; + + /** + * 交易完成时间 + */ + private LocalDateTime endTime; + + /** + * 交易关闭时间 + */ + private LocalDateTime closeTime; + + /** + * 评价时间 + */ + private LocalDateTime commentTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + +} diff --git a/pay-service/src/main/java/com/hmall/pay/domain/po/po/OrderDetail.java b/pay-service/src/main/java/com/hmall/pay/domain/po/po/OrderDetail.java new file mode 100644 index 0000000..c7f4943 --- /dev/null +++ b/pay-service/src/main/java/com/hmall/pay/domain/po/po/OrderDetail.java @@ -0,0 +1,81 @@ +package com.hmall.pay.domain.po.po; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 订单详情表 + *

+ * + * @author 虎哥 + * @since 2023-05-05 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("order_detail") +public class OrderDetail implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 订单详情id + */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * 订单id + */ + private Long orderId; + + /** + * sku商品id + */ + private Long itemId; + + /** + * 购买数量 + */ + private Integer num; + + /** + * 商品标题 + */ + private String name; + + /** + * 商品动态属性键值集 + */ + private String spec; + + /** + * 价格,单位:分 + */ + private Integer price; + + /** + * 商品图片 + */ + private String image; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + +} diff --git a/pay-service/src/main/java/com/hmall/pay/domain/po/po/OrderLogistics.java b/pay-service/src/main/java/com/hmall/pay/domain/po/po/OrderLogistics.java new file mode 100644 index 0000000..a1de9fd --- /dev/null +++ b/pay-service/src/main/java/com/hmall/pay/domain/po/po/OrderLogistics.java @@ -0,0 +1,86 @@ +package com.hmall.pay.domain.po.po; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * + *

+ * + * @author 虎哥 + * @since 2023-05-05 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("order_logistics") +public class OrderLogistics implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 订单id,与订单表一对一 + */ + @TableId(value = "order_id", type = IdType.INPUT) + private Long orderId; + + /** + * 物流单号 + */ + private String logisticsNumber; + + /** + * 物流公司名称 + */ + private String logisticsCompany; + + /** + * 收件人 + */ + private String contact; + + /** + * 收件人手机号码 + */ + private String mobile; + + /** + * 省 + */ + private String province; + + /** + * 市 + */ + private String city; + + /** + * 区 + */ + private String town; + + /** + * 街道 + */ + private String street; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + +} diff --git a/pay-service/src/main/java/com/hmall/pay/domain/po/po/User.java b/pay-service/src/main/java/com/hmall/pay/domain/po/po/User.java new file mode 100644 index 0000000..83342ec --- /dev/null +++ b/pay-service/src/main/java/com/hmall/pay/domain/po/po/User.java @@ -0,0 +1,66 @@ +package com.hmall.pay.domain.po.po; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.hmall.enums.UserStatus; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 用户表 + *

+ * + * @author 虎哥 + * @since 2023-05-05 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("user") +public class User implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * 用户名 + */ + private String username; + + /** + * 密码,加密存储 + */ + private String password; + + /** + * 注册手机号 + */ + private String phone; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + private LocalDateTime updateTime; + + /** + * 使用状态(1正常 2冻结) + */ + private UserStatus status; + + /** + * 账户余额 + */ + private Integer balance; + + +} diff --git a/pay-service/src/main/java/com/hmall/pay/domain/vo/PayOrderVO.java b/pay-service/src/main/java/com/hmall/pay/domain/vo/PayOrderVO.java new file mode 100644 index 0000000..5523cd6 --- /dev/null +++ b/pay-service/src/main/java/com/hmall/pay/domain/vo/PayOrderVO.java @@ -0,0 +1,49 @@ +package com.hmall.pay.domain.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + *

+ * 支付订单 + *

+ */ +@Data +@ApiModel(description = "支付单vo实体") +public class PayOrderVO { + @ApiModelProperty("id") + private Long id; + @ApiModelProperty("业务订单号") + private Long bizOrderNo; + @ApiModelProperty("支付单号") + private Long payOrderNo; + @ApiModelProperty("支付用户id") + private Long bizUserId; + @ApiModelProperty("支付渠道编码") + private String payChannelCode; + @ApiModelProperty("支付金额,单位分") + private Integer amount; + @ApiModelProperty("付类型,1:h5,2:小程序,3:公众号,4:扫码,5:余额支付") + private Integer payType; + @ApiModelProperty("付状态,0:待提交,1:待支付,2:支付超时或取消,3:支付成功") + private Integer status; + @ApiModelProperty("拓展字段,用于传递不同渠道单独处理的字段") + private String expandJson; + @ApiModelProperty("第三方返回业务码") + private String resultCode; + @ApiModelProperty("第三方返回提示信息") + private String resultMsg; + @ApiModelProperty("支付成功时间") + private LocalDateTime paySuccessTime; + @ApiModelProperty("支付超时时间") + private LocalDateTime payOverTime; + @ApiModelProperty("支付二维码链接") + private String qrCodeUrl; + @ApiModelProperty("创建时间") + private LocalDateTime createTime; + @ApiModelProperty("更新时间") + private LocalDateTime updateTime; +} diff --git a/pay-service/src/main/java/com/hmall/pay/enums/PayChannel.java b/pay-service/src/main/java/com/hmall/pay/enums/PayChannel.java new file mode 100644 index 0000000..3d89a06 --- /dev/null +++ b/pay-service/src/main/java/com/hmall/pay/enums/PayChannel.java @@ -0,0 +1,25 @@ +package com.hmall.pay.enums; + +import cn.hutool.core.util.StrUtil; +import lombok.Getter; + +@Getter +public enum PayChannel { + wxPay("微信支付"), + aliPay("支付宝支付"), + balance("余额支付"), + ; + + private final String desc; + + PayChannel(String desc) { + this.desc = desc; + } + + public static String desc(String value){ + if (StrUtil.isBlank(value)) { + return ""; + } + return PayChannel.valueOf(value).getDesc(); + } +} diff --git a/pay-service/src/main/java/com/hmall/pay/enums/PayStatus.java b/pay-service/src/main/java/com/hmall/pay/enums/PayStatus.java new file mode 100644 index 0000000..e64e184 --- /dev/null +++ b/pay-service/src/main/java/com/hmall/pay/enums/PayStatus.java @@ -0,0 +1,27 @@ +package com.hmall.pay.enums; + +import lombok.Getter; + +@Getter +public enum PayStatus { + NOT_COMMIT(0, "未提交"), + WAIT_BUYER_PAY(1, "待支付"), + TRADE_CLOSED(2, "已关闭"), + TRADE_SUCCESS(3, "支付成功"), + TRADE_FINISHED(3, "支付成功"), + ; + private final int value; + private final String desc; + + PayStatus(int value, String desc) { + this.value = value; + this.desc = desc; + } + + public boolean equalsValue(Integer value){ + if (value == null) { + return false; + } + return getValue() == value; + } +} \ No newline at end of file diff --git a/pay-service/src/main/java/com/hmall/pay/enums/PayType.java b/pay-service/src/main/java/com/hmall/pay/enums/PayType.java new file mode 100644 index 0000000..af68b9b --- /dev/null +++ b/pay-service/src/main/java/com/hmall/pay/enums/PayType.java @@ -0,0 +1,27 @@ +package com.hmall.pay.enums; + +import lombok.Getter; + +@Getter +public enum PayType{ + JSAPI(1, "网页支付JS"), + MINI_APP(2, "小程序支付"), + APP(3, "APP支付"), + NATIVE(4, "扫码支付"), + BALANCE(5, "余额支付"), + ; + private final int value; + private final String desc; + + PayType(int value, String desc) { + this.value = value; + this.desc = desc; + } + + public boolean equalsValue(Integer value){ + if (value == null) { + return false; + } + return getValue() == value; + } +} diff --git a/pay-service/src/main/java/com/hmall/pay/mapper/PayOrderMapper.java b/pay-service/src/main/java/com/hmall/pay/mapper/PayOrderMapper.java new file mode 100644 index 0000000..e29431e --- /dev/null +++ b/pay-service/src/main/java/com/hmall/pay/mapper/PayOrderMapper.java @@ -0,0 +1,17 @@ +package com.hmall.pay.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.hmall.pay.domain.po.PayOrder; + + +/** + *

+ * 支付订单 Mapper 接口 + *

+ * + * @author 虎哥 + * @since 2023-05-16 + */ +public interface PayOrderMapper extends BaseMapper { + +} diff --git a/pay-service/src/main/java/com/hmall/pay/service/IPayOrderService.java b/pay-service/src/main/java/com/hmall/pay/service/IPayOrderService.java new file mode 100644 index 0000000..cb653f5 --- /dev/null +++ b/pay-service/src/main/java/com/hmall/pay/service/IPayOrderService.java @@ -0,0 +1,22 @@ +package com.hmall.pay.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.hmall.pay.domain.dto.PayApplyDTO; +import com.hmall.pay.domain.dto.PayOrderFormDTO; +import com.hmall.pay.domain.po.PayOrder; + + +/** + *

+ * 支付订单 服务类 + *

+ * + * @author 虎哥 + * @since 2023-05-16 + */ +public interface IPayOrderService extends IService { + + String applyPayOrder(PayApplyDTO applyDTO); + + void tryPayOrderByBalance(PayOrderFormDTO payOrderFormDTO); +} diff --git a/pay-service/src/main/java/com/hmall/pay/service/impl/PayOrderServiceImpl.java b/pay-service/src/main/java/com/hmall/pay/service/impl/PayOrderServiceImpl.java new file mode 100644 index 0000000..cd3f6b6 --- /dev/null +++ b/pay-service/src/main/java/com/hmall/pay/service/impl/PayOrderServiceImpl.java @@ -0,0 +1,131 @@ +package com.hmall.pay.service.impl; + +import com.baomidou.mybatisplus.core.toolkit.IdWorker; +import com.baomidou.mybatisplus.core.toolkit.StringUtils; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; + +import com.hmall.api.client.TradeClient; +import com.hmall.api.client.UserClient; +import com.hmall.common.exception.BizIllegalException; +import com.hmall.common.utils.BeanUtils; +import com.hmall.common.utils.UserContext; +import com.hmall.enums.PayStatus; +import com.hmall.pay.domain.dto.PayApplyDTO; +import com.hmall.pay.domain.dto.PayOrderFormDTO; +import com.hmall.pay.domain.po.PayOrder; +import com.hmall.pay.mapper.PayOrderMapper; +import com.hmall.pay.service.IPayOrderService; +import com.hmall.service.IOrderService; +import com.hmall.service.IUserService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDateTime; + +/** + *

+ * 支付订单 服务实现类 + *

+ * + * @author 虎哥 + * @since 2023-05-16 + */ +@Service +@RequiredArgsConstructor +public class PayOrderServiceImpl extends ServiceImpl implements IPayOrderService { + + private final UserClient userClient; + + private final TradeClient tradeClient; + + @Override + public String applyPayOrder(PayApplyDTO applyDTO) { + // 1.幂等性校验 + PayOrder payOrder = checkIdempotent(applyDTO); + // 2.返回结果 + return payOrder.getId().toString(); + } + + @Override + @Transactional + public void tryPayOrderByBalance(PayOrderFormDTO payOrderFormDTO) { + // 1.查询支付单 + PayOrder po = getById(payOrderFormDTO.getId()); + // 2.判断状态 + if(!PayStatus.WAIT_BUYER_PAY.equalsValue(po.getStatus())){ + // 订单不是未支付,状态异常 + throw new BizIllegalException("交易已支付或关闭!"); + } + // 3.尝试扣减余额 + userClient.deductMoney(payOrderFormDTO.getPw(), po.getAmount()); + // 4.修改支付单状态 + boolean success = markPayOrderSuccess(payOrderFormDTO.getId(), LocalDateTime.now()); + if (!success) { + throw new BizIllegalException("交易已支付或关闭!"); + } + // 5.修改订单状态 + tradeClient.markOrderPaySuccess(po.getBizOrderNo()); + } + + public boolean markPayOrderSuccess(Long id, LocalDateTime successTime) { + return lambdaUpdate() + .set(PayOrder::getStatus, PayStatus.TRADE_SUCCESS.getValue()) + .set(PayOrder::getPaySuccessTime, successTime) + .eq(PayOrder::getId, id) + // 支付状态的乐观锁判断 + .in(PayOrder::getStatus, PayStatus.NOT_COMMIT.getValue(), PayStatus.WAIT_BUYER_PAY.getValue()) + .update(); + } + + + private PayOrder checkIdempotent(PayApplyDTO applyDTO) { + // 1.首先查询支付单 + PayOrder oldOrder = queryByBizOrderNo(applyDTO.getBizOrderNo()); + // 2.判断是否存在 + if (oldOrder == null) { + // 不存在支付单,说明是第一次,写入新的支付单并返回 + PayOrder payOrder = buildPayOrder(applyDTO); + payOrder.setPayOrderNo(IdWorker.getId()); + save(payOrder); + return payOrder; + } + // 3.旧单已经存在,判断是否支付成功 + if (PayStatus.TRADE_SUCCESS.equalsValue(oldOrder.getStatus())) { + // 已经支付成功,抛出异常 + throw new BizIllegalException("订单已经支付!"); + } + // 4.旧单已经存在,判断是否已经关闭 + if (PayStatus.TRADE_CLOSED.equalsValue(oldOrder.getStatus())) { + // 已经关闭,抛出异常 + throw new BizIllegalException("订单已关闭"); + } + // 5.旧单已经存在,判断支付渠道是否一致 + if (!StringUtils.equals(oldOrder.getPayChannelCode(), applyDTO.getPayChannelCode())) { + // 支付渠道不一致,需要重置数据,然后重新申请支付单 + PayOrder payOrder = buildPayOrder(applyDTO); + payOrder.setId(oldOrder.getId()); + payOrder.setQrCodeUrl(""); + updateById(payOrder); + payOrder.setPayOrderNo(oldOrder.getPayOrderNo()); + return payOrder; + } + // 6.旧单已经存在,且可能是未支付或未提交,且支付渠道一致,直接返回旧数据 + return oldOrder; + } + + private PayOrder buildPayOrder(PayApplyDTO payApplyDTO) { + // 1.数据转换 + PayOrder payOrder = BeanUtils.toBean(payApplyDTO, PayOrder.class); + // 2.初始化数据 + payOrder.setPayOverTime(LocalDateTime.now().plusMinutes(120L)); + payOrder.setStatus(PayStatus.WAIT_BUYER_PAY.getValue()); + payOrder.setBizUserId(UserContext.getUser()); + return payOrder; + } + public PayOrder queryByBizOrderNo(Long bizOrderNo) { + return lambdaQuery() + .eq(PayOrder::getBizOrderNo, bizOrderNo) + .one(); + } +} diff --git a/pay-service/src/main/resources/application-dev.yaml b/pay-service/src/main/resources/application-dev.yaml new file mode 100644 index 0000000..a6fa71e --- /dev/null +++ b/pay-service/src/main/resources/application-dev.yaml @@ -0,0 +1,4 @@ +hm: + db: + host: mysql + pw: 123 \ No newline at end of file diff --git a/pay-service/src/main/resources/application-local.yaml b/pay-service/src/main/resources/application-local.yaml new file mode 100644 index 0000000..e310359 --- /dev/null +++ b/pay-service/src/main/resources/application-local.yaml @@ -0,0 +1,4 @@ +hm: + db: + host: 124.71.159.195 # 修改为你自己的虚拟机IP地址 + pw: 123456 # 修改为docker中的MySQL密码 \ No newline at end of file diff --git a/pay-service/src/main/resources/application.yaml b/pay-service/src/main/resources/application.yaml new file mode 100644 index 0000000..2815d9c --- /dev/null +++ b/pay-service/src/main/resources/application.yaml @@ -0,0 +1,51 @@ +server: + port: 8086 +spring: + application: + name: pay-service + cloud: + nacos: + server-addr: 124.71.159.195:8848 # nacos地址 + profiles: + active: local + datasource: + url: jdbc:mysql://${hm.db.host}:3307/hm-pay?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai + driver-class-name: com.mysql.cj.jdbc.Driver + username: root + password: ${hm.db.pw} +mybatis-plus: + configuration: + default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler + global-config: + db-config: + update-strategy: not_null + id-type: auto +logging: + level: + com.hmall: debug + pattern: + dateformat: HH:mm:ss:SSS + file: + path: "logs/${spring.application.name}" +knife4j: + enable: true + openapi: + title: 黑马商城支付服务接口文档 + description: "黑马商城支付服务接口文档" + email: zhangsan@itcast.cn + concat: 宇哥 + url: https://www.itcast.cn + version: v1.0.0 + group: + default: + group-name: default + api-rule: package + api-rule-resources: + - com.hmall.pay.controller + +feign: + httpclient: + enabled: true # 使用 Apache HttpClient(默认关闭) + + +# keytool -genkeypair -alias hmall -keyalg RSA -keypass hmall123 -keystore hmall.jks -storepass hmall123 \ No newline at end of file diff --git a/pom.xml b/pom.xml index e3e704b..fc5f300 100644 --- a/pom.xml +++ b/pom.xml @@ -15,6 +15,8 @@ cart-service user-service hm-api + trade-service + pay-service diff --git a/trade-service/pom.xml b/trade-service/pom.xml new file mode 100644 index 0000000..87258cc --- /dev/null +++ b/trade-service/pom.xml @@ -0,0 +1,67 @@ + + + + hmall + com.heima + 1.0.0 + + 4.0.0 + + trade-service + + + 17 + 17 + + + + com.heima + hm-api + 1.0.0 + + + + com.heima + hm-common + 1.0.0 + + + + org.springframework.boot + spring-boot-starter-web + + + + + mysql + mysql-connector-java + + + + com.baomidou + mybatis-plus-boot-starter + + + com.heima + hm-service + 1.0.0 + compile + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + + \ No newline at end of file diff --git a/trade-service/src/main/java/com/hmall/trade/TradeApplication.java b/trade-service/src/main/java/com/hmall/trade/TradeApplication.java new file mode 100644 index 0000000..de60d85 --- /dev/null +++ b/trade-service/src/main/java/com/hmall/trade/TradeApplication.java @@ -0,0 +1,16 @@ +package com.hmall.trade; + +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.openfeign.EnableFeignClients; + +@MapperScan("com.hmall.trade.mapper") +@EnableFeignClients(basePackages= "com.hmall.api.client") +@SpringBootApplication +public class TradeApplication { + public static void main(String[] args) { + + SpringApplication.run(TradeApplication.class, args); + } +} \ No newline at end of file diff --git a/trade-service/src/main/java/com/hmall/trade/controller/OrderController.java b/trade-service/src/main/java/com/hmall/trade/controller/OrderController.java new file mode 100644 index 0000000..593ce6a --- /dev/null +++ b/trade-service/src/main/java/com/hmall/trade/controller/OrderController.java @@ -0,0 +1,40 @@ +package com.hmall.trade.controller; + +import com.hmall.common.utils.BeanUtils; + +import com.hmall.trade.domain.dto.OrderFormDTO; +import com.hmall.trade.domain.vo.OrderVO; +import com.hmall.trade.service.IOrderService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.apache.ibatis.annotations.Param; +import org.springframework.web.bind.annotation.*; + +@Api(tags = "订单管理接口") +@RestController +@RequestMapping("/orders") +@RequiredArgsConstructor +public class OrderController { + private final IOrderService orderService; + + @ApiOperation("根据id查询订单") + @GetMapping("{id}") + public OrderVO queryOrderById(@Param ("订单id")@PathVariable("id") Long orderId) { + return BeanUtils.copyBean(orderService.getById(orderId), OrderVO.class); + } + + @ApiOperation("创建订单") + @PostMapping + public Long createOrder(@RequestBody OrderFormDTO orderFormDTO){ + return orderService.createOrder(orderFormDTO); + } + + @ApiOperation("标记订单已支付") + @ApiImplicitParam(name = "orderId", value = "订单id", paramType = "path") + @PutMapping("/{orderId}") + public void markOrderPaySuccess(@PathVariable("orderId") Long orderId) { + orderService.markOrderPaySuccess(orderId); + } +} diff --git a/trade-service/src/main/java/com/hmall/trade/domain/dto/OrderFormDTO.java b/trade-service/src/main/java/com/hmall/trade/domain/dto/OrderFormDTO.java new file mode 100644 index 0000000..bc13a4a --- /dev/null +++ b/trade-service/src/main/java/com/hmall/trade/domain/dto/OrderFormDTO.java @@ -0,0 +1,19 @@ +package com.hmall.trade.domain.dto; + +import com.hmall.api.dto.OrderDetailDTO; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +@Data +@ApiModel(description = "交易下单表单实体") +public class OrderFormDTO { + @ApiModelProperty("收货地址id") + private Long addressId; + @ApiModelProperty("支付类型") + private Integer paymentType; + @ApiModelProperty("下单商品列表") + private List details; +} diff --git a/trade-service/src/main/java/com/hmall/trade/domain/po/Order.java b/trade-service/src/main/java/com/hmall/trade/domain/po/Order.java new file mode 100644 index 0000000..948e5e9 --- /dev/null +++ b/trade-service/src/main/java/com/hmall/trade/domain/po/Order.java @@ -0,0 +1,91 @@ +package com.hmall.trade.domain.po; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * + *

+ * + * @author 虎哥 + * @since 2023-05-05 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("`order`") +public class Order implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 订单id + */ + @TableId(value = "id", type = IdType.ASSIGN_ID) + private Long id; + + /** + * 总金额,单位为分 + */ + private Integer totalFee; + + /** + * 支付类型,1、支付宝,2、微信,3、扣减余额 + */ + private Integer paymentType; + + /** + * 用户id + */ + private Long userId; + + /** + * 订单的状态,1、未付款 2、已付款,未发货 3、已发货,未确认 4、确认收货,交易成功 5、交易取消,订单关闭 6、交易结束,已评价 + */ + private Integer status; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 支付时间 + */ + private LocalDateTime payTime; + + /** + * 发货时间 + */ + private LocalDateTime consignTime; + + /** + * 交易完成时间 + */ + private LocalDateTime endTime; + + /** + * 交易关闭时间 + */ + private LocalDateTime closeTime; + + /** + * 评价时间 + */ + private LocalDateTime commentTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + +} diff --git a/trade-service/src/main/java/com/hmall/trade/domain/po/OrderDetail.java b/trade-service/src/main/java/com/hmall/trade/domain/po/OrderDetail.java new file mode 100644 index 0000000..e2a53f7 --- /dev/null +++ b/trade-service/src/main/java/com/hmall/trade/domain/po/OrderDetail.java @@ -0,0 +1,81 @@ +package com.hmall.trade.domain.po; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 订单详情表 + *

+ * + * @author 虎哥 + * @since 2023-05-05 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("order_detail") +public class OrderDetail implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 订单详情id + */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * 订单id + */ + private Long orderId; + + /** + * sku商品id + */ + private Long itemId; + + /** + * 购买数量 + */ + private Integer num; + + /** + * 商品标题 + */ + private String name; + + /** + * 商品动态属性键值集 + */ + private String spec; + + /** + * 价格,单位:分 + */ + private Integer price; + + /** + * 商品图片 + */ + private String image; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + +} diff --git a/trade-service/src/main/java/com/hmall/trade/domain/po/OrderLogistics.java b/trade-service/src/main/java/com/hmall/trade/domain/po/OrderLogistics.java new file mode 100644 index 0000000..2d9885d --- /dev/null +++ b/trade-service/src/main/java/com/hmall/trade/domain/po/OrderLogistics.java @@ -0,0 +1,86 @@ +package com.hmall.trade.domain.po; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * + *

+ * + * @author 虎哥 + * @since 2023-05-05 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("order_logistics") +public class OrderLogistics implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 订单id,与订单表一对一 + */ + @TableId(value = "order_id", type = IdType.INPUT) + private Long orderId; + + /** + * 物流单号 + */ + private String logisticsNumber; + + /** + * 物流公司名称 + */ + private String logisticsCompany; + + /** + * 收件人 + */ + private String contact; + + /** + * 收件人手机号码 + */ + private String mobile; + + /** + * 省 + */ + private String province; + + /** + * 市 + */ + private String city; + + /** + * 区 + */ + private String town; + + /** + * 街道 + */ + private String street; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + +} diff --git a/trade-service/src/main/java/com/hmall/trade/domain/vo/OrderVO.java b/trade-service/src/main/java/com/hmall/trade/domain/vo/OrderVO.java new file mode 100644 index 0000000..18b2a08 --- /dev/null +++ b/trade-service/src/main/java/com/hmall/trade/domain/vo/OrderVO.java @@ -0,0 +1,34 @@ +package com.hmall.trade.domain.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +@ApiModel(description = "订单页面VO") +public class OrderVO { + @ApiModelProperty("订单id") + private Long id; + @ApiModelProperty("总金额,单位为分") + private Integer totalFee; + @ApiModelProperty("支付类型,1、支付宝,2、微信,3、扣减余额") + private Integer paymentType; + @ApiModelProperty("用户id") + private Long userId; + @ApiModelProperty("订单的状态,1、未付款 2、已付款,未发货 3、已发货,未确认 4、确认收货,交易成功 5、交易取消,订单关闭 6、交易结束,已评价") + private Integer status; + @ApiModelProperty("创建时间") + private LocalDateTime createTime; + @ApiModelProperty("支付时间") + private LocalDateTime payTime; + @ApiModelProperty("发货时间") + private LocalDateTime consignTime; + @ApiModelProperty("交易完成时间") + private LocalDateTime endTime; + @ApiModelProperty("交易关闭时间") + private LocalDateTime closeTime; + @ApiModelProperty("评价时间") + private LocalDateTime commentTime; +} diff --git a/trade-service/src/main/java/com/hmall/trade/mapper/OrderDetailMapper.java b/trade-service/src/main/java/com/hmall/trade/mapper/OrderDetailMapper.java new file mode 100644 index 0000000..8669af1 --- /dev/null +++ b/trade-service/src/main/java/com/hmall/trade/mapper/OrderDetailMapper.java @@ -0,0 +1,17 @@ +package com.hmall.trade.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.hmall.trade.domain.po.OrderDetail; + + +/** + *

+ * 订单详情表 Mapper 接口 + *

+ * + * @author 虎哥 + * @since 2023-05-05 + */ +public interface OrderDetailMapper extends BaseMapper { + +} diff --git a/trade-service/src/main/java/com/hmall/trade/mapper/OrderLogisticsMapper.java b/trade-service/src/main/java/com/hmall/trade/mapper/OrderLogisticsMapper.java new file mode 100644 index 0000000..26195b9 --- /dev/null +++ b/trade-service/src/main/java/com/hmall/trade/mapper/OrderLogisticsMapper.java @@ -0,0 +1,17 @@ +package com.hmall.trade.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.hmall.trade.domain.po.OrderLogistics; + + +/** + *

+ * Mapper 接口 + *

+ * + * @author 虎哥 + * @since 2023-05-05 + */ +public interface OrderLogisticsMapper extends BaseMapper { + +} diff --git a/trade-service/src/main/java/com/hmall/trade/mapper/OrderMapper.java b/trade-service/src/main/java/com/hmall/trade/mapper/OrderMapper.java new file mode 100644 index 0000000..9f76033 --- /dev/null +++ b/trade-service/src/main/java/com/hmall/trade/mapper/OrderMapper.java @@ -0,0 +1,17 @@ +package com.hmall.trade.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.hmall.trade.domain.po.Order; + + +/** + *

+ * Mapper 接口 + *

+ * + * @author 虎哥 + * @since 2023-05-05 + */ +public interface OrderMapper extends BaseMapper { + +} diff --git a/trade-service/src/main/java/com/hmall/trade/service/IOrderDetailService.java b/trade-service/src/main/java/com/hmall/trade/service/IOrderDetailService.java new file mode 100644 index 0000000..cd292cc --- /dev/null +++ b/trade-service/src/main/java/com/hmall/trade/service/IOrderDetailService.java @@ -0,0 +1,17 @@ +package com.hmall.trade.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.hmall.trade.domain.po.OrderDetail; + + +/** + *

+ * 订单详情表 服务类 + *

+ * + * @author 虎哥 + * @since 2023-05-05 + */ +public interface IOrderDetailService extends IService { + +} diff --git a/trade-service/src/main/java/com/hmall/trade/service/IOrderLogisticsService.java b/trade-service/src/main/java/com/hmall/trade/service/IOrderLogisticsService.java new file mode 100644 index 0000000..5e8029f --- /dev/null +++ b/trade-service/src/main/java/com/hmall/trade/service/IOrderLogisticsService.java @@ -0,0 +1,17 @@ +package com.hmall.trade.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.hmall.trade.domain.po.OrderLogistics; + + +/** + *

+ * 服务类 + *

+ * + * @author 虎哥 + * @since 2023-05-05 + */ +public interface IOrderLogisticsService extends IService { + +} diff --git a/trade-service/src/main/java/com/hmall/trade/service/IOrderService.java b/trade-service/src/main/java/com/hmall/trade/service/IOrderService.java new file mode 100644 index 0000000..2efc0a1 --- /dev/null +++ b/trade-service/src/main/java/com/hmall/trade/service/IOrderService.java @@ -0,0 +1,21 @@ +package com.hmall.trade.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.hmall.trade.domain.dto.OrderFormDTO; +import com.hmall.trade.domain.po.Order; + + +/** + *

+ * 服务类 + *

+ * + * @author 虎哥 + * @since 2023-05-05 + */ +public interface IOrderService extends IService { + + Long createOrder(OrderFormDTO orderFormDTO); + + void markOrderPaySuccess(Long orderId); +} diff --git a/trade-service/src/main/java/com/hmall/trade/service/impl/OrderDetailServiceImpl.java b/trade-service/src/main/java/com/hmall/trade/service/impl/OrderDetailServiceImpl.java new file mode 100644 index 0000000..865f255 --- /dev/null +++ b/trade-service/src/main/java/com/hmall/trade/service/impl/OrderDetailServiceImpl.java @@ -0,0 +1,21 @@ +package com.hmall.trade.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; + +import com.hmall.trade.domain.po.OrderDetail; +import com.hmall.trade.mapper.OrderDetailMapper; +import com.hmall.trade.service.IOrderDetailService; +import org.springframework.stereotype.Service; + +/** + *

+ * 订单详情表 服务实现类 + *

+ * + * @author 虎哥 + * @since 2023-05-05 + */ +@Service +public class OrderDetailServiceImpl extends ServiceImpl implements IOrderDetailService { + +} diff --git a/trade-service/src/main/java/com/hmall/trade/service/impl/OrderLogisticsServiceImpl.java b/trade-service/src/main/java/com/hmall/trade/service/impl/OrderLogisticsServiceImpl.java new file mode 100644 index 0000000..7a59916 --- /dev/null +++ b/trade-service/src/main/java/com/hmall/trade/service/impl/OrderLogisticsServiceImpl.java @@ -0,0 +1,21 @@ +package com.hmall.trade.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; + +import com.hmall.trade.domain.po.OrderLogistics; +import com.hmall.trade.mapper.OrderLogisticsMapper; +import com.hmall.trade.service.IOrderLogisticsService; +import org.springframework.stereotype.Service; + +/** + *

+ * 服务实现类 + *

+ * + * @author 虎哥 + * @since 2023-05-05 + */ +@Service +public class OrderLogisticsServiceImpl extends ServiceImpl implements IOrderLogisticsService { + +} diff --git a/trade-service/src/main/java/com/hmall/trade/service/impl/OrderServiceImpl.java b/trade-service/src/main/java/com/hmall/trade/service/impl/OrderServiceImpl.java new file mode 100644 index 0000000..3f721aa --- /dev/null +++ b/trade-service/src/main/java/com/hmall/trade/service/impl/OrderServiceImpl.java @@ -0,0 +1,114 @@ +package com.hmall.trade.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.hmall.api.client.CartClient; +import com.hmall.api.client.ItemClient; +import com.hmall.api.dto.ItemDTO; +import com.hmall.api.dto.OrderDetailDTO; +import com.hmall.common.exception.BadRequestException; +import com.hmall.common.utils.UserContext; + + +import com.hmall.trade.domain.dto.OrderFormDTO; +import com.hmall.trade.domain.po.Order; +import com.hmall.trade.domain.po.OrderDetail; +import com.hmall.trade.mapper.OrderMapper; +import com.hmall.trade.service.IOrderDetailService; +import com.hmall.trade.service.IOrderService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +/** + *

+ * 服务实现类 + *

+ * + * @author 虎哥 + * @since 2023-05-05 + */ +@Service +@RequiredArgsConstructor +public class OrderServiceImpl extends ServiceImpl implements IOrderService { + + private final ItemClient itemClient; + private final IOrderDetailService detailService; + private final CartClient cartClient; + + @Override + @Transactional + public Long createOrder(OrderFormDTO orderFormDTO) { + // 1.订单数据 + Order order = new Order(); + // 1.1.查询商品 + List detailDTOS = orderFormDTO.getDetails(); + // 1.2.获取商品id和数量的Map + Map itemNumMap = detailDTOS.stream() + .collect(Collectors.toMap(OrderDetailDTO::getItemId, OrderDetailDTO::getNum)); + Set itemIds = itemNumMap.keySet(); + // 1.3.查询商品 + List items = itemClient.queryItemByIds(itemIds); + if (items == null || items.size() < itemIds.size()) { + throw new BadRequestException("商品不存在"); + } + // 1.4.基于商品价格、购买数量计算商品总价:totalFee + int total = 0; + for (ItemDTO item : items) { + total += item.getPrice() * itemNumMap.get(item.getId()); + } + order.setTotalFee(total); + // 1.5.其它属性 + order.setPaymentType(orderFormDTO.getPaymentType()); + order.setUserId(UserContext.getUser()); + order.setStatus(1); + // 1.6.将Order写入数据库order表中 + save(order); + + // 2.保存订单详情 + List details = buildDetails(order.getId(), items, itemNumMap); + detailService.saveBatch(details); + + // 3.清理购物车商品 + cartClient.deleteCartItemByIds(itemIds); + + // 4.扣减库存 + try { + itemClient.deductStock(detailDTOS); + } catch (Exception e) { + throw new RuntimeException("库存不足!"); + } + return order.getId(); + } + + @Override + public void markOrderPaySuccess(Long orderId) { + Order order = new Order(); + order.setId(orderId); + order.setStatus(2); + order.setPayTime(LocalDateTime.now()); + updateById(order); + } + + private List buildDetails(Long orderId, List items, Map numMap) { + List details = new ArrayList<>(items.size()); + for (ItemDTO item : items) { + OrderDetail detail = new OrderDetail(); + detail.setName(item.getName()); + detail.setSpec(item.getSpec()); + detail.setPrice(item.getPrice()); + detail.setNum(numMap.get(item.getId())); + detail.setItemId(item.getId()); + detail.setImage(item.getImage()); + detail.setOrderId(orderId); + details.add(detail); + } + return details; + } +} diff --git a/trade-service/src/main/resources/application-dev.yaml b/trade-service/src/main/resources/application-dev.yaml new file mode 100644 index 0000000..a6fa71e --- /dev/null +++ b/trade-service/src/main/resources/application-dev.yaml @@ -0,0 +1,4 @@ +hm: + db: + host: mysql + pw: 123 \ No newline at end of file diff --git a/trade-service/src/main/resources/application-local.yaml b/trade-service/src/main/resources/application-local.yaml new file mode 100644 index 0000000..e310359 --- /dev/null +++ b/trade-service/src/main/resources/application-local.yaml @@ -0,0 +1,4 @@ +hm: + db: + host: 124.71.159.195 # 修改为你自己的虚拟机IP地址 + pw: 123456 # 修改为docker中的MySQL密码 \ No newline at end of file diff --git a/trade-service/src/main/resources/application.yaml b/trade-service/src/main/resources/application.yaml new file mode 100644 index 0000000..7e86336 --- /dev/null +++ b/trade-service/src/main/resources/application.yaml @@ -0,0 +1,51 @@ +server: + port: 8085 +spring: + application: + name: trade-service + cloud: + nacos: + server-addr: 124.71.159.195:8848 # nacos地址 + profiles: + active: local + datasource: + url: jdbc:mysql://${hm.db.host}:3307/hm-trade?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai + driver-class-name: com.mysql.cj.jdbc.Driver + username: root + password: ${hm.db.pw} +mybatis-plus: + configuration: + default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler + global-config: + db-config: + update-strategy: not_null + id-type: auto +logging: + level: + com.hmall: debug + pattern: + dateformat: HH:mm:ss:SSS + file: + path: "logs/${spring.application.name}" +knife4j: + enable: true + openapi: + title: 黑马商城交易服务接口文档 + description: "黑马商城交易服务接口文档" + email: zhangsan@itcast.cn + concat: 宇哥 + url: https://www.itcast.cn + version: v1.0.0 + group: + default: + group-name: default + api-rule: package + api-rule-resources: + - com.hmall.trade.controller + +feign: + httpclient: + enabled: true # 使用 Apache HttpClient(默认关闭) + + +# keytool -genkeypair -alias hmall -keyalg RSA -keypass hmall123 -keystore hmall.jks -storepass hmall123 \ No newline at end of file diff --git a/user-service/src/main/resources/application.yaml b/user-service/src/main/resources/application.yaml index c63315f..1c50136 100644 --- a/user-service/src/main/resources/application.yaml +++ b/user-service/src/main/resources/application.yaml @@ -9,7 +9,7 @@ spring: profiles: active: local datasource: - url: jdbc:mysql://${hm.db.host}:3306/hm-user?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai + url: jdbc:mysql://${hm.db.host}:3307/hm-user?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai driver-class-name: com.mysql.cj.jdbc.Driver username: root password: ${hm.db.pw}