苍穹外卖项目笔记(7)— 微信登录、商品浏览

前言

苍穹外卖项目代码:https://github.com/Echo0701/take-out

1 HttpClient

1.1 介绍

  HttpClient 是 Apche Jakarta Common 下的子项目,可以用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且支持 HTTP 协议最新的版本和建议。

pom.xml :

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.13</version>
</dependency>

1.2 入门案例

HttpClientTest.java

@SpringBootTest
public class HttpClientTest {

    /**
     * 测试通过httpclient 发送 GET 方式请求
     */
    @Test
    public void testGET() throws Exception{
        //创建 httpclient 对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        //创建请求对象
        HttpGet httpGet = new HttpGet("http://localhost:8080/user/shop/status");

        //发送请求,接受响应结果
        CloseableHttpResponse response = httpClient.execute(httpGet);

        //获取服务端返回的状态码
        int statusCode = response.getStatusLine().getStatusCode();
        System.out.println("服务端返回的状态码:" + statusCode);

        //获得响应数据(发现返回数据被封装为了一个 HttpEntity 对象)
        HttpEntity entity = response.getEntity();

        //通过一个工具类 EntityUtils 解析 HttpEntity 对象
        String body = EntityUtils.toString(entity);
        System.out.println("服务端返回的数据为:" + body);

        //关闭资源
        response.close();
        httpClient.close();

    }

    /**
     * 测试通过httpclient 发送 POST 方式请求
     */
    @Test
    public void testPOST() throws Exception {
        //创建 httpclient 对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        //创建请求对象
        HttpPost httpPost = new HttpPost("http://localhost:8080/admin/employee/login");

        //设置post参数,且参数为 json 数据格式
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("username","admin");
        jsonObject.put("password","123456");

        StringEntity entity = new StringEntity(jsonObject.toString());
        //指定请求的编码方式
        entity.setContentEncoding("utf-8");
        //数据格式
        entity.setContentType("application/json");
        httpPost.setEntity(entity);

        //发送请求
        CloseableHttpResponse response = httpClient.execute(httpPost);

        //解析请求结果
        int statusCode = response.getStatusLine().getStatusCode();
        System.out.println("服务端返回状态码:" + statusCode);

        HttpEntity entity1 = response.getEntity();
        String body = EntityUtils.toString(entity1);
        System.out.println("服务端返回的数据为:" + body);

        //关闭资源
        response.close();
        httpClient.close();
    }
}

2 微信小程序开发

2.1 准备工作

2.1.1 注册小程序

注册地址:小程序 (qq.com)

2.1.2 完善小程序信息

2.1.3 下载开发者工具

下载地址:下载 / 稳定版更新日志 (qq.com)

2.2 入门案例

操作步骤:

  • 了解小程序目录结构
  • 编写小程序代码
  • 编译小程序

3 微信登录

3.1 微信登录流程

微信登录:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html

3.2 需求分析和设计

产品原型

接口设计 

 数据库设计(user 表) 

【注】如果是以企业的资质注册的这个小程序是可以获得用户的手机号的,反之,以个人资质注册的不能 

3.3 代码开发

配置微信登录所需配置项:

配置为微信用户生成 jwt 令牌时使用的配置项:

 UserController.java

@RestController
//前面这个user代表的是user用户端,后面这个user代表user模块
@Api(tags = "C端用户相关接口")
@Slf4j
@RequestMapping("/user/user")
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private JwtProperties jwtProperties;

    /**
     * 微信登录
     * @param userLoginDTO
     * @return
     */
    @PostMapping("/login")
    @ApiOperation("微信登录")
    public Result<UserLoginVO> login(@RequestBody UserLoginDTO userLoginDTO) {
        log.info("微信用户登录:{}",userLoginDTO.getCode());

        //微信登录
        User user = userService.wxLogin(userLoginDTO);

        //为微信用户生成 jwt 令牌
        Map<String, Object> claims = new HashMap<>();
        claims.put(JwtClaimsConstant.USER_ID,user.getId());
        String token = JwtUtil.createJWT(jwtProperties.getUserSecretKey(), jwtProperties.getUserTtl(), claims);

        UserLoginVO userLoginVO = UserLoginVO.builder()
                .id(user.getId())
                .openid(user.getOpenid())
                .token(token)
                .build();
        return Result.success(userLoginVO);
    }
}

