32653 字
约 108 分钟
38
appendix_C
无标签

附录C 认证授权中心模块源码详解

模块概览(面向 0 基础读者):

  • 基于 Spring Security OAuth2 实现统一认证与授权。
  • 支持账号密码、第三方登录,统一下发 JWT/网关 Token。
  • 整合用户、角色、权限查询能力,为其它服务提供鉴权基础。

核心目录:

  • xuecheng-plus-auth/pom.xml
  • xuecheng-plus-auth/src/main/java/com/xuecheng/auth/config
  • xuecheng-plus-auth/src/main/java/com/xuecheng/auth/controller
  • xuecheng-plus-auth/src/main/java/com/xuecheng/auth/service (尚未找到,检查路径)
  • xuecheng-plus-auth/src/main/resources

文件:xuecheng-plus-auth/bootstrap.yml

spring: # Spring Boot 顶层配置
  application:
    name: auth # 服务在 Nacos 中注册的名称
  cloud:
    nacos:
      server-addr: 192.168.101.65:8848 # Nacos 地址
      discovery:
        namespace: dev402 # 注册命名空间
        group: xuecheng-plus-project # 注册分组
      config:
        namespace: dev402 # 配置命名空间
        group: xuecheng-plus-project # 配置分组
        file-extension: yaml # 默认读取 yaml 文件
        refresh-enabled: true # 允许动态刷新
        shared-configs: # 引入公共配置
          - data-id: swagger-${spring.profiles.active}.yaml # Swagger 公共配置
            group: xuecheng-plus-common
            refresh: true
          - data-id: logging-${spring.profiles.active}.yaml # 日志公共配置
            group: xuecheng-plus-common
            refresh: true
          - data-id: mysql-${spring.profiles.active}.yaml # MySQL 公共配置
            group: xuecheng-plus-common
            refresh: true
          - data-id: redis-${spring.profiles.active}.yaml # Redis 公共配置
            group: xuecheng-plus-common
            refresh: true

  profiles:
    active: dev # 默认激活 dev 环境

文件:xuecheng-plus-auth/com/xuecheng/auth/config/AuthorizationServer.java

package com.xuecheng.auth.config; // 声明工具类所在的包路径
 // 空行
import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 类
import org.springframework.context.annotation.Bean; // 导入 Bean 类
import org.springframework.context.annotation.Configuration; // 导入 Configuration 类
import org.springframework.http.HttpMethod; // 导入 HttpMethod 类
import org.springframework.security.authentication.AuthenticationManager; // 导入 AuthenticationManager 类
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; // 导入 BCryptPasswordEncoder 类
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; // 导入 ClientDetailsServiceConfigurer 类
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; // 导入 AuthorizationServerConfigurerAdapter 类
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; // 导入 EnableAuthorizationServer 类
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; // 导入 AuthorizationServerEndpointsConfigurer 类
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer; // 导入 AuthorizationServerSecurityConfigurer 类
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices; // 导入 AuthorizationServerTokenServices 类
import org.springframework.security.oauth2.provider.token.DefaultTokenServices; // 导入 DefaultTokenServices 类
 // 空行
import javax.annotation.Resource; // 导入 Resource 类
 // 空行
/** // 多行注释开始
 * @description 授权服务器配置 // 多行注释内容
 * 相当于售票处,你没有这个票你就不能进去 // 多行注释内容
 * @author Mr.M // 多行注释内容
 * @date 2022/9/26 22:25 // 多行注释内容
 * @version 1.0 // 多行注释内容
 */ // 多行注释内容
 @Configuration // 执行通用逻辑
 @EnableAuthorizationServer // 执行通用逻辑
 public class AuthorizationServer extends AuthorizationServerConfigurerAdapter { // 定义 AuthorizationServer 类型
 // 空行
  @Resource(name="authorizationServerTokenServicesCustom") // 执行通用逻辑
  private AuthorizationServerTokenServices authorizationServerTokenServices; // 执行通用逻辑
 // 空行
 @Autowired // 执行通用逻辑
 private AuthenticationManager authenticationManager; // 执行通用逻辑
 // 空行
  //客户端详情服务 // 原始行内注释
 // 配置哪些客户端可以进来 // 原始行内注释
  @Override // 执行通用逻辑
  public void configure(ClientDetailsServiceConfigurer clients) throws Exception { // 定义公有方法 configureClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()// 使用in-memory存储 // 执行通用逻辑
                .withClient("XcWebApp")// client_id(客户端id) // 执行通用逻辑
//                .secret("XcWebApp")//客户端密钥 // 原始行内注释
                .secret(new BCryptPasswordEncoder().encode("XcWebApp"))//客户端密钥 // 执行通用逻辑
                .resourceIds("xuecheng-plus")//资源列表 // 执行通用逻辑
                .authorizedGrantTypes("authorization_code", "password","client_credentials","implicit","refresh_token")// 该client允许的授权类型authorization_code,password,refresh_token,implicit,client_credentials // 执行通用逻辑
                .scopes("all")// 允许的授权范围 // 执行通用逻辑
                .autoApprove(false)//false跳转到授权页面 // 执行通用逻辑
                //客户端接收授权码的重定向地址 // 原始行内注释
                .redirectUris("http://www.51xuecheng.cn")//用于扫码登录 // 执行通用逻辑
   ; // 执行通用逻辑
  } // 代码块结束
 // 空行
 // 空行
  //令牌端点的访问配置,怎么发令牌 // 原始行内注释
  @Override // 执行通用逻辑
  public void configure(AuthorizationServerEndpointsConfigurer endpoints) { // 定义公有方法 configureAuthorizationServerEndpointsConfigurer endpoints) {
   endpoints // 执行通用逻辑
           .authenticationManager(authenticationManager)//认证管理器,验证用户名密码 // 执行通用逻辑
           .tokenServices(authorizationServerTokenServices)//令牌管理服务,自定义令牌规则 // 执行通用逻辑
           .allowedTokenEndpointRequestMethods(HttpMethod.POST);//只允许post请求令牌 // 执行通用逻辑
  } // 代码块结束
 // 空行
  //令牌端点的安全配置,谁可以访问令牌的接口 // 原始行内注释
  @Override // 执行通用逻辑
  public void configure(AuthorizationServerSecurityConfigurer security){ // 定义公有方法 configureAuthorizationServerSecurityConfigurer security){
   security // 执行通用逻辑
           .tokenKeyAccess("permitAll()")                    //oauth/token_key是公开 // 执行通用逻辑
           .checkTokenAccess("permitAll()")                  //oauth/check_token公开 // 执行通用逻辑
           .allowFormAuthenticationForClients()				//表单认证(申请令牌) // 执行通用逻辑
   ; // 执行通用逻辑
  } // 代码块结束
 // 空行
 // 空行
 // 空行
 } // 代码块结束

文件:xuecheng-plus-auth/com/xuecheng/auth/config/DaoAuthenticationProviderCustom.java

package com.xuecheng.auth.config; // 声明工具类所在的包路径
 // 空行
import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 类
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; // 导入 UsernamePasswordAuthenticationToken 类
import org.springframework.security.authentication.dao.DaoAuthenticationProvider; // 导入 DaoAuthenticationProvider 类
import org.springframework.security.core.AuthenticationException; // 导入 AuthenticationException 类
import org.springframework.security.core.userdetails.UserDetails; // 导入 UserDetails 类
import org.springframework.security.core.userdetails.UserDetailsService; // 导入 UserDetailsService 类
import org.springframework.stereotype.Component; // 导入 Component 类
 // 空行
/** // 多行注释开始
 * @author Mr.M // 多行注释内容
 * @version 1.0 // 多行注释内容
 * @description 重写了DaoAuthenticationProvider的校验的密码的方法,因为我们统一认证入口,有一些认证方式不需要校验密码 // 多行注释内容
 * @date 2023/2/24 11:40 // 多行注释内容
 */ // 多行注释内容
@Component // 执行通用逻辑
public class DaoAuthenticationProviderCustom extends DaoAuthenticationProvider { // 定义 DaoAuthenticationProviderCustom 类型
 // 空行
 @Autowired // 执行通用逻辑
 public void setUserDetailsService(UserDetailsService userDetailsService) { // 定义公有方法 setUserDetailsServiceUserDetailsService userDetailsService) {
  super.setUserDetailsService(userDetailsService); // super 调用 setUserDetailsService 方法,调用方法执行操作
 } // 代码块结束
 // 空行
//实现微信登录 // 原始行内注释
 @Override // 执行通用逻辑
 protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException { // 定义受保护方法 additionalAuthenticationChecksUserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
 // 空行
 } // 代码块结束
} // 代码块结束

文件:xuecheng-plus-auth/com/xuecheng/auth/config/MybatisPlusConfig.java

package com.xuecheng.auth.config; // 声明工具类所在的包路径
 // 空行
import com.baomidou.mybatisplus.annotation.DbType; // 导入 DbType 类
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; // 导入 MybatisPlusInterceptor 类
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; // 导入 PaginationInnerInterceptor 类
import org.mybatis.spring.annotation.MapperScan; // 导入 MapperScan 类
import org.springframework.context.annotation.Bean; // 导入 Bean 类
import org.springframework.context.annotation.Configuration; // 导入 Configuration 类
 // 空行
/** // 多行注释开始
 * <P> // 多行注释内容
 * 		Mybatis-Plus 配置 // 多行注释内容
 * </p> // 多行注释内容
 */ // 多行注释内容
@Configuration // 执行通用逻辑
@MapperScan("com.xuecheng.ucenter.mapper") // 执行通用逻辑
public class MybatisPlusConfig { // 定义 MybatisPlusConfig 类型
	/** // 多行注释开始
	 * 新的分页插件 // 多行注释内容
	 * 需要设置 MybatisConfiguration#useDeprecatedExecutor = false // 多行注释内容
	 * 避免缓存出现问题(该属性会在旧插件移除后一同移除) // 多行注释内容
	 */ // 多行注释内容
	@Bean // 执行通用逻辑
	public MybatisPlusInterceptor mybatisPlusInterceptor() { // 定义公有方法 mybatisPlusInterceptor) {
		MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); // 创建 MybatisPlusInterceptor 实例并赋值给 interceptor
		interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); // interceptor 调用 addInnerInterceptor 方法,调用方法执行操作
		return interceptor; // 返回 interceptor 给调用方
	} // 代码块结束
 // 空行
 // 空行
} // 代码块结束

文件:xuecheng-plus-auth/com/xuecheng/auth/config/TokenConfig.java

package com.xuecheng.auth.config; // 声明工具类所在的包路径
 // 空行
import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 类
import org.springframework.context.annotation.Bean; // 导入 Bean 类
import org.springframework.context.annotation.Configuration; // 导入 Configuration 类
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices; // 导入 AuthorizationServerTokenServices 类
import org.springframework.security.oauth2.provider.token.DefaultTokenServices; // 导入 DefaultTokenServices 类
import org.springframework.security.oauth2.provider.token.TokenEnhancerChain; // 导入 TokenEnhancerChain 类
import org.springframework.security.oauth2.provider.token.TokenStore; // 导入 TokenStore 类
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore; // 导入 InMemoryTokenStore 类
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter; // 导入 JwtAccessTokenConverter 类
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore; // 导入 JwtTokenStore 类
 // 空行
import java.util.Arrays; // 导入 Arrays 类
 // 空行
/** // 多行注释开始
 * @author Administrator // 多行注释内容
 * @version 1.0 // 多行注释内容
 * 令牌生成与存储方式的类 // 多行注释内容
 **/ // 多行注释内容
@Configuration // 执行通用逻辑
public class TokenConfig { // 定义 TokenConfig 类型
 // 空行
    private String SIGNING_KEY = "mq123"; // 将 "mq123" 赋值给 SIGNING_KEY
 // 空行
    @Autowired // 执行通用逻辑
    TokenStore tokenStore; // 执行通用逻辑
 // 空行
//    @Bean // 原始行内注释
//    public TokenStore tokenStore() { // 原始行内注释
//        //使用内存存储令牌(普通令牌) // 原始行内注释
//        return new InMemoryTokenStore(); // 原始行内注释
//    } // 原始行内注释
 // 空行
    @Autowired // 执行通用逻辑
    private JwtAccessTokenConverter accessTokenConverter; // 执行通用逻辑
 // 空行
    // 使用jwt存储token // 原始行内注释
    @Bean // 执行通用逻辑
    public TokenStore tokenStore() { // 定义公有方法 tokenStore) {
        return new JwtTokenStore(accessTokenConverter()); // 返回 new JwtTokenStore(accessTokenConverter()) 给调用方
    } // 代码块结束
 // 空行
    // 配置jwt的加密方式 // 原始行内注释
    @Bean // 执行通用逻辑
    public JwtAccessTokenConverter accessTokenConverter() { // 定义公有方法 accessTokenConverter) {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter(); // 创建 JwtAccessTokenConverter 实例并赋值给 converter
        converter.setSigningKey(SIGNING_KEY); // converter 调用 setSigningKey 方法,调用方法执行操作
        return converter; // 返回 converter 给调用方
    } // 代码块结束
 // 空行
    //令牌管理服务 // 原始行内注释
    @Bean(name="authorizationServerTokenServicesCustom") // 执行通用逻辑
    public AuthorizationServerTokenServices tokenService() { // 定义公有方法 tokenService) {
        DefaultTokenServices service=new DefaultTokenServices(); // 创建 DefaultTokenServices 实例并赋值给 service
        service.setSupportRefreshToken(true);//支持刷新令牌 // service 调用 setSupportRefreshToken 方法,调用方法执行操作
        service.setTokenStore(tokenStore);//令牌存储策略 // service 调用 setTokenStore 方法,调用方法执行操作
 // 空行
        TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain(); // 创建 TokenEnhancerChain 实例并赋值给 tokenEnhancerChain
        tokenEnhancerChain.setTokenEnhancers(Arrays.asList(accessTokenConverter)); // tokenEnhancerChain 调用 setTokenEnhancers 方法,调用方法执行操作
        service.setTokenEnhancer(tokenEnhancerChain); // service 调用 setTokenEnhancer 方法,调用方法执行操作
 // 空行
        service.setAccessTokenValiditySeconds(7200); // 令牌默认有效期2小时 // service 调用 setAccessTokenValiditySeconds 方法,调用方法执行操作
        service.setRefreshTokenValiditySeconds(259200); // 刷新令牌默认有效期3天 // service 调用 setRefreshTokenValiditySeconds 方法,调用方法执行操作
        return service; // 返回 service 给调用方
    } // 代码块结束
 // 空行
 // 空行
} // 代码块结束

文件:xuecheng-plus-auth/com/xuecheng/auth/config/WebSecurityConfig.java

package com.xuecheng.auth.config; // 声明工具类所在的包路径
 // 空行
import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 类
import org.springframework.context.annotation.Bean; // 导入 Bean 类
import org.springframework.security.authentication.AuthenticationManager; // 导入 AuthenticationManager 类
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; // 导入 AuthenticationManagerBuilder 类
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; // 导入 EnableGlobalMethodSecurity 类
import org.springframework.security.config.annotation.web.builders.HttpSecurity; // 导入 HttpSecurity 类
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; // 导入 EnableWebSecurity 类
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; // 导入 WebSecurityConfigurerAdapter 类
import org.springframework.security.core.userdetails.User; // 导入 User 类
import org.springframework.security.core.userdetails.UserDetailsService; // 导入 UserDetailsService 类
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; // 导入 BCryptPasswordEncoder 类
import org.springframework.security.crypto.password.NoOpPasswordEncoder; // 导入 NoOpPasswordEncoder 类
import org.springframework.security.crypto.password.PasswordEncoder; // 导入 PasswordEncoder 类
import org.springframework.security.provisioning.InMemoryUserDetailsManager; // 导入 InMemoryUserDetailsManager 类
 // 空行
/** // 多行注释开始
 * @author Mr.M // 多行注释内容
 * @version 1.0 // 多行注释内容
 * @description 安全管理配置 // 多行注释内容
 * @date 2022/9/26 20:53 // 多行注释内容
 */ // 多行注释内容
@EnableWebSecurity // 执行通用逻辑
@EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true) // 执行通用逻辑
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { // 定义 WebSecurityConfig 类型
 // 空行
 // 空行
    @Bean // 执行通用逻辑
    public AuthenticationManager authenticationManagerBean() throws Exception { // 定义公有方法 authenticationManagerBean) throws Exception {
        return super.authenticationManagerBean(); // 返回 super.authenticationManagerBean() 给调用方
    } // 代码块结束
 // 空行
    //配置用户信息服务 // 原始行内注释
//    @Bean // 原始行内注释
//    public UserDetailsService userDetailsService() { // 原始行内注释
//        //这里配置用户信息,这里暂时使用这种方式将用户存储在内存中 // 原始行内注释
//        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); // 原始行内注释
//        manager.createUser(User.withUsername("zhangsan").password("123").authorities("p1").build()); // 原始行内注释
//        manager.createUser(User.withUsername("lisi").password("456").authorities("p2").build()); // 原始行内注释
//        return manager; // 原始行内注释
//    } // 原始行内注释
 // 空行
    @Bean // 执行通用逻辑
    public PasswordEncoder passwordEncoder() { // 定义公有方法 passwordEncoder) {
//        //密码为明文方式 // 原始行内注释
//        return NoOpPasswordEncoder.getInstance(); // 原始行内注释
        return new BCryptPasswordEncoder(); // 返回 new BCryptPasswordEncoder() 给调用方
    } // 代码块结束
 // 空行
    @Autowired // 执行通用逻辑
    DaoAuthenticationProviderCustom daoAuthenticationProviderCustom; // 执行通用逻辑
 // 空行
 // 空行
    @Override // 执行通用逻辑
    protected void configure(AuthenticationManagerBuilder auth) throws Exception { // 定义受保护方法 configureAuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(daoAuthenticationProviderCustom); // auth 调用 authenticationProvider 方法,调用方法执行操作
    } // 代码块结束
 // 空行
    //配置安全拦截机制 // 原始行内注释
    @Override // 执行通用逻辑
    protected void configure(HttpSecurity http) throws Exception { // 定义受保护方法 configureHttpSecurity http) throws Exception {
        http // 执行通用逻辑
                .authorizeRequests() // 执行通用逻辑
                .antMatchers("/r/**").authenticated()//访问/r开始的请求需要认证通过 // 执行通用逻辑
                .anyRequest().permitAll()//其它请求全部放行 // 执行通用逻辑
                .and() // 执行通用逻辑
                .formLogin().successForwardUrl("/login-success");//登录成功跳转到/login-success // 执行通用逻辑
    } // 代码块结束
 // 空行
    public static void main(String[] args) { // 定义公有方法 mainString[] args) {
        String password = "111111"; // 将 "111111" 赋值给 password
        PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); // 创建 BCryptPasswordEncoder 实例并赋值给 passwordEncoder
        for (int i = 0; i < 5; i++) { // 遍历循环
            //生成密码 // 原始行内注释
            String encode = passwordEncoder.encode(password); // 将 passwordEncoder.encode(password) 赋值给 encode
            System.out.println(encode); // System.out 调用 println 方法,打印一行文本
            //校验密码,参数1是输入的明文 ,参数2是正确密码加密后的串 // 原始行内注释
            boolean matches = passwordEncoder.matches(password, encode); // 将 passwordEncoder.matches(password, encode) 赋值给 matches
            System.out.println(matches); // System.out 调用 println 方法,打印一行文本
        } // 代码块结束
 // 空行
        boolean matches = passwordEncoder.matches("1234", "$2a$10$fb2RlvFwr9HsRu9vH1OxCu/YiMRw6wy5UI6u3s0A.0bVSuR1UqdHK"); // 将 passwordEncoder.matches("1234", "$2a$10$fb2RlvFwr9HsRu9vH1OxCu/YiMRw6wy5UI6u3s0A.0bVSuR1UqdHK") 赋值给 matches
        System.out.println(matches); // System.out 调用 println 方法,打印一行文本
    } // 代码块结束
 // 空行
 // 空行
 // 空行
} // 代码块结束

文件:xuecheng-plus-auth/com/xuecheng/auth/controller/LoginController.java

package com.xuecheng.auth.controller; // 声明工具类所在的包路径
 // 空行
import com.xuecheng.ucenter.mapper.XcUserMapper; // 导入 XcUserMapper 类
import com.xuecheng.ucenter.model.po.XcUser; // 导入 XcUser 类
import lombok.extern.slf4j.Slf4j; // 导入 Slf4j 类
import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 类
import org.springframework.security.access.prepost.PreAuthorize; // 导入 PreAuthorize 类
import org.springframework.web.bind.annotation.PathVariable; // 导入 PathVariable 类
import org.springframework.web.bind.annotation.RequestMapping; // 导入 RequestMapping 类
import org.springframework.web.bind.annotation.RestController; // 导入 RestController 类
 // 空行
/** // 多行注释开始
 * @author Mr.M // 多行注释内容
 * @version 1.0 // 多行注释内容
 * @description 测试controller // 多行注释内容
 * @date 2022/9/27 17:25 // 多行注释内容
 */ // 多行注释内容
@Slf4j // 执行通用逻辑
@RestController // 执行通用逻辑
public class LoginController { // 定义 LoginController 类型
 // 空行
    @Autowired // 执行通用逻辑
    XcUserMapper userMapper; // 执行通用逻辑
 // 空行
 // 空行
    @RequestMapping("/login-success") // 执行通用逻辑
    public String loginSuccess() { // 定义公有方法 loginSuccess) {
 // 空行
        return "登录成功"; // 返回 "登录成功" 给调用方
    } // 代码块结束
 // 空行
 // 空行
    @RequestMapping("/user/{id}") // 执行通用逻辑
    public XcUser getuser(@PathVariable("id") String id) { // 定义公有方法 getuserPathVariable"id") String id) {
        XcUser xcUser = userMapper.selectById(id); // 将 userMapper.selectById(id) 赋值给 xcUser
        return xcUser; // 返回 xcUser 给调用方
    } // 代码块结束
 // 空行
    @RequestMapping("/r/r1") // 执行通用逻辑
    @PreAuthorize("hasAuthority('p1')")//拥有p1权限方可访问 // 执行通用逻辑
    public String r1() { // 定义公有方法 r1) {
        return "访问r1资源"; // 返回 "访问r1资源" 给调用方
    } // 代码块结束
 // 空行
    @RequestMapping("/r/r2") // 执行通用逻辑
    @PreAuthorize("hasAuthority('p2')")//拥有p2权限方可访问 // 执行通用逻辑
    public String r2() { // 定义公有方法 r2) {
        return "访问r2资源"; // 返回 "访问r2资源" 给调用方
    } // 代码块结束
 // 空行
 // 空行
 // 空行
} // 代码块结束

文件:xuecheng-plus-auth/com/xuecheng/auth/controller/WxLoginController.java

package com.xuecheng.auth.controller; // 声明工具类所在的包路径
 // 空行
import com.xuecheng.ucenter.model.po.XcUser; // 导入 XcUser 类
import com.xuecheng.ucenter.service.WxAuthService; // 导入 WxAuthService 类
import lombok.extern.slf4j.Slf4j; // 导入 Slf4j 类
import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 类
import org.springframework.stereotype.Controller; // 导入 Controller 类
import org.springframework.web.bind.annotation.RequestMapping; // 导入 RequestMapping 类
 // 空行
import java.io.IOException; // 导入 IOException 类
 // 空行
/** // 多行注释开始
 * @author Mr.M // 多行注释内容
 * @version 1.0 // 多行注释内容
 * @description TODO // 多行注释内容
 * @date 2023/2/24 15:13 // 多行注释内容
 */ // 多行注释内容
@Slf4j // 执行通用逻辑
@Controller // 执行通用逻辑
public class WxLoginController { // 定义 WxLoginController 类型
 // 空行
    @Autowired // 执行通用逻辑
    WxAuthService wxAuthService; // 执行通用逻辑
 // 空行
    @RequestMapping("/wxLogin") // 执行通用逻辑
    public String wxLogin(String code, String state) throws IOException { // 定义公有方法 wxLoginString code, String state) throws IOException {
        log.debug("微信扫码回调,code:{},state:{}", code, state); // log 调用 debug 方法,调用方法执行操作
        //远程调用微信请令牌,拿到令牌查询用户信息,将用户信息写入本项目数据库 // 原始行内注释
        XcUser xcUser = wxAuthService.wxAuth(code); // 将 wxAuthService.wxAuth(code) 赋值给 xcUser
 // 空行
        if (xcUser == null) { // 条件判断
            return "redirect:http://www.51xuecheng.cn/error.html"; // 返回 "redirect:http: 给调用方
        } // 代码块结束
        String username = xcUser.getUsername(); // 把 xcUser.getUsername() 的返回值赋给 username
        return "redirect:http://www.51xuecheng.cn/sign.html?username=" + username + "&authType=wx"; // 返回 "redirect:http: 给调用方
    } // 代码块结束
} // 代码块结束

文件:xuecheng-plus-auth/com/xuecheng/AuthApplication.java

