SpringCLoud+redis+es high concurrency project "Eleven"

Chapter 11 Orders

learning target

  • Configuration of the login page
  • Login successful jump implementation
  • Checkout page query implementation
  • Order fulfillment
  • change inventory
  • Increase points
  • Payment process introduction
  • Introduction to WeChat scan code payment

1 Login page configuration

The previous ones used Postman to implement login, and then we implemented an oauth custom login.

1.1 Preparation

(1) Static resource import

Import 资料/页面/前端login-related static resources into changgou-user-oauth, as shown below.

[The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-MqwntCRE-1619422686357)(images\1562915052385.png)]

(2)Introduce thymeleaf

Modify changgou-user-oauth and introduce thymeleaf template engine

<!--thymeleaf-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

(3)Login configuration

Modify changgou-user-oauth and write a controller com.changgou.oauth.controller.LoginRedirectto jump to the login page. The code is as follows:

@Controller
@RequestMapping(value = "/oauth")
public class LoginRedirect {
    
    

    /***
     * 跳转到登录页面
     * @return
     */
    @GetMapping(value = "/login")
    public String login(){
    
    
        return "login";
    }
}

(4)Login page configuration

For static resources and login pages, we need to ignore security configuration and specify the login page. com.changgou.oauth.config.WebSecurityConfigThe two modified configuremethods, the codes are as follows:

Configuration 1 configure:

[The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-nP9SfX5q-1619422686359) (images\1562915569036.png)]

2nd configureconfiguration:

[The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-Zz0qBzwf-1619422686361)(images\1562915628959.png)]

test

[The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-5E0kFBBq-1619422686363)(images\1562915685045.png)]

1.2 Login implementation

Click the login button and access the previous login method to log in. We need to make some adjustments to the login page.

(1)Introducing the thymeleaf namespace

Modify login.html and introduce namespace

[The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-5VpD971f-1619422686364) (images\1562915939313.png)]

(2)Login script

Click the login button and use vue+axios to log in. We need to define a script to access the background login method.

First add the vue entrance tag: modify login.html and add id="app" to the tag around line 73. The code is as follows:

[The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-ghE3g8aX-1619422686364) (images\1562916130104.png)]

Introduce js

<script src="/js/vue.js"></script>
<script src="/js/axios.js"></script>

Login script implementation:

[The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-lR00vq7y-1619422686365)(images\1562916232437.png)]

(3)Form modification

[The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-7ddCYjcV-1619422686365)(images\1562916009358.png)]

(4) Test

[The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-sJYbEyNr-1619422686366)(images\1562916296639.png)]

1.3 Login jump

When the user is not logged in, we directly access the shopping cart, the effect is as follows:

[The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-h3FQimJF-1619422686366) (images\1565298003250.png)]

We can find that what is returned is only an error status code, which is inconvenient for testing. We can redirect to the login page to allow users to log in. We can modify the header file of the gateway so that users will jump to login every time they are not logged in. page.

Modify changgou-gateway-web com.changgou.filter.AuthorizeFilter, the code is as follows:

[The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-tJs5cBWq-1619422686366)(images\1565298291291.png)]

Test again at this time and you can jump to the login page. Of course, at work, you cannot jump directly to the login page. You should prompt the status to the page and let the page jump based on judgment. This is just for the convenience of testing.

1.4 After successful login, jump to the original access page

[The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-vOCkVD2U-1619422686367) (images\1562918951886.png)]

Although the login jump is implemented above, it does not return to the shopping cart page after successful login. We can pass the page that the user wants to visit as a parameter to the login controller, and the login controller records it. Every time the login is successful, Afterwards, just jump to the record and access the page specified by the path parameter.

(1) Modify the gateway to carry the current URI

Modify changgou-gateway-web com.changgou.filter.AuthorizeFilter, add the FROM parameter and the value of the FROM parameter after the previous URL request.getURI(). The code is as follows:

[The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-f8Ik3zm0-1619422686367) (images\1565298329794.png)]

(2) The authentication server obtains FROM parameters

com.changgou.oauth.controller.LoginRedirectModify the record access source page of changgou-user-oauth , the code is as follows:

