苍穹外卖项目【跳过微信支付的功能测试】

仓库地址:https://github.com/Shmily33/sky-take-out

1 项目介绍

1.1 功能架构

image.png

1.2 技术选型

image.png

1.3 后端环境搭建

image.png

sky-common

image.png

sky-pojo

image.png

sky-server

image.png

1.4 数据库环境

image.png

1.5 前后端联调

思考

image.png

反向代理

image.png

好处

image.png

方向代理配置方式

image.png

负载均衡配置方式

image.png

负载均衡策略

image.png

1.6 完善登录功能

image.png
image.png

1.7 Swagger

1.7.1 介绍

image.png

 <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-spring-boot-starter</artifactId>
        </dependency>

1.7.2 使用方式

image.png

1.7.3 常用注解

image.png

package com.sky.config;

import com.sky.interceptor.JwtTokenAdminInterceptor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;

/**
 * 配置类,注册web层相关组件
 */
@Configuration
@Slf4j
public class WebMvcConfiguration extends WebMvcConfigurationSupport {

    @Autowired
    private JwtTokenAdminInterceptor jwtTokenAdminInterceptor;

    /**
     * 注册自定义拦截器
     *
     * @param registry
     */
    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        log.info("开始注册自定义拦截器...");
        registry.addInterceptor(jwtTokenAdminInterceptor)
                .addPathPatterns("/admin/**")
                .excludePathPatterns("/admin/employee/login");
    }

    /**
     * 通过knife4j生成接口文档
     * @return
     */
    @Bean
    public Docket docket() {
        log.info("准备生成接口文档。。。");
        ApiInfo apiInfo = new ApiInfoBuilder()
                .title("苍穹外卖项目接口文档")
                .version("2.0")
                .description("苍穹外卖项目接口文档")
                .build();
        Docket docket = new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.sky.controller"))
                .paths(PathSelectors.any())
                .build();
        return docket;
    }

    /**
     * 设置静态资源映射
     * @param registry
     */
    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        log.info("开始设置静态资源映射。。。");
        registry.addResourceHandler("/doc.html").addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
    }
}

1.8 DTO与实体类

/*
* 在controller使用的是EmployeeDTO(Data Transfer Object),这样可以与视图层数据一致
* 到service就可以操作真正的Employee实体,交由mapper层与数据库操作
* 
*  对象属性拷贝
    BeanUtils.copyProperties(employeeDTO, employee); // 源->目标

      Employee employee = Employee.builder()
                .id(id).status(status).build();
    builer插件方便赋值 等同set
*/

2 员工管理、分类管理

2.1 ThreadLocal

问题

image.png

JWT认证流程

image.png

ThreadLocal

image.png

2.2 日期格式化

image.png

3 菜品管理

3.1 公共字段自动填充–AOP+反射运用

问题

image.png

解决

image.png

代码

image.png

3.2 新增菜品

逻辑外键–代码:通过上一张表的插入语句,回显赋值id作为下一张表的dish_id

 @Transactional
    @Override
    public void saveWithFlavor(DishDTO dishDTO) { // 两张表操作,保持数据一致性
        Dish dish = new Dish();
        BeanUtils.copyProperties(dishDTO, dish);
        // 菜品表插入1条数据
        dishMapper.insert(dish);

        // 获取insert语句生成的主键值
        // useGeneratedKeys="true" keyProperty="id" 使用产生的主键赋值为id
        Long dishId = dish.getId();

        // 口味表插入n条数据
        List<DishFlavor> flavors = dishDTO.getFlavors();
        if (flavors != null && flavors.size() > 0) { // 不空且有数据存在
            flavors.forEach(f -> {
                f.setDishId(dishId);
            });
            dishFlavorMapper.insertBatch(flavors); // 传入对象批量插入

        }
    }

两张表操作,数据一致性问题

@Transactional 保证方法是原子性 – 方法上添加
@EnableTransactionManagement //开启注解方式的事务管理 --启动类上添加

3.3 修改菜品

插入口味表时,不确定是否有或者需要增删改–先删除后插入

public void updateWithFlavor(DishDTO dishDTO) {
        Dish dish = new Dish();
        BeanUtils.copyProperties(dishDTO, dish);
        dishMapper.update(dish);
        // 口味有可能增删该了。那么我们处理方式先删掉原来的,在插入新的 等于覆盖
        dishFlavorMapper.deleteByDishId(dishDTO.getId());
        List<DishFlavor> dishFlavors = dishDTO.getFlavors();
        // 口味表插入n条数据
        List<DishFlavor> flavors = dishDTO.getFlavors();
        if (flavors != null && flavors.size() > 0) { // 不空且有数据存在
            flavors.forEach(f -> {
                f.setDishId(dishDTO.getId());
            });
            dishFlavorMapper.insertBatch(flavors); // 传入对象批量插入
        }
    }

4 Redis

4.1 简介

image.png

mysql是基于数据文件,存在磁盘上,二维表结构方式

4.2 入门

启动命令

redis-server.exe redis.windows.conf 启动redis
ctrl c 关闭
redis-cli.exe 启动客服端
redis-cli.exe -h () -p () -a () 启动指定的redis服务 -a 后是密码

image.png
image.png

密码设置

image.png
image.png

4.3 常用数据类型

image.png

特点

image.png

4.4 常用命令

字符串

image.png

Hash

image.png

列表

image.png

集合

image.png

有序集合

image.png

通用命令

image.png

4.5 在Java中操作redis

Spring Data Redis

image.png

使用方式

image.png
image.png
image.png

4.6 缓存商品

