Field Type Comment coupon_id decigint(50) NOT NULL 优惠券ID coupon_price decimal(10,2) NULL 优惠券金额 user id bigint(50) NULL 用户ID order id bigint(32)NULL 订单ID is used int(1) NULL 是否使用 0未使用 1已使用 used time timestamp NULL 使用时间 
 
Field Type Comment goods id bigint(50) NOT NULL 主键 goods name varchar(255) NULL 商品名称 goods number int(11) NULL 商品库存 goods_price decimal(10,2) NULL 商品价格 goods desc varchar(255) NULL 商品描述 add time timestamp NULL 添加时间 
 
Field Type Comment order _id bigint(50) NOT NULL 订单ID user _id bigint(50) NULL 用户ID order status int(1) NULL 订单状态 0未确认 1己确认 2已取消 3无效 4退款 pay_status int(1) NULL 支付状态 0未支付 1支付中 2已支付 shipping_status int(1) NULL 发货状态 0未发货 1已发货 2已退货 address varchar(255) NULL 收货地址 consignee varchar(255)NULL 收货人 goods id bigint(50) NULL 商品ID goods number int(11) NULL 商品数量 goods price decimal(10,2) NULL 商品价格 goods amount decimal(10,0) NULL 商品总价 shipping_fee decimal(10,2) NULL 运费 order amount decimal(10,2) NULL 订单价格 coupon_id bigint(50) NULL 优惠券ID coupon_paid decimal(10,2) NULL 优惠券 money_paid decimal(10,2) NULL 已付金额 pay_amount decimal(10,2) NULL 支付金额 add time timestamp NULL 创建时间 
 
Field Type Comment goods id int(11) NOT NULL 商品ID order id varchar(32) NOT NULL 订单ID goods number int(11) NULL 库存数量 log_time datetime NULL 记录时间 
 
Field Type Comment user id bigint(50) NOT NULL 用户ID user_name varchar(255) NULL 用户姓名 user password varchar(255)NULL 用户密码 user mobile varchar(255)NULL 手机号 user score int(11)NULL 积分 user_reg_time timestamp NULL 注册时间 user money decimal(10,0)NULL 用户余额 
 
Field Type Comment Juser id bigint(50) NOT NULL 用户ID order id bigint(50) NOT NULL 订单ID money_log_type int(1) NOT NULL 日志类型 1订单付款 2 订单退款 use money decimal(10,2) NULL 操作金额 create time timestamp NULL 日志时间 
 
Field Type Comment pay_id bigint(50) NOT NULL 支付编号 order id bigint(50) NULL 订单编号 pay_amount decimal(10,2) NULL 支付金额 is_paid int(1) NULL 是否已支付 1否 2是 
 
Field Type Comment id varchar(100) NOT NULL 主键 group _name varchar(100) NULL 生产者组名 msg_topic varchar(100) NULL 消息主题 msg_tag varchar(100) NULL Tag msg_key varchar(100) NULL Key hsg body varchar(500) NULL 消息内容 msg status int(1)NULL 0:未处理;1:已经处理 create time timestamp NOT NULL 记录时间 
 
Field Type Comment msg_id varchar(50) NULL 消息ID group name varchar(100) NOT NULL 消费者组名 msg_tag varchar(100) NOT NULL Tag msg_key varchar(100) NOT NULL Key msg_body varchar(500) NULL 消息体 consumer status int(1) NULL 0:正在处理;1:处理成功;2:处理失败 consumer times int(1)NULL 消费次数 consumer_timestamp timestamp NULL 消费时间 remark varchar(500)NULL 备注 
 
1)用 SQLyong 连接 mysql 数据库
 
保存的连接:localhost  
MySQL Host Address :  如:localhost
用户名:root
密码:root
端口:3306【连接】2)创建 trade 数据库。
 
3)创建 9 个 数据表。
 
