适配 Oracle 数据库

1. 去除关键字,避免数据库的查询冲突
This commit is contained in:
YunaiV 2022-05-01 13:33:02 +08:00
parent 1bd86d6ffd
commit 7db1a58bfc
47 changed files with 878 additions and 868 deletions
sql
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/enums
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject
yudao-module-infra
yudao-module-infra-api/src/main/java/cn/iocoder/yudao/module/infra/enums
yudao-module-infra-biz/src
main/java/cn/iocoder/yudao/module/infra
test/java/cn/iocoder/yudao/module/infra/service/config
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay
dal/mysql/merchant
service/merchant
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system
yudao-server/src/main/resources
yudao-ui-admin/src
utils
views/infra/config

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -2,6 +2,8 @@ package cn.iocoder.yudao.framework.mybatis.core.enums;
/**
* SQL相关常量类
*
* @author 芋道源码
*/
public interface SqlConstants {

View File

@ -66,7 +66,6 @@ public class BpmTaskAssignRuleDO extends BaseDO {
*
* 枚举 {@link BpmTaskAssignRuleTypeEnum}
*/
@TableField("\"type\"")
private Integer type;
/**
* 规则值数组一般关联指定表的编号

View File

@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.bpm.dal.dataobject.oa;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
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 lombok.*;
@ -42,7 +41,6 @@ public class BpmOALeaveDO extends BaseDO {
/**
* 请假类型
*/
@TableField("\"type\"")
private Integer type;
/**
* 原因

View File

@ -13,7 +13,7 @@ public interface ErrorCodeConstants {
ErrorCode CONFIG_NOT_EXISTS = new ErrorCode(1001000001, "参数配置不存在");
ErrorCode CONFIG_KEY_DUPLICATE = new ErrorCode(1001000002, "参数配置 key 重复");
ErrorCode CONFIG_CAN_NOT_DELETE_SYSTEM_TYPE = new ErrorCode(1001000003, "不能删除类型为系统内置的参数配置");
ErrorCode CONFIG_GET_VALUE_ERROR_IF_SENSITIVE = new ErrorCode(1001000004, "不允许获取敏感配置到前端");
ErrorCode CONFIG_GET_VALUE_ERROR_IF_VISIBLE = new ErrorCode(1001000004, "获取参数配置失败,原因:不允许获取不可见配置");
// ========== 定时任务 1001001000 ==========
ErrorCode JOB_NOT_EXISTS = new ErrorCode(1001001000, "定时任务不存在");
@ -36,7 +36,6 @@ public interface ErrorCodeConstants {
ErrorCode CODEGEN_TABLE_EXISTS = new ErrorCode(1003001000, "表定义已经存在");
ErrorCode CODEGEN_IMPORT_TABLE_NULL = new ErrorCode(1003001001, "导入的表不存在");
ErrorCode CODEGEN_IMPORT_COLUMNS_NULL = new ErrorCode(1003001002, "导入的字段不存在");
ErrorCode CODEGEN_PARSE_SQL_ERROR = new ErrorCode(1003001003, "解析 SQL 失败,请检查");
ErrorCode CODEGEN_TABLE_NOT_EXISTS = new ErrorCode(1003001004, "表定义不存在");
ErrorCode CODEGEN_COLUMN_NOT_EXISTS = new ErrorCode(1003001005, "字段义不存在");
ErrorCode CODEGEN_SYNC_COLUMNS_NULL = new ErrorCode(1003001006, "同步的字段不存在");

View File

@ -68,15 +68,15 @@ public class ConfigController {
}
@GetMapping(value = "/get-value-by-key")
@ApiOperation(value = "根据参数键名查询参数值", notes = "敏感配置,不允许返回给前端")
@ApiOperation(value = "根据参数键名查询参数值", notes = "不可见的配置,不允许返回给前端")
@ApiImplicitParam(name = "key", value = "参数键", required = true, example = "yunai.biz.username", dataTypeClass = String.class)
public CommonResult<String> getConfigKey(@RequestParam("key") String key) {
ConfigDO config = configService.getConfigByKey(key);
if (config == null) {
return null;
}
if (config.getSensitive()) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.CONFIG_GET_VALUE_ERROR_IF_SENSITIVE);
if (config.getVisible()) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.CONFIG_GET_VALUE_ERROR_IF_VISIBLE);
}
return success(config.getValue());
}

View File

@ -18,7 +18,7 @@ public class ConfigBaseVO {
@ApiModelProperty(value = "参数分组", required = true, example = "biz")
@NotEmpty(message = "参数分组不能为空")
@Size(max = 50, message = "参数名称不能超过50个字符")
private String group;
private String category;
@ApiModelProperty(value = "参数名称", required = true, example = "数据库名")
@NotBlank(message = "参数名称不能为空")
@ -32,7 +32,7 @@ public class ConfigBaseVO {
@ApiModelProperty(value = "是否敏感", required = true, example = "true")
@NotNull(message = "是否敏感不能为空")
private Boolean sensitive;
private Boolean visible;
@ApiModelProperty(value = "备注", example = "备注一下很帅气!")
private String remark;

View File

@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.infra.controller.admin.config.vo.ConfigRespVO;
import cn.iocoder.yudao.module.infra.controller.admin.config.vo.ConfigUpdateReqVO;
import cn.iocoder.yudao.module.infra.dal.dataobject.config.ConfigDO;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
import java.util.List;
@ -18,12 +19,15 @@ public interface ConfigConvert {
PageResult<ConfigRespVO> convertPage(PageResult<ConfigDO> page);
@Mapping(source = "configKey", target = "key")
ConfigRespVO convert(ConfigDO bean);
@Mapping(source = "key", target = "configKey")
ConfigDO convert(ConfigCreateReqVO bean);
ConfigDO convert(ConfigUpdateReqVO bean);
@Mapping(source = "configKey", target = "key")
List<ConfigExcelVO> convertList(List<ConfigDO> list);
}

View File

@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.infra.dal.dataobject.config;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.infra.enums.config.ConfigTypeEnum;
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 lombok.Data;
@ -28,19 +27,19 @@ public class ConfigDO extends BaseDO {
@TableId
private Long id;
/**
* 参数分
* 参数分
*/
@TableField("\"group\"")
private String group;
private String category;
/**
* 参数名称
*/
private String name;
/**
* 参数键名
*
* 支持多 DB 类型时无法直接使用 key + @TableField("config_key") 来实现转换原因是 "config_key" AS key 而存在报错
*/
@TableField("\"key\"")
private String key;
private String configKey;
/**
* 参数键值
*/
@ -50,15 +49,13 @@ public class ConfigDO extends BaseDO {
*
* 枚举 {@link ConfigTypeEnum}
*/
@TableField("\"type\"")
private Integer type;
/**
* 是否敏感
* 是否可见
*
* 对于敏感配置需要管理权限才能查看
* 不可见的参数一般是敏感参数前端不可获取
*/
@TableField("\"sensitive\"")
private Boolean sensitive;
private Boolean visible;
/**
* 备注
*/

View File

@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.infra.dal.dataobject.file;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
@ -47,7 +46,6 @@ public class FileDO extends BaseDO {
*
* 通过 {@link cn.hutool.core.io.FileTypeUtil#getType(InputStream)} 获取
*/
@TableField("\"type\"")
private String type;
/**
* 文件大小

View File

@ -14,13 +14,13 @@ import java.util.List;
public interface ConfigMapper extends BaseMapperX<ConfigDO> {
default ConfigDO selectByKey(String key) {
return selectOne(ConfigDO::getKey, key);
return selectOne(ConfigDO::getConfigKey, key);
}
default PageResult<ConfigDO> selectPage(ConfigPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<ConfigDO>()
.likeIfPresent(ConfigDO::getName, reqVO.getName())
.likeIfPresent(ConfigDO::getKey, reqVO.getKey())
.likeIfPresent(ConfigDO::getConfigKey, reqVO.getKey())
.eqIfPresent(ConfigDO::getType, reqVO.getType())
.betweenIfPresent(ConfigDO::getCreateTime, reqVO.getBeginTime(), reqVO.getEndTime()));
}
@ -28,7 +28,7 @@ public interface ConfigMapper extends BaseMapperX<ConfigDO> {
default List<ConfigDO> selectList(ConfigExportReqVO reqVO) {
return selectList(new LambdaQueryWrapperX<ConfigDO>()
.likeIfPresent(ConfigDO::getName, reqVO.getName())
.likeIfPresent(ConfigDO::getKey, reqVO.getKey())
.likeIfPresent(ConfigDO::getConfigKey, reqVO.getKey())
.eqIfPresent(ConfigDO::getType, reqVO.getType())
.betweenIfPresent(ConfigDO::getCreateTime, reqVO.getBeginTime(), reqVO.getEndTime()));
}

View File

@ -26,7 +26,7 @@ public interface FileConfigMapper extends BaseMapperX<FileConfigDO> {
.orderByDesc(FileConfigDO::getId));
}
@Select("SELECT id FROM infra_file_config WHERE update_time > #{maxUpdateTime} LIMIT 1")
Long selectExistsByUpdateTimeAfter(Date maxUpdateTime);
@Select("SELECT COUNT(*) FROM infra_file_config WHERE update_time > #{maxUpdateTime}")
Long selectCountByUpdateTimeGt(Date maxUpdateTime);
}

View File

@ -12,6 +12,7 @@ import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO;
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO;
import cn.iocoder.yudao.module.infra.dal.mysql.codegen.CodegenColumnMapper;
import cn.iocoder.yudao.module.infra.dal.mysql.codegen.CodegenTableMapper;
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenSceneEnum;
import cn.iocoder.yudao.module.infra.service.codegen.inner.CodegenBuilder;
import cn.iocoder.yudao.module.infra.service.codegen.inner.CodegenEngine;
import cn.iocoder.yudao.module.infra.service.db.DatabaseTableService;
@ -88,6 +89,7 @@ public class CodegenServiceImpl implements CodegenService {
// 构建 CodegenTableDO 对象插入到 DB
CodegenTableDO table = codegenBuilder.buildTable(tableInfo);
table.setDataSourceConfigId(dataSourceConfigId);
table.setScene(CodegenSceneEnum.ADMIN.getScene()); // 默认配置下使用管理后台的模板
table.setAuthor(userApi.getUser(userId).getNickname());
codegenTableMapper.insert(table);
// 构建 CodegenColumnDO 数组插入到 DB

View File

@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.infra.service.config;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.infra.controller.admin.config.vo.ConfigCreateReqVO;
@ -96,7 +97,9 @@ public class ConfigServiceImpl implements ConfigService {
// 校验自己存在
checkConfigExists(id);
// 校验参数配置 key 的唯一性
checkConfigKeyUnique(id, key);
if (StrUtil.isNotEmpty(key)) {
checkConfigKeyUnique(id, key);
}
}
@VisibleForTesting

View File

@ -123,7 +123,7 @@ public class FileConfigServiceImpl implements FileConfigService {
if (maxUpdateTime == null) { // 如果更新时间为空说明 DB 一定有新数据
log.info("[loadFileConfigIfUpdate][首次加载全量文件配置]");
} else { // 判断数据库中是否有更新的文件配置
if (fileConfigMapper.selectExistsByUpdateTimeAfter(maxUpdateTime) == null) {
if (fileConfigMapper.selectCountByUpdateTimeGt(maxUpdateTime) == 0) {
return null;
}
log.info("[loadFileConfigIfUpdate][增量加载全量文件配置]");

View File

@ -137,7 +137,7 @@ public class ConfigServiceTest extends BaseDbUnitTest {
// 准备参数
String key = randomString();
// mock 数据
configMapper.insert(randomConfigDO(o -> o.setKey(key)));
configMapper.insert(randomConfigDO(o -> o.setConfigKey(key)));
// 调用校验异常
assertServiceException(() -> configService.checkConfigKeyUnique(null, key),
@ -150,7 +150,7 @@ public class ConfigServiceTest extends BaseDbUnitTest {
Long id = randomLongId();
String key = randomString();
// mock 数据
configMapper.insert(randomConfigDO(o -> o.setKey(key)));
configMapper.insert(randomConfigDO(o -> o.setConfigKey(key)));
// 调用校验异常
assertServiceException(() -> configService.checkConfigKeyUnique(id, key),
@ -162,7 +162,7 @@ public class ConfigServiceTest extends BaseDbUnitTest {
// mock 数据
ConfigDO dbConfig = randomConfigDO(o -> { // 等会查询到
o.setName("芋艿");
o.setKey("yunai");
o.setConfigKey("yunai");
o.setType(ConfigTypeEnum.SYSTEM.getType());
o.setCreateTime(buildTime(2021, 2, 1));
});
@ -170,7 +170,7 @@ public class ConfigServiceTest extends BaseDbUnitTest {
// 测试 name 不匹配
configMapper.insert(ObjectUtils.cloneIgnoreId(dbConfig, o -> o.setName("土豆")));
// 测试 key 不匹配
configMapper.insert(ObjectUtils.cloneIgnoreId(dbConfig, o -> o.setKey("tudou")));
configMapper.insert(ObjectUtils.cloneIgnoreId(dbConfig, o -> o.setConfigKey("tudou")));
// 测试 type 不匹配
configMapper.insert(ObjectUtils.cloneIgnoreId(dbConfig, o -> o.setType(ConfigTypeEnum.CUSTOM.getType())));
// 测试 createTime 不匹配
@ -196,7 +196,7 @@ public class ConfigServiceTest extends BaseDbUnitTest {
// mock 数据
ConfigDO dbConfig = randomConfigDO(o -> { // 等会查询到
o.setName("芋艿");
o.setKey("yunai");
o.setConfigKey("yunai");
o.setType(ConfigTypeEnum.SYSTEM.getType());
o.setCreateTime(buildTime(2021, 2, 1));
});
@ -204,7 +204,7 @@ public class ConfigServiceTest extends BaseDbUnitTest {
// 测试 name 不匹配
configMapper.insert(ObjectUtils.cloneIgnoreId(dbConfig, o -> o.setName("土豆")));
// 测试 key 不匹配
configMapper.insert(ObjectUtils.cloneIgnoreId(dbConfig, o -> o.setKey("tudou")));
configMapper.insert(ObjectUtils.cloneIgnoreId(dbConfig, o -> o.setConfigKey("tudou")));
// 测试 type 不匹配
configMapper.insert(ObjectUtils.cloneIgnoreId(dbConfig, o -> o.setType(ConfigTypeEnum.CUSTOM.getType())));
// 测试 createTime 不匹配
@ -230,7 +230,7 @@ public class ConfigServiceTest extends BaseDbUnitTest {
ConfigDO dbConfig = randomConfigDO();
configMapper.insert(dbConfig);// @Sql: 先插入出一条存在的数据
// 准备参数
String key = dbConfig.getKey();
String key = dbConfig.getConfigKey();
// 调用
ConfigDO config = configService.getConfigByKey(key);

View File

@ -21,8 +21,8 @@ public interface PayChannelMapper extends BaseMapperX<PayChannelDO> {
return selectOne(PayChannelDO::getAppId, appId, PayChannelDO::getCode, code);
}
@Select("SELECT id FROM pay_channel WHERE update_time > #{maxUpdateTime} LIMIT 1")
Long selectExistsByUpdateTimeAfter(Date maxUpdateTime);
@Select("SELECT COUNT(*) FROM pay_channel WHERE update_time > #{maxUpdateTime}")
Long selectCountByUpdateTimeGt(Date maxUpdateTime);
default PageResult<PayChannelDO> selectPage(PayChannelPageReqVO reqVO) {
return selectPage(reqVO, new QueryWrapperX<PayChannelDO>()
@ -33,7 +33,7 @@ public interface PayChannelMapper extends BaseMapperX<PayChannelDO> {
.eqIfPresent("merchant_id", reqVO.getMerchantId())
.eqIfPresent("app_id", reqVO.getAppId())
.betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
.orderByDesc("id") );
.orderByDesc("id"));
}
default List<PayChannelDO> selectList(PayChannelExportReqVO reqVO) {
@ -45,7 +45,7 @@ public interface PayChannelMapper extends BaseMapperX<PayChannelDO> {
.eqIfPresent("merchant_id", reqVO.getMerchantId())
.eqIfPresent("app_id", reqVO.getAppId())
.betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
.orderByDesc("id") );
.orderByDesc("id"));
}
/**

View File

@ -106,7 +106,7 @@ public class PayChannelServiceImpl implements PayChannelService {
if (maxUpdateTime == null) { // 如果更新时间为空说明 DB 一定有新数据
log.info("[loadPayChannelIfUpdate][首次加载全量支付渠道]");
} else { // 判断数据库中是否有更新的支付渠道
if (channelMapper.selectExistsByUpdateTimeAfter(maxUpdateTime) == null) {
if (channelMapper.selectCountByUpdateTimeGt(maxUpdateTime) == 0) {
return null;
}
log.info("[loadPayChannelIfUpdate][增量加载全量支付渠道]");

View File

@ -35,7 +35,6 @@ public class DictTypeDO extends BaseDO {
/**
* 字典类型
*/
@TableField("\"type\"")
private String type;
/**
* 状态

View File

@ -72,7 +72,6 @@ public class OperateLogDO extends BaseDO {
*
* 枚举 {@link OperateTypeEnum}
*/
@TableField("operate_type")
private Integer type;
/**
* 操作内容记录整个操作的明细

View File

@ -4,7 +4,6 @@ import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.system.enums.notice.NoticeTypeEnum;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
@ -33,7 +32,6 @@ public class NoticeDO extends BaseDO {
*
* 枚举 {@link NoticeTypeEnum}
*/
@TableField("\"type\"")
private Integer type;
/**
* 公告内容

View File

@ -4,7 +4,6 @@ import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.system.enums.permission.MenuTypeEnum;
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 lombok.Data;
@ -46,7 +45,6 @@ public class MenuDO extends BaseDO {
*
* 枚举 {@link MenuTypeEnum}
*/
@TableField("menu_type")
private Integer type;
/**
* 显示顺序

View File

@ -30,7 +30,7 @@ public interface DeptMapper extends BaseMapperX<DeptDO> {
return selectCount(DeptDO::getParentId, parentId);
}
@Select("SELECT id FROM system_dept WHERE update_time > #{maxUpdateTime} LIMIT 1")
Long selectExistsByUpdateTimeAfter(Date maxUpdateTime);
@Select("SELECT COUNT(*) FROM system_dept WHERE update_time > #{maxUpdateTime}")
Long selectCountByUpdateTimeGt(Date maxUpdateTime);
}

View File

@ -46,7 +46,7 @@ public interface DictDataMapper extends BaseMapperX<DictDataDO> {
.eqIfPresent(DictDataDO::getStatus, reqVO.getStatus()));
}
@Select("SELECT id FROM system_dict_data WHERE update_time > #{maxUpdateTime} LIMIT 1")
Long selectExistsByUpdateTimeAfter(Date maxUpdateTime);
@Select("SELECT COUNT(*) FROM system_dict_data WHERE update_time > #{maxUpdateTime}")
Long selectCountByUpdateTimeGt(Date maxUpdateTime);
}

View File

@ -28,7 +28,7 @@ public interface MenuMapper extends BaseMapperX<MenuDO> {
.eqIfPresent(MenuDO::getStatus, reqVO.getStatus()));
}
@Select("SELECT id FROM system_menu WHERE update_time > #{maxUpdateTime} LIMIT 1")
MenuDO selectExistsByUpdateTimeAfter(Date maxUpdateTime);
@Select("SELECT COUNT(*) FROM system_menu WHERE update_time > #{maxUpdateTime}")
Long selectCountByUpdateTimeGt(Date maxUpdateTime);
}

View File

@ -46,7 +46,7 @@ public interface RoleMapper extends BaseMapperX<RoleDO> {
return selectList(RoleDO::getStatus, statuses);
}
@Select("SELECT id FROM system_role WHERE update_time > #{maxUpdateTime} LIMIT 1")
RoleDO selectExistsByUpdateTimeAfter(Date maxUpdateTime);
@Select("SELECT COUNT(*) FROM system_role WHERE update_time > #{maxUpdateTime}")
Long selectCountByUpdateTimeGt(Date maxUpdateTime);
}

View File

@ -11,7 +11,6 @@ import org.springframework.stereotype.Repository;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
@Mapper
public interface RoleMenuMapper extends BaseMapperX<RoleMenuDO> {
@ -37,7 +36,7 @@ public interface RoleMenuMapper extends BaseMapperX<RoleMenuDO> {
delete(new QueryWrapper<RoleMenuDO>().eq("role_id", roleId));
}
@Select("SELECT id FROM system_role_menu WHERE update_time > #{maxUpdateTime} LIMIT 1")
Long selectExistsByUpdateTimeAfter(Date maxUpdateTime);
@Select("SELECT COUNT(*) FROM system_role_menu WHERE update_time > #{maxUpdateTime}")
Long selectCountByUpdateTimeGt(Date maxUpdateTime);
}

View File

@ -42,6 +42,7 @@ public interface SensitiveWordMapper extends BaseMapperX<SensitiveWordDO> {
return selectOne(SensitiveWordDO::getName, name);
}
@Select("SELECT id FROM system_sensitive_word WHERE update_time > #{maxUpdateTime} LIMIT 1")
SensitiveWordDO selectExistsByUpdateTimeAfter(Date maxUpdateTime);
@Select("SELECT COUNT(*) FROM system_sensitive_word WHERE update_time > #{maxUpdateTime}")
Long selectCountByUpdateTimeGt(Date maxUpdateTime);
}

View File

@ -21,7 +21,7 @@ public interface SmsChannelMapper extends BaseMapperX<SmsChannelDO> {
.orderByDesc(SmsChannelDO::getId));
}
@Select("SELECT id FROM system_sms_channel WHERE update_time > #{maxUpdateTime} LIMIT 1")
Long selectExistsByUpdateTimeAfter(Date maxUpdateTime);
@Select("SELECT COUNT(*) FROM system_sms_channel WHERE update_time > #{maxUpdateTime}")
Long selectCountByUpdateTimeGt(Date maxUpdateTime);
}

View File

@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.system.dal.mysql.sms;
import cn.iocoder.yudao.framework.mybatis.core.enums.SqlConstants;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsCodeDO;
import org.apache.ibatis.annotations.Mapper;
@ -18,9 +18,12 @@ public interface SmsCodeMapper extends BaseMapperX<SmsCodeDO> {
* @return 手机验证码
*/
default SmsCodeDO selectLastByMobile(String mobile, String code, Integer scene) {
return selectOne(new QueryWrapperX<SmsCodeDO>()
.eq("mobile", mobile).eqIfPresent("scene", scene).eqIfPresent("code", code)
.orderByDesc("id").last(SqlConstants.LIMIT1));
return selectOne(new LambdaQueryWrapperX<SmsCodeDO>()
.eq(SmsCodeDO::getCode, mobile)
.eqIfPresent(SmsCodeDO::getScene, scene)
.eqIfPresent(SmsCodeDO::getCode, code)
.orderByDesc(SmsCodeDO::getId)
.last(SqlConstants.LIMIT1));
}
}

View File

@ -15,8 +15,8 @@ import java.util.List;
@Mapper
public interface SmsTemplateMapper extends BaseMapperX<SmsTemplateDO> {
@Select("SELECT id FROM system_sms_template WHERE update_time > #{maxUpdateTime} LIMIT 1")
Long selectExistsByUpdateTimeAfter(Date maxUpdateTime);
@Select("SELECT COUNT(*) FROM system_sms_template WHERE update_time > #{maxUpdateTime}")
Long selectCountByUpdateTimeGt(Date maxUpdateTime);
default SmsTemplateDO selectByCode(String code) {
return selectOne(SmsTemplateDO::getCode, code);

View File

@ -52,7 +52,7 @@ public interface TenantMapper extends BaseMapperX<TenantDO> {
return selectList(TenantDO::getPackageId, packageId);
}
@Select("SELECT id FROM system_tenant WHERE update_time > #{maxUpdateTime} LIMIT 1")
Long selectExistsByUpdateTimeAfter(Date maxUpdateTime);
@Select("SELECT COUNT(*) FROM system_tenant WHERE update_time > #{maxUpdateTime}")
Long selectCountByUpdateTimeGt(Date maxUpdateTime);
}

View File

@ -117,7 +117,7 @@ public class DeptServiceImpl implements DeptService {
if (maxUpdateTime == null) { // 如果更新时间为空说明 DB 一定有新数据
log.info("[loadMenuIfUpdate][首次加载全量部门]");
} else { // 判断数据库中是否有更新的部门
if (deptMapper.selectExistsByUpdateTimeAfter(maxUpdateTime) == null) {
if (deptMapper.selectCountByUpdateTimeGt(maxUpdateTime) == 0) {
return null;
}
log.info("[loadMenuIfUpdate][增量加载全量部门]");

View File

@ -115,7 +115,7 @@ public class DictDataServiceImpl implements DictDataService {
if (maxUpdateTime == null) { // 如果更新时间为空说明 DB 一定有新数据
log.info("[loadDictDataIfUpdate][首次加载全量字典数据]");
} else { // 判断数据库中是否有更新的字典数据
if (dictDataMapper.selectExistsByUpdateTimeAfter(maxUpdateTime) == null) {
if (dictDataMapper.selectCountByUpdateTimeGt(maxUpdateTime) == 0) {
return null;
}
log.info("[loadDictDataIfUpdate][增量加载全量字典数据]");

View File

@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.system.service.dict;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.system.controller.admin.dict.vo.type.DictTypeCreateReqVO;
import cn.iocoder.yudao.module.system.controller.admin.dict.vo.type.DictTypeExportReqVO;
@ -113,6 +114,9 @@ public class DictTypeServiceImpl implements DictTypeService {
@VisibleForTesting
public void checkDictTypeUnique(Long id, String type) {
if (StrUtil.isEmpty(type)) {
return;
}
DictTypeDO dictType = dictTypeMapper.selectByType(type);
if (dictType == null) {
return;

View File

@ -123,7 +123,7 @@ public class MenuServiceImpl implements MenuService {
if (maxUpdateTime == null) { // 如果更新时间为空说明 DB 一定有新数据
log.info("[loadMenuIfUpdate][首次加载全量菜单]");
} else { // 判断数据库中是否有更新的菜单
if (menuMapper.selectExistsByUpdateTimeAfter(maxUpdateTime) == null) {
if (menuMapper.selectCountByUpdateTimeGt(maxUpdateTime) == 0) {
return null;
}
log.info("[loadMenuIfUpdate][增量加载全量菜单]");

View File

@ -144,7 +144,7 @@ public class PermissionServiceImpl implements PermissionService {
if (maxUpdateTime == null) { // 如果更新时间为空说明 DB 一定有新数据
log.info("[loadRoleMenuIfUpdate][首次加载全量角色与菜单的关联]");
} else { // 判断数据库中是否有更新的角色与菜单的关联
if (Objects.isNull(roleMenuMapper.selectExistsByUpdateTimeAfter(maxUpdateTime))) {
if (roleMenuMapper.selectCountByUpdateTimeGt(maxUpdateTime) == 0) {
return null;
}
log.info("[loadRoleMenuIfUpdate][增量加载全量角色与菜单的关联]");

View File

@ -116,7 +116,7 @@ public class RoleServiceImpl implements RoleService {
if (maxUpdateTime == null) { // 如果更新时间为空说明 DB 一定有新数据
log.info("[loadRoleIfUpdate][首次加载全量角色]");
} else { // 判断数据库中是否有更新的角色
if (roleMapper.selectExistsByUpdateTimeAfter(maxUpdateTime) == null) {
if (roleMapper.selectCountByUpdateTimeGt(maxUpdateTime) == 0) {
return null;
}
log.info("[loadRoleIfUpdate][增量加载全量角色]");

View File

@ -139,7 +139,7 @@ public class SensitiveWordServiceImpl implements SensitiveWordService {
if (maxUpdateTime == null) {
log.info("[loadSensitiveWordIfUpdate][首次加载全量敏感词]");
} else { // 判断数据库中是否有更新的敏感词
if (sensitiveWordMapper.selectExistsByUpdateTimeAfter(maxUpdateTime) == null) {
if (sensitiveWordMapper.selectCountByUpdateTimeGt(maxUpdateTime) == 0) {
return null;
}
log.info("[loadSensitiveWordIfUpdate][增量加载全量敏感词]");

View File

@ -94,7 +94,7 @@ public class SmsChannelServiceImpl implements SmsChannelService {
if (maxUpdateTime == null) { // 如果更新时间为空说明 DB 一定有新数据
log.info("[loadSmsChannelIfUpdate][首次加载全量短信渠道]");
} else { // 判断数据库中是否有更新的短信渠道
if (smsChannelMapper.selectExistsByUpdateTimeAfter(maxUpdateTime) == null) {
if (smsChannelMapper.selectCountByUpdateTimeGt(maxUpdateTime) == 0) {
return null;
}
log.info("[loadSmsChannelIfUpdate][增量加载全量短信渠道]");

View File

@ -105,7 +105,7 @@ public class SmsTemplateServiceImpl implements SmsTemplateService {
if (maxUpdateTime == null) { // 如果更新时间为空说明 DB 一定有新数据
log.info("[loadSmsTemplateIfUpdate][首次加载全量短信模板]");
} else { // 判断数据库中是否有更新的短信模板
if (smsTemplateMapper.selectExistsByUpdateTimeAfter(maxUpdateTime) == null) {
if (smsTemplateMapper.selectCountByUpdateTimeGt(maxUpdateTime) == 0) {
return null;
}
log.info("[loadSmsTemplateIfUpdate][增量加载全量短信模板]");

View File

@ -137,7 +137,7 @@ public class TenantServiceImpl implements TenantService {
if (maxUpdateTime == null) { // 如果更新时间为空说明 DB 一定有新数据
log.info("[loadTenantIfUpdate][首次加载全量租户]");
} else { // 判断数据库中是否有更新的租户
if (tenantMapper.selectExistsByUpdateTimeAfter(maxUpdateTime) == null) {
if (tenantMapper.selectCountByUpdateTimeGt(maxUpdateTime) == 0) {
return null;
}
log.info("[loadTenantIfUpdate][增量加载全量租户]");

View File

@ -36,7 +36,7 @@ spring:
time-between-eviction-runs-millis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位:毫秒
min-evictable-idle-time-millis: 300000 # 配置一个连接在池中最小生存的时间,单位:毫秒
max-evictable-idle-time-millis: 900000 # 配置一个连接在池中最大生存的时间,单位:毫秒
validation-query: SELECT 1 # 配置检测连接是否有效
validation-query: SELECT 1 FROM DUAL # 配置检测连接是否有效
test-while-idle: true
test-on-borrow: false
test-on-return: false
@ -44,14 +44,16 @@ spring:
datasource:
master:
name: ruoyi-vue-pro
url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.master.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT # MySQL 连接的示例
# url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.master.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT # MySQL 连接的示例
# url: jdbc:postgresql://127.0.0.1:5432/${spring.datasource.dynamic.datasource.slave.name} # PostgreSQL 连接的示例
url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 连接的示例
username: root
password: 123456
slave: # 模拟从库,可根据自己需要修改
name: ruoyi-vue-pro
url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.slave.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT # MySQL 连接的示例
# url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.slave.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT # MySQL 连接的示例
# url: jdbc:postgresql://127.0.0.1:5432/${spring.datasource.dynamic.datasource.slave.name} # PostgreSQL 连接的示例
url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 连接的示例
username: root
password: 123456

View File

@ -117,8 +117,6 @@ yudao:
- infra_codegen_column
- infra_codegen_table
- infra_test_demo
- tables
- columns
- infra_config
- infra_file_config
- infra_file

View File

@ -15,7 +15,7 @@ const service = axios.create({
// axios中请求配置有baseURL选项表示请求URL公共部分
baseURL: process.env.VUE_APP_BASE_API + '/admin-api/', // 此处的 /admin-api/ 地址,原因是后端的基础路径为 /admin-api/
// 超时
timeout: 10000
timeout: 30000
})
// request拦截器
service.interceptors.request.use(config => {

View File

@ -41,7 +41,7 @@
<el-table v-loading="loading" :data="configList">
<el-table-column label="参数主键" align="center" prop="id" />
<el-table-column label="参数分" align="center" prop="group" />
<el-table-column label="参数分" align="center" prop="group" />
<el-table-column label="参数名称" align="center" prop="name" :show-overflow-tooltip="true" />
<el-table-column label="参数键名" align="center" prop="key" :show-overflow-tooltip="true" />
<el-table-column label="参数键值" align="center" prop="value" />
@ -50,9 +50,9 @@
<dict-tag :type="DICT_TYPE.INFRA_CONFIG_TYPE" :value="scope.row.type" />
</template>
</el-table-column>
<el-table-column label="是否敏感" align="center" prop="sensitive">
<el-table-column label="是否可见" align="center" prop="visible">
<template slot-scope="scope">
<span>{{ scope.row.sensitive ? '是' : '否' }}</span>
<span>{{ scope.row.visible ? '是' : '否' }}</span>
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark" :show-overflow-tooltip="true" />
@ -76,8 +76,8 @@
<!-- 添加或修改参数配置对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="参数分组" prop="group">
<el-input v-model="form.group" placeholder="请输入参数分组" />
<el-form-item label="参数分类" prop="category">
<el-input v-model="form.category" placeholder="请输入参数分类" />
</el-form-item>
<el-form-item label="参数名称" prop="name">
<el-input v-model="form.name" placeholder="请输入参数名称" />
@ -88,8 +88,8 @@
<el-form-item label="参数键值" prop="value">
<el-input v-model="form.value" placeholder="请输入参数键值" />
</el-form-item>
<el-form-item label="是否敏感" prop="type">
<el-radio-group v-model="form.sensitive">
<el-form-item label="是否可见" prop="type">
<el-radio-group v-model="form.visible">
<el-radio :key="true" :label="true"></el-radio>
<el-radio :key="false" :label="false"></el-radio>
</el-radio-group>
@ -143,8 +143,8 @@ export default {
form: {},
//
rules: {
group: [
{ required: true, message: "参数分不能为空", trigger: "blur" }
category: [
{ required: true, message: "参数分不能为空", trigger: "blur" }
],
name: [
{ required: true, message: "参数名称不能为空", trigger: "blur" }