H a i
Loader 1 Loader 2 Loader 3 Loader Main
k e e
  • 开始游览
    • 阅读
      • 好文收藏
      • 经验分享
      • 随心杂记
      • 学习
    • 文章归档
  • 专题
    • 众星
  • 关于
    • 在读
    • 在面
    • 在用
    • 在看
    • 在玩
    • 足迹
    • 画廊
    • 关于我
  • 文档
  • CV

欢迎来到橙黄橘绿,为您导读全站动态
  • ox537u 2日前前留言 666😎
  • ox537u 2025-06-03前留言 😉
2026 年 5 月
日一二三四五六
12
3456789
10111213141516
17181920212223
24252627282930
31
« 4 月  
最近文章
  • 2026-04-26 开源项目Preview
  • 2026-04-01 2030倒计时-书评笔记
  • 2026-03-06 AI辅助科研写作工具、提示词工程资源库推荐
  • 2026-03-06 当我们站在变革的开端
  • 2026-01-24 字节暑期实习面经(1h)
  • 2026-01-17 AI文献速读工具
  • 2026-01-16 期刊级别分类-思维导图
  • 2025-12-29 深入理解 JavaScript 执行机制:从预编译到 AO 对象
热门文章
  • 2026-01-24 字节暑期实习面经(1h)
  • 2023-10-21 若依Springboot整合微信小程序实现登录
  • 2025-05-02 VitePress + GithubAction搭建个人博客
  • 2025-05-02 Spring cloud-gateway整合satoken
  • 2024-06-04 OpenFeign入门和使用Okhttp替换默认HTTP请求框架
  • 2025-05-02 SpringBoot整合Minio
  • 2025-12-29 深入理解 JavaScript 执行机制:从预编译到 AO 对象
  • 2025-08-28 上海
热门标签
  • Halo 1
  • 旅行 3
  • 收藏 1
  • 分享 1
  • java 4
749° 19 3 2
当您评论及浏览文章且浏览器未禁止COOKIE时,会为您显示最近10条回复及前8篇文章的浏览记录。
直行或是转弯 我们最终都会相见

你好,
我是ox537u

    • 1周前

      白嫖GPT成功😊

    • 查看更多瞬间动态
  • 大学 2025-06-01 评论 ox537u
      随心杂记
    大学

    双桥

    SpringBoot整合Minio 2025-05-02 1 条 ox537u
      经验分享
      java
    SpringBoot整合Minio

    使用docker部署minio 拉取镜像 docker pull minio/minio 创建配置和数据目录 mkdir -p /data/minio/config mkdir -p /data/minio/data

    Spring cloud-gateway整合satoken 2025-05-02 评论 ox537u
      经验分享
      java
    Spring cloud-gateway整合satoken

    本文章使用的版本: SpringBoot:2.6.13 JDK:1.8 SpringCloud Alibaba:2021.0.5.0 Satoken:1.37.0 微服务架构下的鉴权一般分为两种: 每个服务各自鉴权 网关统一鉴权 方案一和传统单体鉴权差别不大,不再过多赘述,本篇介绍方案二的整合步骤(

    VitePress + GithubAction搭建个人博客 2025-05-02 评论 ox537u
      经验分享
    VitePress + GithubAction搭建个人博客

    新建一个blog文件夹 先决条件 Node.js 版本 16 或更高版本。 用于通过命令行界面(CLI)访问 VitePress 的终端。 具有 Markdown 语法支持的文本编辑器。推荐使用 VSCode) 以及官方 Vue 扩展。 <

    成都 2025-02-06 评论 ox537u
      旅行
    成都
    OpenFeign入门和使用Okhttp替换默认HTTP请求框架 2024-06-04 评论 ox537u
      经验分享 / 学习
      java
    OpenFeign入门和使用Okhttp替换默认HTTP请求框架

    前言 在使用Openfeign以前,我们利用Nacos实现了服务的治理,利用RestTemplate实现了服务的远程调用。但是远程调用的代码太复杂了: 而且这种调用方式,与原本的本地方法调用差异太大,编程时的体验也不统一,一会儿远程调用,一会儿本地调用。 因此,我们必须想办法改变远程调用的开发模式,

    若依Springboot整合微信小程序实现登录 2023-10-21 评论 ox537u
      经验分享 / 学习
      java
    若依Springboot整合微信小程序实现登录

    微信小程序官方登录流程图 主要的流程就是调用wx.getUserProfile向微信服务器发送请求获取code和其他的一些信息,然后再通过wx.login向我们的后台发送请求获取session_key和openid等其他信息

    若依Springboot整合微信小程序实现登录
    查看完整文章 评论

    微信小程序官方登录流程图

    主要的流程就是调用wx.getUserProfile向微信服务器发送请求获取code和其他的一些信息,然后再通过wx.login向我们的后台发送请求获取session_key和openid等其他信息

    个人实现登录流程

    1️⃣首先去我们的微信公众号平台拿到AppId和AppSecret。等一下我们会用到😉

    2️⃣数据库设计

    CREATE TABLE `user` (
      `pk_id` bigint(20) NOT NULL COMMENT '主键',
      `nickname` varchar(50) DEFAULT NULL COMMENT '用户昵称',
      `service_man_id` bigint(20) DEFAULT NULL,
      `avatarUrl` varchar(200) DEFAULT NULL COMMENT '用户头像',
      `openid` varchar(50) DEFAULT NULL,
      `unionid` varchar(50) DEFAULT NULL COMMENT '用户统一标识。针对一个微信开放平台帐号下的应用,同一用户的unionid是唯一的。',
      `create_time` datetime DEFAULT CURRENT_TIMESTAMP,
      `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
      PRIMARY KEY (`pk_id`) USING BTREE,
      UNIQUE KEY `user_unionid_uindex` (`unionid`) USING BTREE
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
    

    这里service_man_id和unioinid可以不用

    3️⃣Springboot后端

    3.1 将我们刚才从微信公众号平台获取到的appld定义一个常量类

    package com.ruoyi.gas.constant;
    
    /**
     * @Description 系统常量
     * @Author TuNan
     * @Date 2023/10/15
     */
    public class SystemConstant {
        /**
         * 应用唯一标识,在微信开放平台提交应用审核通过后获得
         */
        public static final String APPLETS_APPID="wx98935fbf9774bf5a";
        /**
         * 应用密钥AppSecret,在微信开放平台提交应用审核通过后获得
         */
        public static final String APPLETS_SECRET ="adbecc45d036d4ba52aab8285c159216";
    }
    

    3.2实体类

    package com.ruoyi.gas.domain;
    
    import com.baomidou.mybatisplus.annotation.TableField;
    import com.baomidou.mybatisplus.annotation.TableId;
    import com.baomidou.mybatisplus.annotation.TableName;
    import lombok.Getter;
    import lombok.Setter;
    import lombok.experimental.Accessors;
    
    import java.io.Serializable;
    
    /**
     * 移动端用户对象 gas_xcx_user
     *
     * @author TuNan
     * @date 2023-09-17
     */
    @Getter
    @Setter
    @TableName("user")
    @Accessors(chain = true)
    public class User implements Serializable {
    
        private static final long serialVersionUID = 1L;
    
        @TableId("pk_id")
        private Long pkId;
    
        /**
         * 用户昵称
         */
        @TableField("nickname")
        private String nickname;
    
        /**
         * 用户头像
         */
        @TableField("avatarUrl")
        private String avatarUrl;
    
        /**
         * 用户统一标识。针对一个微信开放平台帐号下的应用,同一用户的unionid是唯一的。
         */
        @TableField("unionid")
        private String unionId;
    
        @TableField("openid")
        private String openid;
    
        private Long ServiceManId;
    }
    
    

    3.3 controller层

    package com.ruoyi.gas.controller;
    
    
    import com.ruoyi.gas.domain.dto.UserDTO;
    import com.ruoyi.gas.domain.vo.ReWxUserInfoVO;
    import com.ruoyi.gas.service.UserService;
    import org.springframework.web.bind.annotation.*;
    
    import javax.annotation.Resource;
    import java.util.Map;
    
    /**
     * <p>
     * 前端控制器
     * </p>
     *
     * @author TuNan
     * @since 2023/10/13
     */
    @RestController
    @RequestMapping("/gas/user")
    public class UserController {
    
        @Resource
        private UserService userService;
    
        /**
         * 微信小程序登录
         *
         * @param requestData 请求参数
         * @return ReWxUserInfoVO
         */
        @PostMapping("/getUserLoginByApplets")
        @SuppressWarnings("unchecked")  // 用于抑制编译器产生警告信息。
        public ReWxUserInfoVO getUserLoginByApplets(@RequestBody Map<String, Object> requestData) {
            String code = (String) requestData.get("code");
            Map<String, Object> userMap = (Map<String, Object>) requestData.get("user");
            UserDTO userDTO = new UserDTO();
            userDTO.setAvatarUrl((String) userMap.get("avatarUrl"));
            userDTO.setCity((String) userMap.get("city"));
            userDTO.setCountry((String) userMap.get("country"));
            userDTO.setGender((Integer) userMap.get("gender"));
            userDTO.setLanguage((String) userMap.get("language"));
            userDTO.setNickName((String) userMap.get("nickName"));
            System.out.println("userDTO = " + userDTO);
            return userService.loginByWxApplets(code , userDTO);
        }
    }
    

    3.4 服务层及实现

    package com.ruoyi.gas.service;
    
    import com.baomidou.mybatisplus.extension.service.IService;
    import com.ruoyi.gas.domain.User;
    import com.ruoyi.gas.domain.dto.UserDTO;
    import com.ruoyi.gas.domain.vo.ReWxUserInfoVO;
    
    /**
     * <p>
     * 服务类
     * </p>
     *
     * @author TuNan
     * @since 2023-09-18
     */
    public interface UserService extends IService<User> {
    
        /**
         * 微信登录 小程序版
         */
        ReWxUserInfoVO loginByWxApplets(String code, UserDTO userDTO);
    }
    
    package com.ruoyi.gas.service.impl;
    
    import cn.dev33.satoken.stp.StpUtil;
    import cn.hutool.core.bean.BeanUtil;
    import cn.hutool.core.util.IdUtil;
    import cn.hutool.core.util.ObjectUtil;
    import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
    import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    import com.ruoyi.common.core.domain.model.LoginUser;
    import com.ruoyi.common.enums.DeviceType;
    import com.ruoyi.common.helper.LoginHelper;
    import com.ruoyi.gas.domain.User;
    import com.ruoyi.gas.domain.dto.UserDTO;
    import com.ruoyi.gas.domain.ro.AppletsWxLoginRO;
    import com.ruoyi.gas.domain.vo.ReWxUserInfoVO;
    import com.ruoyi.gas.mapper.UserMapper;
    import com.ruoyi.gas.service.UserService;
    import com.ruoyi.gas.utils.WxLoginUtil;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.stereotype.Service;
    
    
    /**
     * <p>
     * 服务实现类
     * </p>
     *
     * @author xiahaike
     * @since 2023/10/13
     */
    @Service
    @Slf4j
    public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    
        @Override
        public ReWxUserInfoVO loginByWxApplets(String code, UserDTO userDTO) {
            // 1.通过code 获取到用户的微信信息
            AppletsWxLoginRO getWxUserInfoRO = WxLoginUtil.toAppletsWxLogin(code);
            // 2.数据库对比 unionid 是否已有信息 如果没有就保持数据库
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            // 3.通过查询pk_id 索引优化查询 无需回表查询用户信息 索引 openid
            queryWrapper.eq("openid", getWxUserInfoRO.getOpenid());
            User user = getOne(queryWrapper);
            log.info("数据库查询用户是否已有账号==空则没有==={}====", user);
            // 4.如果用户不存在则创建用户
            if (ObjectUtil.isEmpty(user)) {
                long userId = IdUtil.getSnowflakeNextId();
                String nickName = userDTO.getNickName();
                save(new User().setPkId(userId).setNickname(nickName).setOpenid(getWxUserInfoRO.getOpenid()).setAvatarUrl(userDTO.getAvatarUrl()).setServiceManId(0L));
                LoginUser loginUser = BeanUtil.toBean(new User().setPkId(userId).setNickname(nickName), LoginUser.class);
                loginUser.setUserType("sys_user");
                loginUser.setUserId(IdUtil.getSnowflakeNextId());
                LoginHelper.loginByDevice(loginUser, DeviceType.XCX);
                return new ReWxUserInfoVO().setPkId(userId).setNickname(nickName)
                    .setSession_key(getWxUserInfoRO.getSession_key()).setOpenid(getWxUserInfoRO.getOpenid())
                    .setToken(StpUtil.getTokenValue()).setAvatarUrl(userDTO.getAvatarUrl()).setServiceManId(0L);
            }
            // 5.如果用户存在则直接登录
            LoginUser loginUser = BeanUtil.toBean(user, LoginUser.class);
            loginUser.setUserType("sys_user");
            loginUser.setUserId(IdUtil.getSnowflakeNextId());
            LoginHelper.loginByDevice(loginUser, DeviceType.XCX);
            return new ReWxUserInfoVO().setPkId(user.getPkId()).setNickname(user.getNickname())
                .setAvatarUrl(user.getAvatarUrl()).setSession_key(getWxUserInfoRO.getSession_key())
                .setOpenid(getWxUserInfoRO.getOpenid()).setToken(StpUtil.getTokenValue())
                .setServiceManId(user.getServiceManId());
        }
    }
    
    

    3.5微信登录工具包

    package com.ruoyi.gas.utils;
    
    import cn.hutool.core.text.StrFormatter;
    import cn.hutool.http.HttpUtil;
    import cn.hutool.json.JSONUtil;
    import com.ruoyi.gas.Enum.WxApiType;
    import com.ruoyi.gas.constant.SystemConstant;
    import com.ruoyi.gas.domain.ro.AppletsWxLoginRO;
    import lombok.extern.slf4j.Slf4j;
    
    /**
     * @Description 微信登录工具包
     * @Author TuNan
     * @Date 2023/10/16
     */
    @Slf4j
    public class WxLoginUtil {
    
        /**
         *微信登录
         * @param code 前端请求获取=>微信code
         * @return void
         * @author zhangjunrong
         * @date 2022/12/19 20:16
         */
        public static AppletsWxLoginRO toAppletsWxLogin(String code){
            //1.通过前端给的code获取openid和access_token还有unionid
            String getTokenOpenid = StrFormatter.format(WxApiType.APPLETS_GET_TOKEN_OPENID.getValue(), SystemConstant.APPLETS_APPID,SystemConstant.APPLETS_SECRET, code);
            String data = HttpUtil.get(getTokenOpenid);
            log.info("微信获取获取openid和unionid,返回结果======{}=====",data);
            //json=>bean
            //todo 获取用户信息失败 抛异常
            return JSONUtil.toBean(data, AppletsWxLoginRO.class);
        }
    
    }
    

    3.6 Ro及Vo

    package com.ruoyi.gas.domain.ro;
    
    import lombok.Data;
    
    /**
     * @Description 微信用户基础信息
     * @Author TuNan
     * @Date 2023/10/16
     */
    @Data
    public class WxUserInfoRO {
        /**
         * 用户昵称
         */
        private String nickname;
    
        /**
         * 用户头像
         */
        private String avatarUrl;
        /**
         * 用户微信统一标识
         */
        private String unionid;
    
        private String session_key;
    
        private String openid;
    }
    
    
    package com.ruoyi.gas.domain.ro;
    
    import lombok.Data;
    
    /**
     * @Description TODO
     * @Author TuNan
     * @Date 2023/09/18
     */
    @Data
    public class AppletsWxLoginRO {
        /**
         *普通用户标识,对该公众帐号唯一
         */
        private String openid;
        /**
         *用户在开放平台的唯一标识符
         */
        private String unionid;
    
        private String session_key;
    
    }
    
    package com.ruoyi.gas.domain.vo;
    
    import lombok.Data;
    import lombok.experimental.Accessors;
    
    /**
     * @Description 返回前端微信个人信息
     * @Author TuNan
     * @Date 2023/9/17 15:27
     */
    @Data
    @Accessors(chain = true)
    public class ReWxUserInfoVO {
        /**
         * 用户id
         */
        private Long pkId;
    
        /**
         * 用户昵称
         */
        private String nickname;
    
        /**
         * 用户头像
         */
        private String avatarUrl;
    
        private String unionid;
    
        private String session_key;
    
        private String openid;
    
        private String token;
    
        private Long ServiceManId;
    }
    
    

    以下就是我们后端的所有代码,接下来是小程序端的代码

    4️⃣小程序实现

    4.1首先我们在app.js中定义全局变量

    // app.js
    
    App({
      globalData: {
        token: '',
        openid: null,
        sessionKey: null,
        serviceManId: 0,
        pkId:0, // 用于判断用户是否登录
      }
    })
    

    4.2 然后是我们在主页调用wx.logind的js代码

    const app = getApp()
    
    // 点击登录按钮
      login() {
        if (this.data.pkId != 0) {
          Toast.fail("您已登录,请勿重复提交")
        } else {
          console.log('执行了登录操作');
          wx.getUserProfile({
            desc: 'Wexin',
            // 这里应该是向微信发送请求获取用户名和头像
            success: (res) => {
              this.setData({
                userInfo: res.userInfo
              })
              let user = this.data.userInfo // user里面保存从微信获取的信息(用户名和头像)
              // 向后台发送请求 将code、用户头像、用户名一起发送至后台
              console.log(user)
              wx.login({
                success: (res) => {
                  console.log(res)
                  const code = res.code;
                  wx.request({
                    url: baseUrl + '/gas/user/getUserLoginByApplets',
                    method: "POST",
                    data: {
                      user,
                      code
                    },
                    success: (res) => {
                      // 后端返回的数据
                      var Mydata = res.data
                      // 将从服务器获取的token、session_key等保存到globalData中
                      app.globalData.token = Mydata.token
                      app.globalData.session_key = Mydata.session_key
                      app.globalData.serviceManId = Mydata.serviceManId
                      app.globalData.openid = Mydata.openid
                      app.globalData.pkId = Mydata.pkId
                      // 将serviceId和pkid保存到当前页面中
                      this.setData({
                        serviceManId: app.globalData.serviceManId,
                        pkId: res.data.pkId
                      });
                    }
                  })
                },
              })
            }
          })
        }
      },
    

    到此我们所有流程就结束了🤞,出现以上效果说明就成功登录了😉

    1 2
  • 简述
    直行或是转弯 我们最终都会相见
    [email protected]
    生涯
  • 行业互联网
  • 职业前端(全栈/全干)开发工程师
  • 人生
  • 生活角色保密
  • 社会角色保密
  • 类型
  • 星座 金牛座
  • 生肖 蛇
  • 血型A
  • 数据
  • 发表文章17篇
  • 发表评论2个
  • 星球加热447度
  • 最近的心情能量
      愉快 沮丧
    • 不喜不悲 ,当时发表在「大学」
    • 没有心情 ,当时发表在「SpringBoot整合Minio」
    • 有点愉快 ,当时发表在「Spring cloud-gateway整合satoken」
    • 不喜不悲 ,当时发表在「VitePress + GithubAction搭建个人博客」
    • 不喜不悲 ,当时发表在「成都」
  • 地图数据来源于高德地图
  • infj 提倡者
    infj 提倡者
    • 外向内向
    • 远见现实
    • 理性感受
    • 评判展望
    • 坚决起伏
  • 了解更多信息
今天是我记得

2024-05-16

随机阅读「SpringBoot整合Minio」
阅读
壹行随十人
  • 张鑫旭-鑫空间-鑫生活
  • 云风的 BLOG
  • 阮一峰的个人网站 - Ruan YiFeng's Personal Website
橙黄橘绿版权所有 · 架构于Halo及为您增强体验的THYUU/星度主题