首页 > 编程语言 >深入解析CustomerInfoServiceImpl和CustomerServiceImpl:微信小程序登录功能的实现

深入解析CustomerInfoServiceImpl和CustomerServiceImpl:微信小程序登录功能的实现

时间:2024-08-10 21:52:18浏览次数:7  
标签:CustomerInfoServiceImpl 登录 微信 用户 customerInfo com atguigu import CustomerService

文章目录


在现代移动应用开发中,微信小程序已经成为了许多企业的重要选择。为了支持小程序的用户登录功能,我们需要与微信的认证服务进行集成。这篇文章将带大家深入解析两个关键的服务实现类: CustomerInfoServiceImplCustomerServiceImpl,它们是如何共同工作来实现微信小程序登录功能的。

一、CustomerInfoServiceImpl类详解

CustomerInfoServiceImpl类主要负责处理用户信息的管理和登录日志的记录。它继承了ServiceImpl,并实现了CustomerInfoService接口。下面我们来详细了解它的核心逻辑。

package com.atguigu.daijia.customer.service.impl;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import com.atguigu.daijia.customer.mapper.CustomerInfoMapper;
import com.atguigu.daijia.customer.mapper.CustomerLoginLogMapper;
import com.atguigu.daijia.customer.service.CustomerInfoService;
import com.atguigu.daijia.model.entity.customer.CustomerInfo;
import com.atguigu.daijia.model.entity.customer.CustomerLoginLog;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.stereotype.Service;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
@RequiredArgsConstructor
public class CustomerInfoServiceImpl extends ServiceImpl<CustomerInfoMapper, CustomerInfo> implements
        CustomerInfoService {

    private final WxMaService wxMaService;
    private final CustomerInfoMapper customerInfoMapper;
    private final CustomerLoginLogMapper customerLoginLogMapper;

    // 微信小程序登录接口
    @Override
    public Long login(String code) {
        // 1.获取code值,使用微信工具包对象,获取微信唯一标识openid
        String openid = null;
        try {
            WxMaJscode2SessionResult sessionInfo = wxMaService.getUserService().getSessionInfo(code);
            openid = sessionInfo.getOpenid();
        } catch (WxErrorException e) {
            throw new RuntimeException(e);
        }
        // 2.根据openid查询数据库表,判断是否第一次登录
        // 如果不存返回null,如果存在返回一条记录
        LambdaQueryWrapper<CustomerInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CustomerInfo::getWxOpenId, openid);
        CustomerInfo customerInfo = customerInfoMapper.selectOne(wrapper);
        // 3.如果是第一次登录,将用户信息插入数据库表
        if (customerInfo == null) {
            customerInfo = new CustomerInfo();
            customerInfo.setNickname(String.valueOf(System.currentTimeMillis()));
            customerInfo.setAvatarUrl("https://oss.aliyuncs.com/aliyun_id_photo_bucket/default_handsome.jpg");
            customerInfo.setWxOpenId(openid);
            customerInfoMapper.insert(customerInfo);
        }
        // 4.记录登录日志
        CustomerLoginLog customerLoginLog = new CustomerLoginLog();
        customerLoginLog.setCustomerId(customerInfo.getId());
        customerLoginLog.setMsg("小程序登录");
        customerLoginLogMapper.insert(customerLoginLog);

        // 5.返回用户id
        return customerInfo.getId();
    }
}
  1. 获取微信用户的openid

    在微信小程序中,code是通过调用wx.login接口获取的,作为登录的凭证。我们通过wxMaService来获取openid,这是每个微信用户的唯一标识。

    WxMaJscode2SessionResult sessionInfo = wxMaService.getUserService().getSessionInfo(code);
    String openid = sessionInfo.getOpenid();
    
  2. 检查用户是否是第一次登录

    通过openid在数据库中查询用户信息。如果没有找到对应的用户信息,则说明这是用户的首次登录。在这种情况下,我们会创建一条新的用户记录。

    LambdaQueryWrapper<CustomerInfo> wrapper = new LambdaQueryWrapper<>();
    wrapper.eq(CustomerInfo::getWxOpenId, openid);
    CustomerInfo customerInfo = customerInfoMapper.selectOne(wrapper);
    
    if (customerInfo == null) {
        customerInfo = new CustomerInfo();
        customerInfo.setNickname(String.valueOf(System.currentTimeMillis()));
        customerInfo.setAvatarUrl("https://oss.aliyuncs.com/aliyun_id_photo_bucket/default_handsome.jpg");
        customerInfo.setWxOpenId(openid);
        customerInfoMapper.insert(customerInfo);
    }
    
  3. 记录登录日志

    每次用户登录,我们都会记录一条登录日志,以便后续分析和追踪。

    CustomerLoginLog customerLoginLog = new CustomerLoginLog();
    customerLoginLog.setCustomerId(customerInfo.getId());
    customerLoginLog.setMsg("小程序登录");
    customerLoginLogMapper.insert(customerLoginLog);
    
  4. 返回用户ID

    最后,我们将用户的ID返回,供后续使用。

    return customerInfo.getId();
    
二、CustomerServiceImpl类详解

CustomerServiceImpl类则主要负责与其他微服务的交互以及处理登录后的Token管理。它通过调用远程的用户服务,获取用户的登录信息,并将登录状态存储在Redis中。

package com.atguigu.daijia.customer.service.impl;

import com.atguigu.daijia.common.constant.RedisConstant;
import com.atguigu.daijia.common.execption.GuiguException;
import com.atguigu.daijia.common.result.Result;
import com.atguigu.daijia.common.result.ResultCodeEnum;
import com.atguigu.daijia.customer.client.CustomerInfoFeignClient;
import com.atguigu.daijia.customer.service.CustomerService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
@RequiredArgsConstructor
public class CustomerServiceImpl implements CustomerService {

    // 注入远程调用接口
    private final CustomerInfoFeignClient client;
    private final RedisTemplate redisTemplate;

    @Override
    public String login(String code) {
        // 1.远程调用,返回用户id
        Result<Long> loginResult = client.login(code);

        // 2.判断如果返回失败,返回错误提示
        Integer codeResult = loginResult.getCode();
        if (codeResult != 200) {
            throw new GuiguException(ResultCodeEnum.DATA_ERROR);
        }
        // 3.获取远程调用返回的用户id
        Long customerId = loginResult.getData();
        // 4.判断返回用户id是否为空,如果为空,返回错误提示
        if (customerId == null) {
            throw new GuiguException(ResultCodeEnum.DATA_ERROR);
        }
        // 5.生成token字符串
        String token = UUID.randomUUID().toString().replaceAll("-", "");
        // 6.把用户id放到Redis,设置过期时间
        // key:token value:customerId
        redisTemplate.opsForValue().set(RedisConstant.USER_LOGIN_KEY_PREFIX + token,
                                        customerId.toString(),
                                        RedisConstant.USER_LOGIN_KEY_TIMEOUT,
                                        TimeUnit.SECONDS);
        // 7.返回token字符串
        return token;
    }
}
  1. 远程调用获取用户ID

    CustomerServiceImpl通过Feign客户端远程调用CustomerInfoServicelogin方法,获取用户ID。

    Result<Long> loginResult = client.login(code);
    
  2. 错误处理

    在调用远程服务后,首先要检查返回的结果状态码,如果状态码不为200,说明请求失败,抛出自定义异常。

    if (loginResult.getCode() != 200) {
        throw new GuiguException(ResultCodeEnum.DATA_ERROR);
    }
    
  3. 生成Token并存储到Redis

    为了管理用户的会话状态,我们生成了一个唯一的Token,并将其与用户ID绑定存储到Redis中,这样可以在后续的请求中验证用户身份。

    String token = UUID.randomUUID().toString().replaceAll("-", "");
    redisTemplate.opsForValue().set(RedisConstant.USER_LOGIN_KEY_PREFIX + token,
                                    customerId.toString(),
                                    RedisConstant.USER_LOGIN_KEY_TIMEOUT,
                                    TimeUnit.SECONDS);
    
  4. 返回Token

    最终,将生成的Token返回给前端,前端会在后续的请求中使用这个Token来进行身份验证。

    return token;
    