package com.xuecheng; // 声明工具类所在的包路径
 // 空行
import org.springframework.boot.SpringApplication; // 导入 SpringApplication 类
import org.springframework.boot.autoconfigure.SpringBootApplication; // 导入 SpringBootApplication 类
import org.springframework.cloud.openfeign.EnableFeignClients; // 导入 EnableFeignClients 类
import org.springframework.context.annotation.Bean; // 导入 Bean 类
import org.springframework.http.MediaType; // 导入 MediaType 类
import org.springframework.http.client.OkHttp3ClientHttpRequestFactory; // 导入 OkHttp3ClientHttpRequestFactory 类
import org.springframework.http.converter.HttpMessageConverter; // 导入 HttpMessageConverter 类
import org.springframework.http.converter.StringHttpMessageConverter; // 导入 StringHttpMessageConverter 类
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; // 导入 MappingJackson2HttpMessageConverter 类
import org.springframework.web.client.RestTemplate; // 导入 RestTemplate 类
 // 空行
import java.nio.charset.StandardCharsets; // 导入 StandardCharsets 类
import java.util.ArrayList; // 导入 ArrayList 类
import java.util.List; // 导入 List 类
 // 空行
 // 空行
@EnableFeignClients(basePackages = "com.xuecheng.ucenter.feignclient") // 执行通用逻辑
@SpringBootApplication // 执行通用逻辑
public class AuthApplication { // 定义 AuthApplication 类型
 // 空行
    public static void main(String[] args) { // 定义公有方法 mainString[] args) {
        SpringApplication.run(AuthApplication.class, args); // SpringApplication 调用 run 方法,调用方法执行操作
    } // 代码块结束
 // 空行
    @Bean // 执行通用逻辑
    RestTemplate restTemplate(){ // 执行通用逻辑
        RestTemplate restTemplate = new RestTemplate(new OkHttp3ClientHttpRequestFactory()); // 创建 RestTemplate 实例并赋值给 restTemplate
        return  restTemplate; // 返回 restTemplate 给调用方
    } // 代码块结束
 // 空行
} // 代码块结束

文件:xuecheng-plus-auth/com/xuecheng/ucenter/feignclient/CheckCodeClient.java

package com.xuecheng.ucenter.feignclient; // 声明工具类所在的包路径
 // 空行
import org.springframework.cloud.openfeign.FeignClient; // 导入 FeignClient 类
import org.springframework.web.bind.annotation.PostMapping; // 导入 PostMapping 类
import org.springframework.web.bind.annotation.RequestMapping; // 导入 RequestMapping 类
import org.springframework.web.bind.annotation.RequestParam; // 导入 RequestParam 类
 // 空行
/** // 多行注释开始
 * @author Mr.M // 多行注释内容
 * @version 1.0 // 多行注释内容
 * @description TODO // 多行注释内容
 * @date 2023/2/24 14:45 // 多行注释内容
 */ // 多行注释内容
@FeignClient(value = "checkcode",fallbackFactory = CheckCodeClientFactory.class) // 执行通用逻辑
@RequestMapping("/checkcode") // 执行通用逻辑
public interface CheckCodeClient { // 定义 CheckCodeClient 类型
 // 空行
 @PostMapping(value = "/verify") // 执行通用逻辑
 public Boolean verify(@RequestParam("key") String key, @RequestParam("code") String code); // 执行通用逻辑
 // 空行
} // 代码块结束

文件:xuecheng-plus-auth/com/xuecheng/ucenter/feignclient/CheckCodeClientFactory.java

package com.xuecheng.ucenter.feignclient; // 声明工具类所在的包路径
 // 空行
import feign.hystrix.FallbackFactory; // 导入 FallbackFactory 类
import lombok.extern.slf4j.Slf4j; // 导入 Slf4j 类
import org.springframework.stereotype.Component; // 导入 Component 类
 // 空行
/** // 多行注释开始
 * @author Mr.M // 多行注释内容
 * @version 1.0 // 多行注释内容
 * @description TODO // 多行注释内容
 * @date 2023/2/24 14:46 // 多行注释内容
 */ // 多行注释内容
@Slf4j // 执行通用逻辑
@Component // 执行通用逻辑
public class CheckCodeClientFactory implements FallbackFactory<CheckCodeClient> { // 定义 CheckCodeClientFactory 类型
 @Override // 执行通用逻辑
 public CheckCodeClient create(Throwable throwable) { // 定义公有方法 createThrowable throwable) {
  return new CheckCodeClient() { // 返回 new CheckCodeClient() { 给调用方
 // 空行
   @Override // 执行通用逻辑
   public Boolean verify(String key, String code) { // 定义公有方法 verifyString key, String code) {
    log.debug("调用验证码服务熔断异常:{}", throwable.getMessage()); // log 调用 debug 方法,调用方法执行操作
    return null; // 返回 null 给调用方
   } // 代码块结束
  }; // 执行通用逻辑
 } // 代码块结束
} // 代码块结束

文件:xuecheng-plus-auth/com/xuecheng/ucenter/mapper/XcCompanyMapper.java

package com.xuecheng.ucenter.mapper; // 声明工具类所在的包路径
 // 空行
import com.baomidou.mybatisplus.core.mapper.BaseMapper; // 导入 BaseMapper 类
import com.xuecheng.ucenter.model.po.XcCompany; // 导入 XcCompany 类
 // 空行
/** // 多行注释开始
 * <p> // 多行注释内容
 *  Mapper 接口 // 多行注释内容
 * </p> // 多行注释内容
 * // 多行注释内容
 * @author itcast // 多行注释内容
 */ // 多行注释内容
public interface XcCompanyMapper extends BaseMapper<XcCompany> { // 定义 XcCompanyMapper 类型
 // 空行
} // 代码块结束

文件:xuecheng-plus-auth/com/xuecheng/ucenter/mapper/XcCompanyMapper.xml

<?xml version="1.0" encoding="UTF-8"?> <!-- XML 声明 -->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- SQL 语句片段 -->
<mapper namespace="com.xuecheng.ucenter.mapper.XcCompanyMapper"> <!-- MyBatis 映射文件根标签 -->

    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.xuecheng.ucenter.model.po.XcCompany"> <!-- 定义结果映射 -->
        <id column="id" property="id" /> <!-- 主键映射 -->
        <result column="linkname" property="linkname" /> <!-- 字段与属性映射 -->
        <result column="name" property="name" /> <!-- 字段与属性映射 -->
        <result column="mobile" property="mobile" /> <!-- 字段与属性映射 -->
        <result column="email" property="email" /> <!-- 字段与属性映射 -->
        <result column="intro" property="intro" /> <!-- 字段与属性映射 -->
        <result column="logo" property="logo" /> <!-- 字段与属性映射 -->
        <result column="identitypic" property="identitypic" /> <!-- 字段与属性映射 -->
        <result column="worktype" property="worktype" /> <!-- 字段与属性映射 -->
        <result column="businesspic" property="businesspic" /> <!-- 字段与属性映射 -->
        <result column="status" property="status" /> <!-- 字段与属性映射 -->
    </resultMap> <!-- 结束 resultMap -->

    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List"> <!-- 声明可复用 SQL 片段 -->
        id, linkname, name, mobile, email, intro, logo, identitypic, worktype, businesspic, status <!-- SQL 语句片段 -->
    </sql> <!-- 结束 SQL 片段 -->

</mapper> <!-- 结束 mapper 标签 -->

文件:xuecheng-plus-auth/com/xuecheng/ucenter/mapper/XcCompanyUserMapper.java

package com.xuecheng.ucenter.mapper; // 声明工具类所在的包路径
 // 空行
import com.baomidou.mybatisplus.core.mapper.BaseMapper; // 导入 BaseMapper 类
import com.xuecheng.ucenter.model.po.XcCompanyUser; // 导入 XcCompanyUser 类
 // 空行
/** // 多行注释开始
 * <p> // 多行注释内容
 *  Mapper 接口 // 多行注释内容
 * </p> // 多行注释内容
 * // 多行注释内容
 * @author itcast // 多行注释内容
 */ // 多行注释内容
public interface XcCompanyUserMapper extends BaseMapper<XcCompanyUser> { // 定义 XcCompanyUserMapper 类型
 // 空行
} // 代码块结束

文件:xuecheng-plus-auth/com/xuecheng/ucenter/mapper/XcCompanyUserMapper.xml

<?xml version="1.0" encoding="UTF-8"?> <!-- XML 声明 -->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- SQL 语句片段 -->
<mapper namespace="com.xuecheng.ucenter.mapper.XcCompanyUserMapper"> <!-- MyBatis 映射文件根标签 -->

    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.xuecheng.ucenter.model.po.XcCompanyUser"> <!-- 定义结果映射 -->
        <id column="id" property="id" /> <!-- 主键映射 -->
        <result column="company_id" property="companyId" /> <!-- 字段与属性映射 -->
        <result column="user_id" property="userId" /> <!-- 字段与属性映射 -->
    </resultMap> <!-- 结束 resultMap -->

    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List"> <!-- 声明可复用 SQL 片段 -->
        id, company_id, user_id <!-- SQL 语句片段 -->
    </sql> <!-- 结束 SQL 片段 -->

</mapper> <!-- 结束 mapper 标签 -->

文件:xuecheng-plus-auth/com/xuecheng/ucenter/mapper/XcMenuMapper.java

package com.xuecheng.ucenter.mapper; // 声明工具类所在的包路径
 // 空行
import com.baomidou.mybatisplus.core.mapper.BaseMapper; // 导入 BaseMapper 类
import com.xuecheng.ucenter.model.po.XcMenu; // 导入 XcMenu 类
import org.apache.ibatis.annotations.Param; // 导入 Param 类
import org.apache.ibatis.annotations.Select; // 导入 Select 类
 // 空行
import java.util.List; // 导入 List 类
 // 空行
/** // 多行注释开始
 * <p> // 多行注释内容
 *  Mapper 接口 // 多行注释内容
 * </p> // 多行注释内容
 * // 多行注释内容
 * @author itcast // 多行注释内容
 */ // 多行注释内容
public interface XcMenuMapper extends BaseMapper<XcMenu> { // 定义 XcMenuMapper 类型
    @Select("SELECT	* FROM xc_menu WHERE id IN (SELECT menu_id FROM xc_permission WHERE role_id IN ( SELECT role_id FROM xc_user_role WHERE user_id = #{userId} ))") // 执行通用逻辑
    List<XcMenu> selectPermissionByUserId(@Param("userId") String userId); // 执行通用逻辑
} // 代码块结束

文件:xuecheng-plus-auth/com/xuecheng/ucenter/mapper/XcMenuMapper.xml

<?xml version="1.0" encoding="UTF-8"?> <!-- XML 声明 -->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- SQL 语句片段 -->
<mapper namespace="com.xuecheng.ucenter.mapper.XcMenuMapper"> <!-- MyBatis 映射文件根标签 -->

    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.xuecheng.ucenter.model.po.XcMenu"> <!-- 定义结果映射 -->
        <id column="id" property="id" /> <!-- 主键映射 -->
        <result column="code" property="code" /> <!-- 字段与属性映射 -->
        <result column="p_id" property="pId" /> <!-- 字段与属性映射 -->
        <result column="menu_name" property="menuName" /> <!-- 字段与属性映射 -->
        <result column="url" property="url" /> <!-- 字段与属性映射 -->
        <result column="is_menu" property="isMenu" /> <!-- 字段与属性映射 -->
        <result column="level" property="level" /> <!-- 字段与属性映射 -->
        <result column="sort" property="sort" /> <!-- 字段与属性映射 -->
        <result column="status" property="status" /> <!-- 字段与属性映射 -->
        <result column="icon" property="icon" /> <!-- 字段与属性映射 -->
        <result column="create_time" property="createTime" /> <!-- 字段与属性映射 -->
        <result column="update_time" property="updateTime" /> <!-- 字段与属性映射 -->
    </resultMap> <!-- 结束 resultMap -->

    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List"> <!-- 声明可复用 SQL 片段 -->
        id, code, p_id, menu_name, url, is_menu, level, sort, status, icon, create_time, update_time <!-- SQL 语句片段 -->
    </sql> <!-- 结束 SQL 片段 -->

</mapper> <!-- 结束 mapper 标签 -->

文件:xuecheng-plus-auth/com/xuecheng/ucenter/mapper/XcPermissionMapper.java

package com.xuecheng.ucenter.mapper; // 声明工具类所在的包路径
 // 空行
import com.baomidou.mybatisplus.core.mapper.BaseMapper; // 导入 BaseMapper 类
import com.xuecheng.ucenter.model.po.XcPermission; // 导入 XcPermission 类
 // 空行
/** // 多行注释开始
 * <p> // 多行注释内容
 *  Mapper 接口 // 多行注释内容
 * </p> // 多行注释内容
 * // 多行注释内容
 * @author itcast // 多行注释内容
 */ // 多行注释内容
public interface XcPermissionMapper extends BaseMapper<XcPermission> { // 定义 XcPermissionMapper 类型
 // 空行
} // 代码块结束

文件:xuecheng-plus-auth/com/xuecheng/ucenter/mapper/XcPermissionMapper.xml

<?xml version="1.0" encoding="UTF-8"?> <!-- XML 声明 -->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- SQL 语句片段 -->
<mapper namespace="com.xuecheng.ucenter.mapper.XcPermissionMapper"> <!-- MyBatis 映射文件根标签 -->

    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.xuecheng.ucenter.model.po.XcPermission"> <!-- 定义结果映射 -->
        <id column="id" property="id" /> <!-- 主键映射 -->
        <result column="role_id" property="roleId" /> <!-- 字段与属性映射 -->
        <result column="menu_id" property="menuId" /> <!-- 字段与属性映射 -->
        <result column="create_time" property="createTime" /> <!-- 字段与属性映射 -->
    </resultMap> <!-- 结束 resultMap -->

    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List"> <!-- 声明可复用 SQL 片段 -->
        id, role_id, menu_id, create_time <!-- SQL 语句片段 -->
    </sql> <!-- 结束 SQL 片段 -->

</mapper> <!-- 结束 mapper 标签 -->

文件:xuecheng-plus-auth/com/xuecheng/ucenter/mapper/XcRoleMapper.java

package com.xuecheng.ucenter.mapper; // 声明工具类所在的包路径
 // 空行
import com.baomidou.mybatisplus.core.mapper.BaseMapper; // 导入 BaseMapper 类
import com.xuecheng.ucenter.model.po.XcRole; // 导入 XcRole 类
 // 空行
/** // 多行注释开始
 * <p> // 多行注释内容
 *  Mapper 接口 // 多行注释内容
 * </p> // 多行注释内容
 * // 多行注释内容
 * @author itcast // 多行注释内容
 */ // 多行注释内容
public interface XcRoleMapper extends BaseMapper<XcRole> { // 定义 XcRoleMapper 类型
 // 空行
} // 代码块结束

文件:xuecheng-plus-auth/com/xuecheng/ucenter/mapper/XcRoleMapper.xml

<?xml version="1.0" encoding="UTF-8"?> <!-- XML 声明 -->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- SQL 语句片段 -->
<mapper namespace="com.xuecheng.ucenter.mapper.XcRoleMapper"> <!-- MyBatis 映射文件根标签 -->

    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.xuecheng.ucenter.model.po.XcRole"> <!-- 定义结果映射 -->
        <id column="id" property="id" /> <!-- 主键映射 -->
        <result column="role_name" property="roleName" /> <!-- 字段与属性映射 -->
        <result column="role_code" property="roleCode" /> <!-- 字段与属性映射 -->
        <result column="description" property="description" /> <!-- 字段与属性映射 -->
        <result column="create_time" property="createTime" /> <!-- 字段与属性映射 -->
        <result column="update_time" property="updateTime" /> <!-- 字段与属性映射 -->
        <result column="status" property="status" /> <!-- 字段与属性映射 -->
    </resultMap> <!-- 结束 resultMap -->

    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List"> <!-- 声明可复用 SQL 片段 -->
        id, role_name, role_code, description, create_time, update_time, status <!-- SQL 语句片段 -->
    </sql> <!-- 结束 SQL 片段 -->

</mapper> <!-- 结束 mapper 标签 -->

文件:xuecheng-plus-auth/com/xuecheng/ucenter/mapper/XcTeacherMapper.java

package com.xuecheng.ucenter.mapper; // 声明工具类所在的包路径
 // 空行
import com.baomidou.mybatisplus.core.mapper.BaseMapper; // 导入 BaseMapper 类
import com.xuecheng.ucenter.model.po.XcTeacher; // 导入 XcTeacher 类
 // 空行
/** // 多行注释开始
 * <p> // 多行注释内容
 *  Mapper 接口 // 多行注释内容
 * </p> // 多行注释内容
 * // 多行注释内容
 * @author itcast // 多行注释内容
 */ // 多行注释内容
public interface XcTeacherMapper extends BaseMapper<XcTeacher> { // 定义 XcTeacherMapper 类型
 // 空行
} // 代码块结束

文件:xuecheng-plus-auth/com/xuecheng/ucenter/mapper/XcTeacherMapper.xml

<?xml version="1.0" encoding="UTF-8"?> <!-- XML 声明 -->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- SQL 语句片段 -->
<mapper namespace="com.xuecheng.ucenter.mapper.XcTeacherMapper"> <!-- MyBatis 映射文件根标签 -->

    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.xuecheng.ucenter.model.po.XcTeacher"> <!-- 定义结果映射 -->
        <id column="id" property="id" /> <!-- 主键映射 -->
        <result column="user_id" property="userId" /> <!-- 字段与属性映射 -->
        <result column="name" property="name" /> <!-- 字段与属性映射 -->
        <result column="intro" property="intro" /> <!-- 字段与属性映射 -->
        <result column="resume" property="resume" /> <!-- 字段与属性映射 -->
        <result column="pic" property="pic" /> <!-- 字段与属性映射 -->
    </resultMap> <!-- 结束 resultMap -->

    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List"> <!-- 声明可复用 SQL 片段 -->
        id, user_id, name, intro, resume, pic <!-- SQL 语句片段 -->
    </sql> <!-- 结束 SQL 片段 -->

</mapper> <!-- 结束 mapper 标签 -->

文件:xuecheng-plus-auth/com/xuecheng/ucenter/mapper/XcUserMapper.java

package com.xuecheng.ucenter.mapper; // 声明工具类所在的包路径
 // 空行
import com.baomidou.mybatisplus.core.mapper.BaseMapper; // 导入 BaseMapper 类
import com.xuecheng.ucenter.model.po.XcUser; // 导入 XcUser 类
 // 空行
/** // 多行注释开始
 * <p> // 多行注释内容
 *  Mapper 接口 // 多行注释内容
 * </p> // 多行注释内容
 * // 多行注释内容
 * @author itcast // 多行注释内容
 */ // 多行注释内容
public interface XcUserMapper extends BaseMapper<XcUser> { // 定义 XcUserMapper 类型
 // 空行
} // 代码块结束

文件:xuecheng-plus-auth/com/xuecheng/ucenter/mapper/XcUserMapper.xml

<?xml version="1.0" encoding="UTF-8"?> <!-- XML 声明 -->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- SQL 语句片段 -->
<mapper namespace="com.xuecheng.ucenter.mapper.XcUserMapper"> <!-- MyBatis 映射文件根标签 -->

    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.xuecheng.ucenter.model.po.XcUser"> <!-- 定义结果映射 -->
        <id column="id" property="id" /> <!-- 主键映射 -->
        <result column="username" property="username" /> <!-- 字段与属性映射 -->
        <result column="password" property="password" /> <!-- 字段与属性映射 -->
        <result column="salt" property="salt" /> <!-- 字段与属性映射 -->
        <result column="name" property="name" /> <!-- 字段与属性映射 -->
        <result column="nickname" property="nickname" /> <!-- 字段与属性映射 -->
        <result column="company_id" property="companyId" /> <!-- 字段与属性映射 -->
        <result column="wx_unionid" property="wxUnionid" /> <!-- 字段与属性映射 -->
        <result column="userpic" property="userpic" /> <!-- 字段与属性映射 -->
        <result column="utype" property="utype" /> <!-- 字段与属性映射 -->
        <result column="birthday" property="birthday" /> <!-- 字段与属性映射 -->
        <result column="sex" property="sex" /> <!-- 字段与属性映射 -->
        <result column="email" property="email" /> <!-- 字段与属性映射 -->
        <result column="cellphone" property="cellphone" /> <!-- 字段与属性映射 -->
        <result column="qq" property="qq" /> <!-- 字段与属性映射 -->
        <result column="status" property="status" /> <!-- 字段与属性映射 -->
        <result column="create_time" property="createTime" /> <!-- 字段与属性映射 -->
        <result column="update_time" property="updateTime" /> <!-- 字段与属性映射 -->
    </resultMap> <!-- 结束 resultMap -->

    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List"> <!-- 声明可复用 SQL 片段 -->
        id, username, password, salt, name,nickname,company_id, wx_unionid,userpic, utype, birthday, sex, email, cellphone, qq, status, create_time, update_time <!-- SQL 语句片段 -->
    </sql> <!-- 结束 SQL 片段 -->

</mapper> <!-- 结束 mapper 标签 -->

文件:xuecheng-plus-auth/com/xuecheng/ucenter/mapper/XcUserRoleMapper.java

package com.xuecheng.ucenter.mapper; // 声明工具类所在的包路径
 // 空行
import com.baomidou.mybatisplus.core.mapper.BaseMapper; // 导入 BaseMapper 类
import com.xuecheng.ucenter.model.po.XcUserRole; // 导入 XcUserRole 类
 // 空行
/** // 多行注释开始
 * <p> // 多行注释内容
 *  Mapper 接口 // 多行注释内容
 * </p> // 多行注释内容
 * // 多行注释内容
 * @author itcast // 多行注释内容
 */ // 多行注释内容
public interface XcUserRoleMapper extends BaseMapper<XcUserRole> { // 定义 XcUserRoleMapper 类型
 // 空行
} // 代码块结束

文件:xuecheng-plus-auth/com/xuecheng/ucenter/mapper/XcUserRoleMapper.xml

<?xml version="1.0" encoding="UTF-8"?> <!-- XML 声明 -->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- SQL 语句片段 -->
<mapper namespace="com.xuecheng.ucenter.mapper.XcUserRoleMapper"> <!-- MyBatis 映射文件根标签 -->

    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.xuecheng.ucenter.model.po.XcUserRole"> <!-- 定义结果映射 -->
        <id column="id" property="id" /> <!-- 主键映射 -->
        <result column="user_id" property="userId" /> <!-- 字段与属性映射 -->
        <result column="role_id" property="roleId" /> <!-- 字段与属性映射 -->
        <result column="create_time" property="createTime" /> <!-- 字段与属性映射 -->
        <result column="creator" property="creator" /> <!-- 字段与属性映射 -->
    </resultMap> <!-- 结束 resultMap -->

    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List"> <!-- 声明可复用 SQL 片段 -->
        id, user_id, role_id, create_time, creator <!-- SQL 语句片段 -->
    </sql> <!-- 结束 SQL 片段 -->

</mapper> <!-- 结束 mapper 标签 -->

文件:xuecheng-plus-auth/com/xuecheng/ucenter/model/dto/AuthParamsDto.java

package com.xuecheng.ucenter.model.dto; // 声明工具类所在的包路径
 // 空行
import lombok.Data; // 导入 Data 类
 // 空行
import java.util.HashMap; // 导入 HashMap 类
import java.util.Map; // 导入 Map 类
 // 空行
/** // 多行注释开始
 * @author Mr.M // 多行注释内容
 * @version 1.0 // 多行注释内容
 * @description 认证用户请求参数 // 多行注释内容
 * @date 2022/9/29 10:56 // 多行注释内容
 */ // 多行注释内容
@Data // 执行通用逻辑
public class AuthParamsDto { // 定义 AuthParamsDto 类型
 // 空行
    private String username; //用户名 // 执行通用逻辑
    private String password; //域  用于扩展 // 执行通用逻辑
    private String cellphone;//手机号 // 执行通用逻辑
    private String checkcode;//验证码 // 执行通用逻辑
    private String checkcodekey;//验证码key // 执行通用逻辑
    private String authType; // 认证的类型   password:用户名密码模式类型    sms:短信模式类型 // 执行通用逻辑
    private Map<String, Object> payload = new HashMap<>();//附加数据,作为扩展,不同认证类型可拥有不同的附加数据。如认证类型为短信时包含smsKey : sms:3d21042d054548b08477142bbca95cfa; 所有情况下都包含clientId // 创建 HashMap<> 实例并赋值给 payload
 // 空行
 // 空行
} // 代码块结束

文件:xuecheng-plus-auth/com/xuecheng/ucenter/model/dto/XcUserExt.java

package com.xuecheng.ucenter.model.dto; // 声明工具类所在的包路径
 // 空行
import com.xuecheng.ucenter.model.po.XcUser; // 导入 XcUser 类
import lombok.Data; // 导入 Data 类
 // 空行
