zhanglin8526
2023-05-04 daf1d5e645ba76343f048044405fa08a1573d77a
1、企业微信授权登录
2、调整授权中心接口文档
17个文件已修改
8个文件已添加
1197 ■■■■■ 已修改文件
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/RemoteMemberService.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/RemoteUserService.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/RemoteMemberFallbackFactory.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/RemoteUserFallbackFactory.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/model/OauthUrlVo.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/model/OauthUserVo.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/model/QwH5LoginVo.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/model/QwUserDetailDto.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-auth/pom.xml 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-auth/src/main/java/com/ruoyi/auth/RuoYiAuthApplication.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-auth/src/main/java/com/ruoyi/auth/config/QywxInnerConfig.java 442 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-auth/src/main/java/com/ruoyi/auth/controller/QwH5Controller.java 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-auth/src/main/java/com/ruoyi/auth/service/QywxInnerService.java 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-auth/src/main/java/com/ruoyi/auth/service/SysLoginService.java 44 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-auth/src/main/java/com/ruoyi/auth/utils/RestUtils.java 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-auth/src/main/resources/bootstrap.yml 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/SwaggerProvider.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-job/pom.xml 25 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-member/src/main/java/com/ruoyi/member/service/member/MemberService.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/sys/SysUserController.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/sys/SysUserMapper.java 32 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/sys/SysUserServiceImpl.java 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/sys/ISysUserService.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/RemoteMemberService.java
@@ -7,6 +7,7 @@
import com.ruoyi.system.api.factory.RemoteUserFallbackFactory;
import com.ruoyi.system.api.model.AppMiniLoginDto;
import com.ruoyi.system.api.model.AppMiniLoginVo;
import com.ruoyi.system.api.model.QwUserDetailDto;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/RemoteUserService.java
@@ -2,8 +2,7 @@
import com.ruoyi.system.api.domain.dto.AppEditUserDto;
import com.ruoyi.system.api.domain.poji.config.SysTag;
import com.ruoyi.system.api.model.AppMiniLoginDto;
import com.ruoyi.system.api.model.AppMiniLoginVo;
import com.ruoyi.system.api.model.*;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@@ -15,11 +14,10 @@
import com.ruoyi.common.core.domain.R;
import com.ruoyi.system.api.domain.poji.sys.SysUser;
import com.ruoyi.system.api.factory.RemoteUserFallbackFactory;
import com.ruoyi.system.api.model.LoginUser;
/**
 * 用户服务
 *
 *
 * @author jqs
 */
@FeignClient(contextId = "remoteUserService", value = ServiceNameConstants.SYSTEM_SERVICE, fallbackFactory = RemoteUserFallbackFactory.class)
@@ -46,6 +44,13 @@
    public R<Boolean> registerUserInfo(@RequestBody SysUser sysUser, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
    /**
     * 企业微信H5登录
     * @param qwUserDetail
     * @return
     */
    @PostMapping("/user/qwH5Login")
    public R<QwH5LoginVo> qwH5Login(@RequestBody QwUserDetailDto qwUserDetail);
    /**
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/RemoteMemberFallbackFactory.java
@@ -10,6 +10,7 @@
import com.ruoyi.system.api.model.AppMiniLoginDto;
import com.ruoyi.system.api.model.AppMiniLoginVo;
import com.ruoyi.system.api.model.LoginUser;
import com.ruoyi.system.api.model.QwUserDetailDto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.openfeign.FallbackFactory;
@@ -20,7 +21,7 @@
/**
 * 会员服务
 *
 *
 * @author jqs
 */
@Component
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/RemoteUserFallbackFactory.java
@@ -2,8 +2,7 @@
import com.ruoyi.system.api.domain.dto.AppEditUserDto;
import com.ruoyi.system.api.domain.poji.config.SysTag;
import com.ruoyi.system.api.model.AppMiniLoginDto;
import com.ruoyi.system.api.model.AppMiniLoginVo;
import com.ruoyi.system.api.model.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.openfeign.FallbackFactory;
@@ -11,11 +10,10 @@
import com.ruoyi.common.core.domain.R;
import com.ruoyi.system.api.RemoteUserService;
import com.ruoyi.system.api.domain.poji.sys.SysUser;
import com.ruoyi.system.api.model.LoginUser;
/**
 * 用户服务
 *
 *
 * @author jqs
 */
@Component
@@ -42,6 +40,11 @@
            }
            @Override
            public R<QwH5LoginVo> qwH5Login(QwUserDetailDto qwUserDetail) {
                return R.fail("用户登录:" + throwable.getMessage());
            }
            @Override
            public R<SysUser> getSysUser(Long userId) {
                return R.fail("获取用户失败:" + throwable.getMessage());
            }
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/model/OauthUrlVo.java
New file
@@ -0,0 +1,18 @@
package com.ruoyi.system.api.model;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class OauthUrlVo {
    @ApiModelProperty("企业微信网页授权链接")
    private String oauthUrl;
    public OauthUrlVo(String oauthUrl) {
        this.oauthUrl = oauthUrl;
    }
    public OauthUrlVo() {
    }
}
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/model/OauthUserVo.java
New file
@@ -0,0 +1,20 @@
package com.ruoyi.system.api.model;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class OauthUserVo {
    @ApiModelProperty("成员UserID")
    private String userid;
    @ApiModelProperty("手机")
    private String mobile;
    @ApiModelProperty("token凭证")
    private String accessToken;
    @ApiModelProperty("过期时间")
    private Long expiresIn;
}
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/model/QwH5LoginVo.java
New file
@@ -0,0 +1,18 @@
package com.ruoyi.system.api.model;
import com.ruoyi.system.api.domain.poji.sys.SysUser;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class QwH5LoginVo {
    @ApiModelProperty("成员UserID")
    private String userid;
    @ApiModelProperty("手机")
    private String mobile;
    @ApiModelProperty(value = "用户信息")
    private SysUser sysUser;
}
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/model/QwUserDetailDto.java
New file
@@ -0,0 +1,14 @@
package com.ruoyi.system.api.model;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class QwUserDetailDto {
    @ApiModelProperty("成员UserID")
    private String userid;
    @ApiModelProperty("手机")
    private String mobile;
}
ruoyi-auth/pom.xml
@@ -7,53 +7,66 @@
        <version>3.6.2</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>ruoyi-auth</artifactId>
    <description>
        ruoyi-auth认证授权中心
    </description>
    <dependencies>
        <!-- SpringCloud Alibaba Nacos -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!-- SpringCloud Alibaba Nacos Config -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        <!-- SpringCloud Alibaba Sentinel -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <!-- SpringBoot Web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- SpringBoot Actuator -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!-- RuoYi Common Security-->
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>ruoyi-common-security</artifactId>
        </dependency>
        <!-- Swagger UI -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>${swagger.fox.version}</version>
        </dependency>
        <!-- RuoYi Common Swagger -->
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>ruoyi-common-swagger</artifactId>
        </dependency>
    </dependencies>
    <build>
        <finalName>${project.artifactId}</finalName>
        <plugins>
@@ -70,5 +83,5 @@
            </plugin>
        </plugins>
    </build>
</project>
ruoyi-auth/src/main/java/com/ruoyi/auth/RuoYiAuthApplication.java
@@ -1,5 +1,7 @@
package com.ruoyi.auth;
import com.ruoyi.common.security.annotation.EnableCustomConfig;
import com.ruoyi.common.swagger.annotation.EnableCustomSwagger2;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
@@ -7,9 +9,11 @@
/**
 * 认证授权中心
 *
 *
 * @author jqs
 */
@EnableCustomConfig
@EnableCustomSwagger2
@EnableRyFeignClients
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class })
public class RuoYiAuthApplication
ruoyi-auth/src/main/java/com/ruoyi/auth/config/QywxInnerConfig.java
New file
@@ -0,0 +1,442 @@
package com.ruoyi.auth.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "qywx-inner")
public class QywxInnerConfig {
    private String corpId;
    private String agentId;
    private String agentSecret;
    private String authorizeState;
    private String token;
    private String encodingAESKey;
    public String getAuthorizeState() {
        return authorizeState;
    }
    public void setAuthorizeState(String authorizeState) {
        this.authorizeState = authorizeState;
    }
    public String getAgentId() {
        return agentId;
    }
    public void setAgentId(String agentId) {
        this.agentId = agentId;
    }
    public String getAgentSecret() {
        return agentSecret;
    }
    public void setAgentSecret(String agentSecret) {
        this.agentSecret = agentSecret;
    }
    private Integer authType;
    private String templateId;
    private String approvalFlowId;
    private String baseUrl = "https://qyapi.weixin.qq.com/cgi-bin/";
    //服务商相关
    private String serviceUrl = baseUrl+"service/";
    private String suiteTokenUrl = serviceUrl+"get_suite_token";
    private String permanentCodeUrl = serviceUrl+"get_permanent_code?suite_access_token=%s";
    //获取access_token
    //https://open.work.weixin.qq.com/api/doc/90000/90135/91039
    private String accessTokenUrl = baseUrl+"gettoken?corpid=%s&corpsecret=%s";
    //应用管理
    //https://open.work.weixin.qq.com/api/doc/90000/90135/90227
    private String agentGetUrl = baseUrl+"agent/get?access_token=%s&agentid=%s";
    private String agentSetUrl  = baseUrl + "agent/set?access_token=%s";
    private String AgentMenuCreateUrl  = baseUrl + "menu/create?access_token=%s&agentid=%s";
    private String AgentMenuGetUrl  = baseUrl + "menu/get?access_token=%s&agentid=%s";
    private String AgentMenuDeleteUrl  = baseUrl + "/menu/delete?access_token=%s&agentid=%s";
    //身份验证 扫码授权登录
    //https://open.work.weixin.qq.com/api/doc/90000/90135/91019
    private String ssoAuthUrl = "https://open.work.weixin.qq.com/wwopen/sso/qrConnect?appid=%s&agentid=%s&redirect_uri=%s&state=%s";
    //https://open.work.weixin.qq.com/api/doc/90000/90135/91437
    //与H5登录接口一样
    // private String ssoUserInfoUrl = baseUrl+"user/getuserinfo?access_token=%s&code=%s";
    private String ssoUserInfoUrl = baseUrl+"auth/getuserinfo?access_token=%s&code=%s";
    //公司相关
    //https://open.work.weixin.qq.com/api/doc/90000/90135/90208
    private String departmentUrl = baseUrl+"department/list?access_token=%s";
    //https://open.work.weixin.qq.com/api/doc/90000/90135/90200
    private String userSimplelistUrl = baseUrl+"user/simplelist?access_token=%s&department_id=%s&fetch_child=%s";
    //https://open.work.weixin.qq.com/api/doc/90000/90135/90201
    private String userDetailListUrl = baseUrl+"user/list?access_token=%s&department_id=%s&fetch_child=%s";
    //https://open.work.weixin.qq.com/api/doc/90000/90135/90196
    // 通过userid获取用户信息
    private String userDetailUrl = baseUrl+"user/get?access_token=%s&userid=%s";
    private String userDetailUrlAuth = baseUrl+ "/auth/getuserdetail?access_token=%s";
    //客户联系
    //获取配置了客户联系功能的成员列表 https://open.work.weixin.qq.com/api/doc/90000/90135/92571
    private String extContactFollowUserListUrl = baseUrl+"externalcontact/get_follow_user_list?access_token=%s";
    //获取客户列表 https://open.work.weixin.qq.com/api/doc/90000/90135/92113
    private String extContactListUrl = baseUrl+"externalcontact/list?access_token=%s&userid=%s";
    //获取客户详情 https://open.work.weixin.qq.com/api/doc/90000/90135/92114
    private String extContactDetailUrl = baseUrl+"/externalcontact/get?access_token=%s&external_userid=%s&cursor=%s";
    //获取客户群列表 https://open.work.weixin.qq.com/api/doc/90000/90135/92120
    private String extContactGroupchatListUrl = baseUrl+"externalcontact/groupchat/list?access_token=%s";
    //获取客户群详情 https://open.work.weixin.qq.com/api/doc/90000/90135/92122
    private String extContactGroupchatDetailUrl = baseUrl+"externalcontact/groupchat/get?access_token=%s";
    //添加新客户欢迎 https://open.work.weixin.qq.com/api/doc/90000/90135/92137
    private String extcontactSendWelcomeMsgUrl = baseUrl+"externalcontact/send_welcome_msg?access_token=%s";
    //创建企业群发 https://open.work.weixin.qq.com/api/doc/90000/90135/92135
    private String extcontactAddMsgTemplateUrl = baseUrl+"externalcontact/add_msg_template?access_token=%s";
    //消息推送
    //https://open.work.weixin.qq.com/api/doc/90000/90135/90236
    private String messageSendUrl= baseUrl+"message/send?access_token=%s";
    //素材管理
    //https://open.work.weixin.qq.com/api/doc/90000/90135/91054
    //type    是    媒体文件类型,分别有图片(image)、语音(voice)、视频(video),普通文件(file)
    private String mediaUploadUrl = baseUrl+"media/upload?access_token=%s&type=%s";
    private String mediaUploadimgUrl = baseUrl+"media/uploadimg?access_token=%s";
    private String mediaGetUrl = baseUrl+"media/get?access_token=%s&media_id=%s";
    private String mediaGetJssdkUrl = baseUrl+"media/get/jssdk?access_token=%s&media_id=%s";
    //审批
    //审批应用 https://work.weixin.qq.com/api/doc/90001/90143/91956
    private String oaCopyTemplateUrl ="oa/approval/copytemplate?access_token=%s";
    private String oaGetTemplateUrl ="/oa/gettemplatedetail?access_token=%s";
    private String oaApplyEventUrl = "oa/applyevent?access_token=%s";
    private String oaGetApprovalUrl ="oa/getapprovaldetail?access_token=%s";
    //审批流程引擎 https://work.weixin.qq.com/api/doc/90001/90143/93798
    private String openApprovalDataUrl = baseUrl+"corp/getopenapprovaldata?access_token=%s";
    // H5应用
    //scope    是    应用授权作用域。企业自建应用固定填写:snsapi_base
    // https://open.work.weixin.qq.com/api/doc/90000/90135/91020
    private String oauthUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=snsapi_privateinfo&agentid=%s&state=%s#wechat_redirect";
    //https://open.work.weixin.qq.com/api/doc/90000/90135/91023
    private String oauthUserUrl = baseUrl+"user/getuserinfo?access_token=%s&code=%s";
    //https://work.weixin.qq.com/api/doc/90000/90136/90506
    private String jsapiTicketUrl = baseUrl+"get_jsapi_ticket?access_token=%s";
    private String jsapiTicketAgentUrl = baseUrl+"ticket/get?access_token=%s&type=agent_config";
    //家校沟通
    //https://work.weixin.qq.com/api/doc/90000/90135/91638
    private String extContactMessageSendUrl = baseUrl+"externalcontact/message/send?access_token=%s";
    private String extContactSubscribeQrUrl =  baseUrl+"externalcontact/get_subscribe_qr_code?access_token=%s";
    //此oauth与H5oauth一致  https://work.weixin.qq.com/api/doc/90000/90135/91857
    private String schoolOauthUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s#wechat_redirect";
    //https://work.weixin.qq.com/api/doc/90000/90135/91707
    private String schoolOauthUserUrl = baseUrl+"user/getuserinfo?access_token=%s&code=%s";
    private String schoolUrl = baseUrl+"school/";
    //https://work.weixin.qq.com/api/doc/90000/90135/92337
    private String schoolUserGetUrl = schoolUrl+"user/get?access_token=%s&userid=%s";
    //https://work.weixin.qq.com/api/doc/90000/90135/92343
    private String schoolDepartmentListUrl = schoolUrl+"department/list?access_token=%s&id=%s";
    //https://work.weixin.qq.com/api/doc/90000/90135/92446
    private String schoolUserListUrl = schoolUrl+"user/list?access_token=%s&department_id=%s&fetch_child=%s";
    //效率工具
    private String calendarAddUrl = baseUrl+"oa/calendar/add?access_token=%s";
    private String calendarDetailUrl = baseUrl+"oa/calendar/get?access_token=%s";
    private String scheduleAddUrl = baseUrl+"oa/schedule/add?access_token=%s";
    private String scheduleListUrl = baseUrl+"oa/schedule/get_by_calendar?access_token=%s";
    private String scheduleDetailUrl = baseUrl+"oa/schedule/get?access_token=%s";
    private String meetingCreateUrl =  baseUrl+"meeting/create?access_token=%s";
    private String userMeetingListUrl = baseUrl+"meeting/get_user_meetingid?access_token=%s";
    private String meetingCancelUrl =  baseUrl+"meeting/cancel?access_token=%s";
    private String meetingDetailUrl = baseUrl+"meeting/get_info?access_token=%s";
    //小程序应用
    //小程序登录流程 https://work.weixin.qq.com/api/doc/90000/90136/92426
    //code2Session https://work.weixin.qq.com/api/doc/90000/90136/91507
    private String code2sessionUrl = baseUrl+"miniprogram/jscode2session?access_token=%s&js_code=%s&grant_type=authorization_code";
    public String getSuiteTokenUrl() {
        return suiteTokenUrl;
    }
    public String getPermanentCodeUrl() {
        return permanentCodeUrl;
    }
    public String getJsapiTicketUrl() {
        return jsapiTicketUrl;
    }
    public String getOauthUrl() {
        return oauthUrl;
    }
    public String getUserSimplelistUrl() {
        return userSimplelistUrl;
    }
    public String getAccessTokenUrl() {
        return accessTokenUrl;
    }
    public String getDepartmentUrl() {
        return departmentUrl;
    }
    public String getUserDetailListUrl() {
        return userDetailListUrl;
    }
    public String getCorpId() {
        return corpId;
    }
    public String getToken() {
        return token;
    }
    public String getEncodingAESKey() {
        return encodingAESKey;
    }
    public Integer getAuthType() {
        return authType;
    }
    public String getUserDetailUrl() {
        return userDetailUrl;
    }
    public String getUserDetailUrlAuth(){
        return userDetailUrlAuth;
    }
    public String getOauthUserUrl() {
        return oauthUserUrl;
    }
    public String getCode2sessionUrl() {
        return code2sessionUrl;
    }
    public void setCorpId(String corpId) {
        this.corpId = corpId;
    }
    public void setToken(String token) {
        this.token = token;
    }
    public void setEncodingAESKey(String encodingAESKey) {
        this.encodingAESKey = encodingAESKey;
    }
    public void setAuthType(Integer authType) {
        this.authType = authType;
    }
    public String getTemplateId() {
        return templateId;
    }
    public void setTemplateId(String templateId) {
        this.templateId = templateId;
    }
    public String getApprovalFlowId() {
        return approvalFlowId;
    }
    public void setApprovalFlowId(String approvalFlowId) {
        this.approvalFlowId = approvalFlowId;
    }
    public String getSsoAuthUrl() {
        return ssoAuthUrl;
    }
    public String getJsapiTicketAgentUrl() {
        return jsapiTicketAgentUrl;
    }
    public String getExtContactFollowUserListUrl() {
        return extContactFollowUserListUrl;
    }
    public String getExtContactListUrl() {
        return extContactListUrl;
    }
    public String getExtContactGroupchatListUrl() {
        return extContactGroupchatListUrl;
    }
    public String getMessageSendUrl() {
        return messageSendUrl;
    }
    public String getMediaUploadUrl() {
        return mediaUploadUrl;
    }
    public String getMediaUploadimgUrl() {
        return mediaUploadimgUrl;
    }
    public String getMediaGetUrl() {
        return mediaGetUrl;
    }
    public String getMediaGetJssdkUrl() {
        return mediaGetJssdkUrl;
    }
    public String getOaCopyTemplateUrl() {
        return oaCopyTemplateUrl;
    }
    public String getOaGetTemplateUrl() {
        return oaGetTemplateUrl;
    }
    public String getOaApplyEventUrl() {
        return oaApplyEventUrl;
    }
    public String getOaGetApprovalUrl() {
        return oaGetApprovalUrl;
    }
    public String getOpenApprovalDataUrl() {
        return openApprovalDataUrl;
    }
    public String getSchoolOauthUrl() {
        return schoolOauthUrl;
    }
    public String getSchoolOauthUserUrl() {
        return schoolOauthUserUrl;
    }
    public String getSchoolUserGetUrl() {
        return schoolUserGetUrl;
    }
    public String getSchoolDepartmentListUrl() {
        return schoolDepartmentListUrl;
    }
    public String getSchoolUserListUrl() {
        return schoolUserListUrl;
    }
    public String getExtContactMessageSendUrl() {
        return extContactMessageSendUrl;
    }
    public String getExtContactSubscribeQrUrl() {
        return extContactSubscribeQrUrl;
    }
    public String getSsoUserInfoUrl() {
        return ssoUserInfoUrl;
    }
    public String getAgentGetUrl() {
        return agentGetUrl;
    }
    public String getAgentSetUrl() {
        return agentSetUrl;
    }
    public String getAgentMenuCreateUrl() {
        return AgentMenuCreateUrl;
    }
    public String getAgentMenuGetUrl() {
        return AgentMenuGetUrl;
    }
    public String getAgentMenuDeleteUrl() {
        return AgentMenuDeleteUrl;
    }
    public String getExtContactDetailUrl() {
        return extContactDetailUrl;
    }
    public String getExtcontactSendWelcomeMsgUrl() {
        return extcontactSendWelcomeMsgUrl;
    }
    public String getExtContactGroupchatDetailUrl() {
        return extContactGroupchatDetailUrl;
    }
    public String getExtcontactAddMsgTemplateUrl() {
        return extcontactAddMsgTemplateUrl;
    }
    public String getCalendarAddUrl() {
        return calendarAddUrl;
    }
    public String getCalendarDetailUrl() {
        return calendarDetailUrl;
    }
    public String getScheduleAddUrl() {
        return scheduleAddUrl;
    }
    public String getScheduleListUrl() {
        return scheduleListUrl;
    }
    public String getScheduleDetailUrl() {
        return scheduleDetailUrl;
    }
    public String getMeetingCreateUrl() {
        return meetingCreateUrl;
    }
    public String getUserMeetingListUrl() {
        return userMeetingListUrl;
    }
    public String getMeetingCancelUrl() {
        return meetingCancelUrl;
    }
    public String getMeetingDetailUrl() {
        return meetingDetailUrl;
    }
}
ruoyi-auth/src/main/java/com/ruoyi/auth/controller/QwH5Controller.java
New file
@@ -0,0 +1,69 @@
package com.ruoyi.auth.controller;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.auth.service.QywxInnerService;
import com.ruoyi.auth.service.SysLoginService;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.security.service.TokenService;
import com.ruoyi.system.api.model.OauthUrlVo;
import com.ruoyi.system.api.model.OauthUserVo;
import com.ruoyi.system.api.model.QwH5LoginVo;
import com.ruoyi.system.api.model.QwUserDetailDto;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
/**
 * 企业微信H5应用专用
 */
@RestController
@Api(value = "企业微信授权信息获取", tags = "企业微信授权信息获取")
public class QwH5Controller {
    @Autowired
    private QywxInnerService qywxInnerService;
    @Autowired
    private SysLoginService sysLoginService;
    @Autowired
    private TokenService tokenService;
    /**
     * 构造网页授权链接
     * @param redirectUri
     * @return
     * @throws UnsupportedEncodingException
     */
    @GetMapping({"/h5/oauthUrl"})
    @ApiOperation("构造网页授权链接")
    public R<OauthUrlVo> oauthUrl(@ApiParam(value = "授权重定向地址", required = true) @RequestParam("redirectUri") String redirectUri) throws UnsupportedEncodingException {
        // 普通应用
        String oauthRedirectUrl =  URLEncoder.encode(redirectUri,"utf-8");
        String oauthUrl = qywxInnerService.getOauthUrl(oauthRedirectUrl);
        return R.ok(new OauthUrlVo(oauthUrl));
    }
    @GetMapping("/h5/oauthUser")
    @ApiOperation("通过code获取访问用户登录")
    public R<OauthUserVo> oauthUser(@ApiParam(value = "成员授权获取到的code", required = true) @RequestParam("code") String code) throws IOException {
        // 通过code获取访问用户敏感信息
        JSONObject result = qywxInnerService.getOauthUser(code);
        QwUserDetailDto qwUserDetail = JSONObject.parseObject(result.toJSONString(), QwUserDetailDto.class);
        // 1、查数据库获取人员
        QwH5LoginVo qwH5LoginVo = sysLoginService.qwH5Login(qwUserDetail);
        // 2、生成Token
       return R.ok(tokenService.createQwH5Token(qwH5LoginVo));
    }
}
ruoyi-auth/src/main/java/com/ruoyi/auth/service/QywxInnerService.java
New file
@@ -0,0 +1,99 @@
package com.ruoyi.auth.service;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.auth.config.QywxInnerConfig;
import com.ruoyi.auth.utils.RestUtils;
import com.ruoyi.common.core.constant.Constants;
import com.ruoyi.common.core.exception.ServiceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class QywxInnerService {
    private final static Logger logger = LoggerFactory.getLogger("QywxInnerService");
    @Autowired
    private QywxInnerConfig qywxInnerConfig;
    public String getAccessToken(){
        String corpId = qywxInnerConfig.getCorpId();
        String agentSecret = qywxInnerConfig.getAgentSecret();
        String  accessTokenUrl = String.format(qywxInnerConfig.getAccessTokenUrl(), corpId, agentSecret);
        JSONObject response = RestUtils.get(accessTokenUrl);
        // 获取错误日志
        if(response.containsKey(Constants.QY_WX_ERR_CODE) && response.getInteger(Constants.QY_WX_ERR_CODE) != 0){
            logger.error(response.toString());
            throw new ServiceException("获取企业微信ACCESS_TOKEN异常");
        }
        return response.getString(Constants.QY_WX_ACCESS_TOKEN);
    }
    //********************************** H5应用 Oauth   *************************//
    /**
     * 构造网页授权链接
     * @param oauthRedirectUrl
     * @return
     */
    public String getOauthUrl(String oauthRedirectUrl){
//        应用授权作用域。
//        snsapi_base:静默授权,可获取成员的基础信息(UserId与DeviceId);
//        snsapi_userinfo:静默授权,可获取成员的详细信息,但不包含手机、邮箱等敏感信息;
//        snsapi_privateinfo:手动授权,可获取成员的详细信息,包含手机、邮箱等敏感信息(已不再支持获取手机号/邮箱)。
        String corpId = qywxInnerConfig.getCorpId();
        String state = qywxInnerConfig.getAuthorizeState();
        String agentId = qywxInnerConfig.getAgentId();
        // 构造网页授权链接 redirect_uri
        return String.format(qywxInnerConfig.getOauthUrl(), corpId, oauthRedirectUrl, agentId, state);
    }
    /**
     * 获取访问用户身份
     * 获取访问用户敏感信息
     * @param code
     * @return
     */
    public JSONObject getOauthUser(String code) {
        String accessToken = getAccessToken();
        // 获取访问用户身份
        String getOauthUrl = String.format(qywxInnerConfig.getOauthUserUrl(), accessToken, code);
        JSONObject response = RestUtils.get(getOauthUrl);
        if(response.containsKey(Constants.QY_WX_ERR_CODE) && response.getInteger(Constants.QY_WX_ERR_CODE) != 0){
            logger.error(response.toString());
            throw new ServiceException("获取企业微信信息异常");
        }
        logger.info("----------------userinfo-------------");
        logger.info(response.toString());
        //获取通讯录用户详情get
        String userId = response.getString(Constants.QY_WX_USER_ID);
        // 成员票据,最大为512字节,有效期为1800s。 scope为snsapi_privateinfo,获取访问用户敏感信息
        String userTicket = response.getString(Constants.QY_WX_USER_TICKET);
        // 获取用户详情 包含部门信息
        // String url = String.format(qywxInnerConfig.getUserDetailUrl(),accessToken,userId);
        // 获取访问用户敏感信息
        String url = String.format(qywxInnerConfig.getUserDetailUrlAuth(), accessToken);
        JSONObject json = new JSONObject();
        json.put(Constants.QY_WX_USER_TICKET, userTicket);
        JSONObject detailResponse = RestUtils.post(url, json);
        //获取错误日志
        if(detailResponse.containsKey(Constants.QY_WX_ERR_CODE) && detailResponse.getInteger(Constants.QY_WX_ERR_CODE) != 0){
            logger.error(detailResponse.toString());
            throw new ServiceException("获取企业微信信息异常");
        }
        logger.info("----------------userinfo detail -------------");
        logger.info(detailResponse.toString());
        return detailResponse;
    }
}
ruoyi-auth/src/main/java/com/ruoyi/auth/service/SysLoginService.java
@@ -1,8 +1,7 @@
package com.ruoyi.auth.service;
import com.ruoyi.system.api.RemoteMemberService;
import com.ruoyi.system.api.model.AppMiniLoginDto;
import com.ruoyi.system.api.model.AppMiniLoginVo;
import com.ruoyi.system.api.model.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.ruoyi.common.core.constant.CacheConstants;
@@ -19,11 +18,10 @@
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.system.api.RemoteUserService;
import com.ruoyi.system.api.domain.poji.sys.SysUser;
import com.ruoyi.system.api.model.LoginUser;
/**
 * 登录校验方法
 *
 *
 * @author jqs
 */
@Component
@@ -89,7 +87,7 @@
        {
            throw new ServiceException(userResult.getMsg());
        }
        LoginUser userInfo = userResult.getData();
        SysUser user = userResult.getData().getSysUser();
        if (UserStatus.DELETED.getCode().equals(user.getDelFlag()))
@@ -142,6 +140,42 @@
        return userInfo;
    }
    /**
     * 企业微信H5登录
     */
    public QwH5LoginVo qwH5Login(QwUserDetailDto qwUserDetail)
    {
        // 查询用户信息
        R<QwH5LoginVo> userResult = remoteUserService.qwH5Login(qwUserDetail);
        if (R.FAIL == userResult.getCode())
        {
            throw new ServiceException(userResult.getMsg());
        }
        QwH5LoginVo userInfo = userResult.getData();
        SysUser user = userInfo.getSysUser();
        String username = user.getUserName();
        // IP黑名单校验
        String blackStr = Convert.toStr(redisService.getCacheObject(CacheConstants.SYS_LOGIN_BLACKIPLIST));
        if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr()))
        {
            recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "很遗憾,访问IP已被列入系统黑名单");
            throw new ServiceException("很遗憾,访问IP已被列入系统黑名单");
        }
        if (UserStatus.DELETED.getCode().equals(user.getDelFlag()))
        {
            recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "对不起,您的账号已被删除");
            throw new ServiceException("对不起,您的账号:" + username + " 已被删除");
        }
        if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
        {
            recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "用户已停用,请联系管理员");
            throw new ServiceException("对不起,您的账号:" + username + " 已停用");
        }
        recordLogService.recordLogininfor(username, Constants.LOGIN_SUCCESS, "登录成功");
        return userInfo;
    }
    public void logout(String loginName)
    {
        recordLogService.recordLogininfor(loginName, Constants.LOGOUT, "退出成功");
ruoyi-auth/src/main/java/com/ruoyi/auth/utils/RestUtils.java
New file
@@ -0,0 +1,104 @@
package com.ruoyi.auth.utils;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.system.api.model.QwUserDetailDto;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.*;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
import java.io.IOException;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Map;
import java.util.Objects;
@Configuration
public class RestUtils {
    private static final RestTemplate restTemplate = new RestTemplate();
    public static JSONObject get(String url, Map<String,String> urlParams){
        return get(urlToUri(url,urlParams));
    }
    //在处理企业微信某些参数时有问题
    public static JSONObject get(String url){
        return get(URI.create(url));
    }
    private static JSONObject get(URI uri){
        ResponseEntity<JSONObject> responseEntity =restTemplate.getForEntity(uri,JSONObject.class);
        serverIsRight(responseEntity);   // 判断服务器返回状态码
        return responseEntity.getBody();
    }
    public static JSONObject post(String url,Map<String,String> urlParams,JSONObject json){
        //组装url
        return post(urlToUri(url,urlParams),json);
    }
    public static JSONObject post(String url,JSONObject json){
        //组装urL
        return post(URI.create(url),json);
    }
    private static JSONObject post(URI uri,JSONObject json){
        //组装url
        //设置提交json格式数据
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<JSONObject> request = new HttpEntity(json, headers);
        ResponseEntity<JSONObject> responseEntity = restTemplate.postForEntity(uri,request,JSONObject.class);
        serverIsRight(responseEntity);  //判断服务器返回状态码
        return responseEntity.getBody();
    }
    private static URI urlToUri(String url,Map<String,String> urlParams){
        //设置提交json格式数据
        UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromHttpUrl(url);
        for(Map.Entry<String,String> entry : urlParams.entrySet())  {
            uriBuilder.queryParam((String)entry.getKey(),  (String) entry.getValue()) ;
        }
        return  uriBuilder.build(true).toUri();
    }
    public static JSONObject upload(String url,MultiValueMap formParams){
        //设置表单提交
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(formParams, headers);
        ResponseEntity<JSONObject> responseEntity = restTemplate.postForEntity(url,request,JSONObject.class);
        serverIsRight(responseEntity);  //判断服务器返回状态码
        return responseEntity.getBody();
    }
    public static String download(String url,String targetPath) throws IOException {
        ResponseEntity<byte[]> rsp = restTemplate.getForEntity(url, byte[].class);
        if(rsp.getStatusCode() != HttpStatus.OK){
            System.out.println("文件下载请求结果状态码:" + rsp.getStatusCode());
        }
        // 将下载下来的文件内容保存到本地
        Files.write(Paths.get(targetPath), Objects.requireNonNull(rsp.getBody()));
        return targetPath;
    }
    public static byte[] dowload(String url){
        ResponseEntity<byte[]> rsp = restTemplate.getForEntity(url, byte[].class);
        return rsp.getBody();
    }
    private static void serverIsRight(ResponseEntity responseEntity){
        if(responseEntity.getStatusCodeValue()==200){
//            System.out.println("服务器请求成功:{}"+responseEntity.getStatusCodeValue());
        }else {
            System.out.println("服务器请求异常:{}"+responseEntity.getStatusCodeValue());
        }
    }
}
ruoyi-auth/src/main/resources/bootstrap.yml
@@ -1,9 +1,9 @@
# Tomcat
server:
server:
  port: 8030
# Spring
spring:
spring:
  application:
    # 应用名称
    name: ruoyi-auth
@@ -23,3 +23,13 @@
        # 共享配置
        shared-configs:
          - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
#自建应用配置 非代开发不需要 具体自建应用配置大家写表里就行
qywx-inner:
  corpId: ww78cbcfad600119af
  agentId: 1000005
  agentSecret: 2xMP3DaamA4-zTu6KtsF_y83OSJRXK5UspB8hWKkXmI
  authorizeState: HONGRUITANG
  suiteSecret: ""
  token: ""
  encodingAESKey: ""
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java
@@ -2,7 +2,7 @@
/**
 * 通用常量信息
 *
 *
 * @author jqs
 */
public class Constants
@@ -113,6 +113,27 @@
    public static final long CAPTCHA_EXPIRATION = 2;
    /**
     * 企业微信返回码 返回码
     */
    public static final String QY_WX_ERR_CODE = "errcode";
    /**
     * 企业微信返回码 调用接口凭证
     */
    public static final String QY_WX_ACCESS_TOKEN = "access_token";
    /**
     * 成员UserID
     */
    public static final String QY_WX_USER_ID = "userid";
    /**
     * 成员UserID
     */
    public static final String QY_WX_USER_TICKET = "user_ticket";
    /**
     * 资源映射路径 前缀
     */
    public static final String RESOURCE_PREFIX = "/profile";
ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java
@@ -6,6 +6,8 @@
import javax.servlet.http.HttpServletRequest;
import com.ruoyi.system.api.model.AppMiniLoginVo;
import com.ruoyi.system.api.model.OauthUserVo;
import com.ruoyi.system.api.model.QwH5LoginVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.ruoyi.common.core.constant.CacheConstants;
@@ -21,7 +23,7 @@
/**
 * token验证处理
 *
 *
 * @author jqs
 */
@Component
@@ -55,7 +57,7 @@
        refreshToken(loginUser);
        // Jwt存储信息
        Map<String, Object> claimsMap = new HashMap<String, Object>();
        Map<String, Object> claimsMap = new HashMap<>();
        claimsMap.put(SecurityConstants.USER_KEY, token);
        claimsMap.put(SecurityConstants.DETAILS_USER_ID, userId);
        claimsMap.put(SecurityConstants.DETAILS_USERNAME, userName);
@@ -95,6 +97,37 @@
        rspMap.put("expires_in", expireTime);
        rspMap.put("mini_openid", appMiniLoginVo.getMiniOpenid());
        return rspMap;
    }
    /**
     * 创建小程序令牌
     */
    public OauthUserVo createQwH5Token(QwH5LoginVo qwH5LoginVo)
    {
        LoginUser loginUser = new LoginUser();
        loginUser.setSysUser(qwH5LoginVo.getSysUser());
        String token = IdUtils.fastUUID();
        Long userId = loginUser.getSysUser().getUserId();
        String userName = loginUser.getSysUser().getUserName();
        loginUser.setToken(token);
        loginUser.setUserid(userId);
        loginUser.setUsername(userName);
        loginUser.setIpaddr(IpUtils.getIpAddr());
        refreshToken(loginUser);
        // Jwt存储信息
        Map<String, Object> claimsMap = new HashMap<String, Object>();
        claimsMap.put(SecurityConstants.USER_KEY, token);
        claimsMap.put(SecurityConstants.DETAILS_USER_ID, userId);
        claimsMap.put(SecurityConstants.DETAILS_USERNAME, userName);
        // 接口返回信息
        OauthUserVo oauthUserVo = new OauthUserVo();
        oauthUserVo.setAccessToken(JwtUtils.createToken(claimsMap));
        oauthUserVo.setExpiresIn(expireTime);
        oauthUserVo.setUserid(qwH5LoginVo.getUserid());
        oauthUserVo.setMobile(qwH5LoginVo.getMobile());
        return oauthUserVo;
    }
    /**
@@ -198,4 +231,4 @@
    {
        return ACCESS_TOKEN + token;
    }
}
}
ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/SwaggerProvider.java
@@ -15,7 +15,7 @@
/**
 * 聚合系统接口
 *
 *
 * @author jqs
 */
@Component
@@ -38,7 +38,7 @@
    /**
     * 聚合其他服务接口
     *
     *
     * @return
     */
    @Override
@@ -53,7 +53,7 @@
                        .contains(routeDefinition.getId()))
                .forEach(routeDefinition -> routeDefinition.getPredicates().stream()
                        .filter(predicateDefinition -> "Path".equalsIgnoreCase(predicateDefinition.getName()))
                        .filter(predicateDefinition -> !"ruoyi-auth".equalsIgnoreCase(routeDefinition.getId()))
                        //.filter(predicateDefinition -> !"ruoyi-auth".equalsIgnoreCase(routeDefinition.getId()))
                        .forEach(predicateDefinition -> resourceList
                                .add(swaggerResource(routeDefinition.getId(), predicateDefinition.getArgs()
                                        .get(NameUtils.GENERATED_NAME_PREFIX + "0").replace("/**", SWAGGER2URL)))));
ruoyi-modules/ruoyi-job/pom.xml
@@ -16,38 +16,39 @@
    </description>
    <dependencies>
        <!-- SpringCloud Alibaba Nacos -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!-- SpringCloud Alibaba Nacos Config -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        <!-- SpringCloud Alibaba Sentinel -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <!-- SpringBoot Actuator -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!-- Swagger UI -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>${swagger.fox.version}</version>
        </dependency>
        <!-- Quartz -->
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
@@ -59,25 +60,25 @@
                </exclusion>
            </exclusions>
        </dependency>
        <!-- Mysql Connector -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!-- RuoYi Common Log -->
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>ruoyi-common-log</artifactId>
        </dependency>
        <!-- RuoYi Common Swagger -->
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>ruoyi-common-swagger</artifactId>
        </dependency>
    </dependencies>
    <build>
@@ -96,5 +97,5 @@
            </plugin>
        </plugins>
    </build>
</project>
</project>
ruoyi-modules/ruoyi-member/src/main/java/com/ruoyi/member/service/member/MemberService.java
@@ -33,6 +33,7 @@
     */
    AppMiniLoginVo getMemberByCode(AppMiniLoginDto appMiniLoginDto);
    /**
     * 获取授权信息
     * @param appUserAuthorizeDto
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/sys/SysUserController.java
@@ -1,6 +1,7 @@
package com.ruoyi.system.controller.sys;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.poi.ExcelUtil;
import com.ruoyi.common.core.web.controller.BaseController;
@@ -16,7 +17,10 @@
import com.ruoyi.system.api.domain.poji.sys.SysDept;
import com.ruoyi.system.api.domain.poji.sys.SysRole;
import com.ruoyi.system.api.domain.poji.sys.SysUser;
import com.ruoyi.system.api.model.AppMiniLoginVo;
import com.ruoyi.system.api.model.LoginUser;
import com.ruoyi.system.api.model.QwH5LoginVo;
import com.ruoyi.system.api.model.QwUserDetailDto;
import com.ruoyi.system.service.config.SysTagService;
import com.ruoyi.system.service.sys.*;
import org.apache.commons.lang3.ArrayUtils;
@@ -29,12 +33,13 @@
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
/**
 * 用户信息
 *
 *
 * @author jqs
 */
@RestController
@@ -145,8 +150,29 @@
    }
    /**
     * 企业微信H5登录
     * @param qwUserDetail
     * @return
     */
    @PostMapping("/qwH5Login")
    public R<QwH5LoginVo> qwH5Login(@RequestBody QwUserDetailDto qwUserDetail)
    {
        String mobile = qwUserDetail.getMobile();
        SysUser sysUser = userService.selectUserByPhoneNumber(mobile);
        Optional.ofNullable(sysUser).orElseThrow(() -> new ServiceException("登录失败,未查询到用户"));
        // 构造登录返回信息
        QwH5LoginVo qwH5LoginVo = new QwH5LoginVo();
        qwH5LoginVo.setUserid(qwUserDetail.getUserid());
        qwH5LoginVo.setMobile(qwUserDetail.getMobile());
        qwH5LoginVo.setSysUser(sysUser);
        return R.ok(qwH5LoginVo);
    }
    /**
     * 获取用户信息
     *
     *
     * @return 用户信息
     */
    @GetMapping("getInfo")
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/sys/SysUserMapper.java
@@ -1,19 +1,21 @@
package com.ruoyi.system.mapper.sys;
import java.util.List;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.system.domain.pojo.coupon.Coupon;
import org.apache.ibatis.annotations.Param;
import com.ruoyi.system.api.domain.poji.sys.SysUser;
/**
 * 用户表 数据层
 *
 *
 * @author jqs
 */
