Commit 213a6aa0fc618e08300bfb86378ac1cab30315ac

Authored by YunaiV
2 parents a70463b9 93e8e9c7

Merge branch 'master-jdk17' of https://gitee.com/zhijiantianya/ruoyi-vue-pro into feature/db

# Conflicts:
#	yudao-server/src/main/resources/application-local.yaml
Showing 14 changed files with 110 additions and 46 deletions
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/datasource/config/YudaoDataSourceAutoConfiguration.java
... ... @@ -23,7 +23,7 @@ public class YudaoDataSourceAutoConfiguration {
23 23 * 创建 DruidAdRemoveFilter 过滤器,过滤 common.js 的广告
24 24 */
25 25 @Bean
26   - @ConditionalOnProperty(name = "spring.datasource.druid.web-stat-filter.enabled", havingValue = "true")
  26 + @ConditionalOnProperty(name = "spring.datasource.druid.stat-view-servlet.enabled", havingValue = "true")
27 27 public FilterRegistrationBean<DruidAdRemoveFilter> druidAdRemoveFilterFilter(DruidStatProperties properties) {
28 28 // 获取 druid web 监控页面的参数
29 29 DruidStatProperties.StatViewServlet config = properties.getStatViewServlet();
... ...
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java
... ... @@ -5,7 +5,9 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam;
5 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 6 import cn.iocoder.yudao.framework.common.pojo.SortablePageParam;
7 7 import cn.iocoder.yudao.framework.common.pojo.SortingField;
  8 +import cn.iocoder.yudao.framework.mybatis.core.enums.SqlConstants;
8 9 import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
  10 +import com.baomidou.mybatisplus.annotation.DbType;
9 11 import com.baomidou.mybatisplus.core.conditions.Wrapper;
10 12 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
11 13 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
... ... @@ -20,6 +22,7 @@ import org.apache.ibatis.annotations.Param;
20 22  
21 23 import java.util.Collection;
22 24 import java.util.List;
  25 +import java.util.Objects;
23 26  
24 27 /**
25 28 * 在 MyBatis Plus 的 BaseMapper 的基础上拓展,提供更多的能力
... ... @@ -147,6 +150,11 @@ public interface BaseMapperX&lt;T&gt; extends MPJBaseMapper&lt;T&gt; {
147 150 * @param entities 实体们
148 151 */
149 152 default Boolean insertBatch(Collection<T> entities) {
  153 + // 特殊:SQL Server 批量插入后,获取 id 会报错,因此通过循环处理
  154 + if (Objects.equals(SqlConstants.DB_TYPE, DbType.SQL_SERVER)) {
  155 + entities.forEach(this::insert);
  156 + return CollUtil.isNotEmpty(entities);
  157 + }
150 158 return Db.saveBatch(entities);
151 159 }
152 160  
... ... @@ -157,6 +165,11 @@ public interface BaseMapperX&lt;T&gt; extends MPJBaseMapper&lt;T&gt; {
157 165 * @param size 插入数量 Db.saveBatch 默认为 1000
158 166 */
159 167 default Boolean insertBatch(Collection<T> entities, int size) {
  168 + // 特殊:SQL Server 批量插入后,获取 id 会报错,因此通过循环处理
  169 + if (Objects.equals(SqlConstants.DB_TYPE, DbType.SQL_SERVER)) {
  170 + entities.forEach(this::insert);
  171 + return CollUtil.isNotEmpty(entities);
  172 + }
160 173 return Db.saveBatch(entities, size);
161 174 }
162 175  
... ...
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/apilog/core/interceptor/ApiAccessLogInterceptor.java
... ... @@ -43,7 +43,7 @@ public class ApiAccessLogInterceptor implements HandlerInterceptor {
43 43 log.info("[preHandle][开始请求 URL({}) 无参数]", request.getRequestURI());
44 44 } else {
45 45 log.info("[preHandle][开始请求 URL({}) 参数({})]", request.getRequestURI(),
46   - StrUtil.nullToDefault(requestBody, queryString.toString()));
  46 + StrUtil.blankToDefault(requestBody, queryString.toString()));
47 47 }
48 48 // 计时
49 49 StopWatch stopWatch = new StopWatch();
... ...
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/handler/GlobalExceptionHandler.java
... ... @@ -6,6 +6,7 @@ import cn.hutool.core.util.StrUtil;
6 6 import cn.iocoder.yudao.framework.apilog.core.service.ApiErrorLogFrameworkService;
7 7 import cn.iocoder.yudao.framework.common.exception.ServiceException;
8 8 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  9 +import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
9 10 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
10 11 import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils;
11 12 import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
... ... @@ -32,6 +33,7 @@ import org.springframework.web.servlet.NoHandlerFoundException;
32 33  
33 34 import java.time.LocalDateTime;
34 35 import java.util.Map;
  36 +import java.util.Set;
35 37  
36 38 import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.*;
37 39  
... ... @@ -45,6 +47,11 @@ import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeC
45 47 @Slf4j
46 48 public class GlobalExceptionHandler {
47 49  
  50 + /**
  51 + * 忽略的 ServiceException 错误提示,避免打印过多 logger
  52 + */
  53 + public static final Set<String> IGNORE_ERROR_MESSAGES = SetUtils.asSet("无效的刷新令牌");
  54 +
48 55 @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
49 56 private final String applicationName;
50 57  
... ... @@ -199,7 +206,10 @@ public class GlobalExceptionHandler {
199 206 */
200 207 @ExceptionHandler(value = ServiceException.class)
201 208 public CommonResult<?> serviceExceptionHandler(ServiceException ex) {
202   - log.info("[serviceExceptionHandler]", ex);
  209 + if (!IGNORE_ERROR_MESSAGES.contains(ex.getMessage())) {
  210 + // 不包含的时候,才进行打印,避免 ex 堆栈过多
  211 + log.info("[serviceExceptionHandler]", ex);
  212 + }
203 213 return CommonResult.error(ex.getCode(), ex.getMessage());
204 214 }
205 215  
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessSaveReqVO.java
... ... @@ -66,7 +66,7 @@ public class CrmBusinessSaveReqVO {
66 66 private Long contactId; // 使用场景,在【联系人详情】添加商机时,如果需要关联两者,需要传递 contactId 字段
67 67  
68 68 @Schema(description = "产品列表")
69   - private List<BusinessProduct> businessProducts;
  69 + private List<BusinessProduct> products;
70 70  
71 71 @Schema(description = "产品列表")
72 72 @Data
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java
... ... @@ -89,7 +89,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
89 89 success = CRM_BUSINESS_CREATE_SUCCESS)
90 90 public Long createBusiness(CrmBusinessSaveReqVO createReqVO, Long userId) {
91 91 // 1.1 校验产品项的有效性
92   - List<CrmBusinessProductDO> businessProducts = validateBusinessProducts(createReqVO.getBusinessProducts());
  92 + List<CrmBusinessProductDO> businessProducts = validateBusinessProducts(createReqVO.getProducts());
93 93 // 1.2 校验关联字段
94 94 validateRelationDataExists(createReqVO);
95 95  
... ... @@ -130,7 +130,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
130 130 // 1.1 校验存在
131 131 CrmBusinessDO oldBusiness = validateBusinessExists(updateReqVO.getId());
132 132 // 1.2 校验产品项的有效性
133   - List<CrmBusinessProductDO> businessProducts = validateBusinessProducts(updateReqVO.getBusinessProducts());
  133 + List<CrmBusinessProductDO> businessProducts = validateBusinessProducts(updateReqVO.getProducts());
134 134 // 1.3 校验关联字段
135 135 validateRelationDataExists(updateReqVO);
136 136  
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/JobController.http 0 → 100644
  1 +### 请求 /infra/job/sync 接口 => 成功
  2 +POST {{baseUrl}}/infra/job/sync
  3 +Content-Type: application/json
  4 +tenant-id: {{adminTenentId}}
  5 +Authorization: Bearer {{token}}
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/JobController.java
... ... @@ -90,6 +90,14 @@ public class JobController {
90 90 return success(true);
91 91 }
92 92  
  93 + @PostMapping("/sync")
  94 + @Operation(summary = "同步定时任务")
  95 + @PreAuthorize("@ss.hasPermission('infra:job:create')")
  96 + public CommonResult<Boolean> syncJob() throws SchedulerException {
  97 + jobService.syncJob();
  98 + return success(true);
  99 + }
  100 +
93 101 @GetMapping("/get")
94 102 @Operation(summary = "获得定时任务")
95 103 @Parameter(name = "id", description = "编号", required = true, example = "1024")
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/job/JobService.java
... ... @@ -46,6 +46,13 @@ public interface JobService {
46 46 void triggerJob(Long id) throws SchedulerException;
47 47  
48 48 /**
  49 + * 同步定时任务
  50 + *
  51 + * 目的:自己存储的 Job 信息,强制同步到 Quartz 中
  52 + */
  53 + void syncJob() throws SchedulerException;
  54 +
  55 + /**
49 56 * 删除定时任务
50 57 *
51 58 * @param id 编号
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/job/JobServiceImpl.java
... ... @@ -12,11 +12,15 @@ import cn.iocoder.yudao.module.infra.dal.dataobject.job.JobDO;
12 12 import cn.iocoder.yudao.module.infra.dal.mysql.job.JobMapper;
13 13 import cn.iocoder.yudao.module.infra.enums.job.JobStatusEnum;
14 14 import jakarta.annotation.Resource;
  15 +import lombok.extern.slf4j.Slf4j;
15 16 import org.quartz.SchedulerException;
16 17 import org.springframework.stereotype.Service;
17 18 import org.springframework.transaction.annotation.Transactional;
18 19 import org.springframework.validation.annotation.Validated;
19 20  
  21 +import java.util.List;
  22 +import java.util.Objects;
  23 +
20 24 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
21 25 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.containsAny;
22 26 import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.*;
... ... @@ -28,6 +32,7 @@ import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.*;
28 32 */
29 33 @Service
30 34 @Validated
  35 +@Slf4j
31 36 public class JobServiceImpl implements JobService {
32 37  
33 38 @Resource
... ... @@ -131,6 +136,26 @@ public class JobServiceImpl implements JobService {
131 136  
132 137 @Override
133 138 @Transactional(rollbackFor = Exception.class)
  139 + public void syncJob() throws SchedulerException {
  140 + // 1. 查询 Job 配置
  141 + List<JobDO> jobList = jobMapper.selectList();
  142 +
  143 + // 2. 遍历处理
  144 + for (JobDO job : jobList) {
  145 + // 2.1 先删除,再创建
  146 + schedulerManager.deleteJob(job.getHandlerName());
  147 + schedulerManager.addJob(job.getId(), job.getHandlerName(), job.getHandlerParam(), job.getCronExpression(),
  148 + job.getRetryCount(), job.getRetryInterval());
  149 + // 2.2 如果 status 为暂停,则需要暂停
  150 + if (Objects.equals(job.getStatus(), JobStatusEnum.STOP.getStatus())) {
  151 + schedulerManager.pauseJob(job.getHandlerName());
  152 + }
  153 + log.info("[syncJob][id({}) handlerName({}) 同步完成]", job.getId(), job.getHandlerName());
  154 + }
  155 + }
  156 +
  157 + @Override
  158 + @Transactional(rollbackFor = Exception.class)
134 159 public void deleteJob(Long id) throws SchedulerException {
135 160 // 校验存在
136 161 JobDO job = validateJobExists(id);
... ...
yudao-module-report/yudao-module-report-biz/src/main/java/cn/iocoder/yudao/module/report/framework/jmreport/config/JmReportConfiguration.java
... ... @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.report.framework.jmreport.config;
3 3 import cn.iocoder.yudao.framework.security.config.SecurityProperties;
4 4 import cn.iocoder.yudao.module.system.api.oauth2.OAuth2TokenApi;
5 5 import cn.iocoder.yudao.module.report.framework.jmreport.core.service.JmReportTokenServiceImpl;
  6 +import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
6 7 import org.jeecg.modules.jmreport.api.JmReportTokenServiceI;
7 8 import org.springframework.context.annotation.Bean;
8 9 import org.springframework.context.annotation.ComponentScan;
... ... @@ -19,8 +20,10 @@ public class JmReportConfiguration {
19 20  
20 21 @Bean
21 22 @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
22   - public JmReportTokenServiceI jmReportTokenService(OAuth2TokenApi oAuth2TokenApi, SecurityProperties securityProperties) {
23   - return new JmReportTokenServiceImpl(oAuth2TokenApi, securityProperties);
  23 + public JmReportTokenServiceI jmReportTokenService(OAuth2TokenApi oAuth2TokenApi,
  24 + PermissionApi permissionApi,
  25 + SecurityProperties securityProperties) {
  26 + return new JmReportTokenServiceImpl(oAuth2TokenApi, permissionApi, securityProperties);
24 27 }
25 28  
26 29 }
... ...
yudao-module-report/yudao-module-report-biz/src/main/java/cn/iocoder/yudao/module/report/framework/jmreport/core/service/JmReportTokenServiceImpl.java
... ... @@ -11,12 +11,13 @@ import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
11 11 import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
12 12 import cn.iocoder.yudao.module.system.api.oauth2.OAuth2TokenApi;
13 13 import cn.iocoder.yudao.module.system.api.oauth2.dto.OAuth2AccessTokenCheckRespDTO;
14   -import cn.iocoder.yudao.module.system.api.permission.RoleApi;
  14 +import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
  15 +import cn.iocoder.yudao.module.system.enums.permission.RoleCodeEnum;
  16 +import jakarta.servlet.http.HttpServletRequest;
15 17 import lombok.RequiredArgsConstructor;
16 18 import org.jeecg.modules.jmreport.api.JmReportTokenServiceI;
17 19 import org.springframework.http.HttpHeaders;
18 20  
19   -import jakarta.servlet.http.HttpServletRequest;
20 21 import java.util.Objects;
21 22  
22 23 /**
... ... @@ -37,6 +38,7 @@ public class JmReportTokenServiceImpl implements JmReportTokenServiceI {
37 38 private static final String AUTHORIZATION_FORMAT = SecurityFrameworkUtils.AUTHORIZATION_BEARER + " %s";
38 39  
39 40 private final OAuth2TokenApi oauth2TokenApi;
  41 + private final PermissionApi permissionApi;
40 42  
41 43 private final SecurityProperties securityProperties;
42 44  
... ... @@ -130,9 +132,12 @@ public class JmReportTokenServiceImpl implements JmReportTokenServiceI {
130 132 }
131 133  
132 134 @Override
133   - public String[] getRoles(String s) {
134   - // 暂时不用实现,因为不用 JmReport 的角色
135   - return null;
  135 + public String[] getRoles(String token) {
  136 + // 参见文档 https://help.jeecg.com/jimureport/prodSafe.html 文档
  137 + // 适配:如果是本系统的管理员,则转换成 jimu 报表的管理员
  138 + Long userId = SecurityFrameworkUtils.getLoginUserId();
  139 + return permissionApi.hasAnyRoles(userId, RoleCodeEnum.SUPER_ADMIN.getCode())
  140 + ? new String[]{"admin"} : null;
136 141 }
137 142  
138 143 @Override
... ...
yudao-server/src/main/resources/application-dev.yaml
... ... @@ -40,17 +40,14 @@ spring:
40 40 primary: master
41 41 datasource:
42 42 master:
43   - name: ruoyi-vue-pro
44   - url: jdbc:mysql://400-infra.server.iocoder.cn:3306/${spring.datasource.dynamic.datasource.master.name}?useSSL=false&serverTimezone=CTT&allowPublicKeyRetrieval=true
45   - driver-class-name: com.mysql.jdbc.Driver
  43 + url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
46 44 username: root
47   - password: 3WLiVUBEwTbvAfsh
  45 + password: 123456
48 46 slave: # 模拟从库,可根据自己需要修改 # 模拟从库,可根据自己需要修改
49   - name: ruoyi-vue-pro
50   - url: jdbc:mysql://400-infra.server.iocoder.cn:3306/${spring.datasource.dynamic.datasource.slave.name}?useSSL=false&serverTimezone=CTT&allowPublicKeyRetrieval=true
51   - driver-class-name: com.mysql.jdbc.Driver
  47 + lazy: true # 开启懒加载,保证启动速度
  48 + url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
52 49 username: root
53   - password: 3WLiVUBEwTbvAfsh
  50 + password: 123456
54 51  
55 52 # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
56 53 data:
... ...
yudao-server/src/main/resources/application-local.yaml
... ... @@ -39,39 +39,30 @@ spring:
39 39 time-between-eviction-runs-millis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位:毫秒
40 40 min-evictable-idle-time-millis: 300000 # 配置一个连接在池中最小生存的时间,单位:毫秒
41 41 max-evictable-idle-time-millis: 900000 # 配置一个连接在池中最大生存的时间,单位:毫秒
42   -# validation-query: SELECT 1 FROM DUAL # 配置检测连接是否有效, 不同数据库有所不同, 建议mysql以外的先注释掉
  42 + validation-query: SELECT 1 FROM DUAL # 配置检测连接是否有效
43 43 test-while-idle: true
44 44 test-on-borrow: false
45 45 test-on-return: false
46 46 primary: master
47 47 datasource:
48 48 master:
49   -# url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
50   -# url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT # MySQL Connector/J 5.X 连接的示例
51   -# url: jdbc:postgresql://127.0.0.1:5432/ruoyi-vue-pro?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true # PostgreSQL 连接的示例
52   -# url: jdbc:oracle:thin:@//127.0.0.1:1521/XEPDB1 # Oracle 连接的示例
53   -# url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=ruoyi-vue-pro;SelectMethod=cursor;encrypt=false;rewriteBatchedStatements=true;useUnicode=true;characterEncoding=utf-8 # SQLServer 连接的示例
54   - url: jdbc:dm://localhost:5236 # DM 连接的示例
55   -# username: root
56   -# password: 123456
57   -# username: sa # SQLServer 连接的示例
58   -# password: Yudao@2024 # SQLServer 连接的示例
59   - username: SYSDBA # DM 连接的示例
60   - password: SYSDBA001 # DM 连接的示例
  49 + url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
  50 + # url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=true&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai # MySQL Connector/J 5.X 连接的示例
  51 + # url: jdbc:postgresql://127.0.0.1:5432/ruoyi-vue-pro # PostgreSQL 连接的示例
  52 + # url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 连接的示例
  53 + # url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=ruoyi-vue-pro;SelectMethod=cursor;encrypt=false;rewriteBatchedStatements=true;useUnicode=true;characterEncoding=utf-8 # SQLServer 连接的示例
  54 + # url: jdbc:dm://127.0.0.1:5236?schema=RUOYI_VUE_PRO # DM 连接的示例
  55 + username: root
  56 + password: 123456
  57 + # username: sa # SQL Server 连接的示例
  58 + # password: Yudao@2024 # SQL Server 连接的示例
  59 + # username: SYSDBA # DM 连接的示例
  60 + # password: SYSDBA001 # DM 连接的示例
61 61 slave: # 模拟从库,可根据自己需要修改
62 62 lazy: true # 开启懒加载,保证启动速度
63   -# url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
64   -# url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT # MySQL Connector/J 5.X 连接的示例
65   -# url: jdbc:postgresql://127.0.0.1:5432/ruoyi-vue-pro?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true # PostgreSQL 连接的示例
66   -# url: jdbc:oracle:thin:@//127.0.0.1:1521/XEPDB1 # Oracle 连接的示例
67   -# url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=ruoyi-vue-pro # SQLServer 连接的示例
68   -# url: jdbc:dm://10.211.55.4:5236?schema=RUOYI_VUE_PRO # DM 连接的示例
69   -# username: root
70   -# password: 123456
71   - username: sa # SQLServer 连接的示例
72   - password: Yudao@2024 # SQLServer 连接的示例
73   - # username: SYSDBA # DM 连接的示例
74   - # password: SYSDBA # DM 连接的示例
  63 + url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
  64 + username: root
  65 + password: 123456
75 66  
76 67 # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
77 68 data:
... ...