4.6.1 缓存菜品

问题说明

image.png

实现思路

image.png
image.png

4.6.2 缓存套餐

Spring Cache

image.png

常用注解

image.png

实现思路

image.png

5 HttpClient

5.1 介绍

image.png
image.png

5.2 入门

image.png
image.png

6 微信小程序

6.1 注意

image.png

6.2 目录结构

image.png
image.png

6.3 微信支付

参考:https://pay.weixin.qq.com/static/product/product_index.shtml

6.3.1 时序图

image.png
调用过程如何保证数据安全?
微信后台如何调用到商户系统?

6.3.2 JSAPI

https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_5_1.shtml
image.png
image.png

6.4 获取临时域名

cpolar:https://dashboard.cpolar.com/login

配置

image.png
image.png
image.png

成功示例

image.png

6.5 关于微信支付的代码跳过步骤–否则管理端的订单功能无法测试

6.5.1 小程序端代码改动

注释发送得支付请求功能代码,直接把其中成功跳转页面代码提上来
ctrl+f 搜索handleSave 替换其中的else分支代码

else {
        // 如果支付成功进入成功页
        clearTimeout(this.times);
        var params = {
          orderNumber: this.orderDataInfo.orderNumber,
          payMethod: this.activeRadio === 0 ? 1 : 2 };

        (0, _api.paymentOrder)(params).then(function (res) {
          if (res.code === 1) {
              wx.showModal({
                title: '提示',
                content: '支付成功',
                success:function(){
                  uni.redirectTo({url: '/pages/success/index?orderId=' + _this.orderId });
                }
              })
              console.log('支付成功!')
            // wx.requestPayment({
            //   nonceStr: res.data.nonceStr,
            //   package: res.data.packageStr,
            //   paySign: res.data.paySign,
            //   timeStamp: res.data.timeStamp,
            //   signType: res.data.signType,
            //   success:function(res){
            //     wx.showModal({
            //       title: '提示',
            //       content: '支付成功',
            //       success:function(){
            //         uni.redirectTo({url: '/pages/success/index?orderId=' + _this.orderId });
            //       }
            //     })
            //     console.log('支付成功!')
            //   }
            // })


            //uni.redirectTo({url: '/pages/success/index?orderId=' + _this.orderId });

          } else {
            wx.showModal({
              title: '提示',
              content: res.msg
            })
          }
        });
      }

image.png

6.5.2 后端代码改动

OrderController

注释原先代码,直接按照接口文档返回String类型的预计送达时间

  @PutMapping("/payment")
    @ApiOperation("订单支付")
    public Result<String> payment2(@RequestBody OrdersPaymentDTO ordersPaymentDTO) throws Exception {
        log.info("订单支付:{}", ordersPaymentDTO);
//        OrderPaymentVO orderPaymentVO = orderService.payment(ordersPaymentDTO);
        LocalDateTime time = LocalDateTime.now().plusHours(1);
        // 定义日期时间格式化器
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String estimatedDeliveryTime = time.format(formatter);
        orderService.updateStatus(ordersPaymentDTO);
        return Result.success(estimatedDeliveryTime);
    }

image.png

OrderService

image.png

OrderServiceImpl
 @Override
    public void updateStatus(OrdersPaymentDTO ordersPaymentDTO) {
        Orders orders = orderMapper.getByNumber(ordersPaymentDTO.getOrderNumber());
        orders.setStatus(Orders.TO_BE_CONFIRMED);
        orders.setPayStatus(Orders.PAID);
        orderMapper.update(orders);
    }

image.png

6.5.3 效果

image.png

### 苍穹外卖微信小程序部署教程 #### 准备工作 在准备部署苍穹外卖微信小程序之前,确保已经完成了项目的开发并进行了充分测试项目应遵循官方提供的开发文档以及设计指南[^2]。 #### 创建微信公众平台账号 为了能够发布和管理自己的小程序,需要先注册一个微信公众平台账号,并创建对应的小程序应用。这一步骤涉及到填写基本信息、验证身份等内容。 #### 下载安装微信开发者工具 通过访问官方网站下载最新版本的微信开发者工具。该工具有助于本地调试与预览小程序效果,支持多种实用功能如真机调试等。 #### 导入项目源码至开发者工具 启动微信开发者工具后登录刚才创建好的公众号账户,在新建页面选择“导入项目”,按照提示操作将已完成编码的工作空间加载进来。对于主要依赖后端服务的情况,则可以直接跳过后台接口部分的编写而专注于前端交互逻辑的设计[^1]。 #### 配置服务器域名及相关设置 进入微信公众平台上指定合法的业务域名为后续网络请求做准备;另外还需配置消息安全校验密钥(Token),JS-SDK权限签名算法中的AppSecret等相关参数以保障数据传输的安全性。 #### 构建打包上传代码包 当所有准备工作完成后就可以执行构建命令生成用于发布的压缩文件(.zip格式)。接着回到公众平台控制面板内找到对应的菜单项提交审核材料连同刚刚制作出来的ZIP一起发送出去等待官方团队审查批准上线。 #### 发布前注意事项 在整个过程中务必仔细阅读相关协议条款,确保所使用的素材均获得授权许可,同时也要注意保护用户隐私不违反法律法规的要求。一旦收到通知表示已成功上架便可以通过分享链接让更多人体验到这款便捷的应用啦! ```json { "path": "/pages/index/index", "query": { "id": "1" } } ``` 此JSON片段展示了如何定义首页路径及其携带查询字符串的方式作为默认打开界面的一部分配置信息之一。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bwywb_3

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值