[The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-qL6zEJRt-1619422686368)(images\1562919857116.png)]

Modify the page, obtain the source page information, and store it in the from variable. After successful login, jump to this address.

[The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-bc3C5vbh-1619422686368) (images\1562919950185.png)]

If you test again at this time, you can identify the user who is not logged in, jump to the login page, and then according to the login status, if the login is successful, jump to the source page.

2 Order Closing Page

2.1 Analysis of receiving address

The user clicks checkout from the shopping cart page and jumps to the order settlement page. The settlement page needs to load the user's corresponding receiving address, as shown below:

[The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-7uUpkiK3-1619422686368)(images\1558301821667.png)]

Table structure analysis:

CREATE TABLE `tb_address` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(50) DEFAULT NULL COMMENT '用户名',
  `provinceid` varchar(20) DEFAULT NULL COMMENT '省',
  `cityid` varchar(20) DEFAULT NULL COMMENT '市',
  `areaid` varchar(20) DEFAULT NULL COMMENT '县/区',
  `phone` varchar(20) DEFAULT NULL COMMENT '电话',
  `address` varchar(200) DEFAULT NULL COMMENT '详细地址',
  `contact` varchar(50) DEFAULT NULL COMMENT '联系人',
  `is_default` varchar(1) DEFAULT NULL COMMENT '是否是默认 1默认 0否',
  `alias` varchar(50) DEFAULT NULL COMMENT '别名',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=66 DEFAULT CHARSET=utf8;

We can query the corresponding data in the tb_address table based on the user's login name.

2.2 Implement user receiving address query

2.2.1 Code implementation

(1) Business layer

Business layer interface

To modify the changgou-service-user microservice, you need to change the com.changgou.user.service.AddressService interface and add query for user receiving address information based on the user name. The code is as follows:

/***
 * 收件地址查询
 * @param username
 * @return
 */
List<Address> list(String username);

Business layer interface implementation class

Modify the changgou-service-user microservice, modify the com.changgou.user.service.impl.AddressServiceImpl class, and add the implementation method of querying the user's receiving address information based on the user, as follows:

/***
 * 收件地址查询
 * @param username
 * @return
 */
@Override
public List<Address> list(String username) {
    
    
    Address address = new Address();
    address.setUsername(username);
    return addressMapper.select(address);
}

(2)Control layer

Modify the changgou-service-user microservice, modify com.changgou.user.controller.AddressController, and add a method to query user receipt information based on user name. The code is as follows:

/****
 * 用户收件地址
 */
@GetMapping(value = "/user/list")
public Result<List<Address>> list(){
    
    
    //获取用户登录信息
    Map<String, String> userMap = TokenDecode.getUserInfo();
    String username = userMap.get("username");
    //查询用户收件地址
    List<Address> addressList = addressService.list(username);
    return new Result(true, StatusCode.OK,"查询成功!",addressList);
}

2.2.2 Testing

访问 http://localhost:8001/api/address/user/list

[The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-ibkTwk7k-1619422686369) (images\1565299241187.png)]

2.2.3 Shipping List

[The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-NkvVShGE-1619422686369)(images\1558302467737.png)]

The shipping list is actually the shopping cart list. You can directly query the previous shopping cart list. I won’t explain it here.

3 Place an order

3.1 Business analysis

When you click on the settlement page, order data will be created immediately. Creating order data will store the data into two tables, namely the order table and the order details table. Here you also need to modify the inventory quantity corresponding to the product.

[The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-wfzBellM-1619422686370)(images\1558302715038.png)]

The order table structure is as follows:

CREATE TABLE `tb_order` (
  `id` varchar(50) COLLATE utf8_bin NOT NULL COMMENT '订单id',
  `total_num` int(11) DEFAULT NULL COMMENT '数量合计',
  `total_money` int(11) DEFAULT NULL COMMENT '金额合计',
  `pre_money` int(11) DEFAULT NULL COMMENT '优惠金额',
  `post_fee` int(11) DEFAULT NULL COMMENT '邮费',
  `pay_money` int(11) DEFAULT NULL COMMENT '实付金额',
  `pay_type` varchar(1) COLLATE utf8_bin DEFAULT NULL COMMENT '支付类型,1、在线支付、0 货到付款',
  `create_time` datetime DEFAULT NULL COMMENT '订单创建时间',
  `update_time` datetime DEFAULT NULL COMMENT '订单更新时间',
  `pay_time` datetime DEFAULT NULL COMMENT '付款时间',
  `consign_time` datetime DEFAULT NULL COMMENT '发货时间',
  `end_time` datetime DEFAULT NULL COMMENT '交易完成时间',
  `close_time` datetime DEFAULT NULL COMMENT '交易关闭时间',
  `shipping_name` varchar(20) COLLATE utf8_bin DEFAULT NULL COMMENT '物流名称',
  `shipping_code` varchar(20) COLLATE utf8_bin DEFAULT NULL COMMENT '物流单号',
  `username` varchar(50) COLLATE utf8_bin DEFAULT NULL COMMENT '用户名称',
  `buyer_message` varchar(1000) COLLATE utf8_bin DEFAULT NULL COMMENT '买家留言',
  `buyer_rate` char(1) COLLATE utf8_bin DEFAULT NULL COMMENT '是否评价',
  `receiver_contact` varchar(50) COLLATE utf8_bin DEFAULT NULL COMMENT '收货人',
  `receiver_mobile` varchar(12) COLLATE utf8_bin DEFAULT NULL COMMENT '收货人手机',
  `receiver_address` varchar(200) COLLATE utf8_bin DEFAULT NULL COMMENT '收货人地址',
  `source_type` char(1) COLLATE utf8_bin DEFAULT NULL COMMENT '订单来源:1:web,2:app,3:微信公众号,4:微信小程序  5 H5手机页面',
  `transaction_id` varchar(30) COLLATE utf8_bin DEFAULT NULL COMMENT '交易流水号',
  `order_status` char(1) COLLATE utf8_bin DEFAULT NULL COMMENT '订单状态,0:未完成,1:已完成,2:已退货',
  `pay_status` char(1) COLLATE utf8_bin DEFAULT NULL COMMENT '支付状态,0:未支付,1:已支付,2:支付失败',
  `consign_status` char(1) COLLATE utf8_bin DEFAULT NULL COMMENT '发货状态,0:未发货,1:已发货,2:已收货',
  `is_delete` char(1) COLLATE utf8_bin DEFAULT NULL COMMENT '是否删除',
  PRIMARY KEY (`id`),
  KEY `create_time` (`create_time`),
  KEY `status` (`order_status`),
  KEY `payment_type` (`pay_type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

The structure of the order details table is as follows:

CREATE TABLE `tb_order_item` (
  `id` varchar(50) COLLATE utf8_bin NOT NULL COMMENT 'ID',
  `category_id1` int(11) DEFAULT NULL COMMENT '1级分类',
  `category_id2` int(11) DEFAULT NULL COMMENT '2级分类',
  `category_id3` int(11) DEFAULT NULL COMMENT '3级分类',
  `spu_id` varchar(20) COLLATE utf8_bin DEFAULT NULL COMMENT 'SPU_ID',
  `sku_id` bigint(20) NOT NULL COMMENT 'SKU_ID',
  `order_id` bigint(20) NOT NULL COMMENT '订单ID',
  `name` varchar(200) COLLATE utf8_bin DEFAULT NULL COMMENT '商品名称',
  `price` int(20) DEFAULT NULL COMMENT '单价',
  `num` int(10) DEFAULT NULL COMMENT '数量',
  `money` int(20) DEFAULT NULL COMMENT '总金额',
  `pay_money` int(11) DEFAULT NULL COMMENT '实付金额',
  `image` varchar(200) COLLATE utf8_bin DEFAULT NULL COMMENT '图片地址',
  `weight` int(11) DEFAULT NULL COMMENT '重量',
  `post_fee` int(11) DEFAULT NULL COMMENT '运费',
  `is_return` char(1) COLLATE utf8_bin DEFAULT NULL COMMENT '是否退货,0:未退货,1:已退货',
  PRIMARY KEY (`id`),
  KEY `item_id` (`sku_id`),
  KEY `order_id` (`order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

3.2 Order fulfillment

When placing an order, first add the order to add data to the tb_order table, then add the order details, and add data to the tb_order_item table.

3.2.1 Code implementation

Here we first modify the changgou-service-order microservice to implement the order operation. The order number will be generated here. We first need to create an IdWorker object in the startup class.

com.changgou.OrderApplicationCreate IdWorker in, the code is as follows :

@Bean
public IdWorker idWorker(){
    
    
    return new IdWorker(1,1);
}

(1) Business layer

Modify the changgou-service-order microservice and modify com.changgou.order.service.impl.OrderServiceImpl. The code is as follows:

Modify the order microservice and add com.changgou.order.service.impl.OrderServiceImpl. The code is as follows:

@Service
public class OrderServiceImpl implements OrderService {
    
    

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private OrderItemMapper orderItemMapper;

    @Autowired
    private CartService cartService;

    @Autowired
    private IdWorker idWorker;

    @Autowired
    private RedisTemplate redisTemplate;

    /***
     * 添加订单
     * @param order
     * @return
     */
    @Override
    public int add(Order order) {
    
    
        //查询出用户的所有购物车
        List<OrderItem> orderItems = cartService.list(order.getUsername());

        //统计计算
        int totalMoney = 0;
        int totalPayMoney=0;
        int num = 0;
        for (OrderItem orderItem : orderItems) {
    
    
            //总金额
            totalMoney+=orderItem.getMoney();

            //实际支付金额
            totalPayMoney+=orderItem.getPayMoney();
            //总数量
            num+=orderItem.getNum();
        }
        order.setTotalNum(num);
        order.setTotalMoney(totalMoney);
        order.setPayMoney(totalPayMoney);
        order.setPreMoney(totalMoney-totalPayMoney);

        //其他数据完善
        order.setCreateTime(new Date());
        order.setUpdateTime(order.getCreateTime());
        order.setBuyerRate("0");        //0:未评价,1:已评价
        order.setSourceType("1");       //来源,1:WEB
        order.setOrderStatus("0");      //0:未完成,1:已完成,2:已退货
        order.setPayStatus("0");        //0:未支付,1:已支付,2:支付失败
        order.setConsignStatus("0");    //0:未发货,1:已发货,2:已收货
        order.setId("NO."+idWorker.nextId());
        int count = orderMapper.insertSelective(order);

        //添加订单明细
        for (OrderItem orderItem : orderItems) {
    
    
            orderItem.setId("NO."+idWorker.nextId());
            orderItem.setIsReturn("0");
            orderItem.setOrderId(order.getId());
            orderItemMapper.insertSelective(orderItem);
        }

        //清除Redis缓存购物车数据
        redisTemplate.delete("Cart_"+order.getUsername());
        return count;
    }
}

(2)Control layer

Modify the changgou-service-order microservice and modify the com.changgou.order.controller.OrderController class. The code is as follows:

@Autowired
private TokenDecode tokenDecode;

/***
 * 新增Order数据
 * @param order
 * @return
 */
@PostMapping
public Result add(@RequestBody Order order){
    
    
    //获取用户名
    Map<String, String> userMap = tokenDecode.getUserInfo();
    String username = userMap.get("username");
    //设置购买用户
    order.setUsername(username);
    orderService.add(order);
    return new Result(true,StatusCode.OK,"添加成功");
}

3.2.2 Testing

Save the order test, the table data changes as follows:

tb_order table data:

[The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-TO5IiocU-1619422686370)(images\1558305141933.png)]

tb_order_item table data:

[The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-SUgQi0Ki-1619422686371)(images\1558305178030.png)]

3.3 Inventory changes

3.3.1 Business Analysis

The above operation only implements the order operation, but the corresponding inventory has not been reduced along with it. After placing the order, we should call the product microservice to reduce the inventory of the ordered product and increase sales. Each order microservice only needs to pass the user name to the product microservice. The product microservice queries the corresponding shopping cart data in Redis through the user name, and then performs inventory reduction. Inventory reduction needs to control the current product inventory >= sales quantity.

[The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-1xygsEbY-1619422686371)(images\1558305399244.png)]

How to control inventory quantity >= sales quantity? In fact, it can be achieved through SQL statements. Every time the quantity is reduced, a conditional judgment is added.

where num>=#{num}That’s it.

In this project, you will need to query shopping cart data, so you need to introduce the order API and add the following dependencies in pom.xml:

<!--order api 依赖-->
<dependency>
    <groupId>com.changgou</groupId>
    <artifactId>changgou-service-order-api</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

3.3.2 Code implementation

To call other microservices, the token data in the header file needs to be carried to other microservices, so we cannot use the multi-threaded mode of hystrix and modify the applicationin.yml configuration of changgou-service-goods. The code is as follows:

#hystrix 配置
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 10000
          strategy: SEMAPHORE

Each time you need to use an interceptor to add header file information, modify the configuration class com.changgou.GoodsApplication to add an interceptor, the code is as follows:

@Bean
public FeignInterceptor feignInterceptor(){
    
    
    return new FeignInterceptor();
}

(1) Dao layer

Modify the interface of the changgou-service-goods microservice com.changgou.goods.dao.SkuMapperand add the inventory reduction method. The code is as follows:

/**
 * 递减库存
 * @param orderItem
 * @return
 */
@Update("UPDATE tb_sku SET num=num-#{num},sale_num=sale_num+#{num} WHERE id=#{skuId} AND num>=#{num}")
int decrCount(OrderItem orderItem);

(2)Business layer

Modify the interface of changgou-service-goods microservice com.changgou.goods.service.SkuServiceand add the following method:

/***
 * 库存递减
 * @param username
 */
void decrCount(String username);

Modify the implementation class of changgou-service-goods microservice com.changgou.goods.service.impl.SkuServiceImpland add an implementation method. The code is as follows:

@Autowired
private RedisTemplate redisTemplate;

/***
 * 库存递减
 * @param username
 */
@Override
public void decrCount(String username) {
    
    
    //获取购物车数据
    List<OrderItem> orderItems = redisTemplate.boundHashOps("Cart_" + username).values();

    //循环递减
    for (OrderItem orderItem : orderItems) {
    
    
        //递减库存
        int count = skuMapper.decrCount(orderItem);
        if(count<=0){
    
    
            throw new RuntimeException("库存不足,递减失败!");
        }
    }
}

(3)Control layer

Modify com.changgou.goods.controller.SkuControllerthe class of changgou-service-goods and add the inventory reduction method. The code is as follows:

/***
 * 库存递减
 * @param username
 * @return
 */
@PostMapping(value = "/decr/count")
public Result decrCount(String username){
    
    
    //库存递减
    skuService.decrCount(username);
    return new Result(true,StatusCode.OK,"库存递减成功!");
}

(4)Create feign

At the same time, the implementation is added to the changgou-service-goods-api project com.changgou.goods.feign.SkuFeign. The code is as follows:

/***
 * 库存递减
 * @param username
 * @return
 */
@PostMapping(value = "/decr/count")
Result decrCount(@RequestParam(value = "username") String username);

3.3.3 Call inventory decrease

Modify the add method of the com.changgou.order.service.impl.OrderServiceImpl class of the changgou-service-order microservice and add a call for inventory decrement.

Inject SkuFeign first

@Autowired
private SkuFeign skuFeign;

Call the inventory reduction method again

//库存减库存
skuFeign.decrCount(order.getUsername());

The complete code is as follows:

[The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-fkLGjuFg-1619422686372)(images\1562934989293.png)]

3.3.4 Testing

Before the inventory is reduced, query the database SKU data as follows: quantity 98, sales volume 0

[The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-j5DQUFbW-1619422686372)(images\1558304696063.png)]

Use Postman to execute http://localhost:18081/api/order/add

[The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-kUMRucix-1619422686372)(images\1558305086257.png)]

After executing the test, the remaining inventory is 97 and the sales volume is 1

[The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-Gn5cJXp3-1619422686373)(images\1558304731338.png)]

3.4 Increase points

For example, after each order is placed, 10 points will be added to the user, and a coupon will be given after the payment is completed. The coupon can be used to deduct it again when paying. Let’s complete the adding points function first. As shown in the following table: points represents user points

CREATE TABLE `tb_user` (
  `username` varchar(50) NOT NULL COMMENT '用户名',
  `password` varchar(100) NOT NULL COMMENT '密码,加密存储',
  `phone` varchar(20) DEFAULT NULL COMMENT '注册手机号',
  `email` varchar(50) DEFAULT NULL COMMENT '注册邮箱',
  `created` datetime NOT NULL COMMENT '创建时间',
  `updated` datetime NOT NULL COMMENT '修改时间',
  `source_type` varchar(1) DEFAULT NULL COMMENT '会员来源:1:PC,2:H5,3:Android,4:IOS',
  `nick_name` varchar(50) DEFAULT NULL COMMENT '昵称',
  `name` varchar(50) DEFAULT NULL COMMENT '真实姓名',
  `status` varchar(1) DEFAULT NULL COMMENT '使用状态(1正常 0非正常)',
  `head_pic` varchar(150) DEFAULT NULL COMMENT '头像地址',
  `qq` varchar(20) DEFAULT NULL COMMENT 'QQ号码',
  `is_mobile_check` varchar(1) DEFAULT '0' COMMENT '手机是否验证 (0否  1是)',
  `is_email_check` varchar(1) DEFAULT '0' COMMENT '邮箱是否检测(0否  1是)',
  `sex` varchar(1) DEFAULT '1' COMMENT '性别,1男,0女',
  `user_level` int(11) DEFAULT NULL COMMENT '会员等级',
  `points` int(11) DEFAULT NULL COMMENT '积分',
  `experience_value` int(11) DEFAULT NULL COMMENT '经验值',
  `birthday` datetime DEFAULT NULL COMMENT '出生年月日',
  `last_login_time` datetime DEFAULT NULL COMMENT '最后登录时间',
  PRIMARY KEY (`username`),
  UNIQUE KEY `username` (`username`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户表';

3.4.1 Code implementation

(1)dao layer

Modify the interface of the changgou-service-user microservice com.changgou.user.dao.UserMapperand add a user points method. The code is as follows:

/***
 * 增加用户积分
 * @param username
 * @param pint
 * @return
 */
@Update("UPDATE tb_user SET points=points+#{point} WHERE  username=#{username}")
int addUserPoints(@Param("username") String username, @Param("point") Integer pint);

(2)Business layer

Modify the interface of changgou-service-user microservice com.changgou.user.service.UserService, the code is as follows:

/***
 * 添加用户积分
 * @param username
 * @param pint
 * @return
 */
int addUserPoints(String username,Integer pint);

Modify the changgou-service-user microservice com.changgou.user.service.impl.UserServiceImpland add the points method to implement. The code is as follows:

/***
 * 修改用户积分
 * @param username
 * @param pint
 * @return
 */
@Override
public int addUserPoints(String username, Integer pint) {
    
    
    return userMapper.addUserPoints(username,pint);
}

(3)Control layer

Modify the changgou-service-user microservice com.changgou.user.controller.UserControllerand add a method to increase user points. The code is as follows:

@Autowired
private TokenDecode tokenDecode;

/***
 * 增加用户积分
 * @param points:要添加的积分
 */
@GetMapping(value = "/points/add")
public Result addPoints(Integer points){
    
    
    //获取用户名
    Map<String, String> userMap = tokenDecode.getUserInfo();
    String username = userMap.get("username");

    //添加积分
    userService.addUserPoints(username,points);
    return new Result(true,StatusCode.OK,"添加积分成功!");
}

(4)Feign addition

Modify the changgou-service-user-api project, modify com.changgou.user.feign.UserFeignand add a method to increase user points, the code is as follows:

/***
 * 添加用户积分
 * @param points
 * @return
 */
@GetMapping(value = "/points/add")
Result addPoints(@RequestParam(value = "points")Integer points);

3.4.2 Add points call

Modify changgou-service-order, add the dependency of changgou-service-user-api, modify pom.xml, and add the following dependencies:

<!--user api 依赖-->
<dependency>
    <groupId>com.changgou</groupId>
    <artifactId>changgou-service-user-api</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

com.changgou.order.service.impl.OrderServiceImplWhen adding an order, add user points at the same time, modify the order method of the changgou-service-order microservice , and add a call to the add points method. The code is as follows:

[The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-ZXLiIAEp-1619422686373)(images\1562936344817.png)]

Modify the startup class of changgou-service-order com.changgou.OrderApplicationand add the package path of feign:

[The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-hqVvFaCb-1619422686374) (images\1562938889771.png)]