import java.util.ArrayList; // 导入 ArrayList 类
import java.util.List; // 导入 List 类
 // 空行
/** // 多行注释开始
 * @description 用户扩展信息 // 多行注释内容
 * @author Mr.M // 多行注释内容
 * @date 2022/9/30 13:56 // 多行注释内容
 * @version 1.0 // 多行注释内容
 */ // 多行注释内容
@Data // 执行通用逻辑
public class XcUserExt extends XcUser { // 定义 XcUserExt 类型
    //用户权限 // 原始行内注释
    List<String> permissions = new ArrayList<>(); // 创建 ArrayList<> 实例并赋值给 permissions
} // 代码块结束

文件:xuecheng-plus-auth/com/xuecheng/ucenter/model/po/XcCompany.java

package com.xuecheng.ucenter.model.po; // 声明工具类所在的包路径
 // 空行
import com.baomidou.mybatisplus.annotation.TableName; // 导入 TableName 类
import lombok.Data; // 导入 Data 类
 // 空行
import java.io.Serializable; // 导入 Serializable 类
 // 空行
/** // 多行注释开始
 * <p> // 多行注释内容
 *  // 多行注释内容
 * </p> // 多行注释内容
 * // 多行注释内容
 * @author itcast // 多行注释内容
 */ // 多行注释内容
@Data // 执行通用逻辑
@TableName("xc_company") // 执行通用逻辑
public class XcCompany implements Serializable { // 定义 XcCompany 类型
 // 空行
    private static final long serialVersionUID = 1L; // 将 1L 赋值给 serialVersionUID
 // 空行
    private String id; // 执行通用逻辑
 // 空行
    /** // 多行注释开始
     * 联系人名称 // 多行注释内容
     */ // 多行注释内容
    private String linkname; // 执行通用逻辑
 // 空行
    /** // 多行注释开始
     * 名称 // 多行注释内容
     */ // 多行注释内容
    private String name; // 执行通用逻辑
 // 空行
    private String mobile; // 执行通用逻辑
 // 空行
    private String email; // 执行通用逻辑
 // 空行
    /** // 多行注释开始
     * 简介 // 多行注释内容
     */ // 多行注释内容
    private String intro; // 执行通用逻辑
 // 空行
    /** // 多行注释开始
     * logo // 多行注释内容
     */ // 多行注释内容
    private String logo; // 执行通用逻辑
 // 空行
    /** // 多行注释开始
     * 身份证照片 // 多行注释内容
     */ // 多行注释内容
    private String identitypic; // 执行通用逻辑
 // 空行
    /** // 多行注释开始
     * 工具性质 // 多行注释内容
     */ // 多行注释内容
    private String worktype; // 执行通用逻辑
 // 空行
    /** // 多行注释开始
     * 营业执照 // 多行注释内容
     */ // 多行注释内容
    private String businesspic; // 执行通用逻辑
 // 空行
    /** // 多行注释开始
     * 企业状态 // 多行注释内容
     */ // 多行注释内容
    private String status; // 执行通用逻辑
 // 空行
 // 空行
} // 代码块结束

文件:xuecheng-plus-auth/com/xuecheng/ucenter/model/po/XcCompanyUser.java

package com.xuecheng.ucenter.model.po; // 声明工具类所在的包路径
 // 空行
import com.baomidou.mybatisplus.annotation.TableName; // 导入 TableName 类
import lombok.Data; // 导入 Data 类
 // 空行
import java.io.Serializable; // 导入 Serializable 类
 // 空行
/** // 多行注释开始
 * <p> // 多行注释内容
 *  // 多行注释内容
 * </p> // 多行注释内容
 * // 多行注释内容
 * @author itcast // 多行注释内容
 */ // 多行注释内容
@Data // 执行通用逻辑
@TableName("xc_company_user") // 执行通用逻辑
public class XcCompanyUser implements Serializable { // 定义 XcCompanyUser 类型
 // 空行
    private static final long serialVersionUID = 1L; // 将 1L 赋值给 serialVersionUID
 // 空行
    private String id; // 执行通用逻辑
 // 空行
    private String companyId; // 执行通用逻辑
 // 空行
    private String userId; // 执行通用逻辑
 // 空行
 // 空行
} // 代码块结束

文件:xuecheng-plus-auth/com/xuecheng/ucenter/model/po/XcMenu.java

package com.xuecheng.ucenter.model.po; // 声明工具类所在的包路径
 // 空行
import com.baomidou.mybatisplus.annotation.TableName; // 导入 TableName 类
import lombok.Data; // 导入 Data 类
 // 空行
import java.io.Serializable; // 导入 Serializable 类
import java.time.LocalDateTime; // 导入 LocalDateTime 类
 // 空行
/** // 多行注释开始
 * <p> // 多行注释内容
 *  // 多行注释内容
 * </p> // 多行注释内容
 * // 多行注释内容
 * @author itcast // 多行注释内容
 */ // 多行注释内容
@Data // 执行通用逻辑
@TableName("xc_menu") // 执行通用逻辑
public class XcMenu implements Serializable { // 定义 XcMenu 类型
 // 空行
    private static final long serialVersionUID = 1L; // 将 1L 赋值给 serialVersionUID
 // 空行
    private String id; // 执行通用逻辑
 // 空行
    /** // 多行注释开始
     * 菜单编码 // 多行注释内容
     */ // 多行注释内容
    private String code; // 执行通用逻辑
 // 空行
    /** // 多行注释开始
     * 父菜单ID // 多行注释内容
     */ // 多行注释内容
    private String pId; // 执行通用逻辑
 // 空行
    /** // 多行注释开始
     * 名称 // 多行注释内容
     */ // 多行注释内容
    private String menuName; // 执行通用逻辑
 // 空行
    /** // 多行注释开始
     * 请求地址 // 多行注释内容
     */ // 多行注释内容
    private String url; // 执行通用逻辑
 // 空行
    /** // 多行注释开始
     * 是否是菜单 // 多行注释内容
     */ // 多行注释内容
    private String isMenu; // 执行通用逻辑
 // 空行
    /** // 多行注释开始
     * 菜单层级 // 多行注释内容
     */ // 多行注释内容
    private Integer level; // 执行通用逻辑
 // 空行
    /** // 多行注释开始
     * 菜单排序 // 多行注释内容
     */ // 多行注释内容
    private Integer sort; // 执行通用逻辑
 // 空行
    private String status; // 执行通用逻辑
 // 空行
    private String icon; // 执行通用逻辑
 // 空行
    private LocalDateTime createTime; // 执行通用逻辑
 // 空行
    private LocalDateTime updateTime; // 执行通用逻辑
 // 空行
 // 空行
} // 代码块结束

文件:xuecheng-plus-auth/com/xuecheng/ucenter/model/po/XcPermission.java

package com.xuecheng.ucenter.model.po; // 声明工具类所在的包路径
 // 空行
import com.baomidou.mybatisplus.annotation.TableName; // 导入 TableName 类
import lombok.Data; // 导入 Data 类
 // 空行
import java.io.Serializable; // 导入 Serializable 类
import java.time.LocalDateTime; // 导入 LocalDateTime 类
 // 空行
/** // 多行注释开始
 * <p> // 多行注释内容
 *  // 多行注释内容
 * </p> // 多行注释内容
 * // 多行注释内容
 * @author itcast // 多行注释内容
 */ // 多行注释内容
@Data // 执行通用逻辑
@TableName("xc_permission") // 执行通用逻辑
public class XcPermission implements Serializable { // 定义 XcPermission 类型
 // 空行
    private static final long serialVersionUID = 1L; // 将 1L 赋值给 serialVersionUID
 // 空行
    private String id; // 执行通用逻辑
 // 空行
    private String roleId; // 执行通用逻辑
 // 空行
    private String menuId; // 执行通用逻辑
 // 空行
    private LocalDateTime createTime; // 执行通用逻辑
 // 空行
 // 空行
} // 代码块结束

文件:xuecheng-plus-auth/com/xuecheng/ucenter/model/po/XcRole.java

package com.xuecheng.ucenter.model.po; // 声明工具类所在的包路径
 // 空行
import com.baomidou.mybatisplus.annotation.TableName; // 导入 TableName 类
import lombok.Data; // 导入 Data 类
 // 空行
import java.io.Serializable; // 导入 Serializable 类
import java.time.LocalDateTime; // 导入 LocalDateTime 类
 // 空行
/** // 多行注释开始
 * <p> // 多行注释内容
 *  // 多行注释内容
 * </p> // 多行注释内容
 * // 多行注释内容
 * @author itcast // 多行注释内容
 */ // 多行注释内容
@Data // 执行通用逻辑
@TableName("xc_role") // 执行通用逻辑
public class XcRole implements Serializable { // 定义 XcRole 类型
 // 空行
    private static final long serialVersionUID = 1L; // 将 1L 赋值给 serialVersionUID
 // 空行
    private String id; // 执行通用逻辑
 // 空行
    private String roleName; // 执行通用逻辑
 // 空行
    private String roleCode; // 执行通用逻辑
 // 空行
    private String description; // 执行通用逻辑
 // 空行
    private LocalDateTime createTime; // 执行通用逻辑
 // 空行
    private LocalDateTime updateTime; // 执行通用逻辑
 // 空行
    private String status; // 执行通用逻辑
 // 空行
 // 空行
} // 代码块结束

文件:xuecheng-plus-auth/com/xuecheng/ucenter/model/po/XcTeacher.java

package com.xuecheng.ucenter.model.po; // 声明工具类所在的包路径
 // 空行
import com.baomidou.mybatisplus.annotation.TableName; // 导入 TableName 类
import lombok.Data; // 导入 Data 类
 // 空行
import java.io.Serializable; // 导入 Serializable 类
 // 空行
/** // 多行注释开始
 * <p> // 多行注释内容
 *  // 多行注释内容
 * </p> // 多行注释内容
 * // 多行注释内容
 * @author itcast // 多行注释内容
 */ // 多行注释内容
@Data // 执行通用逻辑
@TableName("xc_teacher") // 执行通用逻辑
public class XcTeacher implements Serializable { // 定义 XcTeacher 类型
 // 空行
    private static final long serialVersionUID = 1L; // 将 1L 赋值给 serialVersionUID
 // 空行
    private String id; // 执行通用逻辑
 // 空行
    /** // 多行注释开始
     * 用户id // 多行注释内容
     */ // 多行注释内容
    private String userId; // 执行通用逻辑
 // 空行
    /** // 多行注释开始
     * 称呼 // 多行注释内容
     */ // 多行注释内容
    private String name; // 执行通用逻辑
 // 空行
    /** // 多行注释开始
     * 个人简介 // 多行注释内容
     */ // 多行注释内容
    private String intro; // 执行通用逻辑
 // 空行
    /** // 多行注释开始
     * 个人简历 // 多行注释内容
     */ // 多行注释内容
    private String resume; // 执行通用逻辑
 // 空行
    /** // 多行注释开始
     * 老师照片 // 多行注释内容
     */ // 多行注释内容
    private String pic; // 执行通用逻辑
 // 空行
 // 空行
} // 代码块结束

文件:xuecheng-plus-auth/com/xuecheng/ucenter/model/po/XcUser.java

package com.xuecheng.ucenter.model.po; // 声明工具类所在的包路径
 // 空行
import com.baomidou.mybatisplus.annotation.TableName; // 导入 TableName 类
import lombok.Data; // 导入 Data 类
 // 空行
import java.io.Serializable; // 导入 Serializable 类
import java.time.LocalDateTime; // 导入 LocalDateTime 类
 // 空行
/** // 多行注释开始
 * <p> // 多行注释内容
 *  // 多行注释内容
 * </p> // 多行注释内容
 * // 多行注释内容
 * @author itcast // 多行注释内容
 */ // 多行注释内容
@Data // 执行通用逻辑
@TableName("xc_user") // 执行通用逻辑
public class XcUser implements Serializable { // 定义 XcUser 类型
 // 空行
    private static final long serialVersionUID = 1L; // 将 1L 赋值给 serialVersionUID
 // 空行
    private String id; // 执行通用逻辑
 // 空行
    private String username; // 执行通用逻辑
 // 空行
    private String password; // 执行通用逻辑
 // 空行
    private String salt; // 执行通用逻辑
 // 空行
    private String name; // 执行通用逻辑
    private String nickname; // 执行通用逻辑
    private String wxUnionid; // 执行通用逻辑
    private String companyId; // 执行通用逻辑
    /** // 多行注释开始
     * 头像 // 多行注释内容
     */ // 多行注释内容
    private String userpic; // 执行通用逻辑
 // 空行
    private String utype; // 执行通用逻辑
 // 空行
    private LocalDateTime birthday; // 执行通用逻辑
 // 空行
    private String sex; // 执行通用逻辑
 // 空行
    private String email; // 执行通用逻辑
 // 空行
    private String cellphone; // 执行通用逻辑
 // 空行
    private String qq; // 执行通用逻辑
 // 空行
    /** // 多行注释开始
     * 用户状态 // 多行注释内容
     */ // 多行注释内容
    private String status; // 执行通用逻辑
 // 空行
    private LocalDateTime createTime; // 执行通用逻辑
 // 空行
    private LocalDateTime updateTime; // 执行通用逻辑
 // 空行
 // 空行
} // 代码块结束

文件:xuecheng-plus-auth/com/xuecheng/ucenter/model/po/XcUserRole.java

package com.xuecheng.ucenter.model.po; // 声明工具类所在的包路径
 // 空行
import com.baomidou.mybatisplus.annotation.TableName; // 导入 TableName 类
import lombok.Data; // 导入 Data 类
 // 空行
import java.io.Serializable; // 导入 Serializable 类
import java.time.LocalDateTime; // 导入 LocalDateTime 类
 // 空行
/** // 多行注释开始
 * <p> // 多行注释内容
 *  // 多行注释内容
 * </p> // 多行注释内容
 * // 多行注释内容
 * @author itcast // 多行注释内容
 */ // 多行注释内容
@Data // 执行通用逻辑
@TableName("xc_user_role") // 执行通用逻辑
public class XcUserRole implements Serializable { // 定义 XcUserRole 类型
 // 空行
    private static final long serialVersionUID = 1L; // 将 1L 赋值给 serialVersionUID
 // 空行
    private String id; // 执行通用逻辑
 // 空行
    private String userId; // 执行通用逻辑
 // 空行
    private String roleId; // 执行通用逻辑
 // 空行
    private LocalDateTime createTime; // 执行通用逻辑
 // 空行
    private String creator; // 执行通用逻辑
 // 空行
 // 空行
} // 代码块结束

文件:xuecheng-plus-auth/com/xuecheng/ucenter/service/AuthService.java

package com.xuecheng.ucenter.service; // 声明工具类所在的包路径
 // 空行
import com.xuecheng.ucenter.model.dto.AuthParamsDto; // 导入 AuthParamsDto 类
import com.xuecheng.ucenter.model.dto.XcUserExt; // 导入 XcUserExt 类
 // 空行
/** // 多行注释开始
 * @author Mr.M // 多行注释内容
 * @version 1.0 // 多行注释内容
 * @description 统一的认证接口 // 多行注释内容
 * @date 2023/2/24 11:55 // 多行注释内容
 */ // 多行注释内容
public interface AuthService { // 定义 AuthService 类型
 // 空行
 /** // 多行注释开始
  * @description 认证方法 // 多行注释内容
  * @param authParamsDto 认证参数 // 多行注释内容
  * @return com.xuecheng.ucenter.model.po.XcUser 用户信息 // 多行注释内容
  * @author Mr.M // 多行注释内容
  * @date 2022/9/29 12:11 // 多行注释内容
  */ // 多行注释内容
 XcUserExt execute(AuthParamsDto authParamsDto); // 执行通用逻辑
 // 空行
} // 代码块结束

文件:xuecheng-plus-auth/com/xuecheng/ucenter/service/impl/PasswordAuthServiceImpl.java

package com.xuecheng.ucenter.service.impl; // 声明工具类所在的包路径
 // 空行
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; // 导入 LambdaQueryWrapper 类
import com.xuecheng.ucenter.feignclient.CheckCodeClient; // 导入 CheckCodeClient 类
import com.xuecheng.ucenter.mapper.XcUserMapper; // 导入 XcUserMapper 类
import com.xuecheng.ucenter.model.dto.AuthParamsDto; // 导入 AuthParamsDto 类
import com.xuecheng.ucenter.model.dto.XcUserExt; // 导入 XcUserExt 类
import com.xuecheng.ucenter.model.po.XcUser; // 导入 XcUser 类
import com.xuecheng.ucenter.service.AuthService; // 导入 AuthService 类
import org.apache.commons.lang.StringUtils; // 导入 StringUtils 类
import org.springframework.beans.BeanUtils; // 导入 BeanUtils 类
import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 类
import org.springframework.security.crypto.password.PasswordEncoder; // 导入 PasswordEncoder 类
import org.springframework.stereotype.Service; // 导入 Service 类
 // 空行
/** // 多行注释开始
 * @author Mr.M // 多行注释内容
 * @version 1.0 // 多行注释内容
 * @description 账号名密码方式 // 多行注释内容
 * @date 2023/2/24 11:56 // 多行注释内容
 */ // 多行注释内容
@Service("password_authservice") // 执行通用逻辑
public class PasswordAuthServiceImpl implements AuthService { // 定义 PasswordAuthServiceImpl 类型
 // 空行
 @Autowired // 执行通用逻辑
 XcUserMapper xcUserMapper; // 执行通用逻辑
 // 空行
 @Autowired // 执行通用逻辑
 PasswordEncoder passwordEncoder; // 执行通用逻辑
 // 空行
 @Autowired // 执行通用逻辑
 CheckCodeClient checkCodeClient; // 执行通用逻辑
 // 空行
 @Override // 执行通用逻辑
 public XcUserExt execute(AuthParamsDto authParamsDto) { // 定义公有方法 executeAuthParamsDto authParamsDto) {
  //账号 // 原始行内注释
  String username = authParamsDto.getUsername(); // 把 authParamsDto.getUsername() 的返回值赋给 username
 // 空行
  //输入的验证码 // 原始行内注释
  String checkcode = authParamsDto.getCheckcode(); // 把 authParamsDto.getCheckcode() 的返回值赋给 checkcode
  //验证码对应的key // 原始行内注释
  String checkcodekey = authParamsDto.getCheckcodekey(); // 把 authParamsDto.getCheckcodekey() 的返回值赋给 checkcodekey
 // 空行
//  if(StringUtils.isEmpty(checkcode) || StringUtils.isEmpty(checkcodekey)){ // 原始行内注释
//   throw new RuntimeException("请输入的验证码"); // 原始行内注释
//  } // 原始行内注释
// // 原始行内注释
//  //远程调用验证码服务接口去校验验证码 // 原始行内注释
//  Boolean verify = checkCodeClient.verify(checkcodekey, checkcode); // 原始行内注释
//  if(verify == null||!verify){ // 原始行内注释
//   throw new RuntimeException("验证码输入错误"); // 原始行内注释
//  } // 原始行内注释
 // 空行
 // 空行
  //账号是否存在 // 原始行内注释
  //根据username账号查询数据库 // 原始行内注释
  XcUser xcUser = xcUserMapper.selectOne(new LambdaQueryWrapper<XcUser>().eq(XcUser::getUsername, username)); // 将 xcUserMapper.selectOne(new LambdaQueryWrapper<XcUser>().eq(XcUser::getUsername, username)) 赋值给 xcUser
 // 空行
  //查询到用户不存在,要返回null即可,spring security框架抛出异常用户不存在 // 原始行内注释
  if(xcUser==null){ // 条件判断
   throw new RuntimeException("账号不存在"); // 主动抛出异常
  } // 代码块结束
 // 空行
  //验证密码是否正确 // 原始行内注释
  //如果查到了用户拿到正确的密码 // 原始行内注释
  String passwordDb = xcUser.getPassword(); // 把 xcUser.getPassword() 的返回值赋给 passwordDb
  //拿到用户输入的密码 // 原始行内注释
  String passwordForm = authParamsDto.getPassword(); // 把 authParamsDto.getPassword() 的返回值赋给 passwordForm
  //校验密码 // 原始行内注释
  boolean matches = passwordEncoder.matches(passwordForm, passwordDb); // 将 passwordEncoder.matches(passwordForm, passwordDb) 赋值给 matches
  if(!matches){ // 条件判断
   throw new RuntimeException("账号或密码错误"); // 主动抛出异常
  } // 代码块结束
  XcUserExt xcUserExt = new XcUserExt(); // 创建 XcUserExt 实例并赋值给 xcUserExt
  BeanUtils.copyProperties(xcUser,xcUserExt); // BeanUtils 调用 copyProperties 方法,调用方法执行操作
 // 空行
  return xcUserExt; // 返回 xcUserExt 给调用方
 } // 代码块结束
} // 代码块结束

文件:xuecheng-plus-auth/com/xuecheng/ucenter/service/impl/UserServiceImpl.java

package com.xuecheng.ucenter.service.impl; // 声明工具类所在的包路径
 // 空行
import com.alibaba.fastjson.JSON; // 导入 JSON 类
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; // 导入 LambdaQueryWrapper 类
import com.xuecheng.ucenter.mapper.XcMenuMapper; // 导入 XcMenuMapper 类
import com.xuecheng.ucenter.mapper.XcUserMapper; // 导入 XcUserMapper 类
import com.xuecheng.ucenter.model.dto.AuthParamsDto; // 导入 AuthParamsDto 类
import com.xuecheng.ucenter.model.dto.XcUserExt; // 导入 XcUserExt 类
import com.xuecheng.ucenter.model.po.XcMenu; // 导入 XcMenu 类
import com.xuecheng.ucenter.model.po.XcUser; // 导入 XcUser 类
import com.xuecheng.ucenter.service.AuthService; // 导入 AuthService 类
import lombok.extern.slf4j.Slf4j; // 导入 Slf4j 类
import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 类
import org.springframework.context.ApplicationContext; // 导入 ApplicationContext 类
import org.springframework.security.core.userdetails.User; // 导入 User 类
import org.springframework.security.core.userdetails.UserDetails; // 导入 UserDetails 类
import org.springframework.security.core.userdetails.UserDetailsService; // 导入 UserDetailsService 类
import org.springframework.security.core.userdetails.UsernameNotFoundException; // 导入 UsernameNotFoundException 类
import org.springframework.stereotype.Component; // 导入 Component 类
 // 空行
import java.util.ArrayList; // 导入 ArrayList 类
import java.util.List; // 导入 List 类
 // 空行
/** // 多行注释开始
 * @author Mr.M // 多行注释内容
 * @version 1.0 // 多行注释内容
 * @description TODO // 多行注释内容
 * @date 2023/2/24 10:37 // 多行注释内容
 */ // 多行注释内容
@Slf4j // 执行通用逻辑
@Component // 执行通用逻辑
public class UserServiceImpl implements UserDetailsService { // 定义 UserServiceImpl 类型
    @Autowired // 执行通用逻辑
    XcUserMapper xcUserMapper; // 执行通用逻辑
 // 空行
    @Autowired // 执行通用逻辑
    XcMenuMapper xcMenuMapper; // 执行通用逻辑
    @Autowired // 执行通用逻辑
    ApplicationContext applicationContext; // 执行通用逻辑
 // 空行
 // 空行
 // 空行
    //传入的请求认证的参数就是AuthParamsDto // 原始行内注释
    @Override // 执行通用逻辑
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException { // 定义公有方法 loadUserByUsernameString s) throws UsernameNotFoundException {
        //将传入的json转成AuthParamsDto对象 // 原始行内注释
        AuthParamsDto authParamsDto = null; // 将变量 authParamsDto 初始化为 null
        try { // 尝试执行可能出错的代码
            authParamsDto = JSON.parseObject(s, AuthParamsDto.class); // 将 JSON.parseObject(s, AuthParamsDto.class) 赋值给 authParamsDto
        } catch (Exception e) { // 结束上一代码块后继续捕获异常
            throw new RuntimeException("请求认证参数不符合要求"); // 主动抛出异常
        } // 代码块结束
 // 空行
        //认证类型,有password,wx。。。 // 原始行内注释
        String authType = authParamsDto.getAuthType(); // 把 authParamsDto.getAuthType() 的返回值赋给 authType
 // 空行
 // 空行
        //根据认证类型从spring容器取出指定的bean // 原始行内注释
        String beanName = authType+"_authservice"; // 将 authType+"_authservice" 赋值给 beanName
        AuthService authService = applicationContext.getBean(beanName, AuthService.class); // 将 applicationContext.getBean(beanName, AuthService.class) 赋值给 authService
        //调用统一execute方法完成认证 // 原始行内注释
        XcUserExt xcUserExt = authService.execute(authParamsDto); // 将 authService.execute(authParamsDto) 赋值给 xcUserExt
        //封装xcUserExt用户信息为UserDetails // 原始行内注释
        //根据UserDetails对象生成令牌 // 原始行内注释
        UserDetails userPrincipal = getUserPrincipal(xcUserExt); // 将 getUserPrincipal(xcUserExt) 赋值给 userPrincipal
 // 空行
        return userPrincipal; // 返回 userPrincipal 给调用方
    } // 代码块结束
 // 空行
    /** // 多行注释开始
     * @description 查询用户信息 // 多行注释内容
     * @param xcUser  用户id,主键 // 多行注释内容
     * @return com.xuecheng.ucenter.model.po.XcUser 用户信息 // 多行注释内容
     * @author Mr.M // 多行注释内容
     * @date 2022/9/29 12:19 // 多行注释内容
     */ // 多行注释内容
    public UserDetails getUserPrincipal(XcUserExt xcUser){ // 定义公有方法 getUserPrincipalXcUserExt xcUser){
        String password = xcUser.getPassword(); // 把 xcUser.getPassword() 的返回值赋给 password
        //权限 // 原始行内注释
        String[] authorities=  {"test"}; // 将 {"test"} 赋值给 authorities
        //根据用户id查询用户的权限 // 原始行内注释
        List<XcMenu> xcMenus = xcMenuMapper.selectPermissionByUserId(xcUser.getId()); // 将 xcMenuMapper.selectPermissionByUserId(xcUser.getId()) 赋值给 xcMenus
        if(xcMenus.size()>0){ // 条件判断
            List<String> permissions =new ArrayList<>(); // 创建 ArrayList<> 实例并赋值给 permissions
            xcMenus.forEach(m->{ // 执行通用逻辑
                //拿到了用户拥有的权限标识符 // 原始行内注释
                permissions.add(m.getCode()); // permissions 调用 add 方法,向集合添加元素
            }); // 执行通用逻辑
            //将permissions转成数组 // 原始行内注释
            authorities = permissions.toArray(new String[0]); // 将 permissions.toArray(new String[0]) 赋值给 authorities
        } // 代码块结束
 // 空行
 // 空行
        xcUser.setPassword(null); // xcUser 调用 setPassword 方法,调用方法执行操作
        //将用户信息转json // 原始行内注释
        String userJson = JSON.toJSONString(xcUser); // 将 JSON.toJSONString(xcUser) 赋值给 userJson
        UserDetails userDetails = User.withUsername(userJson).password(password).authorities(authorities).build(); // 把 User.withUsername(userJson).password(password).authorities(authorities).build() 的返回值赋给 userDetails
        return  userDetails; // 返回 userDetails 给调用方
    } // 代码块结束
 // 空行
 // 空行
} // 代码块结束

文件:xuecheng-plus-auth/com/xuecheng/ucenter/service/impl/WxAuthServiceImpl.java

package com.xuecheng.ucenter.service.impl; // 声明工具类所在的包路径
 // 空行
import com.alibaba.fastjson.JSON; // 导入 JSON 类
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; // 导入 LambdaQueryWrapper 类
import com.xuecheng.ucenter.mapper.XcUserMapper; // 导入 XcUserMapper 类
import com.xuecheng.ucenter.mapper.XcUserRoleMapper; // 导入 XcUserRoleMapper 类
import com.xuecheng.ucenter.model.dto.AuthParamsDto; // 导入 AuthParamsDto 类
import com.xuecheng.ucenter.model.dto.XcUserExt; // 导入 XcUserExt 类
import com.xuecheng.ucenter.model.po.XcUser; // 导入 XcUser 类
import com.xuecheng.ucenter.model.po.XcUserRole; // 导入 XcUserRole 类
import com.xuecheng.ucenter.service.AuthService; // 导入 AuthService 类
import com.xuecheng.ucenter.service.WxAuthService; // 导入 WxAuthService 类
import org.springframework.beans.BeanUtils; // 导入 BeanUtils 类
import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 类
import org.springframework.beans.factory.annotation.Value; // 导入 Value 类
import org.springframework.http.HttpMethod; // 导入 HttpMethod 类
import org.springframework.http.ResponseEntity; // 导入 ResponseEntity 类
import org.springframework.stereotype.Service; // 导入 Service 类
import org.springframework.transaction.annotation.Transactional; // 导入 Transactional 类
import org.springframework.web.client.RestTemplate; // 导入 RestTemplate 类
 // 空行
import java.nio.charset.StandardCharsets; // 导入 StandardCharsets 类
import java.time.LocalDateTime; // 导入 LocalDateTime 类
import java.util.Map; // 导入 Map 类
import java.util.UUID; // 导入 UUID 类
 // 空行
/** // 多行注释开始
 * @author Mr.M // 多行注释内容
 * @version 1.0 // 多行注释内容
 * @description 微信扫码认证 // 多行注释内容
 * @date 2023/2/24 11:57 // 多行注释内容
 */ // 多行注释内容
@Service("wx_authservice") // 执行通用逻辑
public class WxAuthServiceImpl implements AuthService, WxAuthService { // 定义 WxAuthServiceImpl 类型
 // 空行
    @Autowired // 执行通用逻辑
    XcUserMapper xcUserMapper; // 执行通用逻辑
    @Autowired // 执行通用逻辑
    XcUserRoleMapper xcUserRoleMapper; // 执行通用逻辑
 // 空行
    @Autowired // 执行通用逻辑
    WxAuthServiceImpl currentPorxy; // 执行通用逻辑
 // 空行
    @Autowired // 执行通用逻辑
    RestTemplate restTemplate; // 执行通用逻辑
 // 空行
 // 空行
    @Value("${weixin.appid}") // 执行通用逻辑
    String appid; // 执行通用逻辑
    @Value("${weixin.secret}") // 执行通用逻辑
    String secret; // 执行通用逻辑
 // 空行
    @Override // 执行通用逻辑
    public XcUserExt execute(AuthParamsDto authParamsDto) { // 定义公有方法 executeAuthParamsDto authParamsDto) {
        //得到账号 // 原始行内注释
        String username = authParamsDto.getUsername(); // 把 authParamsDto.getUsername() 的返回值赋给 username
        //查询数据库 // 原始行内注释
        XcUser xcUser = xcUserMapper.selectOne(new LambdaQueryWrapper<XcUser>().eq(XcUser::getUsername, username)); // 将 xcUserMapper.selectOne(new LambdaQueryWrapper<XcUser>().eq(XcUser::getUsername, username)) 赋值给 xcUser
        if(xcUser == null){ // 条件判断
            throw new RuntimeException("用户不存在"); // 主动抛出异常
        } // 代码块结束
 // 空行
        XcUserExt xcUserExt = new XcUserExt(); // 创建 XcUserExt 实例并赋值给 xcUserExt
        BeanUtils.copyProperties(xcUser, xcUserExt); // BeanUtils 调用 copyProperties 方法,调用方法执行操作
 // 空行
 // 空行
        return xcUserExt; // 返回 xcUserExt 给调用方
    } // 代码块结束
 // 空行
    @Override // 执行通用逻辑
    public XcUser wxAuth(String code) { // 定义公有方法 wxAuthString code) {
        //申请令牌 // 原始行内注释
        Map<String, String> access_token_map = getAccess_token(code); // 将 getAccess_token(code) 赋值给 access_token_map
        //访问令牌 // 原始行内注释
        String access_token = access_token_map.get("access_token"); // 将 access_token_map.get("access_token") 赋值给 access_token
        String openid = access_token_map.get("openid"); // 将 access_token_map.get("openid") 赋值给 openid
 // 空行
        //携带令牌查询用户信息 // 原始行内注释
        Map<String, String> userinfo = getUserinfo(access_token, openid); // 将 getUserinfo(access_token, openid) 赋值给 userinfo
 // 空行
        // 保存用户信息到数据库 // 原始行内注释
        XcUser xcUser = currentPorxy.addWxUser(userinfo); // 将 currentPorxy.addWxUser(userinfo) 赋值给 xcUser
 // 空行
 // 空行
        return xcUser; // 返回 xcUser 给调用方
    } // 代码块结束
    // 保存用户信息 // 原始行内注释
    @Transactional // 执行通用逻辑
    public XcUser addWxUser(Map<String,String> userInfo_map){ // 定义公有方法 addWxUserMap<String,String> userInfo_map){
        String unionid = userInfo_map.get("unionid"); // 将 userInfo_map.get("unionid") 赋值给 unionid
        String nickname = userInfo_map.get("nickname"); // 将 userInfo_map.get("nickname") 赋值给 nickname
        //根据unionid查询用户信息 // 原始行内注释
        XcUser xcUser = xcUserMapper.selectOne(new LambdaQueryWrapper<XcUser>().eq(XcUser::getWxUnionid, unionid)); // 将 xcUserMapper.selectOne(new LambdaQueryWrapper<XcUser>().eq(XcUser::getWxUnionid, unionid)) 赋值给 xcUser
        if(xcUser !=null){ // 条件判断
            return xcUser; // 返回 xcUser 给调用方
        } // 代码块结束
        //向数据库新增记录 // 原始行内注释
        xcUser = new XcUser(); // 创建 XcUser 实例并赋值给 xcUser
        String userId= UUID.randomUUID().toString(); // 把 UUID.randomUUID().toString() 的返回值赋给 userId
        xcUser.setId(userId);//主键 // xcUser 调用 setId 方法,调用方法执行操作
        xcUser.setUsername(unionid); // xcUser 调用 setUsername 方法,调用方法执行操作
        xcUser.setPassword(unionid); // xcUser 调用 setPassword 方法,调用方法执行操作
        xcUser.setWxUnionid(unionid); // xcUser 调用 setWxUnionid 方法,调用方法执行操作
        xcUser.setNickname(nickname); // xcUser 调用 setNickname 方法,调用方法执行操作
        xcUser.setName(nickname); // xcUser 调用 setName 方法,调用方法执行操作
        xcUser.setUtype("101001");//学生类型 // xcUser 调用 setUtype 方法,调用方法执行操作
        xcUser.setStatus("1");//用户状态 // xcUser 调用 setStatus 方法,调用方法执行操作
        xcUser.setCreateTime(LocalDateTime.now()); // xcUser 调用 setCreateTime 方法,调用方法执行操作
        //插入 // 原始行内注释
        int insert = xcUserMapper.insert(xcUser); // 将 xcUserMapper.insert(xcUser) 赋值给 insert
 // 空行
        //向用户角色关系表新增记录 // 原始行内注释
        XcUserRole xcUserRole = new XcUserRole(); // 创建 XcUserRole 实例并赋值给 xcUserRole
        xcUserRole.setId(UUID.randomUUID().toString()); // xcUserRole 调用 setId 方法,调用方法执行操作
        xcUserRole.setUserId(userId); // xcUserRole 调用 setUserId 方法,调用方法执行操作
        xcUserRole.setRoleId("17");//学生角色 // xcUserRole 调用 setRoleId 方法,调用方法执行操作
        xcUserRole.setCreateTime(LocalDateTime.now()); // xcUserRole 调用 setCreateTime 方法,调用方法执行操作
        xcUserRoleMapper.insert(xcUserRole); // xcUserRoleMapper 调用 insert 方法,调用方法执行操作
        return xcUser; // 返回 xcUser 给调用方
 // 空行
    } // 代码块结束
 // 空行
    /** // 多行注释开始
     * 携带授权码申请令牌 // 多行注释内容
     * https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code // 多行注释内容
     * // 多行注释内容
     * { // 多行注释内容
     * "access_token":"ACCESS_TOKEN", // 多行注释内容
     * "expires_in":7200, // 多行注释内容
     * "refresh_token":"REFRESH_TOKEN", // 多行注释内容
     * "openid":"OPENID", // 多行注释内容
     * "scope":"SCOPE", // 多行注释内容
     * "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL" // 多行注释内容
     * } // 多行注释内容
     * @param code 授权 // 多行注释内容
     * @return // 多行注释内容
     */ // 多行注释内容
    private Map<String,String> getAccess_token(String code){ // 定义私有方法 getAccess_tokenString code){
 // 空行
        String url_template = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code"; // 执行通用逻辑
        //最终的请求路径 // 原始行内注释
        String url = String.format(url_template, appid, secret, code); // 将 String.format(url_template, appid, secret, code) 赋值给 url
 // 空行
        //远程调用此url // 原始行内注释
        ResponseEntity<String> exchange = restTemplate.exchange(url, HttpMethod.POST, null, String.class); // 将 restTemplate.exchange(url, HttpMethod.POST, null, String.class) 赋值给 exchange
        //获取响应的结果 // 原始行内注释
        String result = exchange.getBody(); // 把 exchange.getBody() 的返回值赋给 result
        //将result转成map // 原始行内注释
        Map<String,String> map = JSON.parseObject(result, Map.class); // 将 JSON.parseObject(result, Map.class) 赋值给 map
        return map; // 返回 map 给调用方
 // 空行
 // 空行
    } // 代码块结束
 // 空行
    /** // 多行注释开始
     * 携带令牌查询用户信息 // 多行注释内容
     * // 多行注释内容
     * https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID // 多行注释内容
     * // 多行注释内容
     * { // 多行注释内容
     * "openid":"OPENID", // 多行注释内容
     * "nickname":"NICKNAME", // 多行注释内容
     * "sex":1, // 多行注释内容
     * "province":"PROVINCE", // 多行注释内容
     * "city":"CITY", // 多行注释内容
     * "country":"COUNTRY", // 多行注释内容
     * "headimgurl": "https://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0", // 多行注释内容
     * "privilege":[ // 多行注释内容
     * "PRIVILEGE1", // 多行注释内容
     * "PRIVILEGE2" // 多行注释内容
     * ], // 多行注释内容
     * "unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL" // 多行注释内容
     * // 多行注释内容
     * } // 多行注释内容
     * @param access_token // 多行注释内容
     * @param openid // 多行注释内容
     * @return // 多行注释内容
     */ // 多行注释内容
    private Map<String,String> getUserinfo(String access_token,String openid){ // 定义私有方法 getUserinfoString access_token,String openid){
 // 空行
        String url_template = "https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s"; // 执行通用逻辑
        String url = String.format(url_template, access_token, openid); // 将 String.format(url_template, access_token, openid) 赋值给 url
 // 空行
        ResponseEntity<String> exchange = restTemplate.exchange(url, HttpMethod.GET, null, String.class); // 将 restTemplate.exchange(url, HttpMethod.GET, null, String.class) 赋值给 exchange
 // 空行
        //获取响应的结果 // 原始行内注释
        String result = new String(exchange.getBody().getBytes(StandardCharsets.ISO_8859_1),StandardCharsets.UTF_8); // 创建 String 实例并赋值给 result
        //将result转成map // 原始行内注释
        Map<String,String> map = JSON.parseObject(result, Map.class); // 将 JSON.parseObject(result, Map.class) 赋值给 map
        return map; // 返回 map 给调用方
 // 空行
    } // 代码块结束
} // 代码块结束

文件:xuecheng-plus-auth/com/xuecheng/ucenter/service/WxAuthService.java

package com.xuecheng.ucenter.service; // 声明工具类所在的包路径
 // 空行
import com.xuecheng.ucenter.model.po.XcUser; // 导入 XcUser 类
 // 空行
/** // 多行注释开始
 * @author Mr.M // 多行注释内容
 * @version 1.0 // 多行注释内容
 * @description 微信扫码接入 // 多行注释内容
 * @date 2023/2/24 15:42 // 多行注释内容
 */ // 多行注释内容
public interface WxAuthService { // 定义 WxAuthService 类型
 // 空行
 /** // 多行注释开始
  *  微信扫码认证,申请令牌,携带令牌查询用户信息、保存用户信息到数据库 // 多行注释内容
  * @param code 授权码 // 多行注释内容
  * @return // 多行注释内容
  */ // 多行注释内容
 public XcUser wxAuth(String code); // 执行通用逻辑
} // 代码块结束

文件:xuecheng-plus-auth/log4j2-dev.xml

<?xml version="1.0" encoding="UTF-8"?> <!-- 声明日志配置文件版本 -->
<Configuration monitorInterval="180" packages=""> <!-- 每 180 秒检测一次配置更新 -->
    <properties>
        <property name="logdir">logs</property> <!-- 日志输出目录 -->
        <property name="PATTERN">%date{YYYY-MM-dd HH:mm:ss,SSS} %level [%thread][%file:%line] - %msg%n%throwable</property> <!-- 统一日志格式 -->
    </properties>
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT"> <!-- 控制台输出 -->
            <PatternLayout pattern="${PATTERN}"/>
        </Console>

        <RollingFile name="ErrorAppender" fileName="${logdir}/error.log" <!-- 错误日志文件 -->
            filePattern="${logdir}/$${date:yyyy-MM-dd}/error.%d{yyyy-MM-dd-HH}.log" append="true"> <!-- 按日期小时滚动 -->
            <PatternLayout pattern="${PATTERN}"/>
            <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/> <!-- 只记录 ERROR+ -->
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true" /> <!-- 每小时切割一次 -->
            </Policies>
        </RollingFile>

        <RollingFile name="DebugAppender" fileName="${logdir}/info.log" <!-- 普通日志文件 -->
            filePattern="${logdir}/$${date:yyyy-MM-dd}/info.%d{yyyy-MM-dd-HH}.log" append="true">
            <PatternLayout pattern="${PATTERN}"/>
            <ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/> <!-- 记录 DEBUG+ -->
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true" />
            </Policies>
        </RollingFile>
        
         <Async name="AsyncAppender" includeLocation="true"> <!-- 异步包装,降低性能损耗 -->
            <AppenderRef ref="ErrorAppender"/>
            <AppenderRef ref="DebugAppender"/>
        </Async>
    </Appenders>
    
    <Loggers>
        <!-- 过滤部分框架的冗余日志 -->
        <logger name="org.springframework" level="INFO"/>
        <logger name="org.mybatis" level="INFO"/>
        <logger name="cn.itcast.wanxinp2p.consumer.mapper" level="DEBUG"/>
        <logger name="springfox" level="INFO"/>
        <logger name="org.apache.http" level="INFO"/>
        <logger name="com.netflix.discovery" level="INFO"/>
        <logger name="RocketmqCommon"  level="INFO" />
        <logger name="RocketmqRemoting" level="INFO"  />
        <logger name="RocketmqClient" level="WARN"/>
        <logger name="org.dromara.hmily" level="WARN"/>
        <logger name="org.dromara.hmily.lottery" level="WARN"/>
        <logger name="org.dromara.hmily.bonuspoint" level="WARN"/>
        <!-- 日志级别对照:OFF < FATAL < ERROR < WARN < INFO < DEBUG < TRACE < ALL -->
        <Root level="DEBUG" includeLocation="true"> <!-- 根记录器 -->
            <AppenderRef ref="AsyncAppender"/>
            <AppenderRef ref="Console"/>
            <AppenderRef ref="DebugAppender"/>
        </Root>
    </Loggers>
</Configuration>

文件:xuecheng-plus-auth/pom.xml

<?xml version="1.0" encoding="UTF-8"?> <!-- XML 声明 -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <!-- SQL 语句片段 -->
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <!-- SQL 语句片段 -->
    <modelVersion>4.0.0</modelVersion> <!-- SQL 语句片段 -->
    <parent> <!-- SQL 语句片段 -->
        <artifactId>xuecheng-plus-parent</artifactId> <!-- SQL 语句片段 -->
        <groupId>com.xuecheng</groupId> <!-- SQL 语句片段 -->
        <version>0.0.1-SNAPSHOT</version> <!-- SQL 语句片段 -->
        <relativePath>../xuecheng-plus-parent</relativePath> <!-- SQL 语句片段 -->
    </parent> <!-- SQL 语句片段 -->
    <artifactId>xuecheng-plus-auth</artifactId> <!-- SQL 语句片段 -->


    <dependencies> <!-- SQL 语句片段 -->
        <dependency> <!-- SQL 语句片段 -->
            <groupId>com.alibaba.cloud</groupId> <!-- SQL 语句片段 -->
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <!-- SQL 语句片段 -->
        </dependency> <!-- SQL 语句片段 -->
        <dependency> <!-- SQL 语句片段 -->
            <groupId>com.alibaba.cloud</groupId> <!-- SQL 语句片段 -->
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> <!-- SQL 语句片段 -->
        </dependency> <!-- SQL 语句片段 -->

        <dependency> <!-- SQL 语句片段 -->
            <groupId>org.springframework.cloud</groupId> <!-- SQL 语句片段 -->
            <artifactId>spring-cloud-starter-openfeign</artifactId> <!-- SQL 语句片段 -->
        </dependency> <!-- SQL 语句片段 -->
        <!-- Spring Boot 的 Spring Web MVC 集成 -->
        <dependency> <!-- SQL 语句片段 -->
            <groupId>org.springframework.boot</groupId> <!-- SQL 语句片段 -->
            <artifactId>spring-boot-starter-web</artifactId> <!-- SQL 语句片段 -->
        </dependency> <!-- SQL 语句片段 -->
        <dependency> <!-- SQL 语句片段 -->
            <groupId>org.springframework.boot</groupId> <!-- SQL 语句片段 -->
            <artifactId>spring-boot-starter-validation</artifactId> <!-- SQL 语句片段 -->
        </dependency> <!-- SQL 语句片段 -->
        <!-- MySQL 驱动 -->
        <dependency> <!-- SQL 语句片段 -->
            <groupId>mysql</groupId> <!-- SQL 语句片段 -->
            <artifactId>mysql-connector-java</artifactId> <!-- SQL 语句片段 -->
            <scope>runtime</scope> <!-- SQL 语句片段 -->
        </dependency> <!-- SQL 语句片段 -->

        <!-- mybatis plus的依赖 -->
        <dependency> <!-- SQL 语句片段 -->
            <groupId>com.baomidou</groupId> <!-- SQL 语句片段 -->
            <artifactId>mybatis-plus-boot-starter</artifactId> <!-- SQL 语句片段 -->
        </dependency> <!-- SQL 语句片段 -->
        <!-- 排除 Spring Boot 依赖的日志包冲突 -->
        <dependency> <!-- SQL 语句片段 -->
            <groupId>org.springframework.boot</groupId> <!-- SQL 语句片段 -->
            <artifactId>spring-boot-starter</artifactId> <!-- SQL 语句片段 -->
            <exclusions> <!-- SQL 语句片段 -->
                <exclusion> <!-- SQL 语句片段 -->
                    <groupId>org.springframework.boot</groupId> <!-- SQL 语句片段 -->
                    <artifactId>spring-boot-starter-logging</artifactId> <!-- SQL 语句片段 -->
                </exclusion> <!-- SQL 语句片段 -->
            </exclusions> <!-- SQL 语句片段 -->
        </dependency> <!-- SQL 语句片段 -->
        <!-- Spring Boot 集成 Junit -->
        <dependency> <!-- SQL 语句片段 -->
            <groupId>org.springframework.boot</groupId> <!-- SQL 语句片段 -->
            <artifactId>spring-boot-starter-test</artifactId> <!-- SQL 语句片段 -->
            <scope>test</scope> <!-- SQL 语句片段 -->
        </dependency> <!-- SQL 语句片段 -->
        <!-- Spring Boot 集成 log4j2 -->
        <dependency> <!-- SQL 语句片段 -->
            <groupId>org.springframework.boot</groupId> <!-- SQL 语句片段 -->
            <artifactId>spring-boot-starter-log4j2</artifactId> <!-- SQL 语句片段 -->
        </dependency> <!-- SQL 语句片段 -->

        <!-- Spring Boot 集成 swagger -->
        <dependency> <!-- SQL 语句片段 -->
            <groupId>com.spring4all</groupId> <!-- SQL 语句片段 -->
            <artifactId>swagger-spring-boot-starter</artifactId> <!-- SQL 语句片段 -->
        </dependency> <!-- SQL 语句片段 -->
        <dependency> <!-- SQL 语句片段 -->
            <groupId>org.projectlombok</groupId> <!-- SQL 语句片段 -->
            <artifactId>lombok</artifactId> <!-- SQL 语句片段 -->
        </dependency> <!-- SQL 语句片段 -->
        <dependency> <!-- SQL 语句片段 -->
            <groupId>com.alibaba</groupId> <!-- SQL 语句片段 -->
            <artifactId>fastjson</artifactId> <!-- SQL 语句片段 -->
        </dependency> <!-- SQL 语句片段 -->
        <dependency> <!-- SQL 语句片段 -->
            <groupId>com.squareup.okhttp3</groupId> <!-- SQL 语句片段 -->
            <artifactId>okhttp</artifactId> <!-- SQL 语句片段 -->
        </dependency> <!-- SQL 语句片段 -->

        <dependency> <!-- SQL 语句片段 -->
            <groupId>org.springframework.cloud</groupId> <!-- SQL 语句片段 -->
            <artifactId>spring-cloud-starter-security</artifactId> <!-- SQL 语句片段 -->
        </dependency> <!-- SQL 语句片段 -->
        <dependency> <!-- SQL 语句片段 -->
            <groupId>org.springframework.cloud</groupId> <!-- SQL 语句片段 -->
            <artifactId>spring-cloud-starter-oauth2</artifactId> <!-- SQL 语句片段 -->
        </dependency> <!-- SQL 语句片段 -->

    </dependencies> <!-- SQL 语句片段 -->

    <build> <!-- SQL 语句片段 -->
        <finalName>${project.artifactId}-${project.version}</finalName> <!-- SQL 语句片段 -->
        <plugins> <!-- SQL 语句片段 -->
            <plugin> <!-- SQL 语句片段 -->
                <groupId>org.springframework.boot</groupId> <!-- SQL 语句片段 -->
                <artifactId>spring-boot-maven-plugin</artifactId> <!-- SQL 语句片段 -->
                <version>${spring-boot.version}</version> <!-- SQL 语句片段 -->
                <executions> <!-- SQL 语句片段 -->
                    <execution> <!-- SQL 语句片段 -->
                        <goals> <!-- SQL 语句片段 -->
                            <goal>repackage</goal> <!-- SQL 语句片段 -->
                        </goals> <!-- SQL 语句片段 -->
                    </execution> <!-- SQL 语句片段 -->
                </executions> <!-- SQL 语句片段 -->
            </plugin> <!-- SQL 语句片段 -->
            <plugin> <!-- SQL 语句片段 -->
                <groupId>com.spotify</groupId> <!-- SQL 语句片段 -->
                <artifactId>docker-maven-plugin</artifactId> <!-- SQL 语句片段 -->
                <version>1.2.2</version> <!-- SQL 语句片段 -->
                <configuration> <!-- SQL 语句片段 -->
                    <!--修改imageName节点的内容,改为私有仓库地址和端口,再加上镜像id和 TAG,我们要直接传到私服-->
                    <!--配置最后生成的镜像名,docker images里的,我们这边取项目名:版本-->
                    <!--<imageName>${project.artifactId}:${project.version}</imageName>-->
                    <imageName>192.168.101.65:5000/${project.artifactId}:${project.version}</imageName> <!-- SQL 语句片段 -->
                    <!--也可以通过以下方式定义image的tag信息。 -->
                    <!-- <imageTags>
                         <imageTag>${project.version}</imageTag> <!-- SQL 语句片段 -->
                         &lt;!&ndash;build 时强制覆盖 tag,配合 imageTags 使用&ndash;&gt; <!-- SQL 语句片段 -->
                         <forceTags>true</forceTags> <!-- SQL 语句片段 -->
                         &lt;!&ndash;build 完成后,push 指定 tag 的镜像,配合 imageTags 使用&ndash;&gt; <!-- SQL 语句片段 -->
                         <pushImageTag>true</pushImageTag> <!-- SQL 语句片段 -->
                     </imageTags>--> <!-- SQL 语句片段 -->
                    <baseImage>java:8u20</baseImage> <!-- SQL 语句片段 -->
                    <maintainer>docker_maven [email protected]</maintainer> <!-- SQL 语句片段 -->
                    <workdir>/root</workdir> <!-- SQL 语句片段 -->
                    <cmd>["java", "-version"]</cmd> <!-- SQL 语句片段 -->
                    <!--来指明Dockerfile文件的所在目录,如果配置了dockerDirectory则忽略baseImage,maintainer等配置-->
                    <!--<dockerDirectory>./</dockerDirectory>-->
                    <!--2375是docker的远程端口,插件生成镜像时连接docker,这里需要指定docker远程端口-->
                    <dockerHost>http://192.168.101.65:2375</dockerHost> <!-- SQL 语句片段 -->
                    <!--入口点,project.build.finalName就是project标签下的build标签下 的filename标签内容,testDocker-->
                    <!--相当于启动容器后,会自动执行java -jar ...-->
                    <entryPoint>["java", "-Dfile.encoding=utf-8","-jar", "/root/${project.build.finalName}.jar"]</entryPoint> <!-- SQL 语句片段 -->
                    <!--是否推送到docker私有仓库,旧版本插件要配置maven的settings文件。 -->
                    <pushImage>true</pushImage> <!-- SQL 语句片段 -->
                    <registryUrl>192.168.101.65:5000</registryUrl>  <!-- 这里是复制 jar 包到 docker 容器指定目录配置 --> <!-- SQL 语句片段 -->
                    <resources> <!-- SQL 语句片段 -->
                        <resource> <!-- SQL 语句片段 -->
                            <targetPath>/root</targetPath> <!-- SQL 语句片段 -->
                            <directory>${project.build.directory}</directory> <!-- SQL 语句片段 -->
                            <!--把哪个文件上传到docker,相当于Dockerfile里的add app.jar /-->
                            <include>${project.build.finalName}.jar</include> <!-- 引用公共 SQL 片段 -->
                        </resource> <!-- SQL 语句片段 -->
                    </resources> <!-- SQL 语句片段 -->
                </configuration> <!-- SQL 语句片段 -->
            </plugin> <!-- SQL 语句片段 -->
        </plugins> <!-- SQL 语句片段 -->
    </build> <!-- SQL 语句片段 -->


</project> <!-- SQL 语句片段 -->

文件:xuecheng-plus-auth/pom_temp.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <artifactId>xuecheng-plus-parent</artifactId>
        <groupId>com.xuecheng</groupId>
        <version>0.0.1-SNAPSHOT</version>
        <relativePath>../xuecheng-plus-parent</relativePath>
    </parent>
    <artifactId>xuecheng-plus-auth</artifactId>


    <dependencies>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!-- Spring Boot ?Spring Web MVC 集成 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <!-- MySQL 驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!-- mybatis plus的依?-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </dependency>
        <!-- 排除 Spring Boot 依赖的日志包冲突 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- Spring Boot 集成 Junit -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- Spring Boot 集成 log4j2 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
        </dependency>

        <!-- Spring Boot 集成 swagger -->
        <dependency>
            <groupId>com.spring4all</groupId>
            <artifactId>swagger-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
        </dependency>
        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-oauth2</artifactId>
        </dependency>

    </dependencies>

    <build>
        <finalName>${project.artifactId}-${project.version}</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>com.spotify</groupId>
                <artifactId>docker-maven-plugin</artifactId>
                <version>1.2.2</version>
                <configuration>
                    <!--修改imageName节点的内容,改为私有仓库地址和端口,再加上镜像id?TAG,我们要直接传到私?->
                    <!--配置最后生成的镜像名,docker images里的,我们这边取项目?版本-->
                    <!--<imageName>${project.artifactId}:${project.version}</imageName>-->
                    <imageName>192.168.101.65:5000/${project.artifactId}:${project.version}</imageName>
                    <!--也可以通过以下方式定义image的tag信息?-->
                    <!-- <imageTags>
                         <imageTag>${project.version}</imageTag>
                         &lt;!&ndash;build 时强制覆?tag,配?imageTags 使用&ndash;&gt;
                         <forceTags>true</forceTags>
                         &lt;!&ndash;build 完成后,push 指定 tag 的镜像,配合 imageTags 使用&ndash;&gt;
                         <pushImageTag>true</pushImageTag>
                     </imageTags>-->
                    <baseImage>java:8u20</baseImage>
                    <maintainer>docker_maven [email protected]</maintainer>
                    <workdir>/root</workdir>
                    <cmd>["java", "-version"]</cmd>
                    <!--来指明Dockerfile文件的所在目录,如果配置了dockerDirectory则忽略baseImage,maintainer等配?->
                    <!--<dockerDirectory>./</dockerDirectory>-->
                    <!--2375是docker的远程端口,插件生成镜像时连接docker,这里需要指定docker远程端口-->
                    <dockerHost>http://192.168.101.65:2375</dockerHost>
                    <!--入口点,project.build.finalName就是project标签下的build标签?的filename标签内容,testDocker-->
                    <!--相当于启动容器后,会自动执行java -jar ...-->
                    <entryPoint>["java", "-Dfile.encoding=utf-8","-jar", "/root/${project.build.finalName}.jar"]</entryPoint>
                    <!--是否推送到docker私有仓库,旧版本插件要配置maven的settings文件?-->
                    <pushImage>true</pushImage>
                    <registryUrl>192.168.101.65:5000</registryUrl>  <!-- 这里是复?jar 包到 docker 容器指定目录配置 -->
                    <resources>
                        <resource>
                            <targetPath>/root</targetPath>
                            <directory>${project.build.directory}</directory>
                            <!--把哪个文件上传到docker,相当于Dockerfile里的add app.jar /-->
                            <include>${project.build.finalName}.jar</include>
                        </resource>
                    </resources>
                </configuration>
            </plugin>
        </plugins>
    </build>


</project>

文件:xuecheng-plus-auth/src/main/java/com/xuecheng/auth/config/AuthorizationServer.java

package com.xuecheng.auth.config; // 声明类所在的包路径

import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 类
import org.springframework.context.annotation.Bean; // 导入 Bean 类
import org.springframework.context.annotation.Configuration; // 导入 Configuration 类
import org.springframework.http.HttpMethod; // 导入 HttpMethod 类
import org.springframework.security.authentication.AuthenticationManager; // 导入 AuthenticationManager 类
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; // 导入 BCryptPasswordEncoder 类
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; // 导入 ClientDetailsServiceConfigurer 类
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; // 导入 AuthorizationServerConfigurerAdapter 类
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; // 导入 EnableAuthorizationServer 类
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; // 导入 AuthorizationServerEndpointsConfigurer 类
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer; // 导入 AuthorizationServerSecurityConfigurer 类
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices; // 导入 AuthorizationServerTokenServices 类
import org.springframework.security.oauth2.provider.token.DefaultTokenServices; // 导入 DefaultTokenServices 类

import javax.annotation.Resource; // 导入 Resource 类

/** // 保留原作者写的块注释
 * @description 授权服务器配置 // 保留原作者写的块注释
 * 相当于售票处,你没有这个票你就不能进去 // 保留原作者写的块注释
 * @author Mr.M // 保留原作者写的块注释
 * @date 2022/9/26 22:25 // 保留原作者写的块注释
 * @version 1.0 // 保留原作者写的块注释
 */ // 保留原作者写的块注释
 @Configuration // 使用注解 @Configuration
 @EnableAuthorizationServer // 使用注解 @EnableAuthorizationServer
 public class AuthorizationServer extends AuthorizationServerConfigurerAdapter { // 定义 class AuthorizationServer

  @Resource(name="authorizationServerTokenServicesCustom") // 使用注解 @Resource(name="authorizationServerTokenServicesCustom")
  private AuthorizationServerTokenServices authorizationServerTokenServices; // 执行语句

 @Autowired // 使用注解 @Autowired
 private AuthenticationManager authenticationManager; // 执行语句

  //客户端详情服务 // 保留原作者写的行内注释
 // 配置哪些客户端可以进来 // 保留原作者写的行内注释
  @Override // 使用注解 @Override
  public void configure(ClientDetailsServiceConfigurer clients) throws Exception { // 定义方法 configure(...)
        clients.inMemory()// 使用in-memory存储 // 代码逻辑
                .withClient("XcWebApp")// client_id(客户端id) // 代码逻辑
//                .secret("XcWebApp")//客户端密钥 // 保留原作者写的行内注释
                .secret(new BCryptPasswordEncoder().encode("XcWebApp"))//客户端密钥 // 代码逻辑
                .resourceIds("xuecheng-plus")//资源列表 // 代码逻辑
                .authorizedGrantTypes("authorization_code", "password","client_credentials","implicit","refresh_token")// 该client允许的授权类型authorization_code,password,refresh_token,implicit,client_credentials // 代码逻辑
                .scopes("all")// 允许的授权范围 // 代码逻辑
                .autoApprove(false)//false跳转到授权页面 // 代码逻辑
                //客户端接收授权码的重定向地址 // 保留原作者写的行内注释
                .redirectUris("http://www.51xuecheng.cn")//用于扫码登录 // 代码逻辑
   ; // 执行语句
  } // 代码块结束


  //令牌端点的访问配置,怎么发令牌 // 保留原作者写的行内注释
  @Override // 使用注解 @Override
  public void configure(AuthorizationServerEndpointsConfigurer endpoints) { // 定义方法 configure(...)
   endpoints // 代码逻辑
           .authenticationManager(authenticationManager)//认证管理器,验证用户名密码 // 代码逻辑
           .tokenServices(authorizationServerTokenServices)//令牌管理服务,自定义令牌规则 // 代码逻辑
           .allowedTokenEndpointRequestMethods(HttpMethod.POST);//只允许post请求令牌 // 执行语句
  } // 代码块结束

  //令牌端点的安全配置,谁可以访问令牌的接口 // 保留原作者写的行内注释
  @Override // 使用注解 @Override
  public void configure(AuthorizationServerSecurityConfigurer security){ // 定义方法 configure(...)
   security // 代码逻辑
           .tokenKeyAccess("permitAll()")                    //oauth/token_key是公开 // 代码逻辑
           .checkTokenAccess("permitAll()")                  //oauth/check_token公开 // 代码逻辑
           .allowFormAuthenticationForClients()				//表单认证(申请令牌) // 代码逻辑
   ; // 执行语句
  } // 代码块结束



 } // 代码块结束

文件:xuecheng-plus-auth/src/main/java/com/xuecheng/auth/config/DaoAuthenticationProviderCustom.java

package com.xuecheng.auth.config; // 声明类所在的包路径

import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 类
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; // 导入 UsernamePasswordAuthenticationToken 类
import org.springframework.security.authentication.dao.DaoAuthenticationProvider; // 导入 DaoAuthenticationProvider 类
import org.springframework.security.core.AuthenticationException; // 导入 AuthenticationException 类
import org.springframework.security.core.userdetails.UserDetails; // 导入 UserDetails 类
import org.springframework.security.core.userdetails.UserDetailsService; // 导入 UserDetailsService 类
import org.springframework.stereotype.Component; // 导入 Component 类

/** // 保留原作者写的块注释
 * @author Mr.M // 保留原作者写的块注释
 * @version 1.0 // 保留原作者写的块注释
 * @description 重写了DaoAuthenticationProvider的校验的密码的方法,因为我们统一认证入口,有一些认证方式不需要校验密码 // 保留原作者写的块注释
 * @date 2023/2/24 11:40 // 保留原作者写的块注释
 */ // 保留原作者写的块注释
@Component // 使用注解 @Component
public class DaoAuthenticationProviderCustom extends DaoAuthenticationProvider { // 定义 class DaoAuthenticationProviderCustom

 @Autowired // 使用注解 @Autowired
 public void setUserDetailsService(UserDetailsService userDetailsService) { // 定义方法 setUserDetailsService(...)
  super.setUserDetailsService(userDetailsService); // 执行语句
 } // 代码块结束

//实现微信登录 // 保留原作者写的行内注释
 @Override // 使用注解 @Override
 protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException { // 定义方法 additionalAuthenticationChecks(...)

 } // 代码块结束
} // 代码块结束

文件:xuecheng-plus-auth/src/main/java/com/xuecheng/auth/config/MybatisPlusConfig.java

package com.xuecheng.auth.config; // 声明类所在的包路径

import com.baomidou.mybatisplus.annotation.DbType; // 导入 DbType 类
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; // 导入 MybatisPlusInterceptor 类
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; // 导入 PaginationInnerInterceptor 类
import org.mybatis.spring.annotation.MapperScan; // 导入 MapperScan 类
import org.springframework.context.annotation.Bean; // 导入 Bean 类
import org.springframework.context.annotation.Configuration; // 导入 Configuration 类

/** // 保留原作者写的块注释
 * <P> // 保留原作者写的块注释
 * 		Mybatis-Plus 配置 // 保留原作者写的块注释
 * </p> // 保留原作者写的块注释
 */ // 保留原作者写的块注释
@Configuration // 使用注解 @Configuration
@MapperScan("com.xuecheng.ucenter.mapper") // 使用注解 @MapperScan("com.xuecheng.ucenter.mapper")
public class MybatisPlusConfig { // 定义 class MybatisPlusConfig
	/** // 保留原作者写的块注释
	 * 新的分页插件 // 保留原作者写的块注释
	 * 需要设置 MybatisConfiguration#useDeprecatedExecutor = false // 保留原作者写的块注释
	 * 避免缓存出现问题(该属性会在旧插件移除后一同移除) // 保留原作者写的块注释
	 */ // 保留原作者写的块注释
	@Bean // 使用注解 @Bean
	public MybatisPlusInterceptor mybatisPlusInterceptor() { // 定义方法 mybatisPlusInterceptor(...)
		MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); // 创建 MybatisPlusInterceptor 对象并赋值给 interceptor
		interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); // 执行语句
		return interceptor; // 返回 interceptor
	} // 代码块结束


} // 代码块结束

文件:xuecheng-plus-auth/src/main/java/com/xuecheng/auth/config/TokenConfig.java

package com.xuecheng.auth.config; // 声明类所在的包路径

import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 类
import org.springframework.context.annotation.Bean; // 导入 Bean 类
import org.springframework.context.annotation.Configuration; // 导入 Configuration 类
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices; // 导入 AuthorizationServerTokenServices 类
import org.springframework.security.oauth2.provider.token.DefaultTokenServices; // 导入 DefaultTokenServices 类
import org.springframework.security.oauth2.provider.token.TokenEnhancerChain; // 导入 TokenEnhancerChain 类
import org.springframework.security.oauth2.provider.token.TokenStore; // 导入 TokenStore 类
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore; // 导入 InMemoryTokenStore 类
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter; // 导入 JwtAccessTokenConverter 类
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore; // 导入 JwtTokenStore 类

import java.util.Arrays; // 导入 Arrays 类

/** // 保留原作者写的块注释
 * @author Administrator // 保留原作者写的块注释
 * @version 1.0 // 保留原作者写的块注释
 * 令牌生成与存储方式的类 // 保留原作者写的块注释
 **/ // 保留原作者写的块注释
@Configuration // 使用注解 @Configuration
public class TokenConfig { // 定义 class TokenConfig

    private String SIGNING_KEY = "mq123"; // 把 "mq123" 赋值给 SIGNING_KEY

    @Autowired // 使用注解 @Autowired
    TokenStore tokenStore; // 执行语句

//    @Bean // 保留原作者写的行内注释
//    public TokenStore tokenStore() { // 保留原作者写的行内注释
//        //使用内存存储令牌(普通令牌) // 保留原作者写的行内注释
//        return new InMemoryTokenStore(); // 保留原作者写的行内注释
//    } // 保留原作者写的行内注释

    @Autowired // 使用注解 @Autowired
    private JwtAccessTokenConverter accessTokenConverter; // 执行语句

    // 使用jwt存储token // 保留原作者写的行内注释
    @Bean // 使用注解 @Bean
    public TokenStore tokenStore() { // 定义方法 tokenStore(...)
        return new JwtTokenStore(accessTokenConverter()); // 返回 new JwtTokenStore(accessTokenConverter())
    } // 代码块结束

    // 配置jwt的加密方式 // 保留原作者写的行内注释
    @Bean // 使用注解 @Bean
    public JwtAccessTokenConverter accessTokenConverter() { // 定义方法 accessTokenConverter(...)
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter(); // 创建 JwtAccessTokenConverter 对象并赋值给 converter
        converter.setSigningKey(SIGNING_KEY); // 执行语句
        return converter; // 返回 converter
    } // 代码块结束

    //令牌管理服务 // 保留原作者写的行内注释
    @Bean(name="authorizationServerTokenServicesCustom") // 使用注解 @Bean(name="authorizationServerTokenServicesCustom")
    public AuthorizationServerTokenServices tokenService() { // 定义方法 tokenService(...)
        DefaultTokenServices service=new DefaultTokenServices(); // 创建 DefaultTokenServices 对象并赋值给 service
        service.setSupportRefreshToken(true);//支持刷新令牌 // 执行语句
        service.setTokenStore(tokenStore);//令牌存储策略 // 执行语句

        TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain(); // 创建 TokenEnhancerChain 对象并赋值给 tokenEnhancerChain
        tokenEnhancerChain.setTokenEnhancers(Arrays.asList(accessTokenConverter)); // 执行语句
        service.setTokenEnhancer(tokenEnhancerChain); // 执行语句

        service.setAccessTokenValiditySeconds(7200); // 令牌默认有效期2小时 // 执行语句
        service.setRefreshTokenValiditySeconds(259200); // 刷新令牌默认有效期3天 // 执行语句
        return service; // 返回 service
    } // 代码块结束


} // 代码块结束

文件:xuecheng-plus-auth/src/main/java/com/xuecheng/auth/config/WebSecurityConfig.java

package com.xuecheng.auth.config; // 声明类所在的包路径

import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 类
import org.springframework.context.annotation.Bean; // 导入 Bean 类
import org.springframework.security.authentication.AuthenticationManager; // 导入 AuthenticationManager 类
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; // 导入 AuthenticationManagerBuilder 类
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; // 导入 EnableGlobalMethodSecurity 类
import org.springframework.security.config.annotation.web.builders.HttpSecurity; // 导入 HttpSecurity 类
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; // 导入 EnableWebSecurity 类
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; // 导入 WebSecurityConfigurerAdapter 类
import org.springframework.security.core.userdetails.User; // 导入 User 类
import org.springframework.security.core.userdetails.UserDetailsService; // 导入 UserDetailsService 类
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; // 导入 BCryptPasswordEncoder 类
import org.springframework.security.crypto.password.NoOpPasswordEncoder; // 导入 NoOpPasswordEncoder 类
import org.springframework.security.crypto.password.PasswordEncoder; // 导入 PasswordEncoder 类
import org.springframework.security.provisioning.InMemoryUserDetailsManager; // 导入 InMemoryUserDetailsManager 类

/** // 保留原作者写的块注释
 * @author Mr.M // 保留原作者写的块注释
 * @version 1.0 // 保留原作者写的块注释
 * @description 安全管理配置 // 保留原作者写的块注释
 * @date 2022/9/26 20:53 // 保留原作者写的块注释
 */ // 保留原作者写的块注释
@EnableWebSecurity // 使用注解 @EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true) // 使用注解 @EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { // 定义 class WebSecurityConfig


    @Bean // 使用注解 @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception { // 定义方法 authenticationManagerBean(...)
        return super.authenticationManagerBean(); // 返回 super.authenticationManagerBean()
    } // 代码块结束

    //配置用户信息服务 // 保留原作者写的行内注释
//    @Bean // 保留原作者写的行内注释
//    public UserDetailsService userDetailsService() { // 保留原作者写的行内注释
//        //这里配置用户信息,这里暂时使用这种方式将用户存储在内存中 // 保留原作者写的行内注释
//        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); // 保留原作者写的行内注释
//        manager.createUser(User.withUsername("zhangsan").password("123").authorities("p1").build()); // 保留原作者写的行内注释
//        manager.createUser(User.withUsername("lisi").password("456").authorities("p2").build()); // 保留原作者写的行内注释
//        return manager; // 保留原作者写的行内注释
//    } // 保留原作者写的行内注释

    @Bean // 使用注解 @Bean
    public PasswordEncoder passwordEncoder() { // 定义方法 passwordEncoder(...)
//        //密码为明文方式 // 保留原作者写的行内注释
//        return NoOpPasswordEncoder.getInstance(); // 保留原作者写的行内注释
        return new BCryptPasswordEncoder(); // 返回 new BCryptPasswordEncoder()
    } // 代码块结束

    @Autowired // 使用注解 @Autowired
    DaoAuthenticationProviderCustom daoAuthenticationProviderCustom; // 执行语句


    @Override // 使用注解 @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception { // 定义方法 configure(...)
        auth.authenticationProvider(daoAuthenticationProviderCustom); // 执行语句
    } // 代码块结束

    //配置安全拦截机制 // 保留原作者写的行内注释
    @Override // 使用注解 @Override
    protected void configure(HttpSecurity http) throws Exception { // 定义方法 configure(...)
        http // 代码逻辑
                .authorizeRequests() // 代码逻辑
                .antMatchers("/r/**").authenticated()//访问/r开始的请求需要认证通过 // 代码逻辑
                .anyRequest().permitAll()//其它请求全部放行 // 代码逻辑
                .and() // 代码逻辑
                .formLogin().successForwardUrl("/login-success");//登录成功跳转到/login-success // 执行语句
    } // 代码块结束

    public static void main(String[] args) { // 定义方法 main(...)
        String password = "111111"; // 把 "111111" 赋值给 password
        PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); // 创建 BCryptPasswordEncoder 对象并赋值给 passwordEncoder
        for (int i = 0; i < 5; i++) { // 定义方法 方法(...)
            //生成密码 // 保留原作者写的行内注释
            String encode = passwordEncoder.encode(password); // 把 passwordEncoder.encode(password) 赋值给 encode
            System.out.println(encode); // 执行语句
            //校验密码,参数1是输入的明文 ,参数2是正确密码加密后的串 // 保留原作者写的行内注释
            boolean matches = passwordEncoder.matches(password, encode); // 把 passwordEncoder.matches(password, encode) 赋值给 matches
            System.out.println(matches); // 执行语句
        } // 代码块结束

        boolean matches = passwordEncoder.matches("1234", "$2a$10$fb2RlvFwr9HsRu9vH1OxCu/YiMRw6wy5UI6u3s0A.0bVSuR1UqdHK"); // 把 passwordEncoder.matches("1234", "$2a$10$fb2RlvFwr9HsRu9vH1OxCu/YiMRw6wy5UI6u3s0A.0bVSuR1UqdHK") 赋值给 matches
        System.out.println(matches); // 执行语句
    } // 代码块结束



} // 代码块结束

