合并董潘祥冲突

This commit is contained in:
chy
2026-02-09 23:44:07 +08:00
parent c8b73763bb
commit da95ddf810
3 changed files with 287 additions and 22 deletions

View File

@@ -8,42 +8,29 @@ spring:
primary: master primary: master
datasource: datasource:
master: master:
<<<<<<< HEAD
# MYSQL数据库 主库,业务库 # MYSQL数据库 主库,业务库
url: jdbc:mysql://127.0.0.1:3306/demo?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&rewriteBatchedStatements=true # MySQL Connector/J 8.X 连接的示例 url: jdbc:mysql://127.0.0.1:3306/demo?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&rewriteBatchedStatements=true # MySQL Connector/J 8.X 连接的示例
=======
# MYSQL数据库 主库,业务库
url: jdbc:mysql://127.0.0.1:3306/gr_repoort001?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&rewriteBatchedStatements=true # MySQL Connector/J 8.X 连接的示例
>>>>>>> 20260204
username: root username: root
password: root password: qihua
lideeyunji: # 从库,框架库 lideeyunji: # 从库,框架库
<<<<<<< HEAD url: jdbc:mysql://10.9.0.16:3307/gr_repoort?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&lowerCaseTableNames=1 # MySQL Connector/J 8.X 连接的示例
url: jdbc:mysql://127.0.0.1:3306/demo?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
=======
url: jdbc:mysql://127.0.0.1:3306/gr_repoort001?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
>>>>>>> 20260204
username: root username: root
password: root password: qihua
slave: # 日志库单独 slave: # 日志库单独
lazy: true # 开启懒加载,保证启动速度 lazy: true # 开启懒加载,保证启动速度
<<<<<<< HEAD url: jdbc:mysql://10.9.0.16:3307/gr_repoort?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&lowerCaseTableNames=1 # MySQL Connector/J 8.X 连接的示例
url: jdbc:mysql://127.0.0.1:3306/demo?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
username: root username: root
password: root password: qihua
bidb: # 日志库单独 bidb: # 日志库单独
lazy: true # 开启懒加载,保证启动速度 lazy: true # 开启懒加载,保证启动速度
url: jdbc:mysql://127.0.0.1:3306/erp_bi_data?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例 url: jdbc:mysql://127.0.0.1:3306/erp_bi_data?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
=======
url: jdbc:mysql://127.0.0.1:3306/gr_repoort001?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
>>>>>>> 20260204
username: root username: root
password: root password: qihua
redis: redis:
host: 127.0.0.1 # 地址 host: 10.9.0.116 # 地址
port: 6379 # 端口 port: 6379 # 端口
database: 2 # 数据库索引 database: 2 # 数据库索引
password: lidee@123 # 密码,建议生产环境开启 password: 123456 # 密码,建议生产环境开启
--- #################### 地代码平台相关配置 #################### --- #################### 地代码平台相关配置 ####################

View File

@@ -0,0 +1,121 @@
package com.lideeyunji.service.system.entity;
import com.lideeyunji.tool.framework.common.enums.CommonStatusEnum;
import com.lideeyunji.tool.framework.mybatis.core.dataobject.BaseDO;
import com.lideeyunji.service.system.enums.OAuth2GrantTypeEnum;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.List;
/**
* OAuth2 客户端 DO
*
* @author 金灯剑客
*/
@TableName(value = "system_oauth2_client", autoResultMap = true)
@KeySequence("system_oauth2_client_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
public class OAuth2ClientDO extends BaseDO {
/**
* 编号,数据库自增
*
* 由于 SQL Server 在存储 String 主键有点问题,所以暂时使用 Long 类型
*/
@TableId
private Long id;
/**
* 客户端编号
*/
private String clientId;
/**
* 客户端密钥
*/
private String secret;
/**
* 应用名
*/
private String name;
/**
* 应用分类
*/
private String category;
/**
* 应用图标
*/
private String logo;
/**
* 应用描述
*/
private String description;
/**
* 状态
*
* 枚举 {@link CommonStatusEnum}
*/
private Integer status;
/**
* 访问令牌的有效期
*/
private Integer accessTokenValiditySeconds;
/**
* 刷新令牌的有效期
*/
private Integer refreshTokenValiditySeconds;
// /**
// * 可重定向的 URI 地址
// */
// @TableField(typeHandler = JacksonTypeHandler.class)
// private List<String> redirectUris;
private String redirectUris;
/**
* 授权类型(模式)
*
* 枚举 {@link OAuth2GrantTypeEnum}
*/
@TableField(typeHandler = JacksonTypeHandler.class)
private List<String> authorizedGrantTypes;
/**
* 授权范围
*/
@TableField(typeHandler = JacksonTypeHandler.class)
private List<String> scopes;
/**
* 自动授权的 Scope
*
* code 授权时,如果 scope 在这个范围内,则自动通过
*/
@TableField(typeHandler = JacksonTypeHandler.class)
private List<String> autoApproveScopes;
/**
* 权限
*/
@TableField(typeHandler = JacksonTypeHandler.class)
private List<String> authorities;
/**
* 资源
*/
@TableField(typeHandler = JacksonTypeHandler.class)
private List<String> resourceIds;
/**
* 回调URI地址
*/
private String callbackUris;
/**
* 附加信息JSON 格式
*/
private String additionalInformation;
}

View File

@@ -0,0 +1,157 @@
package com.lideeyunji.service.system.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.lideeyunji.tool.framework.common.enums.CommonStatusEnum;
import com.lideeyunji.tool.framework.common.pojo.PageResult;
import com.lideeyunji.tool.framework.common.util.object.BeanUtils;
import com.lideeyunji.tool.framework.common.util.string.StrUtils;
import com.lideeyunji.service.system.controller.vo.oauth2.client.OAuth2ClientPageReqVO;
import com.lideeyunji.service.system.controller.vo.oauth2.client.OAuth2ClientSaveReqVO;
import com.lideeyunji.service.system.entity.OAuth2ClientDO;
import com.lideeyunji.service.system.mapper.OAuth2ClientMapper;
import com.lideeyunji.service.system.config.redis.RedisKeyConstants;
import com.lideeyunji.service.system.service.IOAuth2ClientService;
import com.google.common.annotations.VisibleForTesting;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.util.Collection;
import static com.lideeyunji.tool.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.lideeyunji.service.system.constant.ErrorCodeConstants.*;
/**
* OAuth2.0 Client Service 实现类
*
* @author 金灯剑客
*/
@Service
@Validated
@Slf4j
public class OAuth2ClientServiceImpl implements IOAuth2ClientService {
@Resource
private OAuth2ClientMapper oauth2ClientMapper;
@Override
public Long createOAuth2Client(OAuth2ClientSaveReqVO createReqVO) {
validateClientIdExists(null, createReqVO.getClientId());
// 插入
OAuth2ClientDO client = BeanUtils.toBean(createReqVO, OAuth2ClientDO.class);
oauth2ClientMapper.insert(client);
return client.getId();
}
@Override
@CacheEvict(cacheNames = RedisKeyConstants.OAUTH_CLIENT,
allEntries = true) // allEntries 清空所有缓存,因为可能修改到 clientId 字段,不好清理
public void updateOAuth2Client(OAuth2ClientSaveReqVO updateReqVO) {
// 校验存在
validateOAuth2ClientExists(updateReqVO.getId());
// 校验 Client 未被占用
validateClientIdExists(updateReqVO.getId(), updateReqVO.getClientId());
// 更新
OAuth2ClientDO updateObj = BeanUtils.toBean(updateReqVO, OAuth2ClientDO.class);
oauth2ClientMapper.updateById(updateObj);
}
@Override
@CacheEvict(cacheNames = RedisKeyConstants.OAUTH_CLIENT,
allEntries = true) // allEntries 清空所有缓存,因为 id 不是直接的缓存 key不好清理
public void deleteOAuth2Client(Long id) {
// 校验存在
validateOAuth2ClientExists(id);
// 删除
oauth2ClientMapper.deleteById(id);
}
private void validateOAuth2ClientExists(Long id) {
if (oauth2ClientMapper.selectById(id) == null) {
throw exception(OAUTH2_CLIENT_NOT_EXISTS);
}
}
@VisibleForTesting
void validateClientIdExists(Long id, String clientId) {
OAuth2ClientDO client = oauth2ClientMapper.selectByClientId(clientId);
if (client == null) {
return;
}
// 如果 id 为空,说明不用比较是否为相同 id 的客户端
if (id == null) {
throw exception(OAUTH2_CLIENT_EXISTS);
}
if (!client.getId().equals(id)) {
throw exception(OAUTH2_CLIENT_EXISTS);
}
}
@Override
public OAuth2ClientDO getOAuth2Client(Long id) {
return oauth2ClientMapper.selectById(id);
}
@Override
@Cacheable(cacheNames = RedisKeyConstants.OAUTH_CLIENT, key = "#clientId",
unless = "#result == null")
public OAuth2ClientDO getOAuth2ClientFromCache(String clientId) {
return oauth2ClientMapper.selectByClientId(clientId);
}
@Override
public PageResult<OAuth2ClientDO> getOAuth2ClientPage(OAuth2ClientPageReqVO pageReqVO) {
return oauth2ClientMapper.selectPage(pageReqVO);
}
@Override
public OAuth2ClientDO validOAuthClientFromCache(String clientId, String clientSecret, String authorizedGrantType,
Collection<String> scopes, String redirectUri) {
// 校验客户端存在、且开启
OAuth2ClientDO client = getSelf().getOAuth2ClientFromCache(clientId);
if (client == null) {
throw exception(OAUTH2_CLIENT_NOT_EXISTS);
}
if (CommonStatusEnum.isDisable(client.getStatus())) {
throw exception(OAUTH2_CLIENT_DISABLE);
}
// 校验客户端密钥
if (StrUtil.isNotEmpty(clientSecret) && ObjectUtil.notEqual(client.getSecret(), clientSecret)) {
throw exception(OAUTH2_CLIENT_CLIENT_SECRET_ERROR);
}
// 校验授权方式
if (StrUtil.isNotEmpty(authorizedGrantType) && !CollUtil.contains(client.getAuthorizedGrantTypes(), authorizedGrantType)) {
throw exception(OAUTH2_CLIENT_AUTHORIZED_GRANT_TYPE_NOT_EXISTS);
}
// 校验授权范围
if (CollUtil.isNotEmpty(scopes) && !CollUtil.containsAll(client.getScopes(), scopes)) {
throw exception(OAUTH2_CLIENT_SCOPE_OVER);
}
// 校验回调地址
// if (StrUtil.isNotEmpty(redirectUri) && !StrUtils.startWithAny(redirectUri, client.getRedirectUris())) {
// throw exception(OAUTH2_CLIENT_REDIRECT_URI_NOT_MATCH, redirectUri);
// }
if (StrUtil.isNotEmpty(redirectUri) && ObjectUtil.notEqual(client.getRedirectUris(), redirectUri)) {
throw exception(OAUTH2_CLIENT_REDIRECT_URI_NOT_MATCH, redirectUri);
}
return client;
}
/**
* 获得自身的代理对象,解决 AOP 生效问题
*
* @return 自己
*/
private OAuth2ClientServiceImpl getSelf() {
return SpringUtil.getBean(getClass());
}
}