/*
SQLyog Ultimate v8.32 
MySQL - 5.5 .49 :  Database - trade
*********************************************************************
*//*! 40101  SET NAMES utf8 */; /*! 40101  SET SQL_MODE = '' */; /*! 40014  SET @OLD_UNIQUE_CHECKS= @@UNIQUE_CHECKS, UNIQUE_CHECKS = 0  */; 
/*! 40014  SET @OLD_FOREIGN_KEY_CHECKS= @@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS = 0  */; 
/*! 40101  SET @OLD_SQL_MODE= @@SQL_MODE, SQL_MODE = 'NO_AUTO_VALUE_ON_ZERO'  */; 
/*! 40111  SET @OLD_SQL_NOTES= @@SQL_NOTES, SQL_NOTES = 0  */; 
CREATE DATABASE /*! 32312  IF NOT EXISTS*/` trade` ! 40100  DEFAULT CHARACTER SET utf8 */; USE ` trade` ; /*Table structure for  table ` trade_coupon` ` trade_coupon` ; CREATE TABLE ` trade_coupon` ( ` coupon_id` ( 50 )  NOT NULL COMMENT '优惠券ID' ,` coupon_price` ( 10,2 )  DEFAULT NULL COMMENT '优惠券金额' ,` user_id` ( 50 )  DEFAULT NULL COMMENT '用户ID' ,` order_id` ( 32 )  DEFAULT NULL COMMENT '订单ID' ,` is_used` ( 1 )  DEFAULT NULL COMMENT '是否使用 0未使用 1已使用' ,` used_time` '使用时间' ,PRIMARY KEY ( ` coupon_id` ) ,KEY ` FK_trade_coupon` ( ` user_id` ) ,KEY ` FK_trade_coupon2` ( ` order_id` ) 
)  ENGINE = InnoDB DEFAULT CHARSET = utf8; /*Data for  the table ` trade_coupon` for  table ` trade_goods` ` trade_goods` ; CREATE TABLE ` trade_goods` ( ` goods_id` ( 50 )  NOT NULL AUTO_INCREMENT,` goods_name` ( 255 )  DEFAULT NULL COMMENT '商品名称' ,` goods_number` ( 11 )  DEFAULT NULL COMMENT '商品库存' ,` goods_price` ( 10,2 )  DEFAULT NULL COMMENT '商品价格' ,` goods_desc` ( 255 )  DEFAULT NULL COMMENT '商品描述' ,` add_time` '添加时间' ,PRIMARY KEY ( ` goods_id` ) 
)  ENGINE = InnoDB AUTO_INCREMENT = 345959443973935105  DEFAULT CHARSET = utf8; /*Data for  the table ` trade_goods` ` trade_goods` ( ` goods_id` ` goods_name` ` goods_number` ` goods_price` ` goods_desc` ` add_time` )  values ( 345959443973935104 ,'华为P30' ,999,'5000.00' ,'夜间拍照更美' ,'2019-07-09 20:38:00' ) ; /*Table structure for  table ` trade_goods_number_log` ` trade_goods_number_log` ; CREATE TABLE ` trade_goods_number_log` ( ` goods_id` ( 50 )  NOT NULL COMMENT '商品ID' ,` order_id` ( 50 )  NOT NULL COMMENT '订单ID' ,` goods_number` ( 11 )  DEFAULT NULL COMMENT '库存数量' ,` log_time` ( ` goods_id` ` order_id` ) ,KEY ` FK_trade_goods_number_log2` ( ` order_id` ) 
)  ENGINE = InnoDB DEFAULT CHARSET = utf8; /*Data for  the table ` trade_goods_number_log` for  table ` trade_mq_consumer_log` ` trade_mq_consumer_log` ; CREATE TABLE ` trade_mq_consumer_log` ( ` msg_id` ( 50 )  DEFAULT NULL,` group_name` ( 100 )  NOT NULL,` msg_tag` ( 100 )  NOT NULL,` msg_key` ( 100 )  NOT NULL,` msg_body` ( 500 )  DEFAULT NULL,` consumer_status` ( 1 )  DEFAULT NULL COMMENT '0:正在处理;1:处理成功;2:处理失败' ,` consumer_times` ( 1 )  DEFAULT NULL,` consumer_timestamp` ` remark` ( 500 )  DEFAULT NULL,PRIMARY KEY ( ` group_name` ` msg_tag` ` msg_key` ) 
)  ENGINE = InnoDB DEFAULT CHARSET = utf8; /*Data for  the table ` trade_mq_consumer_log` for  table ` trade_mq_producer_temp` ` trade_mq_producer_temp` ; CREATE TABLE ` trade_mq_producer_temp` ( ` id ` ( 100 )  NOT NULL,` group_name` ( 100 )  DEFAULT NULL,` msg_topic` ( 100 )  DEFAULT NULL,` msg_tag` ( 100 )  DEFAULT NULL,` msg_key` ( 100 )  DEFAULT NULL,` msg_body` ( 500 )  DEFAULT NULL,` msg_status` ( 1 )  DEFAULT NULL COMMENT '0:未处理;1:已经处理' ,` create_time` ( ` id ` ) 
)  ENGINE = InnoDB DEFAULT CHARSET = utf8; /*Data for  the table ` trade_mq_producer_temp` for  table ` trade_order` ` trade_order` ; CREATE TABLE ` trade_order` ( ` order_id` ( 50 )  NOT NULL COMMENT '订单ID' ,` user_id` ( 50 )  DEFAULT NULL COMMENT '用户ID' ,` order_status` ( 1 )  DEFAULT NULL COMMENT '订单状态 0未确认 1已确认 2已取消 3无效 4退款' ,` pay_status` ( 1 )  DEFAULT NULL COMMENT '支付状态 0未支付 1支付中 2已支付' ,` shipping_status` ( 1 )  DEFAULT NULL COMMENT '发货状态 0未发货 1已发货 2已收货' ,` address` ( 255 )  DEFAULT NULL COMMENT '收货地址' ,` consignee` ( 255 )  DEFAULT NULL COMMENT '收货人' ,` goods_id` ( 50 )  DEFAULT NULL COMMENT '商品ID' ,` goods_number` ( 11 )  DEFAULT NULL COMMENT '商品数量' ,` goods_price` ( 10,2 )  DEFAULT NULL COMMENT '商品价格' ,` goods_amount` ( 10,0 )  DEFAULT NULL COMMENT '商品总价' ,` shipping_fee` ( 10,2 )  DEFAULT NULL COMMENT '运费' ,` order_amount` ( 10,2 )  DEFAULT NULL COMMENT '订单价格' ,` coupon_id` ( 50 )  DEFAULT NULL COMMENT '优惠券ID' ,` coupon_paid` ( 10,2 )  DEFAULT NULL COMMENT '优惠券' ,` money_paid` ( 10,2 )  DEFAULT NULL COMMENT '已付金额' ,` pay_amount` ( 10,2 )  DEFAULT NULL COMMENT '支付金额' ,` add_time` '创建时间' ,` confirm_time` '订单确认时间' ,` pay_time` '支付时间' ,PRIMARY KEY ( ` order_id` ) ,KEY ` FK_trade_order` ( ` user_id` ) ,KEY ` FK_trade_order2` ( ` goods_id` ) ,KEY ` FK_trade_order3` ( ` coupon_id` ) 
)  ENGINE = InnoDB DEFAULT CHARSET = utf8; /*Data for  the table ` trade_order` for  table ` trade_pay` ` trade_pay` ; CREATE TABLE ` trade_pay` ( ` pay_id` ( 50 )  NOT NULL COMMENT '支付编号' ,` order_id` ( 50 )  DEFAULT NULL COMMENT '订单编号' ,` pay_amount` ( 10,2 )  DEFAULT NULL COMMENT '支付金额' ,` is_paid` ( 1 )  DEFAULT NULL COMMENT '是否已支付 1否 2是' ,PRIMARY KEY ( ` pay_id` ) ,KEY ` FK_trade_pay` ( ` order_id` ) 
)  ENGINE = InnoDB DEFAULT CHARSET = utf8; /*Data for  the table ` trade_pay` for  table ` trade_user` ` trade_user` ; CREATE TABLE ` trade_user` ( ` user_id` ( 50 )  NOT NULL AUTO_INCREMENT COMMENT '用户ID' ,` user_name` ( 255 )  DEFAULT NULL COMMENT '用户姓名' ,` user_password` ( 255 )  DEFAULT NULL COMMENT '用户密码' ,` user_mobile` ( 255 )  DEFAULT NULL COMMENT '手机号' ,` user_score` ( 11 )  DEFAULT NULL COMMENT '积分' ,` user_reg_time` '注册时间' ,` user_money` ( 10,0 )  DEFAULT NULL COMMENT '用户余额' ,PRIMARY KEY ( ` user_id` ) 
)  ENGINE = InnoDB AUTO_INCREMENT = 345963634385633281  DEFAULT CHARSET = utf8; /*Data for  the table ` trade_user` ` trade_user` ( ` user_id` ` user_name` ` user_password` ` user_mobile` ` user_score` ` user_reg_time` ` user_money` )  values ( 345963634385633280 ,'刘备' ,'123L' ,'18888888888L' ,100,'2019-07-09 13:37:03' ,'900' ) ; /*Table structure for  table ` trade_user_money_log` ` trade_user_money_log` ; CREATE TABLE ` trade_user_money_log` ( ` user_id` ( 50 )  NOT NULL COMMENT '用户ID' ,` order_id` ( 50 )  NOT NULL COMMENT '订单ID' ,` money_log_type` ( 1 )  NOT NULL COMMENT '日志类型 1订单付款 2 订单退款' ,` use_money` ( 10,2 )  DEFAULT NULL,` create_time` '日志时间' ,PRIMARY KEY ( ` user_id` ` order_id` ` money_log_type` ) ,KEY ` FK_trade_user_money_log2` ( ` order_id` ) 
)  ENGINE = InnoDB DEFAULT CHARSET = utf8; /*Data for  the table ` trade_user_money_log` ! 40101  SET SQL_MODE = @OLD_SQL_MODE */; 
/*! 40014  SET FOREIGN_KEY_CHECKS = @OLD_FOREIGN_KEY_CHECKS */; 
/*! 40014  SET UNIQUE_CHECKS = @OLD_UNIQUE_CHECKS */; 
/*! 40111  SET SQL_NOTES = @OLD_SQL_NOTES */; 
< ?xml version = "1.0"  encoding = "UTF-8" ?> 
< project xmlns = "http://maven.apache.org/POM/4.0.0" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation= "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" > < modelVersion> 4.0 .0 <> < groupId> com.iteima.shop< /groupId> < artifactId> shop-parent< /artifactId> < packaging> pom< /packaging> < version> 1.0 -SNAPSHOT< /version> < parent> < groupId> org.springframework.boot< /groupId> < artifactId> spring-boot-starter-parent< /artifactId> < version> 2.0 .1.RELEASE< /version> < /parent> < properties> < rocketmq-spring-boot-starter-version> 2.0 .3 <> < /properties> < dependencies> < ! --dubbo--> < dependency> < groupId> com.alibaba.spring.boot< /groupId> < artifactId> dubbo-spring-boot-starter< /artifactId> < version> 2.0 .0 <> < /dependency> < ! --spring-boot-stater--> < dependency> < groupId> org.springframework.boot< /groupId> < artifactId> spring-boot-starter< /artifactId> < exclusions> < exclusion> < artifactId> log4j-to-slf4j< /artifactId> < groupId> org.apache.logging.log4j< /groupId> < /exclusion> < /exclusions> < /dependency> < ! --zookeeper--> < dependency> < groupId> org.apache.zookeeper< /groupId> < artifactId> zookeeper< /artifactId> < version> 3.4 .10 <> < exclusions> < exclusion> < groupId> org.slf4j< /groupId> < artifactId> slf4j-log4j12 <> < /exclusion> < exclusion> < groupId> log4j< /groupId> < artifactId> log4j< /artifactId> < /exclusion> < /exclusions> < /dependency> < dependency> < groupId> com.101tec< /groupId> < artifactId> zkclient< /artifactId> < version> 0 .9 <> < exclusions> < exclusion> < artifactId> slf4j-log4j12 <> < groupId> org.slf4j< /groupId> < /exclusion> < /exclusions> < /dependency> < ! --Test--> < dependency> < groupId> org.springframework.boot< /groupId> < artifactId> spring-boot-starter-test< /artifactId> < scope> test< /scope> < /dependency> < dependency> < groupId> junit< /groupId> < artifactId> junit< /artifactId> < /dependency> < ! --RocketMQ--> < dependency> < groupId> org.apache.rocketmq< /groupId> < artifactId> rocketmq-spring-boot-starter< /artifactId> < version> ${rocketmq-spring-boot-starter-version} < /version> < /dependency> < ! --lombok--> < dependency> < groupId> org.projectlombok< /groupId> < artifactId> lombok< /artifactId> < version> 1.18 .6 <> < /dependency> < /dependencies> < modules> < module> .. /shop-order-web< /module> < module> .. /shop-coupon-service< /module> < module> .. /shop-user-service< /module> < module> .. /shop-order-service< /module> < module> .. /shop-pay-web< /module> < module> .. /shop-pojo< /module> < module> .. /shop-common< /module> < module> .. /shop-api< /module> < module> .. /shop-goods-service< /module> < module> .. /shop-pay-service< /module> < /modules> < build> < plugins> < plugin> < groupId> org.apache.maven.plugins< /groupId> < artifactId> maven-compiler-plugin< /artifactId> < version> 3.7 .0 <> < configuration> < target> 1 .8 <> < source> 1 .8 <> < /configuration> < /plugin> < /plugins> < /build> < /project> 
< ! -- D:\ java-test\ idea2019\ shop\ shop-parent\ pom.xml --> 
< ?xml version = "1.0"  encoding = "UTF-8" ?> 
< project xmlns = "http://maven.apache.org/POM/4.0.0" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation= "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" > < parent> < artifactId> shop-parent< /artifactId> < groupId> com.iteima.shop< /groupId> < version> 1.0 -SNAPSHOT< /version> < relativePath> .. /shop-parent/pom.xml< /relativePath> < /parent> < modelVersion> 4.0 .0 <> < artifactId> shop-api< /artifactId> < dependencies> < dependency> < groupId> com.iteima.shop< /groupId> < artifactId> shop-pojo< /artifactId> < version> 1.0 -SNAPSHOT< /version> < /dependency> < /dependencies> < /project> 
< ! -- D:\ java-test\ idea2019\ shop\ shop-api\ pom.xml --> package com.itheima.api; import  com.itheima.entity.Result; 
import  com.itheima.shop.pojo.TradeCoupon; /*** 优惠券接口*/
public interface ICouponService { /*** 根据ID查询优惠券对象* @param coupouId* @return*/public TradeCoupon findOne( Long coupouId) ; /*** 更细优惠券状态* @param coupon* @return*/Result updateCouponStatus( TradeCoupon coupon) ; 
} package com.itheima.api; import  com.itheima.entity.Result; 
import  com.itheima.shop.pojo.TradeGoods; 
import  com.itheima.shop.pojo.TradeGoodsNumberLog; public interface IGoodsService { /*** 根据ID查询商品对象* @param goodsId* @return*/TradeGoods findOne( Long goodsId) ; /*** 扣减库存* @param goodsNumberLog* @return*/Result reduceGoodsNum( TradeGoodsNumberLog goodsNumberLog) ; 
} package com.itheima.api; import  com.itheima.entity.Result; 
import  com.itheima.shop.pojo.TradeOrder; public interface IOrderService { /*** 下单接口* @param order* @return*/public Result confirmOrder( TradeOrder order) ; } package com.itheima.api; import  com.itheima.entity.Result; 
import  com.itheima.shop.pojo.TradePay; 
import  org.apache.rocketmq.client.exception.MQBrokerException; 
import  org.apache.rocketmq.client.exception.MQClientException; 
import  org.apache.rocketmq.remoting.exception.RemotingException; public interface IPayService { public Result createPayment( TradePay tradePay) ; public Result callbackPayment( TradePay tradePay)  throws InterruptedException, RemotingException, MQClientException, MQBrokerException; } package com.itheima.api; import  com.itheima.entity.Result; 
import  com.itheima.shop.pojo.TradeUser; 
import  com.itheima.shop.pojo.TradeUserMoneyLog; public interface IUserService { TradeUser findOne( Long userId) ; Result updateMoneyPaid( TradeUserMoneyLog userMoneyLog) ; 
} 
< ?xml version = "1.0"  encoding = "UTF-8" ?> 
< project xmlns = "http://maven.apache.org/POM/4.0.0" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation= "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" > < parent> < artifactId> shop-parent< /artifactId> < groupId> com.iteima.shop< /groupId> < version> 1.0 -SNAPSHOT< /version> < relativePath> .. /shop-parent/pom.xml< /relativePath> < /parent> < modelVersion> 4.0 .0 <> < artifactId> shop-common< /artifactId> < /project> 
< ! -- D:\ java-test\ idea2019\ shop\ shop-common\ pom.xml --> package com.itheima.constant; /*** @author Think*/public enum ShopCode { //正确SHOP_SUCCESS( true, 1 , "正确" ) ,//错误SHOP_FAIL( false, 0 , "错误" ) ,//付款SHOP_USER_MONEY_PAID( true, 1 , "付款" ) ,//退款SHOP_USER_MONEY_REFUND( true, 2 , "退款" ) ,//订单未确认SHOP_ORDER_NO_CONFIRM( false, 0 , "订单未确认" ) ,//订单已确认SHOP_ORDER_CONFIRM( true, 1 , "订单已经确认" ) ,//订单已取消SHOP_ORDER_CANCEL( false, 2 , "订单已取消" ) ,//订单已取消SHOP_ORDER_INVALID( false, 3 , "订单无效" ) ,//订单已取消SHOP_ORDER_RETURNED( false, 4 , "订单已退货" ) ,//订单已付款SHOP_ORDER_PAY_STATUS_NO_PAY( true,0,"订单未付款" ) ,//订单已付款SHOP_ORDER_PAY_STATUS_PAYING( true,1,"订单正在付款" ) ,//订单已付款SHOP_ORDER_PAY_STATUS_IS_PAY( true,2,"订单已付款" ) ,//消息正在处理SHOP_MQ_MESSAGE_STATUS_PROCESSING( true, 0 , "消息正在处理" ) ,//消息处理成功SHOP_MQ_MESSAGE_STATUS_SUCCESS( true, 1 , "消息处理成功" ) ,//消息处理失败SHOP_MQ_MESSAGE_STATUS_FAIL( false, 2 , "消息处理失败" ) ,//请求参数有误SHOP_REQUEST_PARAMETER_VALID( false, -1, "请求参数有误" ) ,//优惠券已经使用SHOP_COUPON_ISUSED( true, 1 , "优惠券已经使用" ) ,//优惠券未使用SHOP_COUPON_UNUSED( false, 0 , "优惠券未使用" ) ,//快递运费不正确SHOP_ORDER_STATUS_UPDATE_FAIL( false, 10001 , "订单状态修改失败" ) ,//快递运费不正确SHOP_ORDER_SHIPPINGFEE_INVALID( false, 10002 , "订单运费不正确" ) ,//订单总价格不合法SHOP_ORDERAMOUNT_INVALID( false, 10003 , "订单总价格不正确" ) ,//订单保存失败SHOP_ORDER_SAVE_ERROR( false, 10004 , "订单保存失败" ) ,//订单确认失败SHOP_ORDER_CONFIRM_FAIL( false, 10005 , "订单确认失败" ) ,//商品不存在SHOP_GOODS_NO_EXIST( false, 20001 , "商品不存在" ) ,//订单价格非法SHOP_GOODS_PRICE_INVALID( false, 20002 , "商品价格非法" ) ,//商品库存不足SHOP_GOODS_NUM_NOT_ENOUGH( false, 20003 , "商品库存不足" ) ,//扣减库存失败SHOP_REDUCE_GOODS_NUM_FAIL( false, 20004 , "扣减库存失败" ) ,//库存记录为空SHOP_REDUCE_GOODS_NUM_EMPTY( false, 20005 , "扣减库存失败" ) ,//用户账号不能为空SHOP_USER_IS_NULL( false, 30001 , "用户账号不能为空" ) ,//用户信息不存在SHOP_USER_NO_EXIST( false, 30002 , "用户不存在" ) ,//余额扣减失败SHOP_USER_MONEY_REDUCE_FAIL( false, 30003 , "余额扣减失败" ) ,//已经退款SHOP_USER_MONEY_REFUND_ALREADY( true, 30004 , "订单已经退过款" ) ,//优惠券不不存在SHOP_COUPON_NO_EXIST( false, 40001 , "优惠券不存在" ) ,//优惠券不合法SHOP_COUPON_INVALIED( false, 40002 , "优惠券不合法" ) ,//优惠券使用失败SHOP_COUPON_USE_FAIL( false, 40003 , "优惠券使用失败" ) ,//余额不能小于0SHOP_MONEY_PAID_LESS_ZERO( false, 50001 , "余额不能小于0" ) ,//余额非法SHOP_MONEY_PAID_INVALID( false, 50002 , "余额非法" ) ,//Topic不能为空SHOP_MQ_TOPIC_IS_EMPTY( false, 60001 , "Topic不能为空" ) ,//消息体不能为空SHOP_MQ_MESSAGE_BODY_IS_EMPTY( false, 60002 , "消息体不能为空" ) ,//消息发送失败SHOP_MQ_SEND_MESSAGE_FAIL( false,60003,"消息发送失败" ) ,//支付订单未找到SHOP_PAYMENT_NOT_FOUND( false,70001,"支付订单未找到" ) ,//支付订单已支付SHOP_PAYMENT_IS_PAID( false,70002,"支付订单已支付" ) ,//订单付款失败SHOP_PAYMENT_PAY_ERROR( false,70002,"订单支付失败" ) ; Boolean success; Integer code; String message; ShopCode ( )  { } ShopCode( Boolean success, Integer code, String message)  { this.success =  success; this.code =  code; this.message =  message; } public Boolean getSuccess ( )  { return  success; } public void setSuccess( Boolean success)  { this.success =  success; } public Integer getCode ( )  { return  code; } public void setCode( Integer code)  { this.code =  code; } public String getMessage ( )  { return  message; } public void setMessage( String message)  { this.message =  message; } @Overridepublic String toString ( )  { return  "ShopCode{"  +"success="  + success +", code="  + code +", message='"  + message + '\' ' +'}' ; } 
} package com.itheima.exception; import  com.itheima.constant.ShopCode; 
import  lombok.extern.slf4j.Slf4j; /*** 异常抛出类*/
@Slf4j
public class CastException { public static void cast( ShopCode shopCode)  { log.error( shopCode.toString( )) ; throw new CustomerException( shopCode) ; } 
} package com.itheima.exception; import  com.itheima.constant.ShopCode; /*** 自定义异常*/
public class CustomerException extends RuntimeException{ private ShopCode shopCode; public CustomerException( ShopCode shopCode)  { this.shopCode =  shopCode; } 
} package com.itheima.utils; public class IDWorker { /*** 起始的时间戳*/private final static long START_STMP =  1480166465631L; /*** 每一部分占用的位数*/private final static long SEQUENCE_BIT =  12 ;  //序列号占用的位数private final static long MACHINE_BIT =  5 ;    //机器标识占用的位数private final static long DATACENTER_BIT =  5 ; //数据中心占用的位数/*** 每一部分的最大值*/private final static long MAX_DATACENTER_NUM =  -1L  ^ ( -1L <<  DATACENTER_BIT) ; private final static long MAX_MACHINE_NUM =  -1L  ^ ( -1L <<  MACHINE_BIT) ; private final static long MAX_SEQUENCE =  -1L  ^ ( -1L <<  SEQUENCE_BIT) ; /*** 每一部分向左的位移*/private final static long MACHINE_LEFT =  SEQUENCE_BIT; private final static long DATACENTER_LEFT =  SEQUENCE_BIT + MACHINE_BIT; private final static long TIMESTMP_LEFT =  DATACENTER_LEFT + DATACENTER_BIT; private long datacenterId;   //数据中心private long machineId;      //机器标识private long sequence =  0L;  //序列号private long lastStmp =  -1L; //上一次时间戳public IDWorker( long datacenterId, long machineId)  { if  ( datacenterId >  MAX_DATACENTER_NUM ||  datacenterId <  0 )  { throw new IllegalArgumentException( "datacenterId can't be greater than MAX_DATACENTER_NUM or less than 0" ) ; } if  ( machineId >  MAX_MACHINE_NUM ||  machineId <  0 )  { throw new IllegalArgumentException( "machineId can't be greater than MAX_MACHINE_NUM or less than 0" ) ; } this.datacenterId =  datacenterId; this.machineId =  machineId; } /*** 产生下一个ID** @return*/public synchronized long nextId ( )  { long currStmp =  getNewstmp( ) ; if  ( currStmp <  lastStmp)  { throw new RuntimeException( "Clock moved backwards.  Refusing to generate id" ) ; } if  ( currStmp ==  lastStmp)  { //相同毫秒内,序列号自增sequence =  ( sequence + 1 )  &  MAX_SEQUENCE; //同一毫秒的序列数已经达到最大if  ( sequence ==  0L)  { currStmp =  getNextMill( ) ; } }  else  { //不同毫秒内,序列号置为0sequence =  0L; } lastStmp =  currStmp; return  ( currStmp - START_STMP)  <<  TIMESTMP_LEFT //时间戳部分|  datacenterId <<  DATACENTER_LEFT       //数据中心部分|  machineId <<  MACHINE_LEFT             //机器标识部分|  sequence;                              //序列号部分} private long getNextMill ( )  { long mill =  getNewstmp( ) ; while  ( mill <=  lastStmp)  { mill =  getNewstmp( ) ; } return  mill; } private long getNewstmp ( )  { return  System.currentTimeMillis( ) ; } public static void main( String[ ]  args)  { IDWorker idWorker =  new IDWorker( 2 , 3 ) ; for  ( int i =  0 ;  i <  10 ;  i++)  { System.out.println( idWorker.nextId( )) ; } } } 
< ?xml version = "1.0"  encoding = "UTF-8" ?> 
< project xmlns = "http://maven.apache.org/POM/4.0.0" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation= "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" > < parent> < artifactId> shop-parent< /artifactId> < groupId> com.iteima.shop< /groupId> < version> 1.0 -SNAPSHOT< /version> < relativePath> .. /shop-parent/pom.xml< /relativePath> < /parent> < modelVersion> 4.0 .0 <> < artifactId> shop-coupon-service< /artifactId> < dependencies> < ! --mybatis-springboot--> < dependency> < groupId> org.mybatis.spring.boot< /groupId> < artifactId> mybatis-spring-boot-starter< /artifactId> < version> 1.3 .1 <> < /dependency> < ! -- MySQL连接驱动 --> < dependency> < groupId> mysql< /groupId> < artifactId> mysql-connector-java< /artifactId> < /dependency> < dependency> < groupId> com.iteima.shop< /groupId> < artifactId> shop-api< /artifactId> < version> 1.0 -SNAPSHOT< /version> < /dependency> < dependency> < groupId> com.iteima.shop< /groupId> < artifactId> shop-common< /artifactId> < version> 1.0 -SNAPSHOT< /version> < /dependency> < dependency> < groupId> com.iteima.shop< /groupId> < artifactId> shop-pojo< /artifactId> < version> 1.0 -SNAPSHOT< /version> < /dependency> < /dependencies> < /project> 
< ! -- D:\ java-test\ idea2019\ shop\ shop-coupon-service\ pom.xml --> package com.itheima.shop.mapper; import  com.itheima.shop.pojo.TradeCoupon; 
import  com.itheima.shop.pojo.TradeCouponExample; 
import  org.apache.ibatis.annotations.Mapper; 
import  org.apache.ibatis.annotations.Param; import  java.util.List; @Mapper
public interface TradeCouponMapper { int countByExample( TradeCouponExample example) ; int deleteByExample( TradeCouponExample example) ; int deleteByPrimaryKey( Long couponId) ; int insert( TradeCoupon record) ; int insertSelective( TradeCoupon record) ; List< TradeCoupon>  selectByExample( TradeCouponExample example) ; TradeCoupon selectByPrimaryKey( Long couponId) ; int updateByExampleSelective( @Param( "record" )  TradeCoupon record, @Param( "example" )  TradeCouponExample example) ; int updateByExample( @Param( "record" )  TradeCoupon record, @Param( "example" )  TradeCouponExample example) ; int updateByPrimaryKeySelective( TradeCoupon record) ; int updateByPrimaryKey( TradeCoupon record) ; 
} 
package com.itheima.shop.mq; import  com.alibaba.fastjson.JSON; 
import  com.itheima.constant.ShopCode; 
import  com.itheima.entity.MQEntity; 
import  com.itheima.shop.mapper.TradeCouponMapper; 
import  com.itheima.shop.pojo.TradeCoupon; 
import  lombok.extern.slf4j.Slf4j; 
import  org.apache.rocketmq.common.message.MessageExt; 
import  org.apache.rocketmq.spring.annotation.MessageModel; 
import  org.apache.rocketmq.spring.annotation.RocketMQMessageListener; 
import  org.apache.rocketmq.spring.core.RocketMQListener; 
import  org.springframework.beans.factory.annotation.Autowired; 
import  org.springframework.stereotype.Component; import  java.io.UnsupportedEncodingException; @Slf4j
@Component
@RocketMQMessageListener( topic =  "${mq.order.topic} " , consumerGroup =  "${mq.order.consumer.group.name} " , messageModel =  MessageModel.BROADCASTING) 
public class CancelMQListener implements RocketMQListener< MessageExt>  { @Autowiredprivate TradeCouponMapper couponMapper; @Overridepublic void onMessage( MessageExt message)  { try { //1. 解析消息内容String body =  new String( message.getBody( ) , "UTF-8" ) ; MQEntity mqEntity =  JSON.parseObject( body, MQEntity.class) ; log.info( "接收到消息" ) ; if( mqEntity.getCouponId( ) != null) { //2. 查询优惠券信息TradeCoupon coupon =  couponMapper.selectByPrimaryKey( mqEntity.getCouponId( )) ; //3.更改优惠券状态coupon.setUsedTime( null) ; coupon.setIsUsed( ShopCode.SHOP_COUPON_UNUSED.getCode( )) ; coupon.setOrderId( null) ; couponMapper.updateByPrimaryKey( coupon) ; } log.info( "回退优惠券成功" ) ; }  catch ( UnsupportedEncodingException e)  { e.printStackTrace( ) ; log.error( "回退优惠券失败" ) ; } } 
} package com.itheima.shop.service.impl; import  com.alibaba.dubbo.config.annotation.Service; 
import  com.itheima.api.ICouponService; 
import  com.itheima.constant.ShopCode; 
import  com.itheima.entity.Result; 
import  com.itheima.exception.CastException; 
import  com.itheima.shop.mapper.TradeCouponMapper; 
import  com.itheima.shop.pojo.TradeCoupon; 
import  org.springframework.beans.factory.annotation.Autowired; 
import  org.springframework.stereotype.Component; @Component
@Service( interfaceClass =  ICouponService.class) 
public class CouponServiceImpl implements ICouponService{ @Autowiredprivate TradeCouponMapper couponMapper; @Overridepublic TradeCoupon findOne( Long coupouId)  { if( coupouId== null) { CastException.cast( ShopCode.SHOP_REQUEST_PARAMETER_VALID) ; } return  couponMapper.selectByPrimaryKey( coupouId) ; } @Overridepublic Result updateCouponStatus( TradeCoupon coupon)  { if( coupon== null|| coupon.getCouponId( ) == null) { CastException.cast( ShopCode.SHOP_REQUEST_PARAMETER_VALID) ; } //更新优惠券状态couponMapper.updateByPrimaryKey( coupon) ; return  new Result( ShopCode.SHOP_SUCCESS.getSuccess( ) ,ShopCode.SHOP_SUCCESS.getMessage( )) ; } 
} package com.itheima.shop; import  com.alibaba.dubbo.spring.boot.annotation.EnableDubboConfiguration; 
import  org.springframework.boot.SpringApplication; 
import  org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication
@EnableDubboConfiguration
public class CouponServiceApplication { public static void main( String[ ]  args)  { SpringApplication.run( CouponServiceApplication.class,args) ; } } < ?xml version = "1.0"  encoding = "UTF-8"  ?> 
< ! DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  "http://mybatis.org/dtd/mybatis-3-mapper.dtd"  > 
< mapper namespace = "com.itheima.shop.mapper.TradeCouponMapper"  > < resultMap id = "BaseResultMap"  type = "com.itheima.shop.pojo.TradeCoupon"  > < id column = "coupon_id"  property = "couponId"  jdbcType = "BIGINT"  /> < result column = "coupon_price"  property = "couponPrice"  jdbcType = "DECIMAL"  /> < result column = "user_id"  property = "userId"  jdbcType = "BIGINT"  /> < result column = "order_id"  property = "orderId"  jdbcType = "BIGINT"  /> < result column = "is_used"  property = "isUsed"  jdbcType = "INTEGER"  /> < result column = "used_time"  property = "usedTime"  jdbcType = "TIMESTAMP"  /> < /resultMap> < sql id = "Example_Where_Clause"  > < where > < foreach collection = "oredCriteria"  item = "criteria"  separator = "or"  > < if test = "criteria.valid"  > < trim prefix = "("  suffix = ")"  prefixOverrides = "and"  > < foreach collection = "criteria.criteria"  item = "criterion"  > < choose > < when test = "criterion.noValue"  > and ${criterion.condition} < /when> < when test = "criterion.singleValue"  > and ${criterion.condition}  < /when> < when test = "criterion.betweenValue"  > and ${criterion.condition}  < /when> < when test = "criterion.listValue"  > and ${criterion.condition} < foreach collection = "criterion.value"  item = "listItem"  open = "("  close = ")"  separator = ","  > < /foreach> < /when> < /choose> < /foreach> < /trim> < /if> < /foreach> < /where> < /sql> < sql id = "Update_By_Example_Where_Clause"  > < where > < foreach collection = "example.oredCriteria"  item = "criteria"  separator = "or"  > < if test = "criteria.valid"  > < trim prefix = "("  suffix = ")"  prefixOverrides = "and"  > < foreach collection = "criteria.criteria"  item = "criterion"  > < choose > < when test = "criterion.noValue"  > and ${criterion.condition} < /when> < when test = "criterion.singleValue"  > and ${criterion.condition}  < /when> < when test = "criterion.betweenValue"  > and ${criterion.condition}  < /when> < when test = "criterion.listValue"  > and ${criterion.condition} < foreach collection = "criterion.value"  item = "listItem"  open = "("  close = ")"  separator = ","  > < /foreach> < /when> < /choose> < /foreach> < /trim> < /if> < /foreach> < /where> < /sql> < sql id = "Base_Column_List"  > coupon_id, coupon_price, user_id, order_id, is_used, used_time< /sql> < select id = "selectByExample"  resultMap = "BaseResultMap"  parameterType = "com.itheima.shop.pojo.TradeCouponExample"  > select < if test = "distinct"  > distinct< /if> < include refid = "Base_Column_List"  /> from trade_coupon< if test = "_parameter != null"  > < include refid = "Example_Where_Clause"  /> < /if> < if test = "orderByClause != null"  > order by ${orderByClause} < /if> < /select> < select id = "selectByPrimaryKey"  resultMap = "BaseResultMap"  parameterType = "java.lang.Long"  > select  < include refid = "Base_Column_List"  /> from trade_couponwhere coupon_id =  < /select> < delete id = "deleteByPrimaryKey"  parameterType = "java.lang.Long"  > delete from trade_couponwhere coupon_id =  < /delete> < delete id = "deleteByExample"  parameterType = "com.itheima.shop.pojo.TradeCouponExample"  > delete from trade_coupon< if test = "_parameter != null"  > < include refid = "Example_Where_Clause"  /> < /if> < /delete> < insert id = "insert"  parameterType = "com.itheima.shop.pojo.TradeCoupon"  > insert into trade_coupon ( coupon_id, coupon_price, user_id, order_id, is_used, used_time) values ( ) < /insert> < insert id = "insertSelective"  parameterType = "com.itheima.shop.pojo.TradeCoupon"  > insert into trade_coupon< trim prefix = "("  suffix = ")"  suffixOverrides = ","  > < if test = "couponId != null"  > coupon_id,< /if> < if test = "couponPrice != null"  > coupon_price,< /if> < if test = "userId != null"  > user_id,< /if> < if test = "orderId != null"  > order_id,< /if> < if test = "isUsed != null"  > is_used,< /if> < if test = "usedTime != null"  > used_time,< /if> < /trim> < trim prefix = "values ("  suffix = ")"  suffixOverrides = ","  > < if test = "couponId != null"  > < /if> < if test = "couponPrice != null"  > < /if> < if test = "userId != null"  > < /if> < if test = "orderId != null"  > < /if> < if test = "isUsed != null"  > < /if> < if test = "usedTime != null"  > < /if> < /trim> < /insert> < select id = "countByExample"  parameterType = "com.itheima.shop.pojo.TradeCouponExample"  resultType = "java.lang.Integer"  > select  count( *)  from trade_coupon< if test = "_parameter != null"  > < include refid = "Example_Where_Clause"  /> < /if> < /select> < update id = "updateByExampleSelective"  parameterType = "map"  > update trade_coupon< set > < if test = "record.couponId != null"  > coupon_id =  < /if> < if test = "record.couponPrice != null"  > coupon_price =  < /if> < if test = "record.userId != null"  > user_id =  < /if> < if test = "record.orderId != null"  > order_id =  < /if> < if test = "record.isUsed != null"  > is_used =  < /if> < if test = "record.usedTime != null"  > used_time =  < /if> < /set> < if test = "_parameter != null"  > < include refid = "Update_By_Example_Where_Clause"  /> < /if> < /update> < update id = "updateByExample"  parameterType = "map"  > update trade_couponset  coupon_id =  coupon_price =  user_id =  order_id =  is_used =  used_time =  < if test = "_parameter != null"  > < include refid = "Update_By_Example_Where_Clause"  /> < /if> < /update> < update id = "updateByPrimaryKeySelective"  parameterType = "com.itheima.shop.pojo.TradeCoupon"  > update trade_coupon< set > < if test = "couponPrice != null"  > coupon_price =  < /if> < if test = "userId != null"  > user_id =  < /if> < if test = "orderId != null"  > order_id =  < /if> < if test = "isUsed != null"  > is_used =  < /if> < if test = "usedTime != null"  > used_time =  < /if> < /set> where coupon_id =  < /update> < update id = "updateByPrimaryKey"  parameterType = "com.itheima.shop.pojo.TradeCoupon"  > update trade_couponset  coupon_price =  user_id =  order_id =  is_used =  used_time =  where coupon_id =  < /update> 
< /mapper> 
spring.application.name = dubbo-coupon-provider
spring.dubbo.application.id = dubbo-coupon-provider
spring.dubbo.application.name = dubbo-coupon-provider
spring.dubbo.registry.address = zookeeper://192.168.25.140:2181; zookeeper://192.168.25.140:2182; zookeeper://192.168.25.140:2183
spring.dubbo.server = true
spring.dubbo.protocol.name = dubbo
spring.dubbo.protocol.port = 20881 
spring.datasource.driverClassName = com.mysql.jdbc.Driver
spring.datasource.url = jdbc:mysql://127.0.0.1:3306/trade?useUnicode= true& characterEncoding = utf8
spring.datasource.username = root
spring.datasource.password = root
mybatis.type-aliases-package= com.itheima.shop.pojo
mybatis.mapper-locations= classpath:com/itheima/shop/mapper/*Mapper.xml
rocketmq.name-server= 192.168 .25.135:9876; 192.168 .25.138:9876
rocketmq.producer.group = orderProducerGroupmq.order.consumer.group.name = order_orderTopic_cancel_group
mq.order.topic = orderTopic
< ?xml version = "1.0"  encoding = "UTF-8" ?> 
< project xmlns = "http://maven.apache.org/POM/4.0.0" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation= "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" > < parent> < artifactId> shop-parent< /artifactId> < groupId> com.iteima.shop< /groupId> < version> 1.0 -SNAPSHOT< /version> < relativePath> .. /shop-parent/pom.xml< /relativePath> < /parent> < modelVersion> 4.0 .0 <> < artifactId> shop-goods-service< /artifactId> < dependencies> < ! --mybatis-springboot--> < dependency> < groupId> org.mybatis.spring.boot< /groupId> < artifactId> mybatis-spring-boot-starter< /artifactId> < version> 1.3 .1 <> < /dependency> < ! -- MySQL连接驱动 --> < dependency> < groupId> mysql< /groupId> < artifactId> mysql-connector-java< /artifactId> < /dependency> < dependency> < groupId> com.iteima.shop< /groupId> < artifactId> shop-common< /artifactId> < version> 1.0 -SNAPSHOT< /version> < /dependency> < dependency> < groupId> com.iteima.shop< /groupId> < artifactId> shop-pojo< /artifactId> < version> 1.0 -SNAPSHOT< /version> < /dependency> < dependency> < groupId> com.iteima.shop< /groupId> < artifactId> shop-api< /artifactId> < version> 1.0 -SNAPSHOT< /version> < /dependency> < dependency> < groupId> com.iteima.shop< /groupId> < artifactId> shop-pojo< /artifactId> < version> 1.0 -SNAPSHOT< /version> < /dependency> < /dependencies> < /project> 
< ! -- D:\ java-test\ idea2019\ shop\ shop-goods-service\ pom.xml --> package com.itheima.shop.mapper; import  com.itheima.shop.pojo.TradeGoods; 
import  com.itheima.shop.pojo.TradeGoodsExample; 
import  org.apache.ibatis.annotations.Mapper; 
import  org.apache.ibatis.annotations.Param; import  java.util.List; @Mapper
public interface TradeGoodsMapper { int countByExample( TradeGoodsExample example) ; int deleteByExample( TradeGoodsExample example) ; int deleteByPrimaryKey( Long goodsId) ; int insert( TradeGoods record) ; int insertSelective( TradeGoods record) ; List< TradeGoods>  selectByExample( TradeGoodsExample example) ; TradeGoods selectByPrimaryKey( Long goodsId) ; int updateByExampleSelective( @Param( "record" )  TradeGoods record, @Param( "example" )  TradeGoodsExample example) ; int updateByExample( @Param( "record" )  TradeGoods record, @Param( "example" )  TradeGoodsExample example) ; int updateByPrimaryKeySelective( TradeGoods record) ; int updateByPrimaryKey( TradeGoods record) ; 
} 
package com.itheima.shop.mapper; import  com.itheima.shop.pojo.TradeGoodsNumberLog; 
import  com.itheima.shop.pojo.TradeGoodsNumberLogExample; 
import  com.itheima.shop.pojo.TradeGoodsNumberLogKey; 
import  org.apache.ibatis.annotations.Mapper; 
import  org.apache.ibatis.annotations.Param; import  java.util.List; @Mapper
public interface TradeGoodsNumberLogMapper { int countByExample( TradeGoodsNumberLogExample example) ; int deleteByExample( TradeGoodsNumberLogExample example) ; int deleteByPrimaryKey( TradeGoodsNumberLogKey key) ; int insert( TradeGoodsNumberLog record) ; int insertSelective( TradeGoodsNumberLog record) ; List< TradeGoodsNumberLog>  selectByExample( TradeGoodsNumberLogExample example) ; TradeGoodsNumberLog selectByPrimaryKey( TradeGoodsNumberLogKey key) ; int updateByExampleSelective( @Param( "record" )  TradeGoodsNumberLog record, @Param( "example" )  TradeGoodsNumberLogExample example) ; int updateByExample( @Param( "record" )  TradeGoodsNumberLog record, @Param( "example" )  TradeGoodsNumberLogExample example) ; int updateByPrimaryKeySelective( TradeGoodsNumberLog record) ; int updateByPrimaryKey( TradeGoodsNumberLog record) ; 
} 
package com.itheima.shop.mapper; import  com.itheima.shop.pojo.TradeMqConsumerLog; 
import  com.itheima.shop.pojo.TradeMqConsumerLogExample; 
import  com.itheima.shop.pojo.TradeMqConsumerLogKey; 
import  org.apache.ibatis.annotations.Mapper; 
import  org.apache.ibatis.annotations.Param; import  java.util.List; @Mapper
public interface TradeMqConsumerLogMapper { int countByExample( TradeMqConsumerLogExample example) ; int deleteByExample( TradeMqConsumerLogExample example) ; int deleteByPrimaryKey( TradeMqConsumerLogKey key) ; int insert( TradeMqConsumerLog record) ; int insertSelective( TradeMqConsumerLog record) ; List< TradeMqConsumerLog>  selectByExample( TradeMqConsumerLogExample example) ; TradeMqConsumerLog selectByPrimaryKey( TradeMqConsumerLogKey key) ; int updateByExampleSelective( @Param( "record" )  TradeMqConsumerLog record, @Param( "example" )  TradeMqConsumerLogExample example) ; int updateByExample( @Param( "record" )  TradeMqConsumerLog record, @Param( "example" )  TradeMqConsumerLogExample example) ; int updateByPrimaryKeySelective( TradeMqConsumerLog record) ; int updateByPrimaryKey( TradeMqConsumerLog record) ; 
} 
package com.itheima.shop.mq; import  com.alibaba.fastjson.JSON; 
import  com.itheima.constant.ShopCode; 
import  com.itheima.entity.MQEntity; 
import  com.itheima.shop.mapper.TradeGoodsMapper; 
import  com.itheima.shop.mapper.TradeGoodsNumberLogMapper; 
import  com.itheima.shop.mapper.TradeMqConsumerLogMapper; 
import  com.itheima.shop.pojo.*; 
import  lombok.extern.slf4j.Slf4j; 
import  org.apache.rocketmq.common.message.MessageExt; 
import  org.apache.rocketmq.spring.annotation.MessageModel; 
import  org.apache.rocketmq.spring.annotation.RocketMQMessageListener; 
import  org.apache.rocketmq.spring.core.RocketMQListener; 
import  org.springframework.beans.factory.annotation.Autowired; 
import  org.springframework.beans.factory.annotation.Value; 
import  org.springframework.stereotype.Component; import  java.util.Date; @Slf4j
@Component
@RocketMQMessageListener( topic =  "${mq.order.topic} " ,consumerGroup =  "${mq.order.consumer.group.name} " ,messageModel =  MessageModel.BROADCASTING ) 
public class CancelMQListener implements RocketMQListener< MessageExt> { @Value( "${mq.order.consumer.group.name} " ) private String groupName; @Autowiredprivate TradeGoodsMapper goodsMapper; @Autowiredprivate TradeMqConsumerLogMapper mqConsumerLogMapper; @Autowiredprivate TradeGoodsNumberLogMapper goodsNumberLogMapper; @Overridepublic void onMessage( MessageExt messageExt)  { String msgId = null; String tags = null; String keys = null; String body = null; try { //1. 解析消息内容msgId =  messageExt.getMsgId( ) ; tags =  messageExt.getTags( ) ; keys =  messageExt.getKeys( ) ; body =  new String( messageExt.getBody( ) ,"UTF-8" ) ; log.info( "接受消息成功" ) ; //2. 查询消息消费记录TradeMqConsumerLogKey primaryKey =  new TradeMqConsumerLogKey( ) ; primaryKey.setMsgTag( tags) ; primaryKey.setMsgKey( keys) ; primaryKey.setGroupName( groupName) ; TradeMqConsumerLog mqConsumerLog =  mqConsumerLogMapper.selectByPrimaryKey( primaryKey) ; if( mqConsumerLog!= null) { //3. 判断如果消费过.. .//3.1 获得消息处理状态Integer status =  mqConsumerLog.getConsumerStatus( ) ; //处理过.. .返回if( ShopCode.SHOP_MQ_MESSAGE_STATUS_SUCCESS.getCode( ) .intValue( ) == status.intValue( )) { log.info( "消息:" +msgId+",已经处理过" ) ; return ; } //正在处理.. .返回if( ShopCode.SHOP_MQ_MESSAGE_STATUS_PROCESSING.getCode( ) .intValue( ) == status.intValue( )) { log.info( "消息:" +msgId+",正在处理" ) ; return ; } //处理失败if( ShopCode.SHOP_MQ_MESSAGE_STATUS_FAIL.getCode( ) .intValue( ) == status.intValue( )) { //获得消息处理次数Integer times  =  mqConsumerLog.getConsumerTimes( ) ; if( times> 3 ) { log.info( "消息:" +msgId+",消息处理超过3次,不能再进行处理了" ) ; return ; } mqConsumerLog.setConsumerStatus( ShopCode.SHOP_MQ_MESSAGE_STATUS_PROCESSING.getCode( )) ; //使用数据库乐观锁更新TradeMqConsumerLogExample example =  new TradeMqConsumerLogExample( ) ; TradeMqConsumerLogExample.Criteria criteria =  example.createCriteria( ) ; criteria.andMsgTagEqualTo( mqConsumerLog.getMsgTag( )) ; criteria.andMsgKeyEqualTo( mqConsumerLog.getMsgKey( )) ; criteria.andGroupNameEqualTo( groupName) ; criteria.andConsumerTimesEqualTo( mqConsumerLog.getConsumerTimes( )) ; int r =  mqConsumerLogMapper.updateByExampleSelective( mqConsumerLog, example) ; if( r<= 0 ) { //未修改成功,其他线程并发修改log.info( "并发修改,稍后处理" ) ; } } } else{ //4. 判断如果没有消费过.. .mqConsumerLog =  new TradeMqConsumerLog( ) ; mqConsumerLog.setMsgTag( tags) ; mqConsumerLog.setMsgKey( keys) ; mqConsumerLog.setGroupName( groupName) ; mqConsumerLog.setConsumerStatus( ShopCode.SHOP_MQ_MESSAGE_STATUS_PROCESSING.getCode( )) ; mqConsumerLog.setMsgBody( body) ; mqConsumerLog.setMsgId( msgId) ; mqConsumerLog.setConsumerTimes( 0 ) ; //将消息处理信息添加到数据库mqConsumerLogMapper.insert( mqConsumerLog) ; } //5. 回退库存MQEntity mqEntity =  JSON.parseObject( body, MQEntity.class) ; Long goodsId =  mqEntity.getGoodsId( ) ; TradeGoods goods =  goodsMapper.selectByPrimaryKey( goodsId) ; goods.setGoodsNumber( goods.getGoodsNumber( ) +mqEntity.getGoodsNum( )) ; goodsMapper.updateByPrimaryKey( goods) ; //6. 将消息的处理状态改为成功mqConsumerLog.setConsumerStatus( ShopCode.SHOP_MQ_MESSAGE_STATUS_SUCCESS.getCode( )) ; mqConsumerLog.setConsumerTimestamp( new Date( )) ; mqConsumerLogMapper.updateByPrimaryKey( mqConsumerLog) ; log.info( "回退库存成功" ) ; }  catch ( Exception e)  { e.printStackTrace( ) ; TradeMqConsumerLogKey primaryKey =  new TradeMqConsumerLogKey( ) ; primaryKey.setMsgTag( tags) ; primaryKey.setMsgKey( keys) ; primaryKey.setGroupName( groupName) ; TradeMqConsumerLog mqConsumerLog =  mqConsumerLogMapper.selectByPrimaryKey( primaryKey) ; if( mqConsumerLog== null) { //数据库未有记录mqConsumerLog =  new TradeMqConsumerLog( ) ; mqConsumerLog.setMsgTag( tags) ; mqConsumerLog.setMsgKey( keys) ; mqConsumerLog.setGroupName( groupName) ; mqConsumerLog.setConsumerStatus( ShopCode.SHOP_MQ_MESSAGE_STATUS_FAIL.getCode( )) ; mqConsumerLog.setMsgBody( body) ; mqConsumerLog.setMsgId( msgId) ; mqConsumerLog.setConsumerTimes( 1 ) ; mqConsumerLogMapper.insert( mqConsumerLog) ; } else{ mqConsumerLog.setConsumerTimes( mqConsumerLog.getConsumerTimes( ) +1) ; mqConsumerLogMapper.updateByPrimaryKeySelective( mqConsumerLog) ; } } } 
} package com.itheima.shop.service.impl; import  com.alibaba.dubbo.config.annotation.Service; 
import  com.itheima.api.IGoodsService; 
import  com.itheima.constant.ShopCode; 
import  com.itheima.entity.Result; 
import  com.itheima.exception.CastException; 
import  com.itheima.shop.mapper.TradeGoodsMapper; 
import  com.itheima.shop.mapper.TradeGoodsNumberLogMapper; 
import  com.itheima.shop.pojo.TradeGoods; 
import  com.itheima.shop.pojo.TradeGoodsNumberLog; 
import  org.springframework.beans.factory.annotation.Autowired; 
import  org.springframework.stereotype.Component; import  java.util.Date; @Component
@Service( interfaceClass =  IGoodsService.class) 
public class GoodsServiceImpl implements IGoodsService { @Autowiredprivate TradeGoodsMapper goodsMapper; @Autowiredprivate TradeGoodsNumberLogMapper goodsNumberLogMapper; @Overridepublic TradeGoods findOne( Long goodsId)  { if  ( goodsId ==  null)  { CastException.cast( ShopCode.SHOP_REQUEST_PARAMETER_VALID) ; } return  goodsMapper.selectByPrimaryKey( goodsId) ; } @Overridepublic Result reduceGoodsNum( TradeGoodsNumberLog goodsNumberLog)  { if  ( goodsNumberLog ==  null || goodsNumberLog.getGoodsNumber( )  ==  null || goodsNumberLog.getOrderId( )  ==  null || goodsNumberLog.getGoodsNumber( )  ==  null || goodsNumberLog.getGoodsNumber( ) .intValue( )  <=  0 )  { CastException.cast( ShopCode.SHOP_REQUEST_PARAMETER_VALID) ; } TradeGoods goods =  goodsMapper.selectByPrimaryKey( goodsNumberLog.getGoodsId( )) ; if( goods.getGoodsNumber( ) < goodsNumberLog.getGoodsNumber( )) { //库存不足CastException.cast( ShopCode.SHOP_GOODS_NUM_NOT_ENOUGH) ; } //减库存goods.setGoodsNumber( goods.getGoodsNumber( ) -goodsNumberLog.getGoodsNumber( )) ; goodsMapper.updateByPrimaryKey( goods) ; //记录库存操作日志goodsNumberLog.setGoodsNumber( -( goodsNumberLog.getGoodsNumber( )) ) ; goodsNumberLog.setLogTime( new Date( )) ; goodsNumberLogMapper.insert( goodsNumberLog) ; return  new Result( ShopCode.SHOP_SUCCESS.getSuccess( ) ,ShopCode.SHOP_SUCCESS.getMessage( )) ; } } package com.itheima.shop; import  com.alibaba.dubbo.spring.boot.annotation.EnableDubboConfiguration; 
import  org.springframework.boot.SpringApplication; 
import  org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication
@EnableDubboConfiguration
public class GoodsServiceApplication { public static void main( String[ ]  args)  { SpringApplication.run( GoodsServiceApplication.class,args) ; } } < ?xml version = "1.0"  encoding = "UTF-8"  ?> 
< ! DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  "http://mybatis.org/dtd/mybatis-3-mapper.dtd"  > 
< mapper namespace = "com.itheima.shop.mapper.TradeGoodsMapper"  > < resultMap id = "BaseResultMap"  type = "com.itheima.shop.pojo.TradeGoods"  > < id column = "goods_id"  property = "goodsId"  jdbcType = "BIGINT"  /> < result column = "goods_name"  property = "goodsName"  jdbcType = "VARCHAR"  /> < result column = "goods_number"  property = "goodsNumber"  jdbcType = "INTEGER"  /> < result column = "goods_price"  property = "goodsPrice"  jdbcType = "DECIMAL"  /> < result column = "goods_desc"  property = "goodsDesc"  jdbcType = "VARCHAR"  /> < result column = "add_time"  property = "addTime"  jdbcType = "TIMESTAMP"  /> < /resultMap> < sql id = "Example_Where_Clause"  > < where > < foreach collection = "oredCriteria"  item = "criteria"  separator = "or"  > < if test = "criteria.valid"  > < trim prefix = "("  suffix = ")"  prefixOverrides = "and"  > < foreach collection = "criteria.criteria"  item = "criterion"  > < choose > < when test = "criterion.noValue"  > and ${criterion.condition} < /when> < when test = "criterion.singleValue"  > and ${criterion.condition}  < /when> < when test = "criterion.betweenValue"  > and ${criterion.condition}  < /when> < when test = "criterion.listValue"  > and ${criterion.condition} < foreach collection = "criterion.value"  item = "listItem"  open = "("  close = ")"  separator = ","  > < /foreach> < /when> < /choose> < /foreach> < /trim> < /if> < /foreach> < /where> < /sql> < sql id = "Update_By_Example_Where_Clause"  > < where > < foreach collection = "example.oredCriteria"  item = "criteria"  separator = "or"  > < if test = "criteria.valid"  > < trim prefix = "("  suffix = ")"  prefixOverrides = "and"  > < foreach collection = "criteria.criteria"  item = "criterion"  > < choose > < when test = "criterion.noValue"  > and ${criterion.condition} < /when> < when test = "criterion.singleValue"  > and ${criterion.condition}  < /when> < when test = "criterion.betweenValue"  > and ${criterion.condition}  < /when> < when test = "criterion.listValue"  > and ${criterion.condition} < foreach collection = "criterion.value"  item = "listItem"  open = "("  close = ")"  separator = ","  > < /foreach> < /when> < /choose> < /foreach> < /trim> < /if> < /foreach> < /where> < /sql> < sql id = "Base_Column_List"  > goods_id, goods_name, goods_number, goods_price, goods_desc, add_time< /sql> < select id = "selectByExample"  resultMap = "BaseResultMap"  parameterType = "com.itheima.shop.pojo.TradeGoodsExample"  > select < if test = "distinct"  > distinct< /if> < include refid = "Base_Column_List"  /> from trade_goods< if test = "_parameter != null"  > < include refid = "Example_Where_Clause"  /> < /if> < if test = "orderByClause != null"  > order by ${orderByClause} < /if> < /select> < select id = "selectByPrimaryKey"  resultMap = "BaseResultMap"  parameterType = "java.lang.Long"  > select  < include refid = "Base_Column_List"  /> from trade_goodswhere goods_id =  < /select> < delete id = "deleteByPrimaryKey"  parameterType = "java.lang.Long"  > delete from trade_goodswhere goods_id =  < /delete> < delete id = "deleteByExample"  parameterType = "com.itheima.shop.pojo.TradeGoodsExample"  > delete from trade_goods< if test = "_parameter != null"  > < include refid = "Example_Where_Clause"  /> < /if> < /delete> < insert id = "insert"  parameterType = "com.itheima.shop.pojo.TradeGoods"  > insert into trade_goods ( goods_id, goods_name, goods_number, goods_price, goods_desc, add_time) values ( ) < /insert> < insert id = "insertSelective"  parameterType = "com.itheima.shop.pojo.TradeGoods"  > insert into trade_goods< trim prefix = "("  suffix = ")"  suffixOverrides = ","  > < if test = "goodsId != null"  > goods_id,< /if> < if test = "goodsName != null"  > goods_name,< /if> < if test = "goodsNumber != null"  > goods_number,< /if> < if test = "goodsPrice != null"  > goods_price,< /if> < if test = "goodsDesc != null"  > goods_desc,< /if> < if test = "addTime != null"  > add_time,< /if> < /trim> < trim prefix = "values ("  suffix = ")"  suffixOverrides = ","  > < if test = "goodsId != null"  > < /if> < if test = "goodsName != null"  > < /if> < if test = "goodsNumber != null"  > < /if> < if test = "goodsPrice != null"  > < /if> < if test = "goodsDesc != null"  > < /if> < if test = "addTime != null"  > < /if> < /trim> < /insert> < select id = "countByExample"  parameterType = "com.itheima.shop.pojo.TradeGoodsExample"  resultType = "java.lang.Integer"  > select  count( *)  from trade_goods< if test = "_parameter != null"  > < include refid = "Example_Where_Clause"  /> < /if> < /select> < update id = "updateByExampleSelective"  parameterType = "map"  > update trade_goods< set > < if test = "record.goodsId != null"  > goods_id =  < /if> < if test = "record.goodsName != null"  > goods_name =  < /if> < if test = "record.goodsNumber != null"  > goods_number =  < /if> < if test = "record.goodsPrice != null"  > goods_price =  < /if> < if test = "record.goodsDesc != null"  > goods_desc =  < /if> < if test = "record.addTime != null"  > add_time =  < /if> < /set> < if test = "_parameter != null"  > < include refid = "Update_By_Example_Where_Clause"  /> < /if> < /update> < update id = "updateByExample"  parameterType = "map"  > update trade_goodsset  goods_id =  goods_name =  goods_number =  goods_price =  goods_desc =  add_time =  < if test = "_parameter != null"  > < include refid = "Update_By_Example_Where_Clause"  /> < /if> < /update> < update id = "updateByPrimaryKeySelective"  parameterType = "com.itheima.shop.pojo.TradeGoods"  > update trade_goods< set > < if test = "goodsName != null"  > goods_name =  < /if> < if test = "goodsNumber != null"  > goods_number =  < /if> < if test = "goodsPrice != null"  > goods_price =  < /if> < if test = "goodsDesc != null"  > goods_desc =  < /if> < if test = "addTime != null"  > add_time =  < /if> < /set> where goods_id =  < /update> < update id = "updateByPrimaryKey"  parameterType = "com.itheima.shop.pojo.TradeGoods"  > update trade_goodsset  goods_name =  goods_number =  goods_price =  goods_desc =  add_time =  where goods_id =  < /update> 
< /mapper> 
< ?xml version = "1.0"  encoding = "UTF-8"  ?> 
< ! DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  "http://mybatis.org/dtd/mybatis-3-mapper.dtd"  > 
< mapper namespace = "com.itheima.shop.mapper.TradeGoodsNumberLogMapper"  > < resultMap id = "BaseResultMap"  type = "com.itheima.shop.pojo.TradeGoodsNumberLog"  > < id column = "goods_id"  property = "goodsId"  jdbcType = "BIGINT"  /> < id column = "order_id"  property = "orderId"  jdbcType = "BIGINT"  /> < result column = "goods_number"  property = "goodsNumber"  jdbcType = "INTEGER"  /> < result column = "log_time"  property = "logTime"  jdbcType = "TIMESTAMP"  /> < /resultMap> < sql id = "Example_Where_Clause"  > < where > < foreach collection = "oredCriteria"  item = "criteria"  separator = "or"  > < if test = "criteria.valid"  > < trim prefix = "("  suffix = ")"  prefixOverrides = "and"  > < foreach collection = "criteria.criteria"  item = "criterion"  > < choose > < when test = "criterion.noValue"  > and ${criterion.condition} < /when> < when test = "criterion.singleValue"  > and ${criterion.condition}  < /when> < when test = "criterion.betweenValue"  > and ${criterion.condition}  < /when> < when test = "criterion.listValue"  > and ${criterion.condition} < foreach collection = "criterion.value"  item = "listItem"  open = "("  close = ")"  separator = ","  > < /foreach> < /when> < /choose> < /foreach> < /trim> < /if> < /foreach> < /where> < /sql> < sql id = "Update_By_Example_Where_Clause"  > < where > < foreach collection = "example.oredCriteria"  item = "criteria"  separator = "or"  > < if test = "criteria.valid"  > < trim prefix = "("  suffix = ")"  prefixOverrides = "and"  > < foreach collection = "criteria.criteria"  item = "criterion"  > < choose > < when test = "criterion.noValue"  > and ${criterion.condition} < /when> < when test = "criterion.singleValue"  > and ${criterion.condition}  < /when> < when test = "criterion.betweenValue"  > and ${criterion.condition}  < /when> < when test = "criterion.listValue"  > and ${criterion.condition} < foreach collection = "criterion.value"  item = "listItem"  open = "("  close = ")"  separator = ","  > < /foreach> < /when> < /choose> < /foreach> < /trim> < /if> < /foreach> < /where> < /sql> < sql id = "Base_Column_List"  > goods_id, order_id, goods_number, log_time< /sql> < select id = "selectByExample"  resultMap = "BaseResultMap"  parameterType = "com.itheima.shop.pojo.TradeGoodsNumberLogExample"  > select < if test = "distinct"  > distinct< /if> < include refid = "Base_Column_List"  /> from trade_goods_number_log< if test = "_parameter != null"  > < include refid = "Example_Where_Clause"  /> < /if> < if test = "orderByClause != null"  > order by ${orderByClause} < /if> < /select> < select id = "selectByPrimaryKey"  resultMap = "BaseResultMap"  parameterType = "com.itheima.shop.pojo.TradeGoodsNumberLogKey"  > select  < include refid = "Base_Column_List"  /> from trade_goods_number_logwhere goods_id =  and order_id =  < /select> < delete id = "deleteByPrimaryKey"  parameterType = "com.itheima.shop.pojo.TradeGoodsNumberLogKey"  > delete from trade_goods_number_logwhere goods_id =  and order_id =  < /delete> < delete id = "deleteByExample"  parameterType = "com.itheima.shop.pojo.TradeGoodsNumberLogExample"  > delete from trade_goods_number_log< if test = "_parameter != null"  > < include refid = "Example_Where_Clause"  /> < /if> < /delete> < insert id = "insert"  parameterType = "com.itheima.shop.pojo.TradeGoodsNumberLog"  > insert into trade_goods_number_log ( goods_id, order_id, goods_number, log_time) values ( < /insert> < insert id = "insertSelective"  parameterType = "com.itheima.shop.pojo.TradeGoodsNumberLog"  > insert into trade_goods_number_log< trim prefix = "("  suffix = ")"  suffixOverrides = ","  > < if test = "goodsId != null"  > goods_id,< /if> < if test = "orderId != null"  > order_id,< /if> < if test = "goodsNumber != null"  > goods_number,< /if> < if test = "logTime != null"  > log_time,< /if> < /trim> < trim prefix = "values ("  suffix = ")"  suffixOverrides = ","  > < if test = "goodsId != null"  > < /if> < if test = "orderId != null"  > < /if> < if test = "goodsNumber != null"  > < /if> < if test = "logTime != null"  > < /if> < /trim> < /insert> < select id = "countByExample"  parameterType = "com.itheima.shop.pojo.TradeGoodsNumberLogExample"  resultType = "java.lang.Integer"  > select  count( *)  from trade_goods_number_log< if test = "_parameter != null"  > < include refid = "Example_Where_Clause"  /> < /if> < /select> < update id = "updateByExampleSelective"  parameterType = "map"  > update trade_goods_number_log< set > < if test = "record.goodsId != null"  > goods_id =  < /if> < if test = "record.orderId != null"  > order_id =  < /if> < if test = "record.goodsNumber != null"  > goods_number =  < /if> < if test = "record.logTime != null"  > log_time =  < /if> < /set> < if test = "_parameter != null"  > < include refid = "Update_By_Example_Where_Clause"  /> < /if> < /update> < update id = "updateByExample"  parameterType = "map"  > update trade_goods_number_logset  goods_id =  order_id =  goods_number =  log_time =  < if test = "_parameter != null"  > < include refid = "Update_By_Example_Where_Clause"  /> < /if> < /update> < update id = "updateByPrimaryKeySelective"  parameterType = "com.itheima.shop.pojo.TradeGoodsNumberLog"  > update trade_goods_number_log< set > < if test = "goodsNumber != null"  > goods_number =  < /if> < if test = "logTime != null"  > log_time =  < /if> < /set> where goods_id =  and order_id =  < /update> < update id = "updateByPrimaryKey"  parameterType = "com.itheima.shop.pojo.TradeGoodsNumberLog"  > update trade_goods_number_logset  goods_number =  log_time =  where goods_id =  and order_id =  < /update> 
< /mapper> 
< ?xml version = "1.0"  encoding = "UTF-8"  ?> 
< ! DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  "http://mybatis.org/dtd/mybatis-3-mapper.dtd"  > 
< mapper namespace = "com.itheima.shop.mapper.TradeMqConsumerLogMapper"  > < resultMap id = "BaseResultMap"  type = "com.itheima.shop.pojo.TradeMqConsumerLog"  > < id column = "group_name"  property = "groupName"  jdbcType = "VARCHAR"  /> < id column = "msg_tag"  property = "msgTag"  jdbcType = "VARCHAR"  /> < id column = "msg_key"  property = "msgKey"  jdbcType = "VARCHAR"  /> < result column = "msg_id"  property = "msgId"  jdbcType = "VARCHAR"  /> < result column = "msg_body"  property = "msgBody"  jdbcType = "VARCHAR"  /> < result column = "consumer_status"  property = "consumerStatus"  jdbcType = "INTEGER"  /> < result column = "consumer_times"  property = "consumerTimes"  jdbcType = "INTEGER"  /> < result column = "consumer_timestamp"  property = "consumerTimestamp"  jdbcType = "TIMESTAMP"  /> < result column = "remark"  property = "remark"  jdbcType = "VARCHAR"  /> < /resultMap> < sql id = "Example_Where_Clause"  > < where > < foreach collection = "oredCriteria"  item = "criteria"  separator = "or"  > < if test = "criteria.valid"  > < trim prefix = "("  suffix = ")"  prefixOverrides = "and"  > < foreach collection = "criteria.criteria"  item = "criterion"  > < choose > < when test = "criterion.noValue"  > and ${criterion.condition} < /when> < when test = "criterion.singleValue"  > and ${criterion.condition}  < /when> < when test = "criterion.betweenValue"  > and ${criterion.condition}  < /when> < when test = "criterion.listValue"  > and ${criterion.condition} < foreach collection = "criterion.value"  item = "listItem"  open = "("  close = ")"  separator = ","  > < /foreach> < /when> < /choose> < /foreach> < /trim> < /if> < /foreach> < /where> < /sql> < sql id = "Update_By_Example_Where_Clause"  > < where > < foreach collection = "example.oredCriteria"  item = "criteria"  separator = "or"  > < if test = "criteria.valid"  > < trim prefix = "("  suffix = ")"  prefixOverrides = "and"  > < foreach collection = "criteria.criteria"  item = "criterion"  > < choose > < when test = "criterion.noValue"  > and ${criterion.condition} < /when> < when test = "criterion.singleValue"  > and ${criterion.condition}  < /when> < when test = "criterion.betweenValue"  > and ${criterion.condition}  < /when> < when test = "criterion.listValue"  > and ${criterion.condition} < foreach collection = "criterion.value"  item = "listItem"  open = "("  close = ")"  separator = ","  > < /foreach> < /when> < /choose> < /foreach> < /trim> < /if> < /foreach> < /where> < /sql> < sql id = "Base_Column_List"  > group_name, msg_tag, msg_key, msg_id, msg_body, consumer_status, consumer_times, consumer_timestamp, remark< /sql> < select id = "selectByExample"  resultMap = "BaseResultMap"  parameterType = "com.itheima.shop.pojo.TradeMqConsumerLogExample"  > select < if test = "distinct"  > distinct< /if> < include refid = "Base_Column_List"  /> from trade_mq_consumer_log< if test = "_parameter != null"  > < include refid = "Example_Where_Clause"  /> < /if> < if test = "orderByClause != null"  > order by ${orderByClause} < /if> < /select> < select id = "selectByPrimaryKey"  resultMap = "BaseResultMap"  parameterType = "com.itheima.shop.pojo.TradeMqConsumerLogKey"  > select  < include refid = "Base_Column_List"  /> from trade_mq_consumer_logwhere group_name =  and msg_tag =  and msg_key =  < /select> < delete id = "deleteByPrimaryKey"  parameterType = "com.itheima.shop.pojo.TradeMqConsumerLogKey"  > delete from trade_mq_consumer_logwhere group_name =  and msg_tag =  and msg_key =  < /delete> < delete id = "deleteByExample"  parameterType = "com.itheima.shop.pojo.TradeMqConsumerLogExample"  > delete from trade_mq_consumer_log< if test = "_parameter != null"  > < include refid = "Example_Where_Clause"  /> < /if> < /delete> < insert id = "insert"  parameterType = "com.itheima.shop.pojo.TradeMqConsumerLog"  > insert into trade_mq_consumer_log ( group_name, msg_tag, msg_key, msg_id, msg_body, consumer_status, consumer_times, consumer_timestamp, remark) values ( ) < /insert> < insert id = "insertSelective"  parameterType = "com.itheima.shop.pojo.TradeMqConsumerLog"  > insert into trade_mq_consumer_log< trim prefix = "("  suffix = ")"  suffixOverrides = ","  > < if test = "groupName != null"  > group_name,< /if> < if test = "msgTag != null"  > msg_tag,< /if> < if test = "msgKey != null"  > msg_key,< /if> < if test = "msgId != null"  > msg_id,< /if> < if test = "msgBody != null"  > msg_body,< /if> < if test = "consumerStatus != null"  > consumer_status,< /if> < if test = "consumerTimes != null"  > consumer_times,< /if> < if test = "consumerTimestamp != null"  > consumer_timestamp,< /if> < if test = "remark != null"  > remark,< /if> < /trim> < trim prefix = "values ("  suffix = ")"  suffixOverrides = ","  > < if test = "groupName != null"  > < /if> < if test = "msgTag != null"  > < /if> < if test = "msgKey != null"  > < /if> < if test = "msgId != null"  > < /if> < if test = "msgBody != null"  > < /if> < if test = "consumerStatus != null"  > < /if> < if test = "consumerTimes != null"  > < /if> < if test = "consumerTimestamp != null"  > < /if> < if test = "remark != null"  > < /if> < /trim> < /insert> < select id = "countByExample"  parameterType = "com.itheima.shop.pojo.TradeMqConsumerLogExample"  resultType = "java.lang.Integer"  > select  count( *)  from trade_mq_consumer_log< if test = "_parameter != null"  > < include refid = "Example_Where_Clause"  /> < /if> < /select> < update id = "updateByExampleSelective"  parameterType = "map"  > update trade_mq_consumer_log< set > < if test = "record.groupName != null"  > group_name =  < /if> < if test = "record.msgTag != null"  > msg_tag =  < /if> < if test = "record.msgKey != null"  > msg_key =  < /if> < if test = "record.msgId != null"  > msg_id =  < /if> < if test = "record.msgBody != null"  > msg_body =  < /if> < if test = "record.consumerStatus != null"  > consumer_status =  < /if> < if test = "record.consumerTimes != null"  > consumer_times =  < /if> < if test = "record.consumerTimestamp != null"  > consumer_timestamp =  < /if> < if test = "record.remark != null"  > remark =  < /if> < /set> < if test = "_parameter != null"  > < include refid = "Update_By_Example_Where_Clause"  /> < /if> < /update> < update id = "updateByExample"  parameterType = "map"  > update trade_mq_consumer_logset  group_name =  msg_tag =  msg_key =  msg_id =  msg_body =  consumer_status =  consumer_times =  consumer_timestamp =  remark =  < if test = "_parameter != null"  > < include refid = "Update_By_Example_Where_Clause"  /> < /if> < /update> < update id = "updateByPrimaryKeySelective"  parameterType = "com.itheima.shop.pojo.TradeMqConsumerLog"  > update trade_mq_consumer_log< set > < if test = "msgId != null"  > msg_id =  < /if> < if test = "msgBody != null"  > msg_body =  < /if> < if test = "consumerStatus != null"  > consumer_status =  < /if> < if test = "consumerTimes != null"  > consumer_times =  < /if> < if test = "consumerTimestamp != null"  > consumer_timestamp =  < /if> < if test = "remark != null"  > remark =  < /if> < /set> where group_name =  and msg_tag =  and msg_key =  < /update> < update id = "updateByPrimaryKey"  parameterType = "com.itheima.shop.pojo.TradeMqConsumerLog"  > update trade_mq_consumer_logset  msg_id =  msg_body =  consumer_status =  consumer_times =  consumer_timestamp =  remark =  where group_name =  and msg_tag =  and msg_key =  < /update> 
< /mapper> 
spring.application.name = dubbo-goods-provider
spring.dubbo.application.id = dubbo-goods-provider
spring.dubbo.application.name = dubbo-goods-provider
spring.dubbo.registry.address = zookeeper://192.168.25.140:2181; zookeeper://192.168.25.140:2182; zookeeper://192.168.25.140:2183
spring.dubbo.server = true
spring.dubbo.protocol.name = dubbo
spring.dubbo.protocol.port = 20882 
spring.datasource.driverClassName = com.mysql.jdbc.Driver
spring.datasource.url = jdbc:mysql://127.0.0.1:3306/trade?useUnicode= true& characterEncoding = utf8
spring.datasource.username = root
spring.datasource.password = root
mybatis.type-aliases-package= com.itheima.shop.pojo
mybatis.mapper-locations= classpath:com/itheima/shop/mapper/*Mapper.xml
rocketmq.name-server= 192.168 .25.135:9876; 192.168 .25.138:9876
rocketmq.producer.group = orderProducerGroupmq.order.consumer.group.name = order_orderTopic_cancel_group
mq.order.topic = orderTopic
< ?xml version = "1.0"  encoding = "UTF-8" ?> 
< project xmlns = "http://maven.apache.org/POM/4.0.0" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation= "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" > < parent> < artifactId> shop-parent< /artifactId> < groupId> com.iteima.shop< /groupId> < version> 1.0 -SNAPSHOT< /version> < relativePath> .. /shop-parent/pom.xml< /relativePath> < /parent> < modelVersion> 4.0 .0 <> < artifactId> shop-order-service< /artifactId> < dependencies> < ! --mybatis-springboot--> < dependency> < groupId> org.mybatis.spring.boot< /groupId> < artifactId> mybatis-spring-boot-starter< /artifactId> < version> 1.3 .1 <> < /dependency> < ! -- MySQL连接驱动 --> < dependency> < groupId> mysql< /groupId> < artifactId> mysql-connector-java< /artifactId> < /dependency> < ! --common--> < dependency> < groupId> com.iteima.shop< /groupId> < artifactId> shop-common< /artifactId> < version> 1.0 -SNAPSHOT< /version> < /dependency> < ! --接口--> < dependency> < groupId> com.iteima.shop< /groupId> < artifactId> shop-api< /artifactId> < version> 1.0 -SNAPSHOT< /version> < /dependency> < dependency> < groupId> com.iteima.shop< /groupId> < artifactId> shop-pojo< /artifactId> < version> 1.0 -SNAPSHOT< /version> < /dependency> < /dependencies> < /project> 
< ! -- D:\ java-test\ idea2019\ shop\ shop-order-service\ pom.xml --> package com.itheima.shop.mapper; import  com.itheima.shop.pojo.TradeOrder; 
import  com.itheima.shop.pojo.TradeOrderExample; 
import  org.apache.ibatis.annotations.Mapper; 
import  org.apache.ibatis.annotations.Param; import  java.util.List; @Mapper
public interface TradeOrderMapper { int countByExample( TradeOrderExample example) ; int deleteByExample( TradeOrderExample example) ; int deleteByPrimaryKey( Long orderId) ; int insert( TradeOrder record) ; int insertSelective( TradeOrder record) ; List< TradeOrder>  selectByExample( TradeOrderExample example) ; TradeOrder selectByPrimaryKey( Long orderId) ; int updateByExampleSelective( @Param( "record" )  TradeOrder record, @Param( "example" )  TradeOrderExample example) ; int updateByExample( @Param( "record" )  TradeOrder record, @Param( "example" )  TradeOrderExample example) ; int updateByPrimaryKeySelective( TradeOrder record) ; int updateByPrimaryKey( TradeOrder record) ; 
} 
package com.itheima.shop.mq; import  com.alibaba.fastjson.JSON; 
import  com.itheima.constant.ShopCode; 
import  com.itheima.entity.MQEntity; 
import  com.itheima.shop.mapper.TradeOrderMapper; 
import  com.itheima.shop.pojo.TradeOrder; 
import  lombok.extern.slf4j.Slf4j; 
import  org.apache.rocketmq.common.message.MessageExt; 
import  org.apache.rocketmq.spring.annotation.MessageModel; 
import  org.apache.rocketmq.spring.annotation.RocketMQMessageListener; 
import  org.apache.rocketmq.spring.core.RocketMQListener; 
import  org.springframework.beans.factory.annotation.Autowired; 
import  org.springframework.stereotype.Component; import  java.io.UnsupportedEncodingException; @Slf4j
@Component
@RocketMQMessageListener( topic =  "${mq.order.topic} " ,consumerGroup =  "${mq.order.consumer.group.name} " ,messageModel =  MessageModel.BROADCASTING ) 
public class CancelMQListener implements RocketMQListener< MessageExt> { @Autowiredprivate TradeOrderMapper orderMapper; @Overridepublic void onMessage( MessageExt messageExt)  { try { //1. 解析消息内容String body =  new String( messageExt.getBody( ) ,"UTF-8" ) ; MQEntity mqEntity =  JSON.parseObject( body, MQEntity.class) ; log.info( "接受消息成功" ) ; //2. 查询订单TradeOrder order =  orderMapper.selectByPrimaryKey( mqEntity.getOrderId( )) ; //3.更新订单状态为取消order.setOrderStatus( ShopCode.SHOP_ORDER_CANCEL.getCode( )) ; orderMapper.updateByPrimaryKey( order) ; log.info( "订单状态设置为取消" ) ; }  catch ( UnsupportedEncodingException e)  { e.printStackTrace( ) ; log.info( "订单取消失败" ) ; } } 
} package com.itheima.shop.mq; import  com.alibaba.fastjson.JSON; 
import  com.itheima.constant.ShopCode; 
import  com.itheima.shop.mapper.TradeOrderMapper; 
import  com.itheima.shop.pojo.TradeOrder; 
import  com.itheima.shop.pojo.TradePay; 
import  lombok.extern.slf4j.Slf4j; 
import  org.apache.rocketmq.common.message.MessageExt; 
import  org.apache.rocketmq.spring.annotation.MessageModel; 
import  org.apache.rocketmq.spring.annotation.RocketMQMessageListener; 
import  org.apache.rocketmq.spring.core.RocketMQListener; 
import  org.springframework.beans.factory.annotation.Autowired; 
import  org.springframework.stereotype.Component; import  java.io.UnsupportedEncodingException; @Slf4j
@Component
@RocketMQMessageListener( topic =  "${mq.pay.topic} " ,consumerGroup =  "${mq.pay.consumer.group.name} " ,messageModel =  MessageModel.BROADCASTING) 
public class PaymentListener implements RocketMQListener< MessageExt> { @Autowiredprivate TradeOrderMapper orderMapper; @Overridepublic void onMessage( MessageExt messageExt)  { log.info( "接收到支付成功消息" ) ; try { //1.解析消息内容String body =  new String( messageExt.getBody( ) ,"UTF-8" ) ; TradePay tradePay =  JSON.parseObject( body,TradePay.class) ; //2.根据订单ID查询订单对象TradeOrder tradeOrder =  orderMapper.selectByPrimaryKey( tradePay.getOrderId( )) ; //3.更改订单支付状态为已支付tradeOrder.setPayStatus( ShopCode.SHOP_ORDER_PAY_STATUS_IS_PAY.getCode( )) ; //4.更新订单数据到数据库orderMapper.updateByPrimaryKey( tradeOrder) ; log.info( "更改订单支付状态为已支付" ) ; }  catch ( UnsupportedEncodingException e)  { e.printStackTrace( ) ; } } 
} package com.itheima.shop.service; import  com.alibaba.dubbo.config.annotation.Reference; 
import  com.alibaba.dubbo.config.annotation.Service; 
import  com.alibaba.fastjson.JSON; 
import  com.itheima.api.ICouponService; 
import  com.itheima.api.IGoodsService; 
import  com.itheima.api.IOrderService; 
import  com.itheima.api.IUserService; 
import  com.itheima.constant.ShopCode; 
import  com.itheima.entity.MQEntity; 
import  com.itheima.entity.Result; 
import  com.itheima.exception.CastException; 
import  com.itheima.shop.mapper.TradeOrderMapper; 
import  com.itheima.shop.pojo.*; 
import  com.itheima.utils.IDWorker; 
import  lombok.extern.slf4j.Slf4j; 
import  org.apache.rocketmq.client.exception.MQBrokerException; 
import  org.apache.rocketmq.client.exception.MQClientException; 
import  org.apache.rocketmq.common.message.Message; 
import  org.apache.rocketmq.remoting.exception.RemotingException; 
import  org.apache.rocketmq.spring.core.RocketMQTemplate; 
import  org.springframework.beans.factory.annotation.Autowired; 
import  org.springframework.beans.factory.annotation.Value; 
import  org.springframework.stereotype.Component; import  java.math.BigDecimal; 
import  java.util.Date; @Slf4j
@Component
@Service( interfaceClass =  IOrderService.class) 
public class OrderServiceImpl implements IOrderService { @Referenceprivate IGoodsService goodsService; @Referenceprivate IUserService userService; @Referenceprivate ICouponService couponService; @Value( "${mq.order.topic} " ) private String topic; @Value( "${mq.order.tag.cancel} " ) private String tag; @Autowiredprivate TradeOrderMapper orderMapper; @Autowiredprivate IDWorker idWorker; @Autowiredprivate RocketMQTemplate rocketMQTemplate; @Overridepublic Result confirmOrder( TradeOrder order)  { //1.校验订单checkOrder( order) ; //2.生成预订单Long orderId =  savePreOrder( order) ; try { //3.扣减库存reduceGoodsNum( order) ; //4.扣减优惠券updateCouponStatus( order) ; //5.使用余额reduceMoneyPaid( order) ; //模拟异常抛出//CastException.cast( ShopCode.SHOP_FAIL) ; //6.确认订单updateOrderStatus( order) ; //7.返回成功状态return  new Result( ShopCode.SHOP_SUCCESS.getSuccess( ) ,ShopCode.SHOP_SUCCESS.getMessage( )) ; }  catch ( Exception e)  { //1.确认订单失败,发送消息MQEntity mqEntity =  new MQEntity( ) ; mqEntity.setOrderId( orderId) ; mqEntity.setUserId( order.getUserId( )) ; mqEntity.setUserMoney( order.getMoneyPaid( )) ; mqEntity.setGoodsId( order.getGoodsId( )) ; mqEntity.setGoodsNum( order.getGoodsNumber( )) ; mqEntity.setCouponId( order.getCouponId( )) ; //2.返回订单确认失败消息try { sendCancelOrder( topic,tag,order.getOrderId( ) .toString( ) , JSON.toJSONString( mqEntity)) ; }  catch ( Exception e1)  { e1.printStackTrace( ) ; } return  new Result( ShopCode.SHOP_FAIL.getSuccess( ) ,ShopCode.SHOP_FAIL.getMessage( )) ; } } /*** 发送订单确认失败消息* @param topic* @param tag* @param keys* @param body*/private void sendCancelOrder( String topic, String tag, String keys, String body)  throws InterruptedException, RemotingException, MQClientException, MQBrokerException { Message message =  new Message( topic,tag,keys,body.getBytes( )) ; rocketMQTemplate.getProducer( ) .send( message) ; } /*** 确认订单* @param order*/private void updateOrderStatus( TradeOrder order)  { order.setOrderStatus( ShopCode.SHOP_ORDER_CONFIRM.getCode( )) ; order.setPayStatus( ShopCode.SHOP_ORDER_PAY_STATUS_NO_PAY.getCode( )) ; order.setConfirmTime( new Date( )) ; int r =  orderMapper.updateByPrimaryKey( order) ; if( r<= 0 ) { CastException.cast( ShopCode.SHOP_ORDER_CONFIRM_FAIL) ; } log.info( "订单:" +order.getOrderId( ) +"确认订单成功" ) ; } /*** 扣减余额* @param order*/private void reduceMoneyPaid( TradeOrder order)  { if( order.getMoneyPaid( ) != null &&  order.getMoneyPaid( ) .compareTo( BigDecimal.ZERO) == 1 ) { TradeUserMoneyLog userMoneyLog =  new TradeUserMoneyLog( ) ; userMoneyLog.setOrderId( order.getOrderId( )) ; userMoneyLog.setUserId( order.getUserId( )) ; userMoneyLog.setUseMoney( order.getMoneyPaid( )) ; userMoneyLog.setMoneyLogType( ShopCode.SHOP_USER_MONEY_PAID.getCode( )) ; Result result =  userService.updateMoneyPaid( userMoneyLog) ; if( result.getSuccess( ) .equals( ShopCode.SHOP_FAIL.getSuccess( )) ) { CastException.cast( ShopCode.SHOP_USER_MONEY_REDUCE_FAIL) ; } log.info( "订单:" +order.getOrderId( ) +",扣减余额成功" ) ; } } /*** 使用优惠券* @param order*/private void updateCouponStatus( TradeOrder order)  { if( order.getCouponId( ) != null) { TradeCoupon coupon =  couponService.findOne( order.getCouponId( )) ; coupon.setOrderId( order.getOrderId( )) ; coupon.setIsUsed( ShopCode.SHOP_COUPON_ISUSED.getCode( )) ; coupon.setUsedTime( new Date( )) ; //更新优惠券状态Result result =   couponService.updateCouponStatus( coupon) ; if( result.getSuccess( ) .equals( ShopCode.SHOP_FAIL.getSuccess( )) ) { CastException.cast( ShopCode.SHOP_COUPON_USE_FAIL) ; } log.info( "订单:" +order.getOrderId( ) +",使用优惠券" ) ; } } /*** 扣减库存* @param order*/private void reduceGoodsNum( TradeOrder order)  { TradeGoodsNumberLog goodsNumberLog =  new TradeGoodsNumberLog( ) ; goodsNumberLog.setOrderId( order.getOrderId( )) ; goodsNumberLog.setGoodsId( order.getGoodsId( )) ; goodsNumberLog.setGoodsNumber( order.getGoodsNumber( )) ; Result result =  goodsService.reduceGoodsNum( goodsNumberLog) ; if( result.getSuccess( ) .equals( ShopCode.SHOP_FAIL.getSuccess( )) ) { CastException.cast( ShopCode.SHOP_REDUCE_GOODS_NUM_FAIL) ; } log.info( "订单:" +order.getOrderId( ) +"扣减库存成功" ) ; } /*** 生成预订单** @param order* @return*/private Long savePreOrder( TradeOrder order)  { //1. 设置订单状态为不可见order.setOrderStatus( ShopCode.SHOP_ORDER_NO_CONFIRM.getCode( )) ; //2. 设置订单IDlong orderId =  idWorker.nextId( ) ; order.setOrderId( orderId) ; //3. 核算订单运费BigDecimal shippingFee =  calculateShippingFee( order.getOrderAmount( )) ; if( order.getShippingFee( ) .compareTo( shippingFee) != 0 ) { CastException.cast( ShopCode.SHOP_ORDER_SHIPPINGFEE_INVALID) ; } //4. 核算订单总金额是否合法BigDecimal orderAmount =  order.getGoodsPrice( ) .multiply( new BigDecimal( order.getGoodsNumber( )) ) ; orderAmount.add( shippingFee) ; if( order.getOrderAmount( ) .compareTo( orderAmount) != 0 ) { CastException.cast( ShopCode.SHOP_ORDERAMOUNT_INVALID) ; } //5.判断用户是否使用余额BigDecimal moneyPaid =  order.getMoneyPaid( ) ; if( moneyPaid!= null) { //5.1 订单中余额是否合法int r =  moneyPaid.compareTo( BigDecimal.ZERO) ; //余额小于0if( r== -1) { CastException.cast( ShopCode.SHOP_MONEY_PAID_LESS_ZERO) ; } //余额大于0if( r== 1 ) { TradeUser user =  userService.findOne( order.getUserId( )) ; if( moneyPaid.compareTo( new BigDecimal( user.getUserMoney( )) ) == 1 ) { CastException.cast( ShopCode.SHOP_MONEY_PAID_INVALID) ; } } } else{ order.setMoneyPaid( BigDecimal.ZERO) ; } //6.判断用户是否使用优惠券Long couponId =  order.getCouponId( ) ; if( couponId!= null) { TradeCoupon coupon =  couponService.findOne( couponId) ; //6.1 判断优惠券是否存在if( coupon== null) { CastException.cast( ShopCode.SHOP_COUPON_NO_EXIST) ; } //6.2 判断优惠券是否已经被使用if( coupon.getIsUsed( ) .intValue( ) == ShopCode.SHOP_COUPON_ISUSED.getCode( ) .intValue( )) { CastException.cast( ShopCode.SHOP_COUPON_ISUSED) ; } order.setCouponPaid( coupon.getCouponPrice( )) ; } else{ order.setCouponPaid( BigDecimal.ZERO) ; } //7.核算订单支付金额    订单总金额-余额-优惠券金额BigDecimal payAmount =  order.getOrderAmount( ) .subtract( order.getMoneyPaid( )) .subtract( order.getCouponPaid( )) ; order.setPayAmount( payAmount) ; //8.设置下单时间order.setAddTime( new Date( )) ; //9.保存订单到数据库orderMapper.insert( order) ; //10.返回订单IDreturn  orderId; } /*** 核算运费* @param orderAmount* @return*/private BigDecimal calculateShippingFee( BigDecimal orderAmount)  { if( orderAmount.compareTo( new BigDecimal( 100 )) == 1 ) { return  BigDecimal.ZERO; } else{ return  new BigDecimal( 10 ) ; } } /*** 校验订单** @param order*/private void checkOrder( TradeOrder order)  { //1.校验订单是否存在if  ( order ==  null)  { CastException.cast( ShopCode.SHOP_ORDER_INVALID) ; } //2.校验订单中的商品是否存在TradeGoods goods =  goodsService.findOne( order.getGoodsId( )) ; if  ( goods ==  null)  { CastException.cast( ShopCode.SHOP_GOODS_NO_EXIST) ; } //3.校验下单用户是否存在TradeUser user =  userService.findOne( order.getUserId( )) ; if  ( user ==  null)  { CastException.cast( ShopCode.SHOP_USER_NO_EXIST) ; } //4.校验商品单价是否合法if  ( order.getGoodsPrice( ) .compareTo( goods.getGoodsPrice( ))  !=  0 )  { CastException.cast( ShopCode.SHOP_GOODS_PRICE_INVALID) ; } //5.校验订单商品数量是否合法if  ( order.getGoodsNumber( )  >=  goods.getGoodsNumber( ))  { CastException.cast( ShopCode.SHOP_GOODS_NUM_NOT_ENOUGH) ; } log.info( "校验订单通过" ) ; } } package com.itheima.shop; import  com.alibaba.dubbo.spring.boot.annotation.EnableDubboConfiguration; 
import  com.itheima.utils.IDWorker; 
import  org.springframework.boot.SpringApplication; 
import  org.springframework.boot.autoconfigure.SpringBootApplication; 
import  org.springframework.context.annotation.Bean; @SpringBootApplication
@EnableDubboConfiguration
public class OrderServiceApplication { public static void main( String[ ]  args)  { SpringApplication.run( OrderServiceApplication.class,args) ; } @Beanpublic IDWorker getBean ( ) { return  new IDWorker( 1,1 ) ; } } < ?xml version = "1.0"  encoding = "UTF-8"  ?> 
< ! DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  "http://mybatis.org/dtd/mybatis-3-mapper.dtd"  > 
< mapper namespace = "com.itheima.shop.mapper.TradeOrderMapper"  > < resultMap id = "BaseResultMap"  type = "com.itheima.shop.pojo.TradeOrder"  > < id column = "order_id"  property = "orderId"  jdbcType = "BIGINT"  /> < result column = "user_id"  property = "userId"  jdbcType = "BIGINT"  /> < result column = "order_status"  property = "orderStatus"  jdbcType = "INTEGER"  /> < result column = "pay_status"  property = "payStatus"  jdbcType = "INTEGER"  /> < result column = "shipping_status"  property = "shippingStatus"  jdbcType = "INTEGER"  /> < result column = "address"  property = "address"  jdbcType = "VARCHAR"  /> < result column = "consignee"  property = "consignee"  jdbcType = "VARCHAR"  /> < result column = "goods_id"  property = "goodsId"  jdbcType = "BIGINT"  /> < result column = "goods_number"  property = "goodsNumber"  jdbcType = "INTEGER"  /> < result column = "goods_price"  property = "goodsPrice"  jdbcType = "DECIMAL"  /> < result column = "goods_amount"  property = "goodsAmount"  jdbcType = "DECIMAL"  /> < result column = "shipping_fee"  property = "shippingFee"  jdbcType = "DECIMAL"  /> < result column = "order_amount"  property = "orderAmount"  jdbcType = "DECIMAL"  /> < result column = "coupon_id"  property = "couponId"  jdbcType = "BIGINT"  /> < result column = "coupon_paid"  property = "couponPaid"  jdbcType = "DECIMAL"  /> < result column = "money_paid"  property = "moneyPaid"  jdbcType = "DECIMAL"  /> < result column = "pay_amount"  property = "payAmount"  jdbcType = "DECIMAL"  /> < result column = "add_time"  property = "addTime"  jdbcType = "TIMESTAMP"  /> < result column = "confirm_time"  property = "confirmTime"  jdbcType = "TIMESTAMP"  /> < result column = "pay_time"  property = "payTime"  jdbcType = "TIMESTAMP"  /> < /resultMap> < sql id = "Example_Where_Clause"  > < where > < foreach collection = "oredCriteria"  item = "criteria"  separator = "or"  > < if test = "criteria.valid"  > < trim prefix = "("  suffix = ")"  prefixOverrides = "and"  > < foreach collection = "criteria.criteria"  item = "criterion"  > < choose > < when test = "criterion.noValue"  > and ${criterion.condition} < /when> < when test = "criterion.singleValue"  > and ${criterion.condition}  < /when> < when test = "criterion.betweenValue"  > and ${criterion.condition}  < /when> < when test = "criterion.listValue"  > and ${criterion.condition} < foreach collection = "criterion.value"  item = "listItem"  open = "("  close = ")"  separator = ","  > < /foreach> < /when> < /choose> < /foreach> < /trim> < /if> < /foreach> < /where> < /sql> < sql id = "Update_By_Example_Where_Clause"  > < where > < foreach collection = "example.oredCriteria"  item = "criteria"  separator = "or"  > < if test = "criteria.valid"  > < trim prefix = "("  suffix = ")"  prefixOverrides = "and"  > < foreach collection = "criteria.criteria"  item = "criterion"  > < choose > < when test = "criterion.noValue"  > and ${criterion.condition} < /when> < when test = "criterion.singleValue"  > and ${criterion.condition}  < /when> < when test = "criterion.betweenValue"  > and ${criterion.condition}  < /when> < when test = "criterion.listValue"  > and ${criterion.condition} < foreach collection = "criterion.value"  item = "listItem"  open = "("  close = ")"  separator = ","  > < /foreach> < /when> < /choose> < /foreach> < /trim> < /if> < /foreach> < /where> < /sql> < sql id = "Base_Column_List"  > order_id, user_id, order_status, pay_status, shipping_status, address, consignee, goods_id, goods_number, goods_price, goods_amount, shipping_fee, order_amount, coupon_id, coupon_paid, money_paid, pay_amount, add_time, confirm_time, pay_time< /sql> < select id = "selectByExample"  resultMap = "BaseResultMap"  parameterType = "com.itheima.shop.pojo.TradeOrderExample"  > select < if test = "distinct"  > distinct< /if> < include refid = "Base_Column_List"  /> from trade_order< if test = "_parameter != null"  > < include refid = "Example_Where_Clause"  /> < /if> < if test = "orderByClause != null"  > order by ${orderByClause} < /if> < /select> < select id = "selectByPrimaryKey"  resultMap = "BaseResultMap"  parameterType = "java.lang.Long"  > select  < include refid = "Base_Column_List"  /> from trade_orderwhere order_id =  < /select> < delete id = "deleteByPrimaryKey"  parameterType = "java.lang.Long"  > delete from trade_orderwhere order_id =  < /delete> < delete id = "deleteByExample"  parameterType = "com.itheima.shop.pojo.TradeOrderExample"  > delete from trade_order< if test = "_parameter != null"  > < include refid = "Example_Where_Clause"  /> < /if> < /delete> < insert id = "insert"  parameterType = "com.itheima.shop.pojo.TradeOrder"  > insert into trade_order ( order_id, user_id, order_status, pay_status, shipping_status, address, consignee, goods_id, goods_number, goods_price, goods_amount, shipping_fee, order_amount, coupon_id, coupon_paid, money_paid, pay_amount, add_time, confirm_time, pay_time) values ( < /insert> < insert id = "insertSelective"  parameterType = "com.itheima.shop.pojo.TradeOrder"  > insert into trade_order< trim prefix = "("  suffix = ")"  suffixOverrides = ","  > < if test = "orderId != null"  > order_id,< /if> < if test = "userId != null"  > user_id,< /if> < if test = "orderStatus != null"  > order_status,< /if> < if test = "payStatus != null"  > pay_status,< /if> < if test = "shippingStatus != null"  > shipping_status,< /if> < if test = "address != null"  > address,< /if> < if test = "consignee != null"  > consignee,< /if> < if test = "goodsId != null"  > goods_id,< /if> < if test = "goodsNumber != null"  > goods_number,< /if> < if test = "goodsPrice != null"  > goods_price,< /if> < if test = "goodsAmount != null"  > goods_amount,< /if> < if test = "shippingFee != null"  > shipping_fee,< /if> < if test = "orderAmount != null"  > order_amount,< /if> < if test = "couponId != null"  > coupon_id,< /if> < if test = "couponPaid != null"  > coupon_paid,< /if> < if test = "moneyPaid != null"  > money_paid,< /if> < if test = "payAmount != null"  > pay_amount,< /if> < if test = "addTime != null"  > add_time,< /if> < if test = "confirmTime != null"  > confirm_time,< /if> < if test = "payTime != null"  > pay_time,< /if> < /trim> < trim prefix = "values ("  suffix = ")"  suffixOverrides = ","  > < if test = "orderId != null"  > < /if> < if test = "userId != null"  > < /if> < if test = "orderStatus != null"  > < /if> < if test = "payStatus != null"  > < /if> < if test = "shippingStatus != null"  > < /if> < if test = "address != null"  > < /if> < if test = "consignee != null"  > < /if> < if test = "goodsId != null"  > < /if> < if test = "goodsNumber != null"  > < /if> < if test = "goodsPrice != null"  > < /if> < if test = "goodsAmount != null"  > < /if> < if test = "shippingFee != null"  > < /if> < if test = "orderAmount != null"  > < /if> < if test = "couponId != null"  > < /if> < if test = "couponPaid != null"  > < /if> < if test = "moneyPaid != null"  > < /if> < if test = "payAmount != null"  > < /if> < if test = "addTime != null"  > < /if> < if test = "confirmTime != null"  > < /if> < if test = "payTime != null"  > < /if> < /trim> < /insert> < select id = "countByExample"  parameterType = "com.itheima.shop.pojo.TradeOrderExample"  resultType = "java.lang.Integer"  > select  count( *)  from trade_order< if test = "_parameter != null"  > < include refid = "Example_Where_Clause"  /> < /if> < /select> < update id = "updateByExampleSelective"  parameterType = "map"  > update trade_order< set > < if test = "record.orderId != null"  > order_id =  < /if> < if test = "record.userId != null"  > user_id =  < /if> < if test = "record.orderStatus != null"  > order_status =  < /if> < if test = "record.payStatus != null"  > pay_status =  < /if> < if test = "record.shippingStatus != null"  > shipping_status =  < /if> < if test = "record.address != null"  > address =  < /if> < if test = "record.consignee != null"  > consignee =  < /if> < if test = "record.goodsId != null"  > goods_id =  < /if> < if test = "record.goodsNumber != null"  > goods_number =  < /if> < if test = "record.goodsPrice != null"  > goods_price =  < /if> < if test = "record.goodsAmount != null"  > goods_amount =  < /if> < if test = "record.shippingFee != null"  > shipping_fee =  < /if> < if test = "record.orderAmount != null"  > order_amount =  < /if> < if test = "record.couponId != null"  > coupon_id =  < /if> < if test = "record.couponPaid != null"  > coupon_paid =  < /if> < if test = "record.moneyPaid != null"  > money_paid =  < /if> < if test = "record.payAmount != null"  > pay_amount =  < /if> < if test = "record.addTime != null"  > add_time =  < /if> < if test = "record.confirmTime != null"  > confirm_time =  < /if> < if test = "record.payTime != null"  > pay_time =  < /if> < /set> < if test = "_parameter != null"  > < include refid = "Update_By_Example_Where_Clause"  /> < /if> < /update> < update id = "updateByExample"  parameterType = "map"  > update trade_orderset  order_id =  user_id =  order_status =  pay_status =  shipping_status =  address =  consignee =  goods_id =  goods_number =  goods_price =  goods_amount =  shipping_fee =  order_amount =  coupon_id =  coupon_paid =  money_paid =  pay_amount =  add_time =  confirm_time =  pay_time =  < if test = "_parameter != null"  > < include refid = "Update_By_Example_Where_Clause"  /> < /if> < /update> < update id = "updateByPrimaryKeySelective"  parameterType = "com.itheima.shop.pojo.TradeOrder"  > update trade_order< set > < if test = "userId != null"  > user_id =  < /if> < if test = "orderStatus != null"  > order_status =  < /if> < if test = "payStatus != null"  > pay_status =  < /if> < if test = "shippingStatus != null"  > shipping_status =  < /if> < if test = "address != null"  > address =  < /if> < if test = "consignee != null"  > consignee =  < /if> < if test = "goodsId != null"  > goods_id =  < /if> < if test = "goodsNumber != null"  > goods_number =  < /if> < if test = "goodsPrice != null"  > goods_price =  < /if> < if test = "goodsAmount != null"  > goods_amount =  < /if> < if test = "shippingFee != null"  > shipping_fee =  < /if> < if test = "orderAmount != null"  > order_amount =  < /if> < if test = "couponId != null"  > coupon_id =  < /if> < if test = "couponPaid != null"  > coupon_paid =  < /if> < if test = "moneyPaid != null"  > money_paid =  < /if> < if test = "payAmount != null"  > pay_amount =  < /if> < if test = "addTime != null"  > add_time =  < /if> < if test = "confirmTime != null"  > confirm_time =  < /if> < if test = "payTime != null"  > pay_time =  < /if> < /set> where order_id =  < /update> < update id = "updateByPrimaryKey"  parameterType = "com.itheima.shop.pojo.TradeOrder"  > update trade_orderset  user_id =  order_status =  pay_status =  shipping_status =  address =  consignee =  goods_id =  goods_number =  goods_price =  goods_amount =  shipping_fee =  order_amount =  coupon_id =  coupon_paid =  money_paid =  pay_amount =  add_time =  confirm_time =  pay_time =  where order_id =  < /update> 
< /mapper> 
spring.application.name = dubbo-order-provider
spring.dubbo.application.id = dubbo-order-provider
spring.dubbo.application.name = dubbo-order-provider
spring.dubbo.registry.address = zookeeper://192.168.25.140:2181; zookeeper://192.168.25.140:2182; zookeeper://192.168.25.140:2183
spring.dubbo.server = true
spring.dubbo.protocol.name = dubbo
spring.dubbo.protocol.port = 20884 
spring.datasource.driverClassName = com.mysql.jdbc.Driver
spring.datasource.url = jdbc:mysql://127.0.0.1:3306/trade?useUnicode= true& characterEncoding = utf8
spring.datasource.username = root
spring.datasource.password = root
mybatis.type-aliases-package= com.itheima.shop.pojo
mybatis.mapper-locations= classpath:com/itheima/shop/mapper/*Mapper.xml
rocketmq.name-server= 192.168 .25.135:9876; 192.168 .25.138:9876
rocketmq.producer.group = orderProducerGroupmq.order.consumer.group.name = order_orderTopic_cancel_group
mq.order.topic = orderTopic
mq.order.tag.cancel = order_cancelmq.pay.topic = payTopic
mq.pay.consumer.group.name = pay_payTopic_grouppackage com.itheima.test; import  com.itheima.api.IOrderService; 
import  com.itheima.shop.OrderServiceApplication; 
import  com.itheima.shop.pojo.TradeOrder; 
import  org.junit.Test; 
import  org.junit.runner.RunWith; 
import  org.springframework.beans.factory.annotation.Autowired; 
import  org.springframework.boot.test.context.SpringBootTest; 
import  org.springframework.test.context.junit4.SpringRunner; import  java.io.IOException; 
import  java.math.BigDecimal; @RunWith( SpringRunner.class) 
@SpringBootTest( classes =  OrderServiceApplication.class) 
public class OrderServiceTest { @Autowiredprivate IOrderService orderService; @Testpublic void confirmOrder( )  throws IOException { Long coupouId =  345988230098857984L; Long goodsId =  345959443973935104L; Long userId =  345963634385633280L; TradeOrder order =  new TradeOrder( ) ; order.setGoodsId( goodsId) ; order.setUserId( userId) ; order.setCouponId( coupouId) ; order.setAddress( "北京" ) ; order.setGoodsNumber( 1 ) ; order.setGoodsPrice( new BigDecimal( 1000 )) ; order.setShippingFee( BigDecimal.ZERO) ; order.setOrderAmount( new BigDecimal( 1000 )) ; order.setMoneyPaid( new BigDecimal( 100 )) ; orderService.confirmOrder( order) ; System.in.read( ) ; } } 
< ?xml version = "1.0"  encoding = "UTF-8" ?> 
< project xmlns = "http://maven.apache.org/POM/4.0.0" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation= "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" > < parent> < artifactId> shop-parent< /artifactId> < groupId> com.iteima.shop< /groupId> < version> 1.0 -SNAPSHOT< /version> < relativePath> .. /shop-parent/pom.xml< /relativePath> < /parent> < modelVersion> 4.0 .0 <> < artifactId> shop-pay-service< /artifactId> < dependencies> < ! --mybatis-springboot--> < dependency> < groupId> org.mybatis.spring.boot< /groupId> < artifactId> mybatis-spring-boot-starter< /artifactId> < version> 1.3 .1 <> < /dependency> < ! -- MySQL连接驱动 --> < dependency> < groupId> mysql< /groupId> < artifactId> mysql-connector-java< /artifactId> < /dependency> < ! --common--> < dependency> < groupId> com.iteima.shop< /groupId> < artifactId> shop-common< /artifactId> < version> 1.0 -SNAPSHOT< /version> < /dependency> < ! --接口--> < dependency> < groupId> com.iteima.shop< /groupId> < artifactId> shop-api< /artifactId> < version> 1.0 -SNAPSHOT< /version> < /dependency> < dependency> < groupId> com.iteima.shop< /groupId> < artifactId> shop-pojo< /artifactId> < version> 1.0 -SNAPSHOT< /version> < /dependency> < /dependencies> < /project> 
< ! -- D:\ java-test\ idea2019\ shop\ shop-pay-service\ pom.xml --> package com.itheima.shop.mapper; import  com.itheima.shop.pojo.TradeMqProducerTemp; 
import  com.itheima.shop.pojo.TradeMqProducerTempExample; 
import  org.apache.ibatis.annotations.Mapper; 
import  org.apache.ibatis.annotations.Param; import  java.util.List; @Mapper
public interface TradeMqProducerTempMapper { int countByExample( TradeMqProducerTempExample example) ; int deleteByExample( TradeMqProducerTempExample example) ; int deleteByPrimaryKey( String id ) ; int insert( TradeMqProducerTemp record) ; int insertSelective( TradeMqProducerTemp record) ; List< TradeMqProducerTemp>  selectByExample( TradeMqProducerTempExample example) ; TradeMqProducerTemp selectByPrimaryKey( String id ) ; int updateByExampleSelective( @Param( "record" )  TradeMqProducerTemp record, @Param( "example" )  TradeMqProducerTempExample example) ; int updateByExample( @Param( "record" )  TradeMqProducerTemp record, @Param( "example" )  TradeMqProducerTempExample example) ; int updateByPrimaryKeySelective( TradeMqProducerTemp record) ; int updateByPrimaryKey( TradeMqProducerTemp record) ; 
} 
package com.itheima.shop.mapper; import  com.itheima.shop.pojo.TradePay; 
import  com.itheima.shop.pojo.TradePayExample; 
import  org.apache.ibatis.annotations.Mapper; 
import  org.apache.ibatis.annotations.Param; import  java.util.List; 
@Mapper
public interface TradePayMapper { int countByExample( TradePayExample example) ; int deleteByExample( TradePayExample example) ; int deleteByPrimaryKey( Long payId) ; int insert( TradePay record) ; int insertSelective( TradePay record) ; List< TradePay>  selectByExample( TradePayExample example) ; TradePay selectByPrimaryKey( Long payId) ; int updateByExampleSelective( @Param( "record" )  TradePay record, @Param( "example" )  TradePayExample example) ; int updateByExample( @Param( "record" )  TradePay record, @Param( "example" )  TradePayExample example) ; int updateByPrimaryKeySelective( TradePay record) ; int updateByPrimaryKey( TradePay record) ; 
} 
package com.itheima.shop.service.impl; import  com.alibaba.dubbo.config.annotation.Service; 
import  com.alibaba.fastjson.JSON; 
import  com.itheima.api.IPayService; 
import  com.itheima.constant.ShopCode; 
import  com.itheima.entity.Result; 
import  com.itheima.exception.CastException; 
import  com.itheima.shop.mapper.TradeMqProducerTempMapper; 
import  com.itheima.shop.mapper.TradePayMapper; 
import  com.itheima.shop.pojo.TradeMqProducerTemp; 
import  com.itheima.shop.pojo.TradePay; 
import  com.itheima.shop.pojo.TradePayExample; 
import  com.itheima.utils.IDWorker; 
import  lombok.extern.slf4j.Slf4j; 
import  org.apache.rocketmq.client.exception.MQBrokerException; 
import  org.apache.rocketmq.client.exception.MQClientException; 
import  org.apache.rocketmq.client.producer.SendResult; 
import  org.apache.rocketmq.client.producer.SendStatus; 
import  org.apache.rocketmq.common.message.Message; 
import  org.apache.rocketmq.remoting.exception.RemotingException; 
import  org.apache.rocketmq.spring.core.RocketMQTemplate; 
import  org.springframework.beans.factory.annotation.Autowired; 
import  org.springframework.beans.factory.annotation.Value; 
import  org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; 
import  org.springframework.stereotype.Component; 
import  org.springframework.util.StringUtils; import  java.util.Date; @Slf4j
@Component
@Service( interfaceClass =  IPayService.class) 
public class PayServiceImpl implements IPayService{ @Autowiredprivate TradePayMapper tradePayMapper; @Autowiredprivate TradeMqProducerTempMapper mqProducerTempMapper; @Autowiredprivate ThreadPoolTaskExecutor threadPoolTaskExecutor; @Autowiredprivate RocketMQTemplate rocketMQTemplate; @Autowiredprivate IDWorker idWorker; @Value( "${rocketmq.producer.group} " ) private String groupName; @Value( "${mq.topic} " ) private String topic; @Value( "${mq.pay.tag} " ) private String tag; @Overridepublic Result createPayment( TradePay tradePay)  { if( tradePay== null ||  tradePay.getOrderId( ) == null) { CastException.cast( ShopCode.SHOP_REQUEST_PARAMETER_VALID) ; } //1.判断订单支付状态TradePayExample example =  new TradePayExample( ) ; TradePayExample.Criteria criteria =  example.createCriteria( ) ; criteria.andOrderIdEqualTo( tradePay.getOrderId( )) ; criteria.andIsPaidEqualTo( ShopCode.SHOP_PAYMENT_IS_PAID.getCode( )) ; int r =  tradePayMapper.countByExample( example) ; if( r> 0 ) { CastException.cast( ShopCode.SHOP_PAYMENT_IS_PAID) ; } //2.设置订单的状态为未支付tradePay.setIsPaid( ShopCode.SHOP_ORDER_PAY_STATUS_NO_PAY.getCode( )) ; //3.保存支付订单tradePay.setPayId( idWorker.nextId( )) ; tradePayMapper.insert( tradePay) ; return  new Result( ShopCode.SHOP_SUCCESS.getSuccess( ) ,ShopCode.SHOP_SUCCESS.getMessage( )) ; } @Overridepublic Result callbackPayment( TradePay tradePay)  throws InterruptedException, RemotingException, MQClientException, MQBrokerException { log.info( "支付回调" ) ; //1. 判断用户支付状态if( tradePay.getIsPaid( ) .intValue( ) == ShopCode.SHOP_ORDER_PAY_STATUS_IS_PAY.getCode( ) .intValue( )) { //2. 更新支付订单状态为已支付Long payId =  tradePay.getPayId( ) ; TradePay pay =  tradePayMapper.selectByPrimaryKey( payId) ; //判断支付订单是否存在if( pay== null) { CastException.cast( ShopCode.SHOP_PAYMENT_NOT_FOUND) ; } pay.setIsPaid( ShopCode.SHOP_ORDER_PAY_STATUS_IS_PAY.getCode( )) ; int r =  tradePayMapper.updateByPrimaryKeySelective( pay) ; log.info( "支付订单状态改为已支付" ) ; if( r== 1 ) { //3. 创建支付成功的消息TradeMqProducerTemp tradeMqProducerTemp =  new TradeMqProducerTemp( ) ; tradeMqProducerTemp.setId( String.valueOf( idWorker.nextId( )) ) ; tradeMqProducerTemp.setGroupName( groupName) ; tradeMqProducerTemp.setMsgTopic( topic) ; tradeMqProducerTemp.setMsgTag( tag) ; tradeMqProducerTemp.setMsgKey( String.valueOf( tradePay.getPayId( )) ) ; tradeMqProducerTemp.setMsgBody( JSON.toJSONString( tradePay)) ; tradeMqProducerTemp.setCreateTime( new Date( )) ; //4. 将消息持久化数据库mqProducerTempMapper.insert( tradeMqProducerTemp) ; log.info( "将支付成功消息持久化到数据库" ) ; //在线程池中进行处理threadPoolTaskExecutor.submit( new Runnable ( )  { @Overridepublic void run ( )  { //5. 发送消息到MQSendResult result =  null; try { result =  sendMessage( topic, tag, String.valueOf( tradePay.getPayId( )) , JSON.toJSONString( tradePay)) ; }  catch ( Exception e)  { e.printStackTrace( ) ; } if( result.getSendStatus( ) .equals( SendStatus.SEND_OK)) { log.info( "消息发送成功" ) ; //6. 等待发送结果,如果MQ接受到消息,删除发送成功的消息mqProducerTempMapper.deleteByPrimaryKey( tradeMqProducerTemp.getId( )) ; log.info( "持久化到数据库的消息删除" ) ; } } } ) ; } return  new Result( ShopCode.SHOP_SUCCESS.getSuccess( ) ,ShopCode.SHOP_SUCCESS.getMessage( )) ; } else{ CastException.cast( ShopCode.SHOP_PAYMENT_PAY_ERROR) ; return  new Result( ShopCode.SHOP_FAIL.getSuccess( ) ,ShopCode.SHOP_FAIL.getMessage( )) ; } } /*** 发送支付成功消息* @param topic* @param tag* @param key* @param body*/private SendResult sendMessage( String topic, String tag, String key, String body)  throws InterruptedException, RemotingException, MQClientException, MQBrokerException { if( StringUtils.isEmpty( topic)) { CastException.cast( ShopCode.SHOP_MQ_TOPIC_IS_EMPTY) ; } if( StringUtils.isEmpty( body)) { CastException.cast( ShopCode.SHOP_MQ_MESSAGE_BODY_IS_EMPTY) ; } Message message =  new Message( topic,tag,key,body.getBytes( )) ; SendResult sendResult =  rocketMQTemplate.getProducer( ) .send( message) ; return  sendResult; } 
} package com.itheima.shop; import  com.alibaba.dubbo.spring.boot.annotation.EnableDubboConfiguration; 
import  com.itheima.utils.IDWorker; 
import  org.springframework.boot.SpringApplication; 
import  org.springframework.boot.autoconfigure.SpringBootApplication; 
import  org.springframework.context.annotation.Bean; 
import  org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import  java.util.concurrent.ThreadPoolExecutor; @SpringBootApplication
@EnableDubboConfiguration
public class PayServiceApplication { public static void main( String[ ]  args)  { SpringApplication.run( PayServiceApplication.class,args) ; } @Beanpublic IDWorker getBean ( ) { return  new IDWorker( 1,2 ) ; } @Beanpublic ThreadPoolTaskExecutor getThreadPool ( )  { ThreadPoolTaskExecutor executor =  new ThreadPoolTaskExecutor( ) ; executor.setCorePoolSize( 4 ) ; executor.setMaxPoolSize( 8 ) ; executor.setQueueCapacity( 100 ) ; executor.setKeepAliveSeconds( 60 ) ; executor.setThreadNamePrefix( "Pool-A" ) ; executor.setRejectedExecutionHandler( new ThreadPoolExecutor.CallerRunsPolicy( )) ; executor.initialize( ) ; return  executor; } } < ?xml version = "1.0"  encoding = "UTF-8"  ?> 
< ! DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  "http://mybatis.org/dtd/mybatis-3-mapper.dtd"  > 
< mapper namespace = "com.itheima.shop.mapper.TradeMqProducerTempMapper"  > < resultMap id = "BaseResultMap"  type = "com.itheima.shop.pojo.TradeMqProducerTemp"  > < id column = "id"  property = "id"  jdbcType = "VARCHAR"  /> < result column = "group_name"  property = "groupName"  jdbcType = "VARCHAR"  /> < result column = "msg_topic"  property = "msgTopic"  jdbcType = "VARCHAR"  /> < result column = "msg_tag"  property = "msgTag"  jdbcType = "VARCHAR"  /> < result column = "msg_key"  property = "msgKey"  jdbcType = "VARCHAR"  /> < result column = "msg_body"  property = "msgBody"  jdbcType = "VARCHAR"  /> < result column = "msg_status"  property = "msgStatus"  jdbcType = "INTEGER"  /> < result column = "create_time"  property = "createTime"  jdbcType = "TIMESTAMP"  /> < /resultMap> < sql id = "Example_Where_Clause"  > < where > < foreach collection = "oredCriteria"  item = "criteria"  separator = "or"  > < if test = "criteria.valid"  > < trim prefix = "("  suffix = ")"  prefixOverrides = "and"  > < foreach collection = "criteria.criteria"  item = "criterion"  > < choose > < when test = "criterion.noValue"  > and ${criterion.condition} < /when> < when test = "criterion.singleValue"  > and ${criterion.condition}  < /when> < when test = "criterion.betweenValue"  > and ${criterion.condition}  < /when> < when test = "criterion.listValue"  > and ${criterion.condition} < foreach collection = "criterion.value"  item = "listItem"  open = "("  close = ")"  separator = ","  > < /foreach> < /when> < /choose> < /foreach> < /trim> < /if> < /foreach> < /where> < /sql> < sql id = "Update_By_Example_Where_Clause"  > < where > < foreach collection = "example.oredCriteria"  item = "criteria"  separator = "or"  > < if test = "criteria.valid"  > < trim prefix = "("  suffix = ")"  prefixOverrides = "and"  > < foreach collection = "criteria.criteria"  item = "criterion"  > < choose > < when test = "criterion.noValue"  > and ${criterion.condition} < /when> < when test = "criterion.singleValue"  > and ${criterion.condition}  < /when> < when test = "criterion.betweenValue"  > and ${criterion.condition}  < /when> < when test = "criterion.listValue"  > and ${criterion.condition} < foreach collection = "criterion.value"  item = "listItem"  open = "("  close = ")"  separator = ","  > < /foreach> < /when> < /choose> < /foreach> < /trim> < /if> < /foreach> < /where> < /sql> < sql id = "Base_Column_List"  > id, group_name, msg_topic, msg_tag, msg_key, msg_body, msg_status, create_time< /sql> < select id = "selectByExample"  resultMap = "BaseResultMap"  parameterType = "com.itheima.shop.pojo.TradeMqProducerTempExample"  > select < if test = "distinct"  > distinct< /if> < include refid = "Base_Column_List"  /> from trade_mq_producer_temp< if test = "_parameter != null"  > < include refid = "Example_Where_Clause"  /> < /if> < if test = "orderByClause != null"  > order by ${orderByClause} < /if> < /select> < select id = "selectByPrimaryKey"  resultMap = "BaseResultMap"  parameterType = "java.lang.String"  > select  < include refid = "Base_Column_List"  /> from trade_mq_producer_tempwhere id  =  < /select> < delete id = "deleteByPrimaryKey"  parameterType = "java.lang.String"  > delete from trade_mq_producer_tempwhere id  =  < /delete> < delete id = "deleteByExample"  parameterType = "com.itheima.shop.pojo.TradeMqProducerTempExample"  > delete from trade_mq_producer_temp< if test = "_parameter != null"  > < include refid = "Example_Where_Clause"  /> < /if> < /delete> < insert id = "insert"  parameterType = "com.itheima.shop.pojo.TradeMqProducerTemp"  > insert into trade_mq_producer_temp ( id, group_name, msg_topic, msg_tag, msg_key, msg_body, msg_status, create_time) values ( < /insert> < insert id = "insertSelective"  parameterType = "com.itheima.shop.pojo.TradeMqProducerTemp"  > insert into trade_mq_producer_temp< trim prefix = "("  suffix = ")"  suffixOverrides = ","  > < if test = "id != null"  > id,< /if> < if test = "groupName != null"  > group_name,< /if> < if test = "msgTopic != null"  > msg_topic,< /if> < if test = "msgTag != null"  > msg_tag,< /if> < if test = "msgKey != null"  > msg_key,< /if> < if test = "msgBody != null"  > msg_body,< /if> < if test = "msgStatus != null"  > msg_status,< /if> < if test = "createTime != null"  > create_time,< /if> < /trim> < trim prefix = "values ("  suffix = ")"  suffixOverrides = ","  > < if test = "id != null"  > < /if> < if test = "groupName != null"  > < /if> < if test = "msgTopic != null"  > < /if> < if test = "msgTag != null"  > < /if> < if test = "msgKey != null"  > < /if> < if test = "msgBody != null"  > < /if> < if test = "msgStatus != null"  > < /if> < if test = "createTime != null"  > < /if> < /trim> < /insert> < select id = "countByExample"  parameterType = "com.itheima.shop.pojo.TradeMqProducerTempExample"  resultType = "java.lang.Integer"  > select  count( *)  from trade_mq_producer_temp< if test = "_parameter != null"  > < include refid = "Example_Where_Clause"  /> < /if> < /select> < update id = "updateByExampleSelective"  parameterType = "map"  > update trade_mq_producer_temp< set > < if test = "record.id != null"  > id  =  < /if> < if test = "record.groupName != null"  > group_name =  < /if> < if test = "record.msgTopic != null"  > msg_topic =  < /if> < if test = "record.msgTag != null"  > msg_tag =  < /if> < if test = "record.msgKey != null"  > msg_key =  < /if> < if test = "record.msgBody != null"  > msg_body =  < /if> < if test = "record.msgStatus != null"  > msg_status =  < /if> < if test = "record.createTime != null"  > create_time =  < /if> < /set> < if test = "_parameter != null"  > < include refid = "Update_By_Example_Where_Clause"  /> < /if> < /update> < update id = "updateByExample"  parameterType = "map"  > update trade_mq_producer_tempset  id  =  group_name =  msg_topic =  msg_tag =  msg_key =  msg_body =  msg_status =  create_time =  < if test = "_parameter != null"  > < include refid = "Update_By_Example_Where_Clause"  /> < /if> < /update> < update id = "updateByPrimaryKeySelective"  parameterType = "com.itheima.shop.pojo.TradeMqProducerTemp"  > update trade_mq_producer_temp< set > < if test = "groupName != null"  > group_name =  < /if> < if test = "msgTopic != null"  > msg_topic =  < /if> < if test = "msgTag != null"  > msg_tag =  < /if> < if test = "msgKey != null"  > msg_key =  < /if> < if test = "msgBody != null"  > msg_body =  < /if> < if test = "msgStatus != null"  > msg_status =  < /if> < if test = "createTime != null"  > create_time =  < /if> < /set> where id  =  < /update> < update id = "updateByPrimaryKey"  parameterType = "com.itheima.shop.pojo.TradeMqProducerTemp"  > update trade_mq_producer_tempset  group_name =  msg_topic =  msg_tag =  msg_key =  msg_body =  msg_status =  create_time =  where id  =  < /update> 
< /mapper> 
< ?xml version = "1.0"  encoding = "UTF-8"  ?> 
< ! DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  "http://mybatis.org/dtd/mybatis-3-mapper.dtd"  > 
< mapper namespace = "com.itheima.shop.mapper.TradePayMapper"  > < resultMap id = "BaseResultMap"  type = "com.itheima.shop.pojo.TradePay"  > < id column = "pay_id"  property = "payId"  jdbcType = "BIGINT"  /> < result column = "order_id"  property = "orderId"  jdbcType = "BIGINT"  /> < result column = "pay_amount"  property = "payAmount"  jdbcType = "DECIMAL"  /> < result column = "is_paid"  property = "isPaid"  jdbcType = "INTEGER"  /> < /resultMap> < sql id = "Example_Where_Clause"  > < where > < foreach collection = "oredCriteria"  item = "criteria"  separator = "or"  > < if test = "criteria.valid"  > < trim prefix = "("  suffix = ")"  prefixOverrides = "and"  > < foreach collection = "criteria.criteria"  item = "criterion"  > < choose > < when test = "criterion.noValue"  > and ${criterion.condition} < /when> < when test = "criterion.singleValue"  > and ${criterion.condition}  < /when> < when test = "criterion.betweenValue"  > and ${criterion.condition}  < /when> < when test = "criterion.listValue"  > and ${criterion.condition} < foreach collection = "criterion.value"  item = "listItem"  open = "("  close = ")"  separator = ","  > < /foreach> < /when> < /choose> < /foreach> < /trim> < /if> < /foreach> < /where> < /sql> < sql id = "Update_By_Example_Where_Clause"  > < where > < foreach collection = "example.oredCriteria"  item = "criteria"  separator = "or"  > < if test = "criteria.valid"  > < trim prefix = "("  suffix = ")"  prefixOverrides = "and"  > < foreach collection = "criteria.criteria"  item = "criterion"  > < choose > < when test = "criterion.noValue"  > and ${criterion.condition} < /when> < when test = "criterion.singleValue"  > and ${criterion.condition}  < /when> < when test = "criterion.betweenValue"  > and ${criterion.condition}  < /when> < when test = "criterion.listValue"  > and ${criterion.condition} < foreach collection = "criterion.value"  item = "listItem"  open = "("  close = ")"  separator = ","  > < /foreach> < /when> < /choose> < /foreach> < /trim> < /if> < /foreach> < /where> < /sql> < sql id = "Base_Column_List"  > pay_id, order_id, pay_amount, is_paid< /sql> < select id = "selectByExample"  resultMap = "BaseResultMap"  parameterType = "com.itheima.shop.pojo.TradePayExample"  > select < if test = "distinct"  > distinct< /if> < include refid = "Base_Column_List"  /> from trade_pay< if test = "_parameter != null"  > < include refid = "Example_Where_Clause"  /> < /if> < if test = "orderByClause != null"  > order by ${orderByClause} < /if> < /select> < select id = "selectByPrimaryKey"  resultMap = "BaseResultMap"  parameterType = "java.lang.Long"  > select  < include refid = "Base_Column_List"  /> from trade_paywhere pay_id =  < /select> < delete id = "deleteByPrimaryKey"  parameterType = "java.lang.Long"  > delete from trade_paywhere pay_id =  < /delete> < delete id = "deleteByExample"  parameterType = "com.itheima.shop.pojo.TradePayExample"  > delete from trade_pay< if test = "_parameter != null"  > < include refid = "Example_Where_Clause"  /> < /if> < /delete> < insert id = "insert"  parameterType = "com.itheima.shop.pojo.TradePay"  > insert into trade_pay ( pay_id, order_id, pay_amount, is_paid) values ( < /insert> < insert id = "insertSelective"  parameterType = "com.itheima.shop.pojo.TradePay"  > insert into trade_pay< trim prefix = "("  suffix = ")"  suffixOverrides = ","  > < if test = "payId != null"  > pay_id,< /if> < if test = "orderId != null"  > order_id,< /if> < if test = "payAmount != null"  > pay_amount,< /if> < if test = "isPaid != null"  > is_paid,< /if> < /trim> < trim prefix = "values ("  suffix = ")"  suffixOverrides = ","  > < if test = "payId != null"  > < /if> < if test = "orderId != null"  > < /if> < if test = "payAmount != null"  > < /if> < if test = "isPaid != null"  > < /if> < /trim> < /insert> < select id = "countByExample"  parameterType = "com.itheima.shop.pojo.TradePayExample"  resultType = "java.lang.Integer"  > select  count( *)  from trade_pay< if test = "_parameter != null"  > < include refid = "Example_Where_Clause"  /> < /if> < /select> < update id = "updateByExampleSelective"  parameterType = "map"  > update trade_pay< set > < if test = "record.payId != null"  > pay_id =  < /if> < if test = "record.orderId != null"  > order_id =  < /if> < if test = "record.payAmount != null"  > pay_amount =  < /if> < if test = "record.isPaid != null"  > is_paid =  < /if> < /set> < if test = "_parameter != null"  > < include refid = "Update_By_Example_Where_Clause"  /> < /if> < /update> < update id = "updateByExample"  parameterType = "map"  > update trade_payset  pay_id =  order_id =  pay_amount =  is_paid =  < if test = "_parameter != null"  > < include refid = "Update_By_Example_Where_Clause"  /> < /if> < /update> < update id = "updateByPrimaryKeySelective"  parameterType = "com.itheima.shop.pojo.TradePay"  > update trade_pay< set > < if test = "orderId != null"  > order_id =  < /if> < if test = "payAmount != null"  > pay_amount =  < /if> < if test = "isPaid != null"  > is_paid =  < /if> < /set> where pay_id =  < /update> < update id = "updateByPrimaryKey"  parameterType = "com.itheima.shop.pojo.TradePay"  > update trade_payset  order_id =  pay_amount =  is_paid =  where pay_id =  < /update> 
< /mapper> 
spring.application.name = dubbo-pay-provider
spring.dubbo.application.id = dubbo-pay-provider
spring.dubbo.application.name = dubbo-pay-provider
spring.dubbo.registry.address = zookeeper://192.168.25.140:2181; zookeeper://192.168.25.140:2182; zookeeper://192.168.25.140:2183
spring.dubbo.server = true
spring.dubbo.protocol.name = dubbo
spring.dubbo.protocol.port = 20885 
spring.datasource.driverClassName = com.mysql.jdbc.Driver
spring.datasource.url = jdbc:mysql://127.0.0.1:3306/trade?useUnicode= true& characterEncoding = utf8
spring.datasource.username = root
spring.datasource.password = root
mybatis.type-aliases-package= com.itheima.shop.pojo
mybatis.mapper-locations= classpath:com/itheima/shop/mapper/*Mapper.xml
rocketmq.name-server= 192.168 .25.135:9876; 192.168 .25.138:9876
rocketmq.producer.group = payProducerGroupmq.topic = payTopic
mq.pay.tag = paidpackage com.itheima.test; import  com.itheima.api.IPayService; 
import  com.itheima.constant.ShopCode; 
import  com.itheima.shop.PayServiceApplication; 
import  com.itheima.shop.pojo.TradePay; 
import  org.apache.rocketmq.client.exception.MQBrokerException; 
import  org.apache.rocketmq.client.exception.MQClientException; 
import  org.apache.rocketmq.remoting.exception.RemotingException; 
import  org.junit.Test; 
import  org.junit.runner.RunWith; 
import  org.springframework.beans.factory.annotation.Autowired; 
import  org.springframework.boot.test.context.SpringBootTest; 
import  org.springframework.test.context.junit4.SpringRunner; import  java.io.IOException; 
import  java.math.BigDecimal; @RunWith( SpringRunner.class) 
@SpringBootTest( classes =  PayServiceApplication.class) 
public class PayServiceTest { @Autowiredprivate IPayService payService; @Testpublic void createPayment ( ) { long orderId =  351526299216515072L; TradePay tradePay =  new TradePay( ) ; tradePay.setOrderId( orderId) ; tradePay.setPayAmount( new BigDecimal( 880 )) ; payService.createPayment( tradePay) ; } @Testpublic void callbackPayment( )  throws InterruptedException, RemotingException, MQClientException, MQBrokerException, IOException { long payId =  352516176372441088L; long orderId =  351526299216515072L; TradePay tradePay =  new TradePay( ) ; tradePay.setPayId( payId) ; tradePay.setOrderId( orderId) ; tradePay.setIsPaid( ShopCode.SHOP_ORDER_PAY_STATUS_IS_PAY.getCode( )) ; payService.callbackPayment( tradePay) ; System.in.read( ) ; } } 
< ?xml version = "1.0"  encoding = "UTF-8" ?> 
< project xmlns = "http://maven.apache.org/POM/4.0.0" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation= "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" > < parent> < artifactId> shop-parent< /artifactId> < groupId> com.iteima.shop< /groupId> < version> 1.0 -SNAPSHOT< /version> < relativePath> .. /shop-parent/pom.xml< /relativePath> < /parent> < modelVersion> 4.0 .0 <> < artifactId> shop-user-service< /artifactId> < dependencies> < ! --mybatis-springboot--> < dependency> < groupId> org.mybatis.spring.boot< /groupId> < artifactId> mybatis-spring-boot-starter< /artifactId> < version> 1.3 .1 <> < /dependency> < ! -- MySQL连接驱动 --> < dependency> < groupId> mysql< /groupId> < artifactId> mysql-connector-java< /artifactId> < /dependency> < dependency> < groupId> com.iteima.shop< /groupId> < artifactId> shop-api< /artifactId> < version> 1.0 -SNAPSHOT< /version> < /dependency> < dependency> < groupId> com.iteima.shop< /groupId> < artifactId> shop-common< /artifactId> < version> 1.0 -SNAPSHOT< /version> < /dependency> < dependency> < groupId> com.iteima.shop< /groupId> < artifactId> shop-pojo< /artifactId> < version> 1.0 -SNAPSHOT< /version> < /dependency> < /dependencies> < /project> 
< ! -- D:\ java-test\ idea2019\ shop\ shop-user-service\ pom.xml --> package com.itheima.shop.mapper; import  com.itheima.shop.pojo.TradeUser; 
import  com.itheima.shop.pojo.TradeUserExample; 
import  org.apache.ibatis.annotations.Mapper; 
import  org.apache.ibatis.annotations.Param; import  java.util.List; @Mapper
public interface TradeUserMapper { int countByExample( TradeUserExample example) ; int deleteByExample( TradeUserExample example) ; int deleteByPrimaryKey( Long userId) ; int insert( TradeUser record) ; int insertSelective( TradeUser record) ; List< TradeUser>  selectByExample( TradeUserExample example) ; TradeUser selectByPrimaryKey( Long userId) ; int updateByExampleSelective( @Param( "record" )  TradeUser record, @Param( "example" )  TradeUserExample example) ; int updateByExample( @Param( "record" )  TradeUser record, @Param( "example" )  TradeUserExample example) ; int updateByPrimaryKeySelective( TradeUser record) ; int updateByPrimaryKey( TradeUser record) ; 
} 
package com.itheima.shop.mapper; import  com.itheima.shop.pojo.TradeUserMoneyLog; 
import  com.itheima.shop.pojo.TradeUserMoneyLogExample; 
import  com.itheima.shop.pojo.TradeUserMoneyLogKey; 
import  org.apache.ibatis.annotations.Mapper; 
import  org.apache.ibatis.annotations.Param; import  java.util.List; @Mapper
public interface TradeUserMoneyLogMapper { int countByExample( TradeUserMoneyLogExample example) ; int deleteByExample( TradeUserMoneyLogExample example) ; int deleteByPrimaryKey( TradeUserMoneyLogKey key) ; int insert( TradeUserMoneyLog record) ; int insertSelective( TradeUserMoneyLog record) ; List< TradeUserMoneyLog>  selectByExample( TradeUserMoneyLogExample example) ; TradeUserMoneyLog selectByPrimaryKey( TradeUserMoneyLogKey key) ; int updateByExampleSelective( @Param( "record" )  TradeUserMoneyLog record, @Param( "example" )  TradeUserMoneyLogExample example) ; int updateByExample( @Param( "record" )  TradeUserMoneyLog record, @Param( "example" )  TradeUserMoneyLogExample example) ; int updateByPrimaryKeySelective( TradeUserMoneyLog record) ; int updateByPrimaryKey( TradeUserMoneyLog record) ; 
} 
package com.itheima.shop.mq; import  com.alibaba.fastjson.JSON; 
import  com.itheima.api.IUserService; 
import  com.itheima.constant.ShopCode; 
import  com.itheima.entity.MQEntity; 
import  com.itheima.shop.pojo.TradeUserMoneyLog; 
import  lombok.extern.slf4j.Slf4j; 
import  org.apache.rocketmq.common.message.MessageExt; 
import  org.apache.rocketmq.spring.annotation.MessageModel; 
import  org.apache.rocketmq.spring.annotation.RocketMQMessageListener; 
import  org.apache.rocketmq.spring.core.RocketMQListener; 
import  org.springframework.beans.factory.annotation.Autowired; 
import  org.springframework.stereotype.Component; import  java.io.UnsupportedEncodingException; 
import  java.math.BigDecimal; @Slf4j
@Component
@RocketMQMessageListener( topic =  "${mq.order.topic} " ,consumerGroup =  "${mq.order.consumer.group.name} " ,messageModel =  MessageModel.BROADCASTING ) 
public class CancelMQListener implements RocketMQListener< MessageExt> { @Autowiredprivate IUserService userService; @Overridepublic void onMessage( MessageExt messageExt)  { try { //1.解析消息String body =  new String( messageExt.getBody( ) , "UTF-8" ) ; MQEntity mqEntity =  JSON.parseObject( body, MQEntity.class) ; log.info( "接收到消息" ) ; if( mqEntity.getUserMoney( ) != null &&  mqEntity.getUserMoney( ) .compareTo( BigDecimal.ZERO) > 0 ) { //2.调用业务层,进行余额修改TradeUserMoneyLog userMoneyLog =  new TradeUserMoneyLog( ) ; userMoneyLog.setUseMoney( mqEntity.getUserMoney( )) ; userMoneyLog.setMoneyLogType( ShopCode.SHOP_USER_MONEY_REFUND.getCode( )) ; userMoneyLog.setUserId( mqEntity.getUserId( )) ; userMoneyLog.setOrderId( mqEntity.getOrderId( )) ; userService.updateMoneyPaid( userMoneyLog) ; log.info( "余额回退成功" ) ; } }  catch ( UnsupportedEncodingException e)  { e.printStackTrace( ) ; log.error( "余额回退失败" ) ; } } 
} package com.itheima.shop.service.impl; import  com.alibaba.dubbo.config.annotation.Service; 
import  com.itheima.api.IUserService; 
import  com.itheima.constant.ShopCode; 
import  com.itheima.entity.Result; 
import  com.itheima.exception.CastException; 
import  com.itheima.shop.mapper.TradeUserMapper; 
import  com.itheima.shop.mapper.TradeUserMoneyLogMapper; 
import  com.itheima.shop.pojo.TradeUser; 
import  com.itheima.shop.pojo.TradeUserMoneyLog; 
import  com.itheima.shop.pojo.TradeUserMoneyLogExample; 
import  org.springframework.beans.factory.annotation.Autowired; 
import  org.springframework.stereotype.Component; import  java.math.BigDecimal; 
import  java.util.Date; @Component
@Service( interfaceClass =  IUserService.class) 
public class UserServiceImpl implements IUserService{ @Autowiredprivate TradeUserMapper userMapper; @Autowiredprivate TradeUserMoneyLogMapper userMoneyLogMapper; @Overridepublic TradeUser findOne( Long userId)  { if( userId== null) { CastException.cast( ShopCode.SHOP_REQUEST_PARAMETER_VALID) ; } return  userMapper.selectByPrimaryKey( userId) ; } @Overridepublic Result updateMoneyPaid( TradeUserMoneyLog userMoneyLog)  { //1.校验参数是否合法if( userMoneyLog== null || userMoneyLog.getUserId( ) == null || userMoneyLog.getOrderId( ) == null || userMoneyLog.getUseMoney( ) == null|| userMoneyLog.getUseMoney( ) .compareTo( BigDecimal.ZERO) <= 0 ) { CastException.cast( ShopCode.SHOP_REQUEST_PARAMETER_VALID) ; } //2.查询订单余额使用日志TradeUserMoneyLogExample userMoneyLogExample =  new TradeUserMoneyLogExample( ) ; TradeUserMoneyLogExample.Criteria criteria =  userMoneyLogExample.createCriteria( ) ; criteria.andOrderIdEqualTo( userMoneyLog.getOrderId( )) ; criteria.andUserIdEqualTo( userMoneyLog.getUserId( )) ; int r =  userMoneyLogMapper.countByExample( userMoneyLogExample) ; TradeUser tradeUser =  userMapper.selectByPrimaryKey( userMoneyLog.getUserId( )) ; //3.扣减余额.. .if( userMoneyLog.getMoneyLogType( ) .intValue( ) == ShopCode.SHOP_USER_MONEY_PAID.getCode( ) .intValue( )) { if( r> 0 ) { //已经付款CastException.cast( ShopCode.SHOP_ORDER_PAY_STATUS_IS_PAY) ; } //减余额tradeUser.setUserMoney( new BigDecimal( tradeUser.getUserMoney( )) .subtract( userMoneyLog.getUseMoney( )) .longValue( )) ; userMapper.updateByPrimaryKey( tradeUser) ; } //4.回退余额.. .if( userMoneyLog.getMoneyLogType( ) .intValue( ) == ShopCode.SHOP_USER_MONEY_REFUND.getCode( ) .intValue( )) { if( r< 0 ) { //如果没有支付,则不能回退余额CastException.cast( ShopCode.SHOP_ORDER_PAY_STATUS_NO_PAY) ; } //防止多次退款TradeUserMoneyLogExample userMoneyLogExample2 =  new TradeUserMoneyLogExample( ) ; TradeUserMoneyLogExample.Criteria criteria1 =  userMoneyLogExample2.createCriteria( ) ; criteria1.andOrderIdEqualTo( userMoneyLog.getOrderId( )) ; criteria1.andUserIdEqualTo( userMoneyLog.getUserId( )) ; criteria1.andMoneyLogTypeEqualTo( ShopCode.SHOP_USER_MONEY_REFUND.getCode( )) ; int r2 =  userMoneyLogMapper.countByExample( userMoneyLogExample2) ; if( r2 >0 ) { CastException.cast( ShopCode.SHOP_USER_MONEY_REFUND_ALREADY) ; } //退款tradeUser.setUserMoney( new BigDecimal( tradeUser.getUserMoney( )) .add( userMoneyLog.getUseMoney( )) .longValue( )) ; userMapper.updateByPrimaryKey( tradeUser) ; } //5.记录订单余额使用日志userMoneyLog.setCreateTime( new Date( )) ; userMoneyLogMapper.insert( userMoneyLog) ; return  new Result( ShopCode.SHOP_SUCCESS.getSuccess( ) ,ShopCode.SHOP_SUCCESS.getMessage( )) ; } 
} package com.itheima.shop; import  com.alibaba.dubbo.spring.boot.annotation.EnableDubboConfiguration; 
import  org.springframework.boot.SpringApplication; 
import  org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication
@EnableDubboConfiguration
public class UserServiceApplication { public static void main( String[ ]  args)  { SpringApplication.run( UserServiceApplication.class,args) ; } } < ?xml version = "1.0"  encoding = "UTF-8"  ?> 
< ! DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  "http://mybatis.org/dtd/mybatis-3-mapper.dtd"  > 
< mapper namespace = "com.itheima.shop.mapper.TradeUserMapper"  > < resultMap id = "BaseResultMap"  type = "com.itheima.shop.pojo.TradeUser"  > < id column = "user_id"  property = "userId"  jdbcType = "BIGINT"  /> < result column = "user_name"  property = "userName"  jdbcType = "VARCHAR"  /> < result column = "user_password"  property = "userPassword"  jdbcType = "VARCHAR"  /> < result column = "user_mobile"  property = "userMobile"  jdbcType = "VARCHAR"  /> < result column = "user_score"  property = "userScore"  jdbcType = "INTEGER"  /> < result column = "user_reg_time"  property = "userRegTime"  jdbcType = "TIMESTAMP"  /> < result column = "user_money"  property = "userMoney"  jdbcType = "DECIMAL"  /> < /resultMap> < sql id = "Example_Where_Clause"  > < where > < foreach collection = "oredCriteria"  item = "criteria"  separator = "or"  > < if test = "criteria.valid"  > < trim prefix = "("  suffix = ")"  prefixOverrides = "and"  > < foreach collection = "criteria.criteria"  item = "criterion"  > < choose > < when test = "criterion.noValue"  > and ${criterion.condition} < /when> < when test = "criterion.singleValue"  > and ${criterion.condition}  < /when> < when test = "criterion.betweenValue"  > and ${criterion.condition}  < /when> < when test = "criterion.listValue"  > and ${criterion.condition} < foreach collection = "criterion.value"  item = "listItem"  open = "("  close = ")"  separator = ","  > < /foreach> < /when> < /choose> < /foreach> < /trim> < /if> < /foreach> < /where> < /sql> < sql id = "Update_By_Example_Where_Clause"  > < where > < foreach collection = "example.oredCriteria"  item = "criteria"  separator = "or"  > < if test = "criteria.valid"  > < trim prefix = "("  suffix = ")"  prefixOverrides = "and"  > < foreach collection = "criteria.criteria"  item = "criterion"  > < choose > < when test = "criterion.noValue"  > and ${criterion.condition} < /when> < when test = "criterion.singleValue"  > and ${criterion.condition}  < /when> < when test = "criterion.betweenValue"  > and ${criterion.condition}  < /when> < when test = "criterion.listValue"  > and ${criterion.condition} < foreach collection = "criterion.value"  item = "listItem"  open = "("  close = ")"  separator = ","  > < /foreach> < /when> < /choose> < /foreach> < /trim> < /if> < /foreach> < /where> < /sql> < sql id = "Base_Column_List"  > user_id, user_name, user_password, user_mobile, user_score, user_reg_time, user_money< /sql> < select id = "selectByExample"  resultMap = "BaseResultMap"  parameterType = "com.itheima.shop.pojo.TradeUserExample"  > select < if test = "distinct"  > distinct< /if> < include refid = "Base_Column_List"  /> from trade_user< if test = "_parameter != null"  > < include refid = "Example_Where_Clause"  /> < /if> < if test = "orderByClause != null"  > order by ${orderByClause} < /if> < /select> < select id = "selectByPrimaryKey"  resultMap = "BaseResultMap"  parameterType = "java.lang.Long"  > select  < include refid = "Base_Column_List"  /> from trade_userwhere user_id =  < /select> < delete id = "deleteByPrimaryKey"  parameterType = "java.lang.Long"  > delete from trade_userwhere user_id =  < /delete> < delete id = "deleteByExample"  parameterType = "com.itheima.shop.pojo.TradeUserExample"  > delete from trade_user< if test = "_parameter != null"  > < include refid = "Example_Where_Clause"  /> < /if> < /delete> < insert id = "insert"  parameterType = "com.itheima.shop.pojo.TradeUser"  > insert into trade_user ( user_id, user_name, user_password, user_mobile, user_score, user_reg_time, user_money) values ( < /insert> < insert id = "insertSelective"  parameterType = "com.itheima.shop.pojo.TradeUser"  > insert into trade_user< trim prefix = "("  suffix = ")"  suffixOverrides = ","  > < if test = "userId != null"  > user_id,< /if> < if test = "userName != null"  > user_name,< /if> < if test = "userPassword != null"  > user_password,< /if> < if test = "userMobile != null"  > user_mobile,< /if> < if test = "userScore != null"  > user_score,< /if> < if test = "userRegTime != null"  > user_reg_time,< /if> < if test = "userMoney != null"  > user_money,< /if> < /trim> < trim prefix = "values ("  suffix = ")"  suffixOverrides = ","  > < if test = "userId != null"  > < /if> < if test = "userName != null"  > < /if> < if test = "userPassword != null"  > < /if> < if test = "userMobile != null"  > < /if> < if test = "userScore != null"  > < /if> < if test = "userRegTime != null"  > < /if> < if test = "userMoney != null"  > < /if> < /trim> < /insert> < select id = "countByExample"  parameterType = "com.itheima.shop.pojo.TradeUserExample"  resultType = "java.lang.Integer"  > select  count( *)  from trade_user< if test = "_parameter != null"  > < include refid = "Example_Where_Clause"  /> < /if> < /select> < update id = "updateByExampleSelective"  parameterType = "map"  > update trade_user< set > < if test = "record.userId != null"  > user_id =  < /if> < if test = "record.userName != null"  > user_name =  < /if> < if test = "record.userPassword != null"  > user_password =  < /if> < if test = "record.userMobile != null"  > user_mobile =  < /if> < if test = "record.userScore != null"  > user_score =  < /if> < if test = "record.userRegTime != null"  > user_reg_time =  < /if> < if test = "record.userMoney != null"  > user_money =  < /if> < /set> < if test = "_parameter != null"  > < include refid = "Update_By_Example_Where_Clause"  /> < /if> < /update> < update id = "updateByExample"  parameterType = "map"  > update trade_userset  user_id =  user_name =  user_password =  user_mobile =  user_score =  user_reg_time =  user_money =  < if test = "_parameter != null"  > < include refid = "Update_By_Example_Where_Clause"  /> < /if> < /update> < update id = "updateByPrimaryKeySelective"  parameterType = "com.itheima.shop.pojo.TradeUser"  > update trade_user< set > < if test = "userName != null"  > user_name =  < /if> < if test = "userPassword != null"  > user_password =  < /if> < if test = "userMobile != null"  > user_mobile =  < /if> < if test = "userScore != null"  > user_score =  < /if> < if test = "userRegTime != null"  > user_reg_time =  < /if> < if test = "userMoney != null"  > user_money =  < /if> < /set> where user_id =  < /update> < update id = "updateByPrimaryKey"  parameterType = "com.itheima.shop.pojo.TradeUser"  > update trade_userset  user_name =  user_password =  user_mobile =  user_score =  user_reg_time =  user_money =  where user_id =  < /update> 
< /mapper> 
< ?xml version = "1.0"  encoding = "UTF-8"  ?> 
< ! DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  "http://mybatis.org/dtd/mybatis-3-mapper.dtd"  > 
< mapper namespace = "com.itheima.shop.mapper.TradeUserMoneyLogMapper"  > < resultMap id = "BaseResultMap"  type = "com.itheima.shop.pojo.TradeUserMoneyLog"  > < id column = "user_id"  property = "userId"  jdbcType = "BIGINT"  /> < id column = "order_id"  property = "orderId"  jdbcType = "BIGINT"  /> < id column = "money_log_type"  property = "moneyLogType"  jdbcType = "INTEGER"  /> < result column = "use_money"  property = "useMoney"  jdbcType = "DECIMAL"  /> < result column = "create_time"  property = "createTime"  jdbcType = "TIMESTAMP"  /> < /resultMap> < sql id = "Example_Where_Clause"  > < where > < foreach collection = "oredCriteria"  item = "criteria"  separator = "or"  > < if test = "criteria.valid"  > < trim prefix = "("  suffix = ")"  prefixOverrides = "and"  > < foreach collection = "criteria.criteria"  item = "criterion"  > < choose > < when test = "criterion.noValue"  > and ${criterion.condition} < /when> < when test = "criterion.singleValue"  > and ${criterion.condition}  < /when> < when test = "criterion.betweenValue"  > and ${criterion.condition}  < /when> < when test = "criterion.listValue"  > and ${criterion.condition} < foreach collection = "criterion.value"  item = "listItem"  open = "("  close = ")"  separator = ","  > < /foreach> < /when> < /choose> < /foreach> < /trim> < /if> < /foreach> < /where> < /sql> < sql id = "Update_By_Example_Where_Clause"  > < where > < foreach collection = "example.oredCriteria"  item = "criteria"  separator = "or"  > < if test = "criteria.valid"  > < trim prefix = "("  suffix = ")"  prefixOverrides = "and"  > < foreach collection = "criteria.criteria"  item = "criterion"  > < choose > < when test = "criterion.noValue"  > and ${criterion.condition} < /when> < when test = "criterion.singleValue"  > and ${criterion.condition}  < /when> < when test = "criterion.betweenValue"  > and ${criterion.condition}  < /when> < when test = "criterion.listValue"  > and ${criterion.condition} < foreach collection = "criterion.value"  item = "listItem"  open = "("  close = ")"  separator = ","  > < /foreach> < /when> < /choose> < /foreach> < /trim> < /if> < /foreach> < /where> < /sql> < sql id = "Base_Column_List"  > user_id, order_id, money_log_type, use_money, create_time< /sql> < select id = "selectByExample"  resultMap = "BaseResultMap"  parameterType = "com.itheima.shop.pojo.TradeUserMoneyLogExample"  > select < if test = "distinct"  > distinct< /if> < include refid = "Base_Column_List"  /> from trade_user_money_log< if test = "_parameter != null"  > < include refid = "Example_Where_Clause"  /> < /if> < if test = "orderByClause != null"  > order by ${orderByClause} < /if> < /select> < select id = "selectByPrimaryKey"  resultMap = "BaseResultMap"  parameterType = "com.itheima.shop.pojo.TradeUserMoneyLogKey"  > select  < include refid = "Base_Column_List"  /> from trade_user_money_logwhere user_id =  and order_id =  and money_log_type =  < /select> < delete id = "deleteByPrimaryKey"  parameterType = "com.itheima.shop.pojo.TradeUserMoneyLogKey"  > delete from trade_user_money_logwhere user_id =  and order_id =  and money_log_type =  < /delete> < delete id = "deleteByExample"  parameterType = "com.itheima.shop.pojo.TradeUserMoneyLogExample"  > delete from trade_user_money_log< if test = "_parameter != null"  > < include refid = "Example_Where_Clause"  /> < /if> < /delete> < insert id = "insert"  parameterType = "com.itheima.shop.pojo.TradeUserMoneyLog"  > insert into trade_user_money_log ( user_id, order_id, money_log_type, use_money, create_time) values ( < /insert> < insert id = "insertSelective"  parameterType = "com.itheima.shop.pojo.TradeUserMoneyLog"  > insert into trade_user_money_log< trim prefix = "("  suffix = ")"  suffixOverrides = ","  > < if test = "userId != null"  > user_id,< /if> < if test = "orderId != null"  > order_id,< /if> < if test = "moneyLogType != null"  > money_log_type,< /if> < if test = "useMoney != null"  > use_money,< /if> < if test = "createTime != null"  > create_time,< /if> < /trim> < trim prefix = "values ("  suffix = ")"  suffixOverrides = ","  > < if test = "userId != null"  > < /if> < if test = "orderId != null"  > < /if> < if test = "moneyLogType != null"  > < /if> < if test = "useMoney != null"  > < /if> < if test = "createTime != null"  > < /if> < /trim> < /insert> < select id = "countByExample"  parameterType = "com.itheima.shop.pojo.TradeUserMoneyLogExample"  resultType = "java.lang.Integer"  > select  count( *)  from trade_user_money_log< if test = "_parameter != null"  > < include refid = "Example_Where_Clause"  /> < /if> < /select> < update id = "updateByExampleSelective"  parameterType = "map"  > update trade_user_money_log< set > < if test = "record.userId != null"  > user_id =  < /if> < if test = "record.orderId != null"  > order_id =  < /if> < if test = "record.moneyLogType != null"  > money_log_type =  < /if> < if test = "record.useMoney != null"  > use_money =  < /if> < if test = "record.createTime != null"  > create_time =  < /if> < /set> < if test = "_parameter != null"  > < include refid = "Update_By_Example_Where_Clause"  /> < /if> < /update> < update id = "updateByExample"  parameterType = "map"  > update trade_user_money_logset  user_id =  order_id =  money_log_type =  use_money =  create_time =  < if test = "_parameter != null"  > < include refid = "Update_By_Example_Where_Clause"  /> < /if> < /update> < update id = "updateByPrimaryKeySelective"  parameterType = "com.itheima.shop.pojo.TradeUserMoneyLog"  > update trade_user_money_log< set > < if test = "useMoney != null"  > use_money =  < /if> < if test = "createTime != null"  > create_time =  < /if> < /set> where user_id =  and order_id =  and money_log_type =  < /update> < update id = "updateByPrimaryKey"  parameterType = "com.itheima.shop.pojo.TradeUserMoneyLog"  > update trade_user_money_logset  use_money =  create_time =  where user_id =  and order_id =  and money_log_type =  < /update> 
< /mapper> 
spring.application.name = dubbo-user-provider
spring.dubbo.application.id = dubbo-user-provider
spring.dubbo.application.name = dubbo-user-provider
spring.dubbo.registry.address = zookeeper://192.168.25.140:2181; zookeeper://192.168.25.140:2182; zookeeper://192.168.25.140:2183
spring.dubbo.server = true
spring.dubbo.protocol.name = dubbo
spring.dubbo.protocol.port = 20883 
spring.datasource.driverClassName = com.mysql.jdbc.Driver
spring.datasource.url = jdbc:mysql://127.0.0.1:3306/trade?useUnicode= true& characterEncoding = utf8
spring.datasource.username = root
spring.datasource.password = root
mybatis.type-aliases-package= com.itheima.shop.pojo
mybatis.mapper-locations= classpath:com/itheima/shop/mapper/*Mapper.xml
rocketmq.name-server= 192.168 .25.135:9876; 192.168 .25.138:9876
rocketmq.producer.group = orderProducerGroupmq.order.consumer.group.name = order_orderTopic_cancel_group
mq.order.topic = orderTopic
< ?xml version = "1.0"  encoding = "UTF-8" ?> 
< project xmlns = "http://maven.apache.org/POM/4.0.0" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation= "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" > < parent> < artifactId> shop-parent< /artifactId> < groupId> com.iteima.shop< /groupId> < version> 1.0 -SNAPSHOT< /version> < relativePath> .. /shop-parent/pom.xml< /relativePath> < /parent> < modelVersion> 4.0 .0 <> < artifactId> shop-order-web< /artifactId> < dependencies> < ! --spring-webmvc--> < dependency> < groupId> org.springframework.boot< /groupId> < artifactId> spring-boot-starter-web< /artifactId> < /dependency> < ! --API--> < dependency> < groupId> com.iteima.shop< /groupId> < artifactId> shop-api< /artifactId> < version> 1.0 -SNAPSHOT< /version> < /dependency> < dependency> < groupId> com.iteima.shop< /groupId> < artifactId> shop-common< /artifactId> < version> 1.0 -SNAPSHOT< /version> < /dependency> < /dependencies> < /project> 
< ! -- D:\ java-test\ idea2019\ shop\ shop-order-web\ pom.xml --> package com.itheima.shop; import  com.alibaba.dubbo.spring.boot.annotation.EnableDubboConfiguration; 
import  org.springframework.boot.SpringApplication; 
import  org.springframework.boot.autoconfigure.SpringBootApplication; @EnableDubboConfiguration
@SpringBootApplication
public class OrderWebApplication { public static void main( String[ ]  args)  { SpringApplication.run( OrderWebApplication.class,args) ; } } package com.itheima.shop.controller; import  com.alibaba.dubbo.config.annotation.Reference; 
import  com.itheima.api.IOrderService; 
import  com.itheima.entity.Result; 
import  com.itheima.shop.pojo.TradeOrder; 
import  org.springframework.web.bind.annotation.RequestBody; 
import  org.springframework.web.bind.annotation.RequestMapping; 
import  org.springframework.web.bind.annotation.RestController; @RestController
@RequestMapping( "/order" ) 
public class OrderControllre { @Referenceprivate IOrderService orderService; @RequestMapping( "/confirm" ) public Result confirmOrder( @RequestBody TradeOrder order) { return  orderService.confirmOrder( order) ; } } package com.itheima.shop.config; import  org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 
import  org.springframework.context.annotation.Bean; 
import  org.springframework.context.annotation.Configuration; 
import  org.springframework.http.client.ClientHttpRequestFactory; 
import  org.springframework.http.client.SimpleClientHttpRequestFactory; 
import  org.springframework.http.converter.HttpMessageConverter; 
import  org.springframework.http.converter.StringHttpMessageConverter; 
import  org.springframework.web.client.RestOperations; 
import  org.springframework.web.client.RestTemplate; import  java.nio.charset.Charset; 
import  java.util.Iterator; 
import  java.util.List; @Configuration
public class RestTemplateConfig { @Bean@ConditionalOnMissingBean( {  RestOperations.class, RestTemplate.class } ) public RestTemplate restTemplate( ClientHttpRequestFactory factory)  { RestTemplate restTemplate =  new RestTemplate( factory) ; // 使用 utf-8 编码集的 conver 替换默认的 conver(默认的 string conver 的编码集为"ISO-8859-1" )List< HttpMessageConverter< ?>>  messageConverters =  restTemplate.getMessageConverters( ) ; Iterator< HttpMessageConverter< ?>>  iterator =  messageConverters.iterator( ) ; while  ( iterator.hasNext( ))  { HttpMessageConverter< ?>  converter =  iterator.next( ) ; if  ( converter instanceof StringHttpMessageConverter)  { iterator.remove( ) ; } } messageConverters.add( new StringHttpMessageConverter( Charset.forName( "UTF-8" )) ) ; return  restTemplate; } @Bean@ConditionalOnMissingBean( { ClientHttpRequestFactory.class} ) public ClientHttpRequestFactory simpleClientHttpRequestFactory ( )  { SimpleClientHttpRequestFactory factory =  new SimpleClientHttpRequestFactory( ) ; // msfactory.setReadTimeout( 15000 ) ; // msfactory.setConnectTimeout( 15000 ) ; return  factory; } } server.host = http://localhost
server.servlet.path = /order-web
server.port = 8080 
spring.application.name = dubbo-order-consumer
spring.dubbo.application.id = dubbo-order-consumer
spring.dubbo.application.name = dubbo-order-consumer
spring.dubbo.registry.address = zookeeper://192.168.25.140:2181; zookeeper://192.168.25.140:2182; zookeeper://192.168.25.140:2183order.port = 8080 
shop.order.baseURI = ${server.host} : ${order.port} ${server.servlet.path} 
shop.order.confirm = /order/confirm
package com.itheima.test; import  com.itheima.entity.Result; 
import  com.itheima.shop.OrderWebApplication; 
import  com.itheima.shop.pojo.TradeOrder; 
import  org.junit.Test; 
import  org.junit.runner.RunWith; 
import  org.springframework.beans.factory.annotation.Autowired; 
import  org.springframework.beans.factory.annotation.Value; 
import  org.springframework.boot.test.context.SpringBootTest; 
import  org.springframework.test.context.junit4.SpringRunner; 
import  org.springframework.web.client.RestTemplate; import  java.math.BigDecimal; @RunWith( SpringRunner.class) 
@SpringBootTest( classes =  OrderWebApplication.class) 
public class OrderWebTest { @Autowiredprivate RestTemplate restTemplate; @Value( "${shop.order.baseURI} " ) private String baseURI; @Value( "${shop.order.confirm} " ) private String confirmOrderPath; @Testpublic void confirmOrder ( ) { Long coupouId =  345988230098857984L; Long goodsId =  345959443973935104L; Long userId =  345963634385633280L; TradeOrder order =  new TradeOrder( ) ; order.setGoodsId( goodsId) ; order.setUserId( userId) ; order.setCouponId( coupouId) ; order.setAddress( "北京" ) ; order.setGoodsNumber( 1 ) ; order.setGoodsPrice( new BigDecimal( 1000 )) ; order.setShippingFee( BigDecimal.ZERO) ; order.setOrderAmount( new BigDecimal( 1000 )) ; order.setMoneyPaid( new BigDecimal( 100 )) ; Result result =  restTemplate.postForEntity( baseURI + confirmOrderPath, order, Result.class) .getBody( ) ; System.out.println( result) ; } } 
< ?xml version = "1.0"  encoding = "UTF-8" ?> 
< project xmlns = "http://maven.apache.org/POM/4.0.0" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation= "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" > < parent> < artifactId> shop-parent< /artifactId> < groupId> com.iteima.shop< /groupId> < version> 1.0 -SNAPSHOT< /version> < relativePath> .. /shop-parent/pom.xml< /relativePath> < /parent> < modelVersion> 4.0 .0 <> < artifactId> shop-pay-web< /artifactId> < dependencies> < ! --spring-webmvc--> < dependency> < groupId> org.springframework.boot< /groupId> < artifactId> spring-boot-starter-web< /artifactId> < /dependency> < ! --API--> < dependency> < groupId> com.iteima.shop< /groupId> < artifactId> shop-api< /artifactId> < version> 1.0 -SNAPSHOT< /version> < /dependency> < dependency> < groupId> com.iteima.shop< /groupId> < artifactId> shop-common< /artifactId> < version> 1.0 -SNAPSHOT< /version> < /dependency> < /dependencies> < /project> 
< ! -- D:\ java-test\ idea2019\ shop\ shop-pay-web\ pom.xml --> package com.itheima.shop; import  com.alibaba.dubbo.spring.boot.annotation.EnableDubboConfiguration; 
import  org.springframework.boot.SpringApplication; 
import  org.springframework.boot.autoconfigure.SpringBootApplication; @EnableDubboConfiguration
@SpringBootApplication
public class PayWebApplication { public static void main( String[ ]  args)  { SpringApplication.run( PayWebApplication.class,args) ; } } package com.itheima.shop.controller; import  com.alibaba.dubbo.config.annotation.Reference; 
import  com.itheima.api.IPayService; 
import  com.itheima.entity.Result; 
import  com.itheima.shop.pojo.TradePay; 
import  org.springframework.web.bind.annotation.RequestBody; 
import  org.springframework.web.bind.annotation.RequestMapping; 
import  org.springframework.web.bind.annotation.RestController; @RestController
@RequestMapping( "/pay" ) 
public class PayController { @Referenceprivate IPayService payService; @RequestMapping( "/createPayment" ) public Result createPayment( @RequestBody TradePay pay) { return  payService.createPayment( pay) ; } @RequestMapping( "/callBackPayment" ) public Result callBackPayment( @RequestBody TradePay pay)  throws Exception { return  payService.callbackPayment( pay) ; } } package com.itheima.shop.config; import  org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 
import  org.springframework.context.annotation.Bean; 
import  org.springframework.context.annotation.Configuration; 
import  org.springframework.http.client.ClientHttpRequestFactory; 
import  org.springframework.http.client.SimpleClientHttpRequestFactory; 
import  org.springframework.http.converter.HttpMessageConverter; 
import  org.springframework.http.converter.StringHttpMessageConverter; 
import  org.springframework.web.client.RestOperations; 
import  org.springframework.web.client.RestTemplate; import  java.nio.charset.Charset; 
import  java.util.Iterator; 
import  java.util.List; @Configuration
public class RestTemplateConfig { @Bean@ConditionalOnMissingBean( {  RestOperations.class, RestTemplate.class } ) public RestTemplate restTemplate( ClientHttpRequestFactory factory)  { RestTemplate restTemplate =  new RestTemplate( factory) ; // 使用 utf-8 编码集的 conver 替换默认的 conver(默认的 string conver 的编码集为"ISO-8859-1" )List< HttpMessageConverter< ?>>  messageConverters =  restTemplate.getMessageConverters( ) ; Iterator< HttpMessageConverter< ?>>  iterator =  messageConverters.iterator( ) ; while  ( iterator.hasNext( ))  { HttpMessageConverter< ?>  converter =  iterator.next( ) ; if  ( converter instanceof StringHttpMessageConverter)  { iterator.remove( ) ; } } messageConverters.add( new StringHttpMessageConverter( Charset.forName( "UTF-8" )) ) ; return  restTemplate; } @Bean@ConditionalOnMissingBean( { ClientHttpRequestFactory.class} ) public ClientHttpRequestFactory simpleClientHttpRequestFactory ( )  { SimpleClientHttpRequestFactory factory =  new SimpleClientHttpRequestFactory( ) ; // msfactory.setReadTimeout( 15000 ) ; // msfactory.setConnectTimeout( 15000 ) ; return  factory; } } server.host = http://localhost
server.servlet.path = /pay-web
server.port = 9090 
spring.application.name = dubbo-pay-consumer
spring.dubbo.application.id = dubbo-pay-consumer
spring.dubbo.application.name = dubbo-pay-consumer
spring.dubbo.registry.address = zookeeper://192.168.25.140:2181; zookeeper://192.168.25.140:2182; zookeeper://192.168.25.140:2183pay.port = 9090 shop.pay.baseURI = ${server.host} : ${pay.port} ${server.servlet.path} shop.pay.createPayment = /pay/createPaymentshop.pay.callbackPayment = /pay/callBackPaymentpackage com.itheima.test; import  com.itheima.constant.ShopCode; 
import  com.itheima.entity.Result; 
import  com.itheima.shop.PayWebApplication; 
import  com.itheima.shop.pojo.TradePay; 
import  org.junit.Test; 
import  org.junit.runner.RunWith; 
import  org.springframework.beans.factory.annotation.Autowired; 
import  org.springframework.beans.factory.annotation.Value; 
import  org.springframework.boot.test.context.SpringBootTest; 
import  org.springframework.test.context.junit4.SpringRunner; 
import  org.springframework.web.client.RestTemplate; import  java.math.BigDecimal; @RunWith( SpringRunner.class) 
@SpringBootTest( classes =  PayWebApplication.class) 
public class PayWebTest { @Autowiredprivate RestTemplate restTemplate; @Value( "${shop.pay.baseURI} " ) private String baseURI; @Value( "${shop.pay.createPayment} " ) private String createPaymentPath; @Value( "${shop.pay.callbackPayment} " ) private String callBackPaymentPath; @Testpublic void createPayment ( ) { long orderId =  352537369385242624L; TradePay tradePay =  new TradePay( ) ; tradePay.setOrderId( orderId) ; tradePay.setPayAmount( new BigDecimal( 880 )) ; Result result =  restTemplate.postForEntity( baseURI + createPaymentPath, tradePay, Result.class) .getBody( ) ; System.out.println( result) ; } @Testpublic void callBackPayment ( ) { long payId =  352542415984402432L; long orderId =  352537369385242624L; TradePay tradePay =  new TradePay( ) ; tradePay.setPayId( payId) ; tradePay.setOrderId( orderId) ; tradePay.setIsPaid( ShopCode.SHOP_ORDER_PAY_STATUS_IS_PAY.getCode( )) ; Result result =  restTemplate.postForEntity( baseURI + callBackPaymentPath, tradePay, Result.class) .getBody( ) ; System.out.println( result) ; } } 
< ?xml version = "1.0"  encoding = "UTF-8" ?> 
< project xmlns = "http://maven.apache.org/POM/4.0.0" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation= "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" > < parent> < artifactId> shop-parent< /artifactId> < groupId> com.iteima.shop< /groupId> < version> 1.0 -SNAPSHOT< /version> < relativePath> .. /shop-parent/pom.xml< /relativePath> < /parent> < modelVersion> 4.0 .0 <> < artifactId> shop-pojo< /artifactId> < /project> 
< ! -- D:\ java-test\ idea2019\ shop\ shop-pojo\ pom.xml --> 上一节关联链接请点击: