zhuo
2025-03-13 fe7fa03c8f6047fe32c8477c0d3548d8f30e151d
Merge branch 'dev' into dev_dz
已修改4个文件
已添加3个文件
319 ■■■■■ 文件已修改
basic-server/src/main/java/com/ruoyi/basic/service/impl/LaboratoryServiceImpl.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/application.yml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/config/SsoBean.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/model/SsoOauthTokenModel.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/model/SsoUserInfoModel.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java 163 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
basic-server/src/main/java/com/ruoyi/basic/service/impl/LaboratoryServiceImpl.java
@@ -1,14 +1,19 @@
package com.ruoyi.basic.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.basic.mapper.StructureTestObjectMapper;
import com.ruoyi.basic.pojo.StructureTestObject;
import com.ruoyi.common.utils.QueryWrappers;
import com.ruoyi.basic.mapper.LaboratoryMapper;
import com.ruoyi.basic.pojo.Laboratory;
import com.ruoyi.basic.service.LaboratoryService;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@@ -23,6 +28,9 @@
    private LaboratoryMapper laboratoryMapper;
    @Autowired
    private StructureTestObjectMapper structureTestObjectMapper;
    @Override
    public IPage<Laboratory> selectItemParameter(Page page, Laboratory itemParameter) {
        return laboratoryMapper.selectItemParameter(page, QueryWrappers.queryWrappers(itemParameter));
@@ -35,6 +43,13 @@
    @Override
    public int delParameter(Integer id) {
        // åˆ¤æ–­æ˜¯å¦ç»‘定对象
        QueryWrapper<StructureTestObject> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("laboratory_id",id);
        List<StructureTestObject> structureTestObjectList = structureTestObjectMapper.selectList(queryWrapper);
        if(!CollectionUtils.isEmpty(structureTestObjectList)){
            throw new RuntimeException("已绑定对象,禁止删除");
        }
        return laboratoryMapper.deleteById(id);
    }
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java
@@ -2,6 +2,10 @@
import java.util.List;
import java.util.Set;
import java.util.UUID;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.config.SsoBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@@ -38,6 +42,9 @@
    @Autowired
    private TokenService tokenService;
    @Autowired
    private SsoBean ssoBean;
    /**
     * ç™»å½•方法
@@ -94,4 +101,33 @@
        List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId);
        return AjaxResult.success(menuService.buildMenus(menus));
    }
    /**
     * èŽ·å–ç»Ÿä¸€ç™»å½•å¹³å°èŽ·å–CODE地址
     *
     * @return
     */
    @Anonymous
    @GetMapping("/getSsoAuthUrl")
    public AjaxResult getSsoAuthUrl() {
        String uuid = UUID.randomUUID().toString();
        return AjaxResult.success(ssoBean.getUrl() + "/oauth2/auth?response_type=code&scope=openid&client_id=" + ssoBean.getClientId() + "&redirect_uri=" + ssoBean.getCallbackUrl() + "&state=" + uuid);
    }
    /**
     * å•点登录
     *
     * @param code ç™»å½•信息
     * @return ç»“æžœ
     */
    @PostMapping("/loginBySSO")
    public AjaxResult loginBySSO(String code)
    {
        AjaxResult ajax = AjaxResult.success();
        // ç”Ÿæˆä»¤ç‰Œ
        String token = loginService.loginBySSO(code);
        ajax.put(Constants.TOKEN, token);
        return ajax;
    }
}
ruoyi-admin/src/main/resources/application.yml
@@ -95,4 +95,11 @@
  # åŒ¹é…é“¾æŽ¥
  urlPatterns: /system/*,/monitor/*,/tool/*
#集团统一登录测试库
sso:
  url:
  clientId:
  clientSecret:
  callbackUrl:
ruoyi-common/src/main/java/com/ruoyi/common/config/SsoBean.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,38 @@
package com.ruoyi.common.config;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
/**
 * zhuo
 */
@Configuration
@Component
@ConfigurationProperties(prefix = "sso")
@Data
public class SsoBean {
    /**
     * å•点登录应用id
     */
    private String clientId;
    /**
     * å•点登录应用秘钥
     */
    private String clientSecret;
    /**
     * å•点登录服务地址
     */
    private String url;
    /**
     * å•点登录回调地址
     */
    private String callbackUrl;
}
ruoyi-framework/src/main/java/com/ruoyi/framework/model/SsoOauthTokenModel.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
package com.ruoyi.framework.model;
import lombok.Data;
/**
 * zhuo
 */
@Data
public class SsoOauthTokenModel {
    private String access_token;
    private String expires_in;
    private String id_token;
    private String scope;
    private String token_type;
}
ruoyi-framework/src/main/java/com/ruoyi/framework/model/SsoUserInfoModel.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,40 @@
package com.ruoyi.framework.model;
import com.alibaba.fastjson2.annotation.JSONField;
import lombok.Data;
/**
 * zhuo
 */
@Data
public class SsoUserInfoModel {
    private String avatar;
    @JSONField(name="nick_name")
    private String nickName;
    private String openid;
    @JSONField(name="org_id")
    private String orgId;
    @JSONField(name="org_name")
    private String orgName;
    @JSONField(name="org_role")
    private String orgRole;
    @JSONField(name="phone_number")
    private String phoneNumber;
    private String sid;
    private String sub;
    @JSONField(name="employee_id")
    private String employeeId;
    @JSONField(name="department_code")
    private String departmentCode;
}
ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java
@@ -1,6 +1,28 @@
package com.ruoyi.framework.web.service;
import javax.annotation.Resource;
import javax.net.ssl.SSLContext;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.PropertyNamingStrategy;
import com.alibaba.fastjson.parser.ParserConfig;
import com.ruoyi.common.config.SsoBean;
import com.ruoyi.framework.model.SsoOauthTokenModel;
import com.ruoyi.framework.model.SsoUserInfoModel;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
@@ -29,12 +51,23 @@
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysUserService;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
 * ç™»å½•校验方法
 *
 *
 * @author ruoyi
 */
@Component
@Slf4j
public class SysLoginService
{
    @Autowired
@@ -45,16 +78,19 @@
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private ISysUserService userService;
    @Autowired
    private ISysConfigService configService;
    @Autowired
    private SsoBean ssoBean;
    /**
     * ç™»å½•验证
     *
     *
     * @param username ç”¨æˆ·å
     * @param password å¯†ç 
     * @param code éªŒè¯ç 
@@ -102,7 +138,7 @@
    /**
     * æ ¡éªŒéªŒè¯ç 
     *
     *
     * @param username ç”¨æˆ·å
     * @param code éªŒè¯ç 
     * @param uuid å”¯ä¸€æ ‡è¯†
@@ -178,4 +214,123 @@
        sysUser.setLoginDate(DateUtils.getNowDate());
        userService.updateUserProfile(sysUser);
    }
    /**
     * å•点登录
     * @param code
     * @return
     */
    public String loginBySSO(String code) {
        // èŽ·å–å•ç‚¹ç™»å½•token
        SsoOauthTokenModel tokenModel = this.getSsoAccessToken(code);
        if (tokenModel == null) {
            return null;
        }
        // èŽ·å–å•ç‚¹ç™»å½•ç”¨æˆ·ä¿¡æ¯
        SsoUserInfoModel userInfo = this.getSsoUserInfo(tokenModel.getAccess_token());
        if (userInfo == null) {
            return null;
        }
        // æŸ¥è¯¢æœ¬åœ°ç”¨æˆ·ä¿¡æ¯
        // ç”Ÿæˆtoken
        return tokenService.createToken(null);
    }
    /**
     * **** èŽ·å–å•ç‚¹ç™»å½•token ****
     * @param code
     * @return
     */
    public SsoOauthTokenModel getSsoAccessToken(String code) {
        List<NameValuePair> list = new LinkedList<>();
        list.add(new BasicNameValuePair("grant_type", "authorization_code"));
        list.add(new BasicNameValuePair("code", code));
        list.add(new BasicNameValuePair("client_id", ssoBean.getClientId()));
        list.add(new BasicNameValuePair("client_secret", ssoBean.getClientSecret()));
        list.add(new BasicNameValuePair("redirect_uri", ssoBean.getCallbackUrl()));
        Map<String, String> headers = new HashMap<>();
        headers.put("Content-Type", "application/x-www-form-urlencoded");
        headers.put("Accept", "application/json");
        String result = doPost(ssoBean.getUrl() + "/oauth2/token", headers, list);
        if (org.apache.commons.lang3.StringUtils.isBlank(result)) {
            return null;
        }
        return JSON.parseObject(result, SsoOauthTokenModel.class);
    }
    /**
     * ***获取单点登录用户信息***
     * @param accessToken
     * @return
     */
    public SsoUserInfoModel getSsoUserInfo(String accessToken) {
        Map<String, String> headers = new HashMap<>();
        headers.put("Authorization", "Bearer " + accessToken);
        String result = doPost(ssoBean.getUrl() + "/userinfo", headers, null);
        if (org.apache.commons.lang3.StringUtils.isBlank(result)) {
            return null;
        }
        return JSON.parseObject(result, SsoUserInfoModel.class);
    }
    public static String doPost(String url, Map<String, String> headers, List<NameValuePair> params) {
        CloseableHttpClient client = createSSLClientDefault();
        CloseableHttpResponse response = null;
        try {
            HttpPost method = new HttpPost(url);
            headers.forEach(method::setHeader);
            if (params != null) {
                method.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
            }
            response = client.execute(method);
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                HttpEntity entity = response.getEntity();
                return EntityUtils.toString(entity);
            }
        } catch (Exception e) {
            log.error("统一登录请求出现异常", e.getMessage());
        } finally {
            try {
                if (client != null) {
                    client.close();
                }
                if (response != null) {
                    response.close();
                }
            } catch (Exception e) {
                log.error("统一登录请求出现异常", e.getMessage());
            }
        }
        return null;
    }
    private static CloseableHttpClient createSSLClientDefault() {
        try {
            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
                //信任所有
                @Override
                public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                    return true;
                }
            }).build();
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);
            return HttpClients.custom().setSSLSocketFactory(sslsf).build();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        }
        return HttpClients.createDefault();
    }
}