文件:xuecheng-plus-auth/src/main/java/com/xuecheng/auth/controller/LoginController.java

package com.xuecheng.auth.controller; // 声明类所在的包路径

import com.xuecheng.ucenter.mapper.XcUserMapper; // 导入 XcUserMapper 类
import com.xuecheng.ucenter.model.po.XcUser; // 导入 XcUser 类
import lombok.extern.slf4j.Slf4j; // 导入 Slf4j 类
import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 类
import org.springframework.security.access.prepost.PreAuthorize; // 导入 PreAuthorize 类
import org.springframework.web.bind.annotation.PathVariable; // 导入 PathVariable 类
import org.springframework.web.bind.annotation.RequestMapping; // 导入 RequestMapping 类
import org.springframework.web.bind.annotation.RestController; // 导入 RestController 类

/** // 保留原作者写的块注释
 * @author Mr.M // 保留原作者写的块注释
 * @version 1.0 // 保留原作者写的块注释
 * @description 测试controller // 保留原作者写的块注释
 * @date 2022/9/27 17:25 // 保留原作者写的块注释
 */ // 保留原作者写的块注释
@Slf4j // 使用注解 @Slf4j
@RestController // 使用注解 @RestController
public class LoginController { // 定义 class LoginController

    @Autowired // 使用注解 @Autowired
    XcUserMapper userMapper; // 执行语句


    @RequestMapping("/login-success") // 使用注解 @RequestMapping("/login-success")
    public String loginSuccess() { // 定义方法 loginSuccess(...)

        return "登录成功"; // 返回 "登录成功"
    } // 代码块结束


    @RequestMapping("/user/{id}") // 使用注解 @RequestMapping("/user/{id}")
    public XcUser getuser(@PathVariable("id") String id) { // 定义方法 getuser(...)
        XcUser xcUser = userMapper.selectById(id); // 把 userMapper.selectById(id) 赋值给 xcUser
        return xcUser; // 返回 xcUser
    } // 代码块结束

    @RequestMapping("/r/r1") // 使用注解 @RequestMapping("/r/r1")
    @PreAuthorize("hasAuthority('p1')")//拥有p1权限方可访问 // 使用注解 @PreAuthorize("hasAuthority('p1')")
    public String r1() { // 定义方法 r1(...)
        return "访问r1资源"; // 返回 "访问r1资源"
    } // 代码块结束

    @RequestMapping("/r/r2") // 使用注解 @RequestMapping("/r/r2")
    @PreAuthorize("hasAuthority('p2')")//拥有p2权限方可访问 // 使用注解 @PreAuthorize("hasAuthority('p2')")
    public String r2() { // 定义方法 r2(...)
        return "访问r2资源"; // 返回 "访问r2资源"
    } // 代码块结束



} // 代码块结束

文件:xuecheng-plus-auth/src/main/java/com/xuecheng/auth/controller/WxLoginController.java

package com.xuecheng.auth.controller; // 声明类所在的包路径

import com.xuecheng.ucenter.model.po.XcUser; // 导入 XcUser 类
import com.xuecheng.ucenter.service.WxAuthService; // 导入 WxAuthService 类
import lombok.extern.slf4j.Slf4j; // 导入 Slf4j 类
import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 类
import org.springframework.stereotype.Controller; // 导入 Controller 类
import org.springframework.web.bind.annotation.RequestMapping; // 导入 RequestMapping 类

import java.io.IOException; // 导入 IOException 类

/** // 保留原作者写的块注释
 * @author Mr.M // 保留原作者写的块注释
 * @version 1.0 // 保留原作者写的块注释
 * @description TODO // 保留原作者写的块注释
 * @date 2023/2/24 15:13 // 保留原作者写的块注释
 */ // 保留原作者写的块注释
@Slf4j // 使用注解 @Slf4j
@Controller // 使用注解 @Controller
public class WxLoginController { // 定义 class WxLoginController

    @Autowired // 使用注解 @Autowired
    WxAuthService wxAuthService; // 执行语句

    @RequestMapping("/wxLogin") // 使用注解 @RequestMapping("/wxLogin")
    public String wxLogin(String code, String state) throws IOException { // 定义方法 wxLogin(...)
        log.debug("微信扫码回调,code:{},state:{}", code, state); // 执行语句
        //远程调用微信请令牌,拿到令牌查询用户信息,将用户信息写入本项目数据库 // 保留原作者写的行内注释
        XcUser xcUser = wxAuthService.wxAuth(code); // 把 wxAuthService.wxAuth(code) 赋值给 xcUser

        if (xcUser == null) { // 定义方法 方法(...)
            return "redirect:http://www.51xuecheng.cn/error.html"; // 返回 "redirect:http:
        } // 代码块结束
        String username = xcUser.getUsername(); // 把 xcUser.getUsername() 的返回值赋给 username
        return "redirect:http://www.51xuecheng.cn/sign.html?username=" + username + "&authType=wx"; // 返回 "redirect:http:
    } // 代码块结束
} // 代码块结束

文件:xuecheng-plus-auth/src/main/java/com/xuecheng/AuthApplication.java

package com.xuecheng; // 声明类所在的包路径

import org.springframework.boot.SpringApplication; // 导入 SpringApplication 类
import org.springframework.boot.autoconfigure.SpringBootApplication; // 导入 SpringBootApplication 类
import org.springframework.cloud.openfeign.EnableFeignClients; // 导入 EnableFeignClients 类
import org.springframework.context.annotation.Bean; // 导入 Bean 类
import org.springframework.http.MediaType; // 导入 MediaType 类
import org.springframework.http.client.OkHttp3ClientHttpRequestFactory; // 导入 OkHttp3ClientHttpRequestFactory 类
import org.springframework.http.converter.HttpMessageConverter; // 导入 HttpMessageConverter 类
import org.springframework.http.converter.StringHttpMessageConverter; // 导入 StringHttpMessageConverter 类
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; // 导入 MappingJackson2HttpMessageConverter 类
import org.springframework.web.client.RestTemplate; // 导入 RestTemplate 类

import java.nio.charset.StandardCharsets; // 导入 StandardCharsets 类
import java.util.ArrayList; // 导入 ArrayList 类
import java.util.List; // 导入 List 类


@EnableFeignClients(basePackages = "com.xuecheng.ucenter.feignclient") // 使用注解 @EnableFeignClients(basePackages = "com.xuecheng.ucenter.feignclient")
@SpringBootApplication // 使用注解 @SpringBootApplication
public class AuthApplication { // 定义 class AuthApplication

    public static void main(String[] args) { // 定义方法 main(...)
        SpringApplication.run(AuthApplication.class, args); // 执行语句
    } // 代码块结束

    @Bean // 使用注解 @Bean
    RestTemplate restTemplate(){ // 定义方法 restTemplate(...)
        RestTemplate restTemplate = new RestTemplate(new OkHttp3ClientHttpRequestFactory()); // 创建 RestTemplate 对象并赋值给 restTemplate
        return  restTemplate; // 返回  restTemplate
    } // 代码块结束

} // 代码块结束

文件:xuecheng-plus-auth/src/main/java/com/xuecheng/ucenter/feignclient/CheckCodeClient.java

package com.xuecheng.ucenter.feignclient; // 声明类所在的包路径

import org.springframework.cloud.openfeign.FeignClient; // 导入 FeignClient 类
import org.springframework.web.bind.annotation.PostMapping; // 导入 PostMapping 类
import org.springframework.web.bind.annotation.RequestMapping; // 导入 RequestMapping 类
import org.springframework.web.bind.annotation.RequestParam; // 导入 RequestParam 类

/** // 保留原作者写的块注释
 * @author Mr.M // 保留原作者写的块注释
 * @version 1.0 // 保留原作者写的块注释
 * @description TODO // 保留原作者写的块注释
 * @date 2023/2/24 14:45 // 保留原作者写的块注释
 */ // 保留原作者写的块注释
@FeignClient(value = "checkcode",fallbackFactory = CheckCodeClientFactory.class) // 使用注解 @FeignClient(value = "checkcode",fallbackFactory = CheckCodeClientFactory.class)
@RequestMapping("/checkcode") // 使用注解 @RequestMapping("/checkcode")
public interface CheckCodeClient { // 定义 interface CheckCodeClient

 @PostMapping(value = "/verify") // 使用注解 @PostMapping(value = "/verify")
 public Boolean verify(@RequestParam("key") String key, @RequestParam("code") String code); // 执行语句

} // 代码块结束

文件:xuecheng-plus-auth/src/main/java/com/xuecheng/ucenter/feignclient/CheckCodeClientFactory.java

package com.xuecheng.ucenter.feignclient; // 声明类所在的包路径

import feign.hystrix.FallbackFactory; // 导入 FallbackFactory 类
import lombok.extern.slf4j.Slf4j; // 导入 Slf4j 类
import org.springframework.stereotype.Component; // 导入 Component 类

/** // 保留原作者写的块注释
 * @author Mr.M // 保留原作者写的块注释
 * @version 1.0 // 保留原作者写的块注释
 * @description TODO // 保留原作者写的块注释
 * @date 2023/2/24 14:46 // 保留原作者写的块注释
 */ // 保留原作者写的块注释
@Slf4j // 使用注解 @Slf4j
@Component // 使用注解 @Component
public class CheckCodeClientFactory implements FallbackFactory<CheckCodeClient> { // 定义 class CheckCodeClientFactory
 @Override // 使用注解 @Override
 public CheckCodeClient create(Throwable throwable) { // 定义方法 create(...)
  return new CheckCodeClient() { // 定义方法 CheckCodeClient(...)

   @Override // 使用注解 @Override
   public Boolean verify(String key, String code) { // 定义方法 verify(...)
    log.debug("调用验证码服务熔断异常:{}", throwable.getMessage()); // 执行语句
    return null; // 返回 null
   } // 代码块结束
  }; // 执行语句
 } // 代码块结束
} // 代码块结束

文件:xuecheng-plus-auth/src/main/java/com/xuecheng/ucenter/mapper/XcCompanyMapper.java

package com.xuecheng.ucenter.mapper; // 声明类所在的包路径

import com.baomidou.mybatisplus.core.mapper.BaseMapper; // 导入 BaseMapper 类
import com.xuecheng.ucenter.model.po.XcCompany; // 导入 XcCompany 类

/** // 保留原作者写的块注释
 * <p> // 保留原作者写的块注释
 *  Mapper 接口 // 保留原作者写的块注释
 * </p> // 保留原作者写的块注释
 * // 保留原作者写的块注释
 * @author itcast // 保留原作者写的块注释
 */ // 保留原作者写的块注释
public interface XcCompanyMapper extends BaseMapper<XcCompany> { // 定义 interface XcCompanyMapper

} // 代码块结束

文件:xuecheng-plus-auth/src/main/java/com/xuecheng/ucenter/mapper/XcCompanyMapper.xml

<?xml version="1.0" encoding="UTF-8"?> <!-- XML 声明 -->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- SQL 语句片段 -->
<mapper namespace="com.xuecheng.ucenter.mapper.XcCompanyMapper"> <!-- MyBatis 映射文件的根标签 -->

    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.xuecheng.ucenter.model.po.XcCompany"> <!-- 定义结果映射 -->
        <id column="id" property="id" /> <!-- 主键列的映射规则 -->
        <result column="linkname" property="linkname" /> <!-- 字段与属性的映射规则 -->
        <result column="name" property="name" /> <!-- 字段与属性的映射规则 -->
        <result column="mobile" property="mobile" /> <!-- 字段与属性的映射规则 -->
        <result column="email" property="email" /> <!-- 字段与属性的映射规则 -->
        <result column="intro" property="intro" /> <!-- 字段与属性的映射规则 -->
        <result column="logo" property="logo" /> <!-- 字段与属性的映射规则 -->
        <result column="identitypic" property="identitypic" /> <!-- 字段与属性的映射规则 -->
        <result column="worktype" property="worktype" /> <!-- 字段与属性的映射规则 -->
        <result column="businesspic" property="businesspic" /> <!-- 字段与属性的映射规则 -->
        <result column="status" property="status" /> <!-- 字段与属性的映射规则 -->
    </resultMap> <!-- 结束 resultMap 区块 -->

    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List"> <!-- 声明可复用的 SQL 片段 -->
        id, linkname, name, mobile, email, intro, logo, identitypic, worktype, businesspic, status <!-- SQL 语句片段 -->
    </sql> <!-- 结束 SQL 片段 -->

</mapper> <!-- 结束 mapper 标签 -->

文件:xuecheng-plus-auth/src/main/java/com/xuecheng/ucenter/mapper/XcCompanyUserMapper.java

package com.xuecheng.ucenter.mapper; // 声明类所在的包路径

import com.baomidou.mybatisplus.core.mapper.BaseMapper; // 导入 BaseMapper 类
import com.xuecheng.ucenter.model.po.XcCompanyUser; // 导入 XcCompanyUser 类

/** // 保留原作者写的块注释
 * <p> // 保留原作者写的块注释
 *  Mapper 接口 // 保留原作者写的块注释
 * </p> // 保留原作者写的块注释
 * // 保留原作者写的块注释
 * @author itcast // 保留原作者写的块注释
 */ // 保留原作者写的块注释
public interface XcCompanyUserMapper extends BaseMapper<XcCompanyUser> { // 定义 interface XcCompanyUserMapper

} // 代码块结束

文件:xuecheng-plus-auth/src/main/java/com/xuecheng/ucenter/mapper/XcCompanyUserMapper.xml

<?xml version="1.0" encoding="UTF-8"?> <!-- XML 声明 -->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- SQL 语句片段 -->
<mapper namespace="com.xuecheng.ucenter.mapper.XcCompanyUserMapper"> <!-- MyBatis 映射文件的根标签 -->

    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.xuecheng.ucenter.model.po.XcCompanyUser"> <!-- 定义结果映射 -->
        <id column="id" property="id" /> <!-- 主键列的映射规则 -->
        <result column="company_id" property="companyId" /> <!-- 字段与属性的映射规则 -->
        <result column="user_id" property="userId" /> <!-- 字段与属性的映射规则 -->
    </resultMap> <!-- 结束 resultMap 区块 -->

    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List"> <!-- 声明可复用的 SQL 片段 -->
        id, company_id, user_id <!-- SQL 语句片段 -->
    </sql> <!-- 结束 SQL 片段 -->

</mapper> <!-- 结束 mapper 标签 -->

文件:xuecheng-plus-auth/src/main/java/com/xuecheng/ucenter/mapper/XcMenuMapper.java

package com.xuecheng.ucenter.mapper; // 声明类所在的包路径

import com.baomidou.mybatisplus.core.mapper.BaseMapper; // 导入 BaseMapper 类
import com.xuecheng.ucenter.model.po.XcMenu; // 导入 XcMenu 类
import org.apache.ibatis.annotations.Param; // 导入 Param 类
import org.apache.ibatis.annotations.Select; // 导入 Select 类

import java.util.List; // 导入 List 类

/** // 保留原作者写的块注释
 * <p> // 保留原作者写的块注释
 *  Mapper 接口 // 保留原作者写的块注释
 * </p> // 保留原作者写的块注释
 * // 保留原作者写的块注释
 * @author itcast // 保留原作者写的块注释
 */ // 保留原作者写的块注释
public interface XcMenuMapper extends BaseMapper<XcMenu> { // 定义 interface XcMenuMapper
    @Select("SELECT	* FROM xc_menu WHERE id IN (SELECT menu_id FROM xc_permission WHERE role_id IN ( SELECT role_id FROM xc_user_role WHERE user_id = #{userId} ))") // 使用注解 @Select("SELECT	* FROM xc_menu WHERE id IN (SELECT menu_id FROM xc_permission WHERE role_id IN ( SELECT role_id FROM xc_user_role WHERE user_id = #{userId} ))")
    List<XcMenu> selectPermissionByUserId(@Param("userId") String userId); // 执行语句
} // 代码块结束

文件:xuecheng-plus-auth/src/main/java/com/xuecheng/ucenter/mapper/XcMenuMapper.xml

<?xml version="1.0" encoding="UTF-8"?> <!-- XML 声明 -->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- SQL 语句片段 -->
<mapper namespace="com.xuecheng.ucenter.mapper.XcMenuMapper"> <!-- MyBatis 映射文件的根标签 -->

    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.xuecheng.ucenter.model.po.XcMenu"> <!-- 定义结果映射 -->
        <id column="id" property="id" /> <!-- 主键列的映射规则 -->
        <result column="code" property="code" /> <!-- 字段与属性的映射规则 -->
        <result column="p_id" property="pId" /> <!-- 字段与属性的映射规则 -->
        <result column="menu_name" property="menuName" /> <!-- 字段与属性的映射规则 -->
        <result column="url" property="url" /> <!-- 字段与属性的映射规则 -->
        <result column="is_menu" property="isMenu" /> <!-- 字段与属性的映射规则 -->
        <result column="level" property="level" /> <!-- 字段与属性的映射规则 -->
        <result column="sort" property="sort" /> <!-- 字段与属性的映射规则 -->
        <result column="status" property="status" /> <!-- 字段与属性的映射规则 -->
        <result column="icon" property="icon" /> <!-- 字段与属性的映射规则 -->
        <result column="create_time" property="createTime" /> <!-- 字段与属性的映射规则 -->
        <result column="update_time" property="updateTime" /> <!-- 字段与属性的映射规则 -->
    </resultMap> <!-- 结束 resultMap 区块 -->

    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List"> <!-- 声明可复用的 SQL 片段 -->
        id, code, p_id, menu_name, url, is_menu, level, sort, status, icon, create_time, update_time <!-- SQL 语句片段 -->
    </sql> <!-- 结束 SQL 片段 -->

</mapper> <!-- 结束 mapper 标签 -->

文件:xuecheng-plus-auth/src/main/java/com/xuecheng/ucenter/mapper/XcPermissionMapper.java

package com.xuecheng.ucenter.mapper; // 声明类所在的包路径

import com.baomidou.mybatisplus.core.mapper.BaseMapper; // 导入 BaseMapper 类
import com.xuecheng.ucenter.model.po.XcPermission; // 导入 XcPermission 类

/** // 保留原作者写的块注释
 * <p> // 保留原作者写的块注释
 *  Mapper 接口 // 保留原作者写的块注释
 * </p> // 保留原作者写的块注释
 * // 保留原作者写的块注释
 * @author itcast // 保留原作者写的块注释
 */ // 保留原作者写的块注释
public interface XcPermissionMapper extends BaseMapper<XcPermission> { // 定义 interface XcPermissionMapper

} // 代码块结束

文件:xuecheng-plus-auth/src/main/java/com/xuecheng/ucenter/mapper/XcPermissionMapper.xml

<?xml version="1.0" encoding="UTF-8"?> <!-- XML 声明 -->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- SQL 语句片段 -->
<mapper namespace="com.xuecheng.ucenter.mapper.XcPermissionMapper"> <!-- MyBatis 映射文件的根标签 -->

    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.xuecheng.ucenter.model.po.XcPermission"> <!-- 定义结果映射 -->
        <id column="id" property="id" /> <!-- 主键列的映射规则 -->
        <result column="role_id" property="roleId" /> <!-- 字段与属性的映射规则 -->
        <result column="menu_id" property="menuId" /> <!-- 字段与属性的映射规则 -->
        <result column="create_time" property="createTime" /> <!-- 字段与属性的映射规则 -->
    </resultMap> <!-- 结束 resultMap 区块 -->

    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List"> <!-- 声明可复用的 SQL 片段 -->
        id, role_id, menu_id, create_time <!-- SQL 语句片段 -->
    </sql> <!-- 结束 SQL 片段 -->

</mapper> <!-- 结束 mapper 标签 -->

文件:xuecheng-plus-auth/src/main/java/com/xuecheng/ucenter/mapper/XcRoleMapper.java

package com.xuecheng.ucenter.mapper; // 声明类所在的包路径

import com.baomidou.mybatisplus.core.mapper.BaseMapper; // 导入 BaseMapper 类
import com.xuecheng.ucenter.model.po.XcRole; // 导入 XcRole 类

/** // 保留原作者写的块注释
 * <p> // 保留原作者写的块注释
 *  Mapper 接口 // 保留原作者写的块注释
 * </p> // 保留原作者写的块注释
 * // 保留原作者写的块注释
 * @author itcast // 保留原作者写的块注释
 */ // 保留原作者写的块注释
public interface XcRoleMapper extends BaseMapper<XcRole> { // 定义 interface XcRoleMapper

} // 代码块结束

文件:xuecheng-plus-auth/src/main/java/com/xuecheng/ucenter/mapper/XcRoleMapper.xml

<?xml version="1.0" encoding="UTF-8"?> <!-- XML 声明 -->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- SQL 语句片段 -->
<mapper namespace="com.xuecheng.ucenter.mapper.XcRoleMapper"> <!-- MyBatis 映射文件的根标签 -->

    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.xuecheng.ucenter.model.po.XcRole"> <!-- 定义结果映射 -->
        <id column="id" property="id" /> <!-- 主键列的映射规则 -->
        <result column="role_name" property="roleName" /> <!-- 字段与属性的映射规则 -->
        <result column="role_code" property="roleCode" /> <!-- 字段与属性的映射规则 -->
        <result column="description" property="description" /> <!-- 字段与属性的映射规则 -->
        <result column="create_time" property="createTime" /> <!-- 字段与属性的映射规则 -->
        <result column="update_time" property="updateTime" /> <!-- 字段与属性的映射规则 -->
        <result column="status" property="status" /> <!-- 字段与属性的映射规则 -->
    </resultMap> <!-- 结束 resultMap 区块 -->

    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List"> <!-- 声明可复用的 SQL 片段 -->
        id, role_name, role_code, description, create_time, update_time, status <!-- SQL 语句片段 -->
    </sql> <!-- 结束 SQL 片段 -->

</mapper> <!-- 结束 mapper 标签 -->

文件:xuecheng-plus-auth/src/main/java/com/xuecheng/ucenter/mapper/XcTeacherMapper.java

package com.xuecheng.ucenter.mapper; // 声明类所在的包路径

import com.baomidou.mybatisplus.core.mapper.BaseMapper; // 导入 BaseMapper 类
import com.xuecheng.ucenter.model.po.XcTeacher; // 导入 XcTeacher 类

/** // 保留原作者写的块注释
 * <p> // 保留原作者写的块注释
 *  Mapper 接口 // 保留原作者写的块注释
 * </p> // 保留原作者写的块注释
 * // 保留原作者写的块注释
 * @author itcast // 保留原作者写的块注释
 */ // 保留原作者写的块注释
public interface XcTeacherMapper extends BaseMapper<XcTeacher> { // 定义 interface XcTeacherMapper

} // 代码块结束

文件:xuecheng-plus-auth/src/main/java/com/xuecheng/ucenter/mapper/XcTeacherMapper.xml

<?xml version="1.0" encoding="UTF-8"?> <!-- XML 声明 -->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- SQL 语句片段 -->
<mapper namespace="com.xuecheng.ucenter.mapper.XcTeacherMapper"> <!-- MyBatis 映射文件的根标签 -->

    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.xuecheng.ucenter.model.po.XcTeacher"> <!-- 定义结果映射 -->
        <id column="id" property="id" /> <!-- 主键列的映射规则 -->
        <result column="user_id" property="userId" /> <!-- 字段与属性的映射规则 -->
        <result column="name" property="name" /> <!-- 字段与属性的映射规则 -->
        <result column="intro" property="intro" /> <!-- 字段与属性的映射规则 -->
        <result column="resume" property="resume" /> <!-- 字段与属性的映射规则 -->
        <result column="pic" property="pic" /> <!-- 字段与属性的映射规则 -->
    </resultMap> <!-- 结束 resultMap 区块 -->

    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List"> <!-- 声明可复用的 SQL 片段 -->
        id, user_id, name, intro, resume, pic <!-- SQL 语句片段 -->
    </sql> <!-- 结束 SQL 片段 -->

</mapper> <!-- 结束 mapper 标签 -->

文件:xuecheng-plus-auth/src/main/java/com/xuecheng/ucenter/mapper/XcUserMapper.java

package com.xuecheng.ucenter.mapper; // 声明类所在的包路径

import com.baomidou.mybatisplus.core.mapper.BaseMapper; // 导入 BaseMapper 类
import com.xuecheng.ucenter.model.po.XcUser; // 导入 XcUser 类

/** // 保留原作者写的块注释
 * <p> // 保留原作者写的块注释
 *  Mapper 接口 // 保留原作者写的块注释
 * </p> // 保留原作者写的块注释
 * // 保留原作者写的块注释
 * @author itcast // 保留原作者写的块注释
 */ // 保留原作者写的块注释
public interface XcUserMapper extends BaseMapper<XcUser> { // 定义 interface XcUserMapper

} // 代码块结束