4 Payment Process Analysis

4.1 Analysis of order payment

[The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-wRlgbriE-1619422686374)(images/1558490059984.png)]

As shown above, the steps are analyzed as follows:

1.用户下单之后,订单数据会存入到MySQL中,同时会将订单对应的支付日志存入到Redis,以队列的方式存储。
2.用户下单后,进入支付页面,支付页面调用支付系统,从微信支付获取二维码数据,并在页面生成支付二维码。
3.用户扫码支付后,微信支付服务器会通调用前预留的回调地址,并携带支付状态信息。
4.支付系统接到支付状态信息后,将支付状态信息发送给RabbitMQ
5.订单系统监听RabbitMQ中的消息获取支付状态,并根据支付状态修改订单状态
6.为了防止网络问题导致notifyurl没有接到对应数据,定时任务定时获取Redis中队列数据去微信支付接口查询状态,并定时更新对应状态。

4.2 QR code creation (understanding)

Today we will mainly talk about WeChat payment. In order to see the effect later, we will briefly talk about using qrious to create a QR code plug-in.

qrious is a pure JS QR code generation plug-in based on HTML5 Canvas. Various QR codes can be quickly generated through qrious.js. You can control the size and color of the QR code, and you can also Base64 encode the generated QR code.

The available configuration parameters of the qrious.js QR code plug-in are as follows:

parameter type Defaults describe
background String “white” The background color of the QR code.
foreground String “black” The foreground color of the QR code.
level String “L” Error correction level of QR code (L, M, Q, H).
mime String “image/png” The MIME type when the QR code is output as an image.
size Number 100 The size of the QR code in pixels.
value String “” The value that needs to be encoded as a QR code

The following code can generate a QR code

<html>
<head>
<title>二维码入门小demo</title>
</head>
<body>
<img id="qrious">
<script src="qrious.js"></script>
<script>
 var qr = new QRious({
     
     
	    element:document.getElementById('qrious'),
	    size:250, 	   
     	level:'H',	   
     	value:'http://www.itheima.com'
	});
</script>
</body>
</html>

running result:

[The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-fNSWFwEi-1619422686374)(images/1549706445665.png)]

Everyone takes out their mobile phones and scans to see if they will see the official website of Dark Horse?

5 Introduction to WeChat scan code payment

5.1 WeChat scan code payment application

WeChat scan code payment is a mode in which the merchant system generates a payment QR code according to the WeChat payment protocol, and the user then uses WeChat to "scan" to complete the payment. This model is suitable for scenarios such as PC website payment, physical store item or order payment, and media advertising payment.

Application steps: (understand)

Step 1: Register a public account (the type must be: service account)

Please select the following entities to register according to the type of business license: individual industrial and commercial household | enterprise/company | government | media | other types .

Step 2: Verify the public account

Only after the official account is certified can you apply for WeChat payment. Certification fee: 300 yuan/time.

Step 3: Submit information to apply for WeChat payment

Log in to the public platform, click [WeChat Payment] on the left menu, start filling in the information and wait for review, which will take 1-5 working days.

Step 4: After successfully opening the account, log in to the merchant platform for verification.

After the information is approved, please log in to the contact's email to check the merchant number and password, and log in to the merchant platform to fill in the small amount of funds in the Tenpay reserve fund to complete the account verification.

Step 5: Sign the agreement online

This agreement is an online electronic agreement. Transactions and fund settlements can only be carried out after signing. It will take effect immediately after signing.