JwtTokenUserInterceptor.java

/**
 * jwt令牌校验的拦截器
 */
@Component
@Slf4j
public class JwtTokenUserInterceptor implements HandlerInterceptor {

    @Autowired
    private JwtProperties jwtProperties;

    /**
     * 校验jwt
     *
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //判断当前拦截到的是Controller的方法还是其他资源
        if (!(handler instanceof HandlerMethod)) {
            //当前拦截到的不是动态方法,直接放行
            return true;
        }

        //1、从请求头中获取令牌
        String token = request.getHeader(jwtProperties.getUserTokenName());

        //2、校验令牌
        try {
            log.info("jwt校验:{}", token);
            Claims claims = JwtUtil.parseJWT(jwtProperties.getUserSecretKey(), token);
            Long userId = Long.valueOf(claims.get(JwtClaimsConstant.USER_ID).toString());
            log.info("当前用户id:{}", userId);
            BaseContext.setCurrentId(userId);  // 把 id 存到线程的独立空间 ThreadLocal 里面去了
            //3、通过,放行
            return true;
        } catch (Exception ex) {
            //4、不通过,响应401状态码
            response.setStatus(401);
            return false;
        }
    }
}

  UserService.java

public interface UserService {

    /**
     * 微信登录
     * @param userLoginDTO
     * @return
     */
    User wxLogin(UserLoginDTO userLoginDTO);
}

 UserServiceImpl.java

@Service
@Slf4j
public class UserServiceImpl implements UserService {

    //微信服务接口地址
    public static final String WX_LOGIN = "https://api.weixin.qq.com/sns/jscode2session";

    @Autowired
    private WeChatProperties weChatProperties;
    @Autowired
    private UserMapper userMapper;

    /**
     * 微信登录
     * @param userLoginDTO
     * @return
     */
    public User wxLogin(UserLoginDTO userLoginDTO) {

        String openid = getOpenid(userLoginDTO.getCode());

        //判断openid是否为空,如果为空表示登录失败,抛出业务异常
        if(openid == null) {
            throw new LoginFailedException(MessageConstant.LOGIN_FAILED);
        }

        //判断当前用户是否为新用户(需要查询用户表,所以这里新建一个UserMapper)
        User user = userMapper.getByOpenid(openid);

        //如果是新用户,自动完成注册
        if (user == null) {
            user = User.builder()
                    .openid(openid)
                    .createTime(LocalDateTime.now())
                    .build();
            userMapper.insert(user);
        }

        //返回这个用户对象
        return user;
    }

    /**
     * 调用微信服务接口,获取微信用户的openid
     * @param code
     * @return
     */
    private String getOpenid (String code) {
        //调用微信接口获得当前用户的openid
        Map<String, String> map = new HashMap<>();
        map.put("appid", weChatProperties.getAppid());
        map.put("secret", weChatProperties.getSecret());
        map.put("js_code", code);
        map.put("grant_type", "authorization_code");
        String json = HttpClientUtil.doGet(WX_LOGIN, map);
        //解析json数据,先获得一个json对象,然后获取json里面的openid
        JSONObject jsonObject = JSON.parseObject(json);
        String openid = jsonObject.getString("openid");
        return openid;
    }
}

 UserMapper.java

@Mapper
public interface UserMapper {

    /**
     * 根据openid查询用户
     * @param openid
     * @return
     */
    @Select("select * from user where openid = #{openid}")
    User getByOpenid(String openid);

    /**
     * 插入数据
     * @param user
     */
    //需要返回主键值,这里需要通过xml文件 usegeneratekeys 来获取
    void insert(User user);
}

 UserMapper.xml 

<?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.sky.mapper.UserMapper">