文件:xuecheng-plus-auth/src/main/java/com/xuecheng/ucenter/mapper/XcUserMapper.xml

<?xml version="1.0" encoding="UTF-8"?> <!-- XML 声明 -->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- SQL 语句片段 -->
<mapper namespace="com.xuecheng.ucenter.mapper.XcUserMapper"> <!-- MyBatis 映射文件的根标签 -->

    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.xuecheng.ucenter.model.po.XcUser"> <!-- 定义结果映射 -->
        <id column="id" property="id" /> <!-- 主键列的映射规则 -->
        <result column="username" property="username" /> <!-- 字段与属性的映射规则 -->
        <result column="password" property="password" /> <!-- 字段与属性的映射规则 -->
        <result column="salt" property="salt" /> <!-- 字段与属性的映射规则 -->
        <result column="name" property="name" /> <!-- 字段与属性的映射规则 -->
        <result column="nickname" property="nickname" /> <!-- 字段与属性的映射规则 -->
        <result column="company_id" property="companyId" /> <!-- 字段与属性的映射规则 -->
        <result column="wx_unionid" property="wxUnionid" /> <!-- 字段与属性的映射规则 -->
        <result column="userpic" property="userpic" /> <!-- 字段与属性的映射规则 -->
        <result column="utype" property="utype" /> <!-- 字段与属性的映射规则 -->
        <result column="birthday" property="birthday" /> <!-- 字段与属性的映射规则 -->
        <result column="sex" property="sex" /> <!-- 字段与属性的映射规则 -->
        <result column="email" property="email" /> <!-- 字段与属性的映射规则 -->
        <result column="cellphone" property="cellphone" /> <!-- 字段与属性的映射规则 -->
        <result column="qq" property="qq" /> <!-- 字段与属性的映射规则 -->
        <result column="status" property="status" /> <!-- 字段与属性的映射规则 -->
        <result column="create_time" property="createTime" /> <!-- 字段与属性的映射规则 -->
        <result column="update_time" property="updateTime" /> <!-- 字段与属性的映射规则 -->
    </resultMap> <!-- 结束 resultMap 区块 -->

    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List"> <!-- 声明可复用的 SQL 片段 -->
        id, username, password, salt, name,nickname,company_id, wx_unionid,userpic, utype, birthday, sex, email, cellphone, qq, status, create_time, update_time <!-- SQL 语句片段 -->
    </sql> <!-- 结束 SQL 片段 -->

</mapper> <!-- 结束 mapper 标签 -->

文件:xuecheng-plus-auth/src/main/java/com/xuecheng/ucenter/mapper/XcUserRoleMapper.java

package com.xuecheng.ucenter.mapper; // 声明类所在的包路径

import com.baomidou.mybatisplus.core.mapper.BaseMapper; // 导入 BaseMapper 类
import com.xuecheng.ucenter.model.po.XcUserRole; // 导入 XcUserRole 类

/** // 保留原作者写的块注释
 * <p> // 保留原作者写的块注释
 *  Mapper 接口 // 保留原作者写的块注释
 * </p> // 保留原作者写的块注释
 * // 保留原作者写的块注释
 * @author itcast // 保留原作者写的块注释
 */ // 保留原作者写的块注释
public interface XcUserRoleMapper extends BaseMapper<XcUserRole> { // 定义 interface XcUserRoleMapper

} // 代码块结束

文件:xuecheng-plus-auth/src/main/java/com/xuecheng/ucenter/mapper/XcUserRoleMapper.xml

<?xml version="1.0" encoding="UTF-8"?> <!-- XML 声明 -->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- SQL 语句片段 -->
<mapper namespace="com.xuecheng.ucenter.mapper.XcUserRoleMapper"> <!-- MyBatis 映射文件的根标签 -->

    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.xuecheng.ucenter.model.po.XcUserRole"> <!-- 定义结果映射 -->
        <id column="id" property="id" /> <!-- 主键列的映射规则 -->
        <result column="user_id" property="userId" /> <!-- 字段与属性的映射规则 -->
        <result column="role_id" property="roleId" /> <!-- 字段与属性的映射规则 -->
        <result column="create_time" property="createTime" /> <!-- 字段与属性的映射规则 -->
        <result column="creator" property="creator" /> <!-- 字段与属性的映射规则 -->
    </resultMap> <!-- 结束 resultMap 区块 -->

    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List"> <!-- 声明可复用的 SQL 片段 -->
        id, user_id, role_id, create_time, creator <!-- SQL 语句片段 -->
    </sql> <!-- 结束 SQL 片段 -->

</mapper> <!-- 结束 mapper 标签 -->

文件:xuecheng-plus-auth/src/main/java/com/xuecheng/ucenter/model/dto/AuthParamsDto.java

package com.xuecheng.ucenter.model.dto; // 声明类所在的包路径

import lombok.Data; // 导入 Data 类

import java.util.HashMap; // 导入 HashMap 类
import java.util.Map; // 导入 Map 类

/** // 保留原作者写的块注释
 * @author Mr.M // 保留原作者写的块注释
 * @version 1.0 // 保留原作者写的块注释
 * @description 认证用户请求参数 // 保留原作者写的块注释
 * @date 2022/9/29 10:56 // 保留原作者写的块注释
 */ // 保留原作者写的块注释
@Data // 使用注解 @Data
public class AuthParamsDto { // 定义 class AuthParamsDto

    private String username; //用户名 // 执行语句
    private String password; //域  用于扩展 // 执行语句
    private String cellphone;//手机号 // 执行语句
    private String checkcode;//验证码 // 执行语句
    private String checkcodekey;//验证码key // 执行语句
    private String authType; // 认证的类型   password:用户名密码模式类型    sms:短信模式类型 // 执行语句
    private Map<String, Object> payload = new HashMap<>();//附加数据,作为扩展,不同认证类型可拥有不同的附加数据。如认证类型为短信时包含smsKey : sms:3d21042d054548b08477142bbca95cfa; 所有情况下都包含clientId // 创建 HashMap<> 对象并赋值给 payload


} // 代码块结束

文件:xuecheng-plus-auth/src/main/java/com/xuecheng/ucenter/model/dto/XcUserExt.java

package com.xuecheng.ucenter.model.dto; // 声明类所在的包路径

import com.xuecheng.ucenter.model.po.XcUser; // 导入 XcUser 类
import lombok.Data; // 导入 Data 类

import java.util.ArrayList; // 导入 ArrayList 类
import java.util.List; // 导入 List 类

/** // 保留原作者写的块注释
 * @description 用户扩展信息 // 保留原作者写的块注释
 * @author Mr.M // 保留原作者写的块注释
 * @date 2022/9/30 13:56 // 保留原作者写的块注释
 * @version 1.0 // 保留原作者写的块注释
 */ // 保留原作者写的块注释
@Data // 使用注解 @Data
public class XcUserExt extends XcUser { // 定义 class XcUserExt
    //用户权限 // 保留原作者写的行内注释
    List<String> permissions = new ArrayList<>(); // 创建 ArrayList<> 对象并赋值给 permissions
} // 代码块结束

文件:xuecheng-plus-auth/src/main/java/com/xuecheng/ucenter/model/po/XcCompany.java

package com.xuecheng.ucenter.model.po; // 声明类所在的包路径

import com.baomidou.mybatisplus.annotation.TableName; // 导入 TableName 类
import lombok.Data; // 导入 Data 类

import java.io.Serializable; // 导入 Serializable 类

/** // 保留原作者写的块注释
 * <p> // 保留原作者写的块注释
 *  // 保留原作者写的块注释
 * </p> // 保留原作者写的块注释
 * // 保留原作者写的块注释
 * @author itcast // 保留原作者写的块注释
 */ // 保留原作者写的块注释
@Data // 使用注解 @Data
@TableName("xc_company") // 使用注解 @TableName("xc_company")
public class XcCompany implements Serializable { // 定义 class XcCompany

    private static final long serialVersionUID = 1L; // 把 1L 赋值给 serialVersionUID

    private String id; // 执行语句

    /** // 保留原作者写的块注释
     * 联系人名称 // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    private String linkname; // 执行语句

    /** // 保留原作者写的块注释
     * 名称 // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    private String name; // 执行语句

    private String mobile; // 执行语句

    private String email; // 执行语句

    /** // 保留原作者写的块注释
     * 简介 // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    private String intro; // 执行语句

    /** // 保留原作者写的块注释
     * logo // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    private String logo; // 执行语句

    /** // 保留原作者写的块注释
     * 身份证照片 // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    private String identitypic; // 执行语句

    /** // 保留原作者写的块注释
     * 工具性质 // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    private String worktype; // 执行语句

    /** // 保留原作者写的块注释
     * 营业执照 // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    private String businesspic; // 执行语句

    /** // 保留原作者写的块注释
     * 企业状态 // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    private String status; // 执行语句


} // 代码块结束

文件:xuecheng-plus-auth/src/main/java/com/xuecheng/ucenter/model/po/XcCompanyUser.java

package com.xuecheng.ucenter.model.po; // 声明类所在的包路径

import com.baomidou.mybatisplus.annotation.TableName; // 导入 TableName 类
import lombok.Data; // 导入 Data 类

import java.io.Serializable; // 导入 Serializable 类

/** // 保留原作者写的块注释
 * <p> // 保留原作者写的块注释
 *  // 保留原作者写的块注释
 * </p> // 保留原作者写的块注释
 * // 保留原作者写的块注释
 * @author itcast // 保留原作者写的块注释
 */ // 保留原作者写的块注释
@Data // 使用注解 @Data
@TableName("xc_company_user") // 使用注解 @TableName("xc_company_user")
public class XcCompanyUser implements Serializable { // 定义 class XcCompanyUser

    private static final long serialVersionUID = 1L; // 把 1L 赋值给 serialVersionUID

    private String id; // 执行语句

    private String companyId; // 执行语句

    private String userId; // 执行语句


} // 代码块结束

文件:xuecheng-plus-auth/src/main/java/com/xuecheng/ucenter/model/po/XcMenu.java

package com.xuecheng.ucenter.model.po; // 声明类所在的包路径

import com.baomidou.mybatisplus.annotation.TableName; // 导入 TableName 类
import lombok.Data; // 导入 Data 类

import java.io.Serializable; // 导入 Serializable 类
import java.time.LocalDateTime; // 导入 LocalDateTime 类

/** // 保留原作者写的块注释
 * <p> // 保留原作者写的块注释
 *  // 保留原作者写的块注释
 * </p> // 保留原作者写的块注释
 * // 保留原作者写的块注释
 * @author itcast // 保留原作者写的块注释
 */ // 保留原作者写的块注释
@Data // 使用注解 @Data
@TableName("xc_menu") // 使用注解 @TableName("xc_menu")
public class XcMenu implements Serializable { // 定义 class XcMenu

    private static final long serialVersionUID = 1L; // 把 1L 赋值给 serialVersionUID

    private String id; // 执行语句

    /** // 保留原作者写的块注释
     * 菜单编码 // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    private String code; // 执行语句

    /** // 保留原作者写的块注释
     * 父菜单ID // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    private String pId; // 执行语句

    /** // 保留原作者写的块注释
     * 名称 // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    private String menuName; // 执行语句

    /** // 保留原作者写的块注释
     * 请求地址 // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    private String url; // 执行语句

    /** // 保留原作者写的块注释
     * 是否是菜单 // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    private String isMenu; // 执行语句

    /** // 保留原作者写的块注释
     * 菜单层级 // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    private Integer level; // 执行语句

    /** // 保留原作者写的块注释
     * 菜单排序 // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    private Integer sort; // 执行语句

    private String status; // 执行语句

    private String icon; // 执行语句

    private LocalDateTime createTime; // 执行语句

    private LocalDateTime updateTime; // 执行语句


} // 代码块结束

文件:xuecheng-plus-auth/src/main/java/com/xuecheng/ucenter/model/po/XcPermission.java

package com.xuecheng.ucenter.model.po; // 声明类所在的包路径

import com.baomidou.mybatisplus.annotation.TableName; // 导入 TableName 类
import lombok.Data; // 导入 Data 类

import java.io.Serializable; // 导入 Serializable 类
import java.time.LocalDateTime; // 导入 LocalDateTime 类

/** // 保留原作者写的块注释
 * <p> // 保留原作者写的块注释
 *  // 保留原作者写的块注释
 * </p> // 保留原作者写的块注释
 * // 保留原作者写的块注释
 * @author itcast // 保留原作者写的块注释
 */ // 保留原作者写的块注释
@Data // 使用注解 @Data
@TableName("xc_permission") // 使用注解 @TableName("xc_permission")
public class XcPermission implements Serializable { // 定义 class XcPermission

    private static final long serialVersionUID = 1L; // 把 1L 赋值给 serialVersionUID

    private String id; // 执行语句

    private String roleId; // 执行语句

    private String menuId; // 执行语句

    private LocalDateTime createTime; // 执行语句


} // 代码块结束

文件:xuecheng-plus-auth/src/main/java/com/xuecheng/ucenter/model/po/XcRole.java

package com.xuecheng.ucenter.model.po; // 声明类所在的包路径

import com.baomidou.mybatisplus.annotation.TableName; // 导入 TableName 类
import lombok.Data; // 导入 Data 类

import java.io.Serializable; // 导入 Serializable 类
import java.time.LocalDateTime; // 导入 LocalDateTime 类

/** // 保留原作者写的块注释
 * <p> // 保留原作者写的块注释
 *  // 保留原作者写的块注释
 * </p> // 保留原作者写的块注释
 * // 保留原作者写的块注释
 * @author itcast // 保留原作者写的块注释
 */ // 保留原作者写的块注释
@Data // 使用注解 @Data
@TableName("xc_role") // 使用注解 @TableName("xc_role")
public class XcRole implements Serializable { // 定义 class XcRole

    private static final long serialVersionUID = 1L; // 把 1L 赋值给 serialVersionUID

    private String id; // 执行语句

    private String roleName; // 执行语句

    private String roleCode; // 执行语句

    private String description; // 执行语句

    private LocalDateTime createTime; // 执行语句

    private LocalDateTime updateTime; // 执行语句

    private String status; // 执行语句


} // 代码块结束

文件:xuecheng-plus-auth/src/main/java/com/xuecheng/ucenter/model/po/XcTeacher.java

package com.xuecheng.ucenter.model.po; // 声明类所在的包路径

import com.baomidou.mybatisplus.annotation.TableName; // 导入 TableName 类
import lombok.Data; // 导入 Data 类

import java.io.Serializable; // 导入 Serializable 类

/** // 保留原作者写的块注释
 * <p> // 保留原作者写的块注释
 *  // 保留原作者写的块注释
 * </p> // 保留原作者写的块注释
 * // 保留原作者写的块注释
 * @author itcast // 保留原作者写的块注释
 */ // 保留原作者写的块注释
@Data // 使用注解 @Data
@TableName("xc_teacher") // 使用注解 @TableName("xc_teacher")
public class XcTeacher implements Serializable { // 定义 class XcTeacher

    private static final long serialVersionUID = 1L; // 把 1L 赋值给 serialVersionUID

    private String id; // 执行语句

    /** // 保留原作者写的块注释
     * 用户id // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    private String userId; // 执行语句

    /** // 保留原作者写的块注释
     * 称呼 // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    private String name; // 执行语句

    /** // 保留原作者写的块注释
     * 个人简介 // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    private String intro; // 执行语句

    /** // 保留原作者写的块注释
     * 个人简历 // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    private String resume; // 执行语句

    /** // 保留原作者写的块注释
     * 老师照片 // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    private String pic; // 执行语句


} // 代码块结束

文件:xuecheng-plus-auth/src/main/java/com/xuecheng/ucenter/model/po/XcUser.java

package com.xuecheng.ucenter.model.po; // 声明类所在的包路径

import com.baomidou.mybatisplus.annotation.TableName; // 导入 TableName 类
import lombok.Data; // 导入 Data 类

import java.io.Serializable; // 导入 Serializable 类
import java.time.LocalDateTime; // 导入 LocalDateTime 类

/** // 保留原作者写的块注释
 * <p> // 保留原作者写的块注释
 *  // 保留原作者写的块注释
 * </p> // 保留原作者写的块注释
 * // 保留原作者写的块注释
 * @author itcast // 保留原作者写的块注释
 */ // 保留原作者写的块注释
@Data // 使用注解 @Data
@TableName("xc_user") // 使用注解 @TableName("xc_user")
public class XcUser implements Serializable { // 定义 class XcUser

    private static final long serialVersionUID = 1L; // 把 1L 赋值给 serialVersionUID

    private String id; // 执行语句

    private String username; // 执行语句

    private String password; // 执行语句

    private String salt; // 执行语句

    private String name; // 执行语句
    private String nickname; // 执行语句
    private String wxUnionid; // 执行语句
    private String companyId; // 执行语句
    /** // 保留原作者写的块注释
     * 头像 // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    private String userpic; // 执行语句

    private String utype; // 执行语句

    private LocalDateTime birthday; // 执行语句

    private String sex; // 执行语句

    private String email; // 执行语句

    private String cellphone; // 执行语句

    private String qq; // 执行语句

    /** // 保留原作者写的块注释
     * 用户状态 // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    private String status; // 执行语句

    private LocalDateTime createTime; // 执行语句

    private LocalDateTime updateTime; // 执行语句


} // 代码块结束

文件:xuecheng-plus-auth/src/main/java/com/xuecheng/ucenter/model/po/XcUserRole.java

package com.xuecheng.ucenter.model.po; // 声明类所在的包路径

import com.baomidou.mybatisplus.annotation.TableName; // 导入 TableName 类
import lombok.Data; // 导入 Data 类

import java.io.Serializable; // 导入 Serializable 类
import java.time.LocalDateTime; // 导入 LocalDateTime 类

/** // 保留原作者写的块注释
 * <p> // 保留原作者写的块注释
 *  // 保留原作者写的块注释
 * </p> // 保留原作者写的块注释
 * // 保留原作者写的块注释
 * @author itcast // 保留原作者写的块注释
 */ // 保留原作者写的块注释
@Data // 使用注解 @Data
@TableName("xc_user_role") // 使用注解 @TableName("xc_user_role")
public class XcUserRole implements Serializable { // 定义 class XcUserRole

    private static final long serialVersionUID = 1L; // 把 1L 赋值给 serialVersionUID

    private String id; // 执行语句

    private String userId; // 执行语句

    private String roleId; // 执行语句

    private LocalDateTime createTime; // 执行语句

    private String creator; // 执行语句


} // 代码块结束

文件:xuecheng-plus-auth/src/main/java/com/xuecheng/ucenter/service/AuthService.java

package com.xuecheng.ucenter.service; // 声明类所在的包路径

import com.xuecheng.ucenter.model.dto.AuthParamsDto; // 导入 AuthParamsDto 类
import com.xuecheng.ucenter.model.dto.XcUserExt; // 导入 XcUserExt 类

/** // 保留原作者写的块注释
 * @author Mr.M // 保留原作者写的块注释
 * @version 1.0 // 保留原作者写的块注释
 * @description 统一的认证接口 // 保留原作者写的块注释
 * @date 2023/2/24 11:55 // 保留原作者写的块注释
 */ // 保留原作者写的块注释
public interface AuthService { // 定义 interface AuthService

 /** // 保留原作者写的块注释
  * @description 认证方法 // 保留原作者写的块注释
  * @param authParamsDto 认证参数 // 保留原作者写的块注释
  * @return com.xuecheng.ucenter.model.po.XcUser 用户信息 // 保留原作者写的块注释
  * @author Mr.M // 保留原作者写的块注释
  * @date 2022/9/29 12:11 // 保留原作者写的块注释
  */ // 保留原作者写的块注释
 XcUserExt execute(AuthParamsDto authParamsDto); // 执行语句

} // 代码块结束

文件:xuecheng-plus-auth/src/main/java/com/xuecheng/ucenter/service/impl/PasswordAuthServiceImpl.java

package com.xuecheng.ucenter.service.impl; // 声明类所在的包路径

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; // 导入 LambdaQueryWrapper 类
import com.xuecheng.ucenter.feignclient.CheckCodeClient; // 导入 CheckCodeClient 类
import com.xuecheng.ucenter.mapper.XcUserMapper; // 导入 XcUserMapper 类
import com.xuecheng.ucenter.model.dto.AuthParamsDto; // 导入 AuthParamsDto 类
import com.xuecheng.ucenter.model.dto.XcUserExt; // 导入 XcUserExt 类
import com.xuecheng.ucenter.model.po.XcUser; // 导入 XcUser 类
import com.xuecheng.ucenter.service.AuthService; // 导入 AuthService 类
import org.apache.commons.lang.StringUtils; // 导入 StringUtils 类
import org.springframework.beans.BeanUtils; // 导入 BeanUtils 类
import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 类
import org.springframework.security.crypto.password.PasswordEncoder; // 导入 PasswordEncoder 类
import org.springframework.stereotype.Service; // 导入 Service 类

/** // 保留原作者写的块注释
 * @author Mr.M // 保留原作者写的块注释
 * @version 1.0 // 保留原作者写的块注释
 * @description 账号名密码方式 // 保留原作者写的块注释
 * @date 2023/2/24 11:56 // 保留原作者写的块注释
 */ // 保留原作者写的块注释
@Service("password_authservice") // 使用注解 @Service("password_authservice")
public class PasswordAuthServiceImpl implements AuthService { // 定义 class PasswordAuthServiceImpl

 @Autowired // 使用注解 @Autowired
 XcUserMapper xcUserMapper; // 执行语句

 @Autowired // 使用注解 @Autowired
 PasswordEncoder passwordEncoder; // 执行语句

 @Autowired // 使用注解 @Autowired
 CheckCodeClient checkCodeClient; // 执行语句

 @Override // 使用注解 @Override
 public XcUserExt execute(AuthParamsDto authParamsDto) { // 定义方法 execute(...)
  //账号 // 保留原作者写的行内注释
  String username = authParamsDto.getUsername(); // 把 authParamsDto.getUsername() 的返回值赋给 username

  //输入的验证码 // 保留原作者写的行内注释
  String checkcode = authParamsDto.getCheckcode(); // 把 authParamsDto.getCheckcode() 的返回值赋给 checkcode
  //验证码对应的key // 保留原作者写的行内注释
  String checkcodekey = authParamsDto.getCheckcodekey(); // 把 authParamsDto.getCheckcodekey() 的返回值赋给 checkcodekey

//  if(StringUtils.isEmpty(checkcode) || StringUtils.isEmpty(checkcodekey)){ // 保留原作者写的行内注释
//   throw new RuntimeException("请输入的验证码"); // 保留原作者写的行内注释
//  } // 保留原作者写的行内注释
// // 保留原作者写的行内注释
//  //远程调用验证码服务接口去校验验证码 // 保留原作者写的行内注释
//  Boolean verify = checkCodeClient.verify(checkcodekey, checkcode); // 保留原作者写的行内注释
//  if(verify == null||!verify){ // 保留原作者写的行内注释
//   throw new RuntimeException("验证码输入错误"); // 保留原作者写的行内注释
//  } // 保留原作者写的行内注释


  //账号是否存在 // 保留原作者写的行内注释
  //根据username账号查询数据库 // 保留原作者写的行内注释
  XcUser xcUser = xcUserMapper.selectOne(new LambdaQueryWrapper<XcUser>().eq(XcUser::getUsername, username)); // 把 xcUserMapper.selectOne(new LambdaQueryWrapper<XcUser>().eq(XcUser::getUsername, username)) 赋值给 xcUser

  //查询到用户不存在,要返回null即可,spring security框架抛出异常用户不存在 // 保留原作者写的行内注释
  if(xcUser==null){ // 定义方法 方法(...)
   throw new RuntimeException("账号不存在"); // 主动抛出异常
  } // 代码块结束

  //验证密码是否正确 // 保留原作者写的行内注释
  //如果查到了用户拿到正确的密码 // 保留原作者写的行内注释
  String passwordDb = xcUser.getPassword(); // 把 xcUser.getPassword() 的返回值赋给 passwordDb
  //拿到用户输入的密码 // 保留原作者写的行内注释
  String passwordForm = authParamsDto.getPassword(); // 把 authParamsDto.getPassword() 的返回值赋给 passwordForm
  //校验密码 // 保留原作者写的行内注释
  boolean matches = passwordEncoder.matches(passwordForm, passwordDb); // 把 passwordEncoder.matches(passwordForm, passwordDb) 赋值给 matches
  if(!matches){ // 定义方法 方法(...)
   throw new RuntimeException("账号或密码错误"); // 主动抛出异常
  } // 代码块结束
  XcUserExt xcUserExt = new XcUserExt(); // 创建 XcUserExt 对象并赋值给 xcUserExt
  BeanUtils.copyProperties(xcUser,xcUserExt); // 执行语句

  return xcUserExt; // 返回 xcUserExt
 } // 代码块结束
} // 代码块结束

文件:xuecheng-plus-auth/src/main/java/com/xuecheng/ucenter/service/impl/UserServiceImpl.java

package com.xuecheng.ucenter.service.impl; // 声明类所在的包路径

import com.alibaba.fastjson.JSON; // 导入 JSON 类
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; // 导入 LambdaQueryWrapper 类
import com.xuecheng.ucenter.mapper.XcMenuMapper; // 导入 XcMenuMapper 类
import com.xuecheng.ucenter.mapper.XcUserMapper; // 导入 XcUserMapper 类
import com.xuecheng.ucenter.model.dto.AuthParamsDto; // 导入 AuthParamsDto 类
import com.xuecheng.ucenter.model.dto.XcUserExt; // 导入 XcUserExt 类
import com.xuecheng.ucenter.model.po.XcMenu; // 导入 XcMenu 类
import com.xuecheng.ucenter.model.po.XcUser; // 导入 XcUser 类
import com.xuecheng.ucenter.service.AuthService; // 导入 AuthService 类
import lombok.extern.slf4j.Slf4j; // 导入 Slf4j 类
import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 类
import org.springframework.context.ApplicationContext; // 导入 ApplicationContext 类
import org.springframework.security.core.userdetails.User; // 导入 User 类
import org.springframework.security.core.userdetails.UserDetails; // 导入 UserDetails 类
import org.springframework.security.core.userdetails.UserDetailsService; // 导入 UserDetailsService 类
import org.springframework.security.core.userdetails.UsernameNotFoundException; // 导入 UsernameNotFoundException 类
import org.springframework.stereotype.Component; // 导入 Component 类

import java.util.ArrayList; // 导入 ArrayList 类
import java.util.List; // 导入 List 类

/** // 保留原作者写的块注释
 * @author Mr.M // 保留原作者写的块注释
 * @version 1.0 // 保留原作者写的块注释
 * @description TODO // 保留原作者写的块注释
 * @date 2023/2/24 10:37 // 保留原作者写的块注释
 */ // 保留原作者写的块注释
@Slf4j // 使用注解 @Slf4j
@Component // 使用注解 @Component
public class UserServiceImpl implements UserDetailsService { // 定义 class UserServiceImpl
    @Autowired // 使用注解 @Autowired
    XcUserMapper xcUserMapper; // 执行语句