This course has already provided the WeChat payment account of "Chuanzhi Podcast", and students do not need to apply.

5.2 Development Documentation

The overall idea of ​​calling the WeChat payment interface:

Assemble parameters according to API requirements and send (POST) them to the WeChat payment interface (URL) in XML mode, and the WeChat payment interface also responds in XML mode. The program generates a QR code or determines the order status based on the returned results (including the payment URL).

Online WeChat payment development documents:

https://pay.weixin.qq.com/wiki/doc/api/index.html

If you cannot connect to the Internet, please check the handout supporting resources (Resources\Supporting Software\WeChat Scan QR Code Payment\Development Documents)

We will use the two APIs of "unified order" and "query order" in this chapter.

1. appid:微信公众账号或开放平台APP的唯一标识
2. mch_id:商户号  (配置文件中的partner)
3. partnerkey:商户密钥
4. sign:数字签名, 根据微信官方提供的密钥和一套算法生成的一个加密信息, 就是为了保证交易的安全性

5.3 Introduction to WeChat payment model

5.3.1 Mode 1

[The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-xWICVmRR-1619422686375)(images/1558448158371.png)]

Business process description:

1.商户后台系统根据微信支付规定格式生成二维码(规则见下文),展示给用户扫码。
2.用户打开微信“扫一扫”扫描二维码,微信客户端将扫码内容发送到微信支付系统。
3.微信支付系统收到客户端请求,发起对商户后台系统支付回调URL的调用。调用请求将带productid和用户的openid等参数,并要求商户系统返回交数据包,详细请见"本节3.1回调数据输入参数"
4.商户后台系统收到微信支付系统的回调请求,根据productid生成商户系统的订单。
5.商户系统调用微信支付【统一下单API】请求下单,获取交易会话标识(prepay_id)
6.微信支付系统根据商户系统的请求生成预支付交易,并返回交易会话标识(prepay_id)。
7.商户后台系统得到交易会话标识prepay_id(2小时内有效)。
8.商户后台系统将prepay_id返回给微信支付系统。返回数据见"本节3.2回调数据输出参数"
9.微信支付系统根据交易会话标识,发起用户端授权支付流程。
10.用户在微信客户端输入密码,确认支付后,微信客户端提交支付授权。
11.微信支付系统验证后扣款,完成支付交易。
12.微信支付系统完成支付交易后给微信客户端返回交易结果,并将交易结果通过短信、微信消息提示用户。微信客户端展示支付交易结果页面。
13.微信支付系统通过发送异步消息通知商户后台系统支付结果。商户后台系统需回复接收情况,通知微信后台系统不再发送该单的支付通知。
14.未收到支付通知的情况,商户后台系统调用【查询订单API】。
15.商户确认订单已支付后给用户发货。

5.3.2 Mode 2

[The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-YZqidTsR-1619422686375)(images/1558448510488.png)]

Business process description:

1.商户后台系统根据用户选购的商品生成订单。
2.用户确认支付后调用微信支付【统一下单API】生成预支付交易;
3.微信支付系统收到请求后生成预支付交易单,并返回交易会话的二维码链接code_url。
4.商户后台系统根据返回的code_url生成二维码。
5.用户打开微信“扫一扫”扫描二维码,微信客户端将扫码内容发送到微信支付系统。
6.微信支付系统收到客户端请求,验证链接有效性后发起用户支付,要求用户授权。
7.用户在微信客户端输入密码,确认支付后,微信客户端提交授权。
8.微信支付系统根据用户授权完成支付交易。
9.微信支付系统完成支付交易后给微信客户端返回交易结果,并将交易结果通过短信、微信消息提示用户。微信客户端展示支付交易结果页面。
10.微信支付系统通过发送异步消息通知商户后台系统支付结果。商户后台系统需回复接收情况,通知微信后台系统不再发送该单的支付通知。
11.未收到支付通知的情况,商户后台系统调用【查询订单API】。
12.商户确认订单已支付后给用户发货。

Guess you like

Origin blog.csdn.net/qq_36644198/article/details/116158321