public interface SysUserMapper
{
public interface SysUserMapper extends BaseMapper<SysUser> {
    /**
     * 根据条件分页查询用户列表
     *
     *
     * @param sysUser 用户信息
     * @return 用户信息集合信息
     */
@@ -21,7 +23,7 @@
    /**
     * 根据条件分页查询已配用户角色列表
     *
     *
     * @param user 用户信息
     * @return 用户信息集合信息
     */
@@ -29,7 +31,7 @@
    /**
     * 根据条件分页查询未分配用户角色列表
     *
     *
     * @param user 用户信息
     * @return 用户信息集合信息
     */
@@ -37,7 +39,7 @@
    /**
     * 通过用户名查询用户
     *
     *
     * @param userName 用户名
     * @return 用户对象信息
     */
@@ -45,7 +47,7 @@
    /**
     * 通过用户ID查询用户
     *
     *
     * @param userId 用户ID
     * @return 用户对象信息
     */
@@ -53,7 +55,7 @@
    /**
     * 新增用户信息
     *
     *
     * @param user 用户信息
     * @return 结果
     */
@@ -61,7 +63,7 @@
    /**
     * 修改用户信息
     *
     *
     * @param user 用户信息
     * @return 结果
     */
@@ -69,7 +71,7 @@
    /**
     * 修改用户头像
     *
     *
     * @param userName 用户名
     * @param avatar 头像地址
     * @return 结果
@@ -78,7 +80,7 @@
    /**
     * 重置用户密码
     *
     *
     * @param userName 用户名
     * @param password 密码
     * @return 结果
@@ -87,7 +89,7 @@
    /**
     * 通过用户ID删除用户
     *
     *
     * @param userId 用户ID
     * @return 结果
     */
@@ -95,7 +97,7 @@
    /**
     * 批量删除用户信息
     *
     *
     * @param userIds 需要删除的用户ID
     * @return 结果
     */
@@ -103,7 +105,7 @@
    /**
     * 校验用户名称是否唯一
     *
     *
     * @param userName 用户名称
     * @return 结果
     */
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/sys/SysUserServiceImpl.java
@@ -6,8 +6,13 @@
import java.util.stream.Collectors;
import javax.validation.Validator;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.system.api.domain.dto.AppEditUserDto;
import com.ruoyi.system.api.domain.poji.member.Member;
import com.ruoyi.system.domain.pojo.coupon.Coupon;
import com.ruoyi.system.mapper.coupon.CouponMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -33,14 +38,15 @@
import com.ruoyi.system.mapper.sys.SysUserRoleMapper;
import com.ruoyi.system.service.sys.ISysConfigService;
import com.ruoyi.system.service.sys.ISysUserService;
import org.springframework.util.ObjectUtils;
/**
 * 用户 业务层处理
 *
 *
 * @author jqs
 */
@Service
public class SysUserServiceImpl implements ISysUserService
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser>  implements ISysUserService
{
    private static final Logger log = LoggerFactory.getLogger(SysUserServiceImpl.class);
@@ -67,7 +73,7 @@
    /**
     * 根据条件分页查询用户列表
     *
     *
     * @param user 用户信息
     * @return 用户信息集合信息
     */
@@ -78,9 +84,21 @@
        return userMapper.selectUserList(user);
    }
    @Override
    public SysUser selectUserByPhoneNumber(String phoneNumber) {
        SysUser sysUser = new SysUser();
        sysUser.setPhonenumber(phoneNumber);
        List<SysUser> userList = this.selectUserList(sysUser);
        SysUser queryUser = null;
        if(!userList.isEmpty()){
            queryUser = userList.get(0);
        }
        return queryUser;
    }
    /**
     * 根据条件分页查询已分配用户角色列表
     *
     *
     * @param user 用户信息
     * @return 用户信息集合信息
     */
@@ -93,7 +111,7 @@
    /**
     * 根据条件分页查询未分配用户角色列表
     *
     *
     * @param user 用户信息
     * @return 用户信息集合信息
     */
@@ -106,7 +124,7 @@
    /**
     * 通过用户名查询用户
     *
     *
     * @param userName 用户名
     * @return 用户对象信息
     */
@@ -118,7 +136,7 @@
    /**
     * 通过用户ID查询用户
     *
     *
     * @param userId 用户ID
     * @return 用户对象信息
     */
@@ -130,7 +148,7 @@
    /**
     * 查询用户所属角色组
     *
     *
     * @param userName 用户名
     * @return 结果
     */
@@ -147,7 +165,7 @@
    /**
     * 查询用户所属岗位组
     *
     *
     * @param userName 用户名
     * @return 结果
     */
@@ -164,7 +182,7 @@
    /**
     * 校验用户名称是否唯一
     *
     *
     * @param user 用户信息
     * @return 结果
     */
@@ -218,7 +236,7 @@
    /**
     * 校验用户是否允许操作
     *
     *
     * @param user 用户信息
     */
    @Override
@@ -232,7 +250,7 @@
    /**
     * 校验用户是否有数据权限
     *
     *
     * @param userId 用户id
     */
    @Override
@@ -252,7 +270,7 @@
    /**
     * 新增保存用户信息
     *
     *
     * @param user 用户信息
     * @return 结果
     */
@@ -271,7 +289,7 @@
    /**
     * 注册用户信息
     *
     *
     * @param user 用户信息
     * @return 结果
     */
@@ -283,7 +301,7 @@
    /**
     * 修改保存用户信息
     *
     *
     * @param user 用户信息
     * @return 结果
     */
@@ -305,7 +323,7 @@
    /**
     * 用户授权角色
     *
     *
     * @param userId 用户ID
     * @param roleIds 角色组
     */
@@ -319,7 +337,7 @@
    /**
     * 修改用户状态
     *
     *
     * @param user 用户信息
     * @return 结果
     */
@@ -331,7 +349,7 @@
    /**
     * 修改用户基本信息
     *
     *
     * @param user 用户信息
     * @return 结果
     */
@@ -343,7 +361,7 @@
    /**
     * 修改用户头像
     *
     *
     * @param userName 用户名
     * @param avatar 头像地址
     * @return 结果
@@ -356,7 +374,7 @@
    /**
     * 重置用户密码
     *
     *
     * @param user 用户信息
     * @return 结果
     */
@@ -368,7 +386,7 @@
    /**
     * 重置用户密码
     *
     *
     * @param userName 用户名
     * @param password 密码
     * @return 结果
@@ -381,7 +399,7 @@
    /**
     * 新增用户角色信息
     *
     *
     * @param user 用户对象
     */
    public void insertUserRole(SysUser user)
@@ -391,7 +409,7 @@
    /**
     * 新增用户岗位信息
     *
     *
     * @param user 用户对象
     */
    public void insertUserPost(SysUser user)
@@ -414,7 +432,7 @@
    /**
     * 新增用户角色信息
     *
     *
     * @param userId 用户ID
     * @param roleIds 角色组
     */
@@ -437,7 +455,7 @@
    /**
     * 通过用户ID删除用户
     *
     *
     * @param userId 用户ID
     * @return 结果
     */
@@ -454,7 +472,7 @@
    /**
     * 批量删除用户信息
     *
     *
     * @param userIds 需要删除的用户ID
     * @return 结果
     */
@@ -476,7 +494,7 @@
    /**
     * 导入用户数据
     *
     *
     * @param userList 用户数据列表
     * @param isUpdateSupport 是否更新支持,如果已存在,则进行更新数据
     * @param operName 操作用户
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/sys/ISysUserService.java
@@ -2,27 +2,35 @@
import java.util.List;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.system.api.domain.dto.AppEditUserDto;
import com.ruoyi.system.api.domain.poji.sys.SysUser;
import com.ruoyi.system.domain.pojo.coupon.Coupon;
/**
 * 用户 业务层
 *
 *
 * @author jqs
 */
public interface ISysUserService
public interface ISysUserService extends IService<SysUser>
{
    /**
     * 根据条件分页查询用户列表
     *
     *
     * @param user 用户信息
     * @return 用户信息集合信息
     */
    public List<SysUser> selectUserList(SysUser user);
    /**
     * 通过电话号码查询用户
     *
     */
    public SysUser selectUserByPhoneNumber(String phonenumber);
    /**
     * 根据条件分页查询已分配用户角色列表
     *
     *
     * @param user 用户信息
     * @return 用户信息集合信息
     */
@@ -30,7 +38,7 @@
    /**
     * 根据条件分页查询未分配用户角色列表
     *
     *
     * @param user 用户信息
     * @return 用户信息集合信息
     */
@@ -38,7 +46,7 @@
    /**
     * 通过用户名查询用户
     *
     *
     * @param userName 用户名
     * @return 用户对象信息
     */
@@ -46,7 +54,7 @@
    /**
     * 通过用户ID查询用户
     *
     *
     * @param userId 用户ID
     * @return 用户对象信息
     */
@@ -54,7 +62,7 @@
    /**
     * 根据用户ID查询用户所属角色组
     *
     *
     * @param userName 用户名
     * @return 结果
     */
@@ -62,7 +70,7 @@
    /**
     * 根据用户ID查询用户所属岗位组
     *
     *
     * @param userName 用户名
     * @return 结果
     */
@@ -70,7 +78,7 @@
    /**
     * 校验用户名称是否唯一
     *
     *
     * @param user 用户信息
     * @return 结果
     */
@@ -94,21 +102,21 @@
    /**
     * 校验用户是否允许操作
     *
     *
     * @param user 用户信息
     */
    public void checkUserAllowed(SysUser user);
    /**
     * 校验用户是否有数据权限
     *
     *
     * @param userId 用户id
     */
    public void checkUserDataScope(Long userId);
    /**
     * 新增用户信息
     *
     *
     * @param user 用户信息
     * @return 结果
     */
@@ -116,7 +124,7 @@
    /**
     * 注册用户信息
     *
     *
     * @param user 用户信息
     * @return 结果
     */
@@ -124,7 +132,7 @@
    /**
     * 修改用户信息
     *
     *
     * @param user 用户信息
     * @return 结果
     */
@@ -132,7 +140,7 @@
    /**
     * 用户授权角色
     *
     *
     * @param userId 用户ID
     * @param roleIds 角色组
     */
@@ -140,7 +148,7 @@
    /**
     * 修改用户状态
     *
     *
     * @param user 用户信息
     * @return 结果
     */
@@ -148,7 +156,7 @@
    /**
     * 修改用户基本信息
     *
     *
     * @param user 用户信息
     * @return 结果
     */
@@ -156,7 +164,7 @@
    /**
     * 修改用户头像
     *
     *
     * @param userName 用户名
     * @param avatar 头像地址
     * @return 结果
@@ -165,7 +173,7 @@
    /**
     * 重置用户密码
     *
     *
     * @param user 用户信息
     * @return 结果
     */
@@ -173,7 +181,7 @@
    /**
     * 重置用户密码
     *
     *
     * @param userName 用户名
     * @param password 密码
     * @return 结果
@@ -182,7 +190,7 @@
    /**
     * 通过用户ID删除用户
     *
     *
     * @param userId 用户ID
     * @return 结果
     */
@@ -190,7 +198,7 @@
    /**
     * 批量删除用户信息
     *
     *
     * @param userIds 需要删除的用户ID
     * @return 结果
     */
@@ -198,7 +206,7 @@
    /**
     * 导入用户数据
     *
     *
     * @param userList 用户数据列表
     * @param isUpdateSupport 是否更新支持,如果已存在,则进行更新数据
     * @param operName 操作用户