三、总结

CustomerInfoServiceImplCustomerServiceImpl这两个类的协作,完整实现了微信小程序的用户登录功能。前者负责处理微信用户信息的管理,后者则负责会话状态的管理与安全。这种设计使得代码清晰且职责明确,便于维护和扩展。

标签:CustomerInfoServiceImpl,登录,微信,用户,customerInfo,com,atguigu,import,CustomerService
From: https://blog.csdn.net/Takumilove/article/details/141096838

相关文章

  • 基于java+ssm+vue的大学生社团活动管理微信小程序
    ......
  • uniapp-微信小程序实现分享给好友功能且动态页面
        uniapp全局设置分享朋友及分享到朋友圈功能,在我们没有配置微信的分享时候,微信小程序的时候可用看到,分享链接和这两个都是置灰的,如果我们想要让别人可以分享或者复制链接分享我们的小程序的话,就想要自己开发和配置。接下来分享全局实现的步骤(不需要在每个页面单......
  • wechat crawler url拼接 url解析 微信爬虫 json序列化 反序列化
    WechatPublicRequest\Program.csusingSystem.Collections.Specialized;usingSystem.Diagnostics;usingSystem.Web;usingNewtonsoft.Json;classProgram{staticasyncTaskMain(){varlatestTxtFilePath=GetLatestTxtFilePath();......
  • 【笔记】微信抢红包-3千万的技术架构
    总体思路Redis服务器两台虚拟机,2C4G规格redis服务部署客户端pom文件<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"......
  • Java计算机毕业设计基于微信小程序的HPV疫苗预约与抢苗系统的设计与实现(开题+源码+论
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着健康意识的提升,人们对疾病预防的重视程度日益增强,尤其是针对女性健康的HPV(人乳头瘤病毒)疫苗,其作为预防宫颈癌等恶性肿瘤的有效手段,需求量急剧增......
  • Java计算机毕业设计基于微信小程序的网络文学管理平台(开题+源码+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着移动互联网的迅猛发展,网络文学已成为大众文化消费的重要组成部分,其便捷性、互动性和丰富性深受读者喜爱。然而,传统网络文学平台多依赖于网页或AP......
  • php程序对微信你昵称的表情处理导出excel文件
     php程序对微信昵称的表情处理,若转义存数据库,怎么读出并导出成excel文件.<?phpinclude(dirname(__FILE__).'/phpexcel-1.7.7/Classes/PHPExcel.php');include(dirname(__FILE__).'/phpexcel-1.7.7/Classes/PHPExcel/IOFactory.php');$name2="[[EMOJI:%F0%9F%......
  • 使用微信小程序开发制作一个简易的在线投票应用
    一、项目概述在线投票应用是一个基于微信小程序开发的应用,用于用户创建投票活动并进行投票。用户可以创建投票活动,设置投票选项和投票方式,然后将活动分享给其他用户进行投票。二、开发环境准备微信开发者工具:用于项目的开发和调试。小程序注册账号:用于获取小程序的AppID。云......
  • Java计算机毕业设计共享茶室预约微信小程序(开题报告+源码+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景在快节奏的现代生活中,人们对于休闲放松的需求日益增长,茶文化作为中国传统文化的重要组成部分,正逐渐成为一种流行的生活方式。然而,传统茶室在预约、管......
  • 毕业设计:基于Springboot的口腔医院微信小程序【代码+论文+PPT】
    全文内容包括:1、采用技术;2、系统功能;3、系统截图;4、配套内容。索取方式见文末微信号,欢迎关注收藏!一、采用技术语言:Java1.8框架:SpringBoot数据库:MySQL5.7、8.0开发工具:IntelliJIDEA旗舰版、微信开发工具其他:Maven3.8以上二、系统功能系统首页:展示口腔医院微信小程序的主......