<!--useGeneratedKeys="true",keyProperty="id":表明我需要这个sql语句的主键返回值,而且这个主键值会赋给我们这个的id属性(为了获得这个id 然后返回给后面的口味处理的部分)-->
    <insert id = "insert" useGeneratedKeys="true" keyProperty="id">
        insert into user (openid, name, phone, sex, id_number, avatar, create_time)
                values (#{openid}, #{name}, #{phone}, #{sex}, #{idNumber}, #{avatar}, #{createTime})
    </insert>

</mapper>

4 导入商品浏览功能代码

4.1 需求分析和设计

产品原型

接口设计

① 查询分类

② 根据分类 id 查询菜品 (查询菜品的时候关联的口味数据也一并查询)

③ 根据分类 id 查询套餐

④ 根据套餐 id 查询包含的菜品

4.2 代码导入

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/222945.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[LeetCode周赛复盘] 第 374 场周赛20231203

[LeetCode周赛复盘] 第 374 场周赛20231203 一、本周周赛总结100144. 找出峰值1. 题目描述2. 思路分析3. 代码实现 100153. 需要添加的硬币的最小数量1. 题目描述2. 思路分析3. 代码实现 100145. 统计完全子字符串1. 题目描述2. 思路分析3. 代码实现 100146. 统计感冒序列的数…

LeetCode Hot100 994.腐烂的橘子

题目&#xff1a; 在给定的 m x n 网格 grid 中&#xff0c;每个单元格可以有以下三个值之一&#xff1a; 值 0 代表空单元格&#xff1b;值 1 代表新鲜橘子&#xff1b;值 2 代表腐烂的橘子。 每分钟&#xff0c;腐烂的橘子 周围 4 个方向上相邻 的新鲜橘子都会腐烂。 返回…

计算机速成课Crash Course - 08. 指令和程序

今天开始计算机速成课Crash Course的系列讲解。 更多技术文章&#xff0c;全网首发公众号 “摸鱼IT” 锁定 -上午11点 - &#xff0c;感谢大家关注、转发、点赞&#xff01; 计算机速成课Crash Course - 08. 指令和程序 08. 指令和程序 上集我们把 ALU, 控制单元, RAM, 时钟…

观测云实现日志存储与分析 10 倍性价比提升|SelectDB 技术团队

作者&#xff1a;观测云 CEO 蒋烁淼 & 飞轮科技技术团队 在云计算逐渐成熟的当下&#xff0c;越来越多的企业开始将业务迁移到云端&#xff0c;传统的监控和故障排查方法已经无法满足企业的需求。而观测云可提供整体数据的分析、洞察、可视化、自动化、监测告警、智能巡查…

单周爆售150w+,“不是羽绒服买不起,而是军大衣更有性价比”

拼多多收盘市值超过阿里&#xff0c;成在美中概股市值第一。 截至美股收盘&#xff08;11月30日&#xff09;&#xff0c;拼多多收盘市值超过阿里巴巴&#xff0c;成为在美中概股中的市值第一股。拼多多收涨4.03%&#xff0c;报147.44美元&#xff0c;市值1959亿美元&#xff…

Tiled Matrix Multiplication

if(true) { (function(i,s,o,g,r,a,m){i[‘GoogleAnalyticsObject’]r;i[r]i[r]||function(){ (i[r].qi[r].q||[]).push(arguments)},i[r].l1*new Date();as.createElement(o), ms.getElementsByTagName(o)[0];a.async1;a.srcg;m.parentNode.insertBefore(a,m) })(window,docum…

uniapp微信小程序分包,小程序分包

前言&#xff0c;都知道我是一个后端开发、所以今天来写一下uniapp。 起因是美工给我的切图太大&#xff0c;微信小程序不让了&#xff0c;在网上找了一大堆分包的文章&#xff0c;我心思我照着写的啊&#xff0c;怎么就一直报错呢&#xff1f; 错误原因 tabBar的页面被我放在分…

五肽-13|提亮肤色,美白肌肤

五肽-13 INCI名称&#xff1a;五肽-13 说明&#xff1a; 五肽-13是一种合成肽&#xff0c;由丙氨酸、精氨酸、赖氨酸、脯氨酸和缬氨酸组成 功能&#xff1a; 五肽-13起到增白剂的作用 应用程序&#xff1a; 提亮和美白

2023年2月8日 Go生态洞察:Profile-Guided Optimization预览

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

Streamlit框架的定制化

Streamlit框架的定制化 最近做了一个关于streamlit框架的项目&#xff0c;颇有感触&#xff0c;所以在这里记录一下。 什么是streamlit? Streamlit 是一个python的WEB UI库&#xff0c;它做了高度的封装以便于不懂后前端开发的人员也能轻松构建画面。你可以从官网进行详细的…

Linux文件结构与文件权限

基于centos了解Linux文件结构 了解一下文件类型 Linux采用的一切皆文件的思想&#xff0c;将硬件设备、软件等所有数据信息都以文件的形式呈现在用户面前&#xff0c;这就使得我们对计算机的管理更加方便。所以本篇文章会对Linux操作系统的文件结构和文件权限进行讲解。 首先…

halcon如何设置窗口背景颜色?

halcon窗口背景默认是黑色&#xff0c;有时候图片背景是黑色&#xff0c;不方便观察边缘&#xff0c;如果需要设置窗口背景颜色&#xff0c;可以使用如下算子。 设置窗口背景颜色&#xff1a;白色 set_window_param (WindowHandle, background_color, white) 设置白色后的效…

13款趣味性不错(炫酷)的前端动画特效及源码(预览获取)分享(附源码)

文字激光打印特效 基于canvas实现的动画特效&#xff0c;你既可以设置初始的打印文字也可以在下方输入文字可实现激光字体打印&#xff0c;精简易用。 预览获取 核心代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8&q…

关于 mapboxgl 的常用方法及效果

给地图标记点 实现效果 /*** 在地图上添加标记点* point: [lng, lat]* color: #83f7a0*/addMarkerOnMap(point, color #83f7a0) {const marker new mapboxgl.Marker({draggable: false,color: color,}).setLngLat(point).addTo(this.map);this.markersList.push(marker);},…

从【注意力机制】开始的,零基础【大模型】系列

注意力机制 原理&#xff1a;从关注全部到关注重点软注意力-计算方式传统注意力问题 键值注意力&#xff1a;单标签的检索系统计算方式 多头注意力&#xff1a;多标签的检索系统自注意力&#xff1a;对输入数据内部关系进行预处理计算方式 Transformer 原理&#xff1a;从关注全…

医院预约挂号平台的设计与实现

摘 要 网络的空前发展给人们的工作和生活带来了极大的便利&#xff0c;信息技术已成为节约运营成本、提高工作效率的首选。相比之下&#xff0c;国内相当多的中小医院在医院预约工作中的手工工作比较保守&#xff0c;数据查询和存储成本都很高&#xff0c;但效率很低。为了使医…

docker-compose部署sonarqube 8.9 版本

官方部署文档注意需求版本 所以选择8.9版本 一、准备部署配置 1、持久化目录 rootlocalhost:/root# mkdir -p /data/sonar/postgres /data/sonar/sonarqube/data /data/sonar/sonarqube/logs /data/sonar/sonarqube/extensions rootlocalhost:/root# chmod 777 /data/sona…

天眼销为电销行业降低获客成本

当下&#xff0c;做电销的老板都有一个深刻体会&#xff1a;市场竞争越来越激烈&#xff0c;获客成本不断攀升&#xff0c;但效率不升返降&#xff0c;企业经营困难。特别是在这一两年&#xff0c;市场环境紧张&#xff0c;业务不好开展&#xff0c;更是雪上加霜。 销售也感觉…

Matlab 曲线动态绘制

axes(handles.axes1); % 选定所画坐标轴 figure也可 h1 animatedline; h1.Color b; h1.LineWidth 2; h1.LineStyle -; % 线属性设置 for i 1 : length(x)addpoints(h1,x(i),y(i)); % x/y为待绘制曲线数据drawnow;pause(0.01); % 画点间停顿 end 示例&#xff1a; figure…

BearPi Std 板从入门到放弃 - 引气入体篇(8)(ADC)

简介 基于前面的文章, 缩略STM32CubeMx创建项目的过程&#xff0c;直接添加ADC相关初 始化; 开发板 &#xff1a; Bearpi Std(小熊派标准板) 主芯片: STM32L431RCT6 LED : PC13 \ 推挽输出即可 \ 高电平点亮 串口: Usart1 ADC1: PC2步骤 创建STM32CubeMX LED/串口ADC1初始…