    @Autowired // 使用注解 @Autowired
    XcMenuMapper xcMenuMapper; // 执行语句
    @Autowired // 使用注解 @Autowired
    ApplicationContext applicationContext; // 执行语句



    //传入的请求认证的参数就是AuthParamsDto // 保留原作者写的行内注释
    @Override // 使用注解 @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException { // 定义方法 loadUserByUsername(...)
        //将传入的json转成AuthParamsDto对象 // 保留原作者写的行内注释
        AuthParamsDto authParamsDto = null; // 把变量 authParamsDto 初始化为 null
        try { // 尝试执行可能抛出异常的代码
            authParamsDto = JSON.parseObject(s, AuthParamsDto.class); // 把 JSON.parseObject(s, AuthParamsDto.class) 赋值给 authParamsDto
        } catch (Exception e) { // 定义方法 catch(...)
            throw new RuntimeException("请求认证参数不符合要求"); // 主动抛出异常
        } // 代码块结束

        //认证类型,有password,wx。。。 // 保留原作者写的行内注释
        String authType = authParamsDto.getAuthType(); // 把 authParamsDto.getAuthType() 的返回值赋给 authType


        //根据认证类型从spring容器取出指定的bean // 保留原作者写的行内注释
        String beanName = authType+"_authservice"; // 把 authType+"_authservice" 赋值给 beanName
        AuthService authService = applicationContext.getBean(beanName, AuthService.class); // 把 applicationContext.getBean(beanName, AuthService.class) 赋值给 authService
        //调用统一execute方法完成认证 // 保留原作者写的行内注释
        XcUserExt xcUserExt = authService.execute(authParamsDto); // 把 authService.execute(authParamsDto) 赋值给 xcUserExt
        //封装xcUserExt用户信息为UserDetails // 保留原作者写的行内注释
        //根据UserDetails对象生成令牌 // 保留原作者写的行内注释
        UserDetails userPrincipal = getUserPrincipal(xcUserExt); // 把 getUserPrincipal(xcUserExt) 赋值给 userPrincipal

        return userPrincipal; // 返回 userPrincipal
    } // 代码块结束

    /** // 保留原作者写的块注释
     * @description 查询用户信息 // 保留原作者写的块注释
     * @param xcUser  用户id,主键 // 保留原作者写的块注释
     * @return com.xuecheng.ucenter.model.po.XcUser 用户信息 // 保留原作者写的块注释
     * @author Mr.M // 保留原作者写的块注释
     * @date 2022/9/29 12:19 // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    public UserDetails getUserPrincipal(XcUserExt xcUser){ // 定义方法 getUserPrincipal(...)
        String password = xcUser.getPassword(); // 把 xcUser.getPassword() 的返回值赋给 password
        //权限 // 保留原作者写的行内注释
        String[] authorities=  {"test"}; // 把 {"test"} 赋值给 authorities
        //根据用户id查询用户的权限 // 保留原作者写的行内注释
        List<XcMenu> xcMenus = xcMenuMapper.selectPermissionByUserId(xcUser.getId()); // 把 xcMenuMapper.selectPermissionByUserId(xcUser.getId()) 赋值给 xcMenus
        if(xcMenus.size()>0){ // 定义方法 方法(...)
            List<String> permissions =new ArrayList<>(); // 创建 ArrayList<> 对象并赋值给 permissions
            xcMenus.forEach(m->{ // 定义方法 方法(...)
                //拿到了用户拥有的权限标识符 // 保留原作者写的行内注释
                permissions.add(m.getCode()); // 执行语句
            }); // 执行语句
            //将permissions转成数组 // 保留原作者写的行内注释
            authorities = permissions.toArray(new String[0]); // 把 permissions.toArray(new String[0]) 赋值给 authorities
        } // 代码块结束


        xcUser.setPassword(null); // 执行语句
        //将用户信息转json // 保留原作者写的行内注释
        String userJson = JSON.toJSONString(xcUser); // 把 JSON.toJSONString(xcUser) 赋值给 userJson
        UserDetails userDetails = User.withUsername(userJson).password(password).authorities(authorities).build(); // 把 User.withUsername(userJson).password(password).authorities(authorities).build() 的返回值赋给 userDetails
        return  userDetails; // 返回  userDetails
    } // 代码块结束


} // 代码块结束

文件:xuecheng-plus-auth/src/main/java/com/xuecheng/ucenter/service/impl/WxAuthServiceImpl.java

package com.xuecheng.ucenter.service.impl; // 声明类所在的包路径

import com.alibaba.fastjson.JSON; // 导入 JSON 类
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; // 导入 LambdaQueryWrapper 类
import com.xuecheng.ucenter.mapper.XcUserMapper; // 导入 XcUserMapper 类
import com.xuecheng.ucenter.mapper.XcUserRoleMapper; // 导入 XcUserRoleMapper 类
import com.xuecheng.ucenter.model.dto.AuthParamsDto; // 导入 AuthParamsDto 类
import com.xuecheng.ucenter.model.dto.XcUserExt; // 导入 XcUserExt 类
import com.xuecheng.ucenter.model.po.XcUser; // 导入 XcUser 类
import com.xuecheng.ucenter.model.po.XcUserRole; // 导入 XcUserRole 类
import com.xuecheng.ucenter.service.AuthService; // 导入 AuthService 类
import com.xuecheng.ucenter.service.WxAuthService; // 导入 WxAuthService 类
import org.springframework.beans.BeanUtils; // 导入 BeanUtils 类
import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 类
import org.springframework.beans.factory.annotation.Value; // 导入 Value 类
import org.springframework.http.HttpMethod; // 导入 HttpMethod 类
import org.springframework.http.ResponseEntity; // 导入 ResponseEntity 类
import org.springframework.stereotype.Service; // 导入 Service 类
import org.springframework.transaction.annotation.Transactional; // 导入 Transactional 类
import org.springframework.web.client.RestTemplate; // 导入 RestTemplate 类

import java.nio.charset.StandardCharsets; // 导入 StandardCharsets 类
import java.time.LocalDateTime; // 导入 LocalDateTime 类
import java.util.Map; // 导入 Map 类
import java.util.UUID; // 导入 UUID 类

/** // 保留原作者写的块注释
 * @author Mr.M // 保留原作者写的块注释
 * @version 1.0 // 保留原作者写的块注释
 * @description 微信扫码认证 // 保留原作者写的块注释
 * @date 2023/2/24 11:57 // 保留原作者写的块注释
 */ // 保留原作者写的块注释
@Service("wx_authservice") // 使用注解 @Service("wx_authservice")
public class WxAuthServiceImpl implements AuthService, WxAuthService { // 定义 class WxAuthServiceImpl

    @Autowired // 使用注解 @Autowired
    XcUserMapper xcUserMapper; // 执行语句
    @Autowired // 使用注解 @Autowired
    XcUserRoleMapper xcUserRoleMapper; // 执行语句

    @Autowired // 使用注解 @Autowired
    WxAuthServiceImpl currentPorxy; // 执行语句

    @Autowired // 使用注解 @Autowired
    RestTemplate restTemplate; // 执行语句


    @Value("${weixin.appid}") // 使用注解 @Value("${weixin.appid}")
    String appid; // 执行语句
    @Value("${weixin.secret}") // 使用注解 @Value("${weixin.secret}")
    String secret; // 执行语句

    @Override // 使用注解 @Override
    public XcUserExt execute(AuthParamsDto authParamsDto) { // 定义方法 execute(...)
        //得到账号 // 保留原作者写的行内注释
        String username = authParamsDto.getUsername(); // 把 authParamsDto.getUsername() 的返回值赋给 username
        //查询数据库 // 保留原作者写的行内注释
        XcUser xcUser = xcUserMapper.selectOne(new LambdaQueryWrapper<XcUser>().eq(XcUser::getUsername, username)); // 把 xcUserMapper.selectOne(new LambdaQueryWrapper<XcUser>().eq(XcUser::getUsername, username)) 赋值给 xcUser
        if(xcUser == null){ // 定义方法 方法(...)
            throw new RuntimeException("用户不存在"); // 主动抛出异常
        } // 代码块结束

        XcUserExt xcUserExt = new XcUserExt(); // 创建 XcUserExt 对象并赋值给 xcUserExt
        BeanUtils.copyProperties(xcUser, xcUserExt); // 执行语句


        return xcUserExt; // 返回 xcUserExt
    } // 代码块结束

    @Override // 使用注解 @Override
    public XcUser wxAuth(String code) { // 定义方法 wxAuth(...)
        //申请令牌 // 保留原作者写的行内注释
        Map<String, String> access_token_map = getAccess_token(code); // 把 getAccess_token(code) 赋值给 access_token_map
        //访问令牌 // 保留原作者写的行内注释
        String access_token = access_token_map.get("access_token"); // 把 access_token_map.get("access_token") 赋值给 access_token
        String openid = access_token_map.get("openid"); // 把 access_token_map.get("openid") 赋值给 openid

        //携带令牌查询用户信息 // 保留原作者写的行内注释
        Map<String, String> userinfo = getUserinfo(access_token, openid); // 把 getUserinfo(access_token, openid) 赋值给 userinfo

        // 保存用户信息到数据库 // 保留原作者写的行内注释
        XcUser xcUser = currentPorxy.addWxUser(userinfo); // 把 currentPorxy.addWxUser(userinfo) 赋值给 xcUser


        return xcUser; // 返回 xcUser
    } // 代码块结束
    // 保存用户信息 // 保留原作者写的行内注释
    @Transactional // 使用注解 @Transactional
    public XcUser addWxUser(Map<String,String> userInfo_map){ // 定义方法 addWxUser(...)
        String unionid = userInfo_map.get("unionid"); // 把 userInfo_map.get("unionid") 赋值给 unionid
        String nickname = userInfo_map.get("nickname"); // 把 userInfo_map.get("nickname") 赋值给 nickname
        //根据unionid查询用户信息 // 保留原作者写的行内注释
        XcUser xcUser = xcUserMapper.selectOne(new LambdaQueryWrapper<XcUser>().eq(XcUser::getWxUnionid, unionid)); // 把 xcUserMapper.selectOne(new LambdaQueryWrapper<XcUser>().eq(XcUser::getWxUnionid, unionid)) 赋值给 xcUser
        if(xcUser !=null){ // 定义方法 方法(...)
            return xcUser; // 返回 xcUser
        } // 代码块结束
        //向数据库新增记录 // 保留原作者写的行内注释
        xcUser = new XcUser(); // 创建 XcUser 对象并赋值给 xcUser
        String userId= UUID.randomUUID().toString(); // 把 UUID.randomUUID().toString() 的返回值赋给 userId
        xcUser.setId(userId);//主键 // 执行语句
        xcUser.setUsername(unionid); // 执行语句
        xcUser.setPassword(unionid); // 执行语句
        xcUser.setWxUnionid(unionid); // 执行语句
        xcUser.setNickname(nickname); // 执行语句
        xcUser.setName(nickname); // 执行语句
        xcUser.setUtype("101001");//学生类型 // 执行语句
        xcUser.setStatus("1");//用户状态 // 执行语句
        xcUser.setCreateTime(LocalDateTime.now()); // 执行语句
        //插入 // 保留原作者写的行内注释
        int insert = xcUserMapper.insert(xcUser); // 把 xcUserMapper.insert(xcUser) 赋值给 insert

        //向用户角色关系表新增记录 // 保留原作者写的行内注释
        XcUserRole xcUserRole = new XcUserRole(); // 创建 XcUserRole 对象并赋值给 xcUserRole
        xcUserRole.setId(UUID.randomUUID().toString()); // 执行语句
        xcUserRole.setUserId(userId); // 执行语句
        xcUserRole.setRoleId("17");//学生角色 // 执行语句
        xcUserRole.setCreateTime(LocalDateTime.now()); // 执行语句
        xcUserRoleMapper.insert(xcUserRole); // 执行语句
        return xcUser; // 返回 xcUser

    } // 代码块结束

    /** // 保留原作者写的块注释
     * 携带授权码申请令牌 // 保留原作者写的块注释
     * https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code // 保留原作者写的块注释
     * // 保留原作者写的块注释
     * { // 保留原作者写的块注释
     * "access_token":"ACCESS_TOKEN", // 保留原作者写的块注释
     * "expires_in":7200, // 保留原作者写的块注释
     * "refresh_token":"REFRESH_TOKEN", // 保留原作者写的块注释
     * "openid":"OPENID", // 保留原作者写的块注释
     * "scope":"SCOPE", // 保留原作者写的块注释
     * "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL" // 保留原作者写的块注释
     * } // 保留原作者写的块注释
     * @param code 授权 // 保留原作者写的块注释
     * @return // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    private Map<String,String> getAccess_token(String code){ // 定义方法 getAccess_token(...)

        String url_template = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code"; // 代码逻辑
        //最终的请求路径 // 保留原作者写的行内注释
        String url = String.format(url_template, appid, secret, code); // 把 String.format(url_template, appid, secret, code) 赋值给 url

        //远程调用此url // 保留原作者写的行内注释
        ResponseEntity<String> exchange = restTemplate.exchange(url, HttpMethod.POST, null, String.class); // 把 restTemplate.exchange(url, HttpMethod.POST, null, String.class) 赋值给 exchange
        //获取响应的结果 // 保留原作者写的行内注释
        String result = exchange.getBody(); // 把 exchange.getBody() 的返回值赋给 result
        //将result转成map // 保留原作者写的行内注释
        Map<String,String> map = JSON.parseObject(result, Map.class); // 把 JSON.parseObject(result, Map.class) 赋值给 map
        return map; // 返回 map


    } // 代码块结束

    /** // 保留原作者写的块注释
     * 携带令牌查询用户信息 // 保留原作者写的块注释
     * // 保留原作者写的块注释
     * https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID // 保留原作者写的块注释
     * // 保留原作者写的块注释
     * { // 保留原作者写的块注释
     * "openid":"OPENID", // 保留原作者写的块注释
     * "nickname":"NICKNAME", // 保留原作者写的块注释
     * "sex":1, // 保留原作者写的块注释
     * "province":"PROVINCE", // 保留原作者写的块注释
     * "city":"CITY", // 保留原作者写的块注释
     * "country":"COUNTRY", // 保留原作者写的块注释
     * "headimgurl": "https://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0", // 保留原作者写的块注释
     * "privilege":[ // 保留原作者写的块注释
     * "PRIVILEGE1", // 保留原作者写的块注释
     * "PRIVILEGE2" // 保留原作者写的块注释
     * ], // 保留原作者写的块注释
     * "unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL" // 保留原作者写的块注释
     * // 保留原作者写的块注释
     * } // 保留原作者写的块注释
     * @param access_token // 保留原作者写的块注释
     * @param openid // 保留原作者写的块注释
     * @return // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    private Map<String,String> getUserinfo(String access_token,String openid){ // 定义方法 getUserinfo(...)

        String url_template = "https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s"; // 代码逻辑
        String url = String.format(url_template, access_token, openid); // 把 String.format(url_template, access_token, openid) 赋值给 url

        ResponseEntity<String> exchange = restTemplate.exchange(url, HttpMethod.GET, null, String.class); // 把 restTemplate.exchange(url, HttpMethod.GET, null, String.class) 赋值给 exchange

        //获取响应的结果 // 保留原作者写的行内注释
        String result = new String(exchange.getBody().getBytes(StandardCharsets.ISO_8859_1),StandardCharsets.UTF_8); // 创建 String 对象并赋值给 result
        //将result转成map // 保留原作者写的行内注释
        Map<String,String> map = JSON.parseObject(result, Map.class); // 把 JSON.parseObject(result, Map.class) 赋值给 map
        return map; // 返回 map

    } // 代码块结束
} // 代码块结束

文件:xuecheng-plus-auth/src/main/java/com/xuecheng/ucenter/service/WxAuthService.java

package com.xuecheng.ucenter.service; // 声明类所在的包路径

import com.xuecheng.ucenter.model.po.XcUser; // 导入 XcUser 类

/** // 保留原作者写的块注释
 * @author Mr.M // 保留原作者写的块注释
 * @version 1.0 // 保留原作者写的块注释
 * @description 微信扫码接入 // 保留原作者写的块注释
 * @date 2023/2/24 15:42 // 保留原作者写的块注释
 */ // 保留原作者写的块注释
public interface WxAuthService { // 定义 interface WxAuthService

 /** // 保留原作者写的块注释
  *  微信扫码认证,申请令牌,携带令牌查询用户信息、保存用户信息到数据库 // 保留原作者写的块注释
  * @param code 授权码 // 保留原作者写的块注释
  * @return // 保留原作者写的块注释
  */ // 保留原作者写的块注释
 public XcUser wxAuth(String code); // 执行语句
} // 代码块结束

文件:xuecheng-plus-auth/src/main/resources/bootstrap.yml

spring:
  application:
    name: auth-service
  cloud:
    nacos:
      server-addr: 192.168.101.65:8848
      discovery:
        namespace: dev402
        group: xuecheng-plus-project
      config:
        namespace: dev402
        group: xuecheng-plus-project
        file-extension: yaml
        refresh-enabled: true
        shared-configs:
          - data-id: swagger-${spring.profiles.active}.yaml
            group: xuecheng-plus-common
            refresh: true
          - data-id: logging-${spring.profiles.active}.yaml
            group: xuecheng-plus-common
            refresh: true
          - data-id: feign-${spring.profiles.active}.yaml
            group: xuecheng-plus-common
            refresh: true

  profiles:
    active: dev


文件:xuecheng-plus-auth/src/main/resources/log4j2-dev.xml

<?xml version="1.0" encoding="UTF-8"?> <!-- XML 声明 -->
<Configuration monitorInterval="180" packages=""> <!-- SQL 语句片段 -->
    <properties> <!-- SQL 语句片段 -->
        <property name="logdir">logs</property> <!-- SQL 语句片段 -->
        <property name="PATTERN">%date{YYYY-MM-dd HH:mm:ss,SSS} %level [%thread][%file:%line] - %msg%n%throwable</property> <!-- SQL 语句片段 -->
    </properties> <!-- SQL 语句片段 -->
    <Appenders> <!-- SQL 语句片段 -->
        <Console name="Console" target="SYSTEM_OUT"> <!-- SQL 语句片段 -->
            <PatternLayout pattern="${PATTERN}"/> <!-- SQL 语句片段 -->
        </Console> <!-- SQL 语句片段 -->

        <RollingFile name="ErrorAppender" fileName="${logdir}/error.log" <!-- SQL 语句片段 -->
            filePattern="${logdir}/$${date:yyyy-MM-dd}/error.%d{yyyy-MM-dd-HH}.log" append="true"> <!-- SQL 语句片段 -->
            <PatternLayout pattern="${PATTERN}"/> <!-- SQL 语句片段 -->
            <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/> <!-- SQL 语句片段 -->
            <Policies> <!-- SQL 语句片段 -->
                <TimeBasedTriggeringPolicy interval="1" modulate="true" /> <!-- SQL 语句片段 -->
            </Policies> <!-- SQL 语句片段 -->
        </RollingFile> <!-- SQL 语句片段 -->

        <RollingFile name="DebugAppender" fileName="${logdir}/info.log" <!-- SQL 语句片段 -->
            filePattern="${logdir}/$${date:yyyy-MM-dd}/info.%d{yyyy-MM-dd-HH}.log" append="true"> <!-- SQL 语句片段 -->
            <PatternLayout pattern="${PATTERN}"/> <!-- SQL 语句片段 -->
            <ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/> <!-- SQL 语句片段 -->
            <Policies> <!-- SQL 语句片段 -->
                <TimeBasedTriggeringPolicy interval="1" modulate="true" /> <!-- SQL 语句片段 -->
            </Policies> <!-- SQL 语句片段 -->
        </RollingFile> <!-- SQL 语句片段 -->
        
        <!--异步appender-->
         <Async name="AsyncAppender" includeLocation="true"> <!-- SQL 语句片段 -->
            <AppenderRef ref="ErrorAppender"/> <!-- SQL 语句片段 -->
            <AppenderRef ref="DebugAppender"/> <!-- SQL 语句片段 -->
        </Async> <!-- SQL 语句片段 -->
    </Appenders> <!-- SQL 语句片段 -->
    
    <Loggers> <!-- SQL 语句片段 -->
         <!--过滤掉spring和mybatis的一些无用的debug信息-->
        <logger name="org.springframework" level="INFO"> <!-- SQL 语句片段 -->
        </logger> <!-- SQL 语句片段 -->
        <logger name="org.mybatis" level="INFO"> <!-- SQL 语句片段 -->
        </logger> <!-- SQL 语句片段 -->
        <logger name="cn.itcast.wanxinp2p.consumer.mapper" level="DEBUG"> <!-- SQL 语句片段 -->
        </logger> <!-- SQL 语句片段 -->

        <logger name="springfox" level="INFO"> <!-- SQL 语句片段 -->
        </logger> <!-- SQL 语句片段 -->
		<logger name="org.apache.http" level="INFO"> <!-- SQL 语句片段 -->
        </logger> <!-- SQL 语句片段 -->
        <logger name="com.netflix.discovery" level="INFO"> <!-- SQL 语句片段 -->
        </logger> <!-- SQL 语句片段 -->
        
        <logger name="RocketmqCommon"  level="INFO" > <!-- SQL 语句片段 -->
		</logger> <!-- SQL 语句片段 -->
		
		<logger name="RocketmqRemoting" level="INFO"  > <!-- SQL 语句片段 -->
		</logger> <!-- SQL 语句片段 -->
		
		<logger name="RocketmqClient" level="WARN"> <!-- SQL 语句片段 -->
		</logger> <!-- SQL 语句片段 -->

        <logger name="org.dromara.hmily" level="WARN"> <!-- SQL 语句片段 -->
        </logger> <!-- SQL 语句片段 -->

        <logger name="org.dromara.hmily.lottery" level="WARN"> <!-- SQL 语句片段 -->
        </logger> <!-- SQL 语句片段 -->

        <logger name="org.dromara.hmily.bonuspoint" level="WARN"> <!-- SQL 语句片段 -->
        </logger> <!-- SQL 语句片段 -->
		
        <!--OFF   0-->
        <!--FATAL   100-->
        <!--ERROR   200-->
        <!--WARN   300-->
        <!--INFO   400-->
        <!--DEBUG   500-->
        <!--TRACE   600-->
        <!--ALL   Integer.MAX_VALUE-->
        <Root level="DEBUG" includeLocation="true"> <!-- SQL 语句片段 -->
            <AppenderRef ref="AsyncAppender"/> <!-- SQL 语句片段 -->
            <AppenderRef ref="Console"/> <!-- SQL 语句片段 -->
            <AppenderRef ref="DebugAppender"/> <!-- SQL 语句片段 -->
        </Root> <!-- SQL 语句片段 -->
    </Loggers> <!-- SQL 语句片段 -->
</Configuration> <!-- SQL 语句片段 -->
appendix_C
https://clxhxhhr.top/posts/4370/
作者
clxstart
发布于
2026-09-26
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。