Merge branch 'upstream/master'

# Conflicts:
#	sql/ruoyi-vue-pro.sql
This commit is contained in:
anzhen 2022-05-02 11:50:35 +08:00
commit 18a3f4d3eb
199 changed files with 13057 additions and 7226 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

2443
sql/mysql/ruoyi-vue-pro.sql Normal file

File diff suppressed because it is too large Load Diff

4118
sql/oracle/ruoyi-vue-pro.sql Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,288 +0,0 @@
/*
Navicat Premium Data Transfer
Source Server : 127.0.0.1
Source Server Type : MySQL
Source Server Version : 80026
Source Host : localhost:3306
Source Schema : ruoyi-vue-pro
Target Server Type : MySQL
Target Server Version : 80026
File Encoding : 65001
Date: 05/02/2022 00:50:30
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for QRTZ_BLOB_TRIGGERS
-- ----------------------------
DROP TABLE IF EXISTS `QRTZ_BLOB_TRIGGERS`;
CREATE TABLE `QRTZ_BLOB_TRIGGERS` (
`SCHED_NAME` varchar(120) COLLATE utf8mb4_unicode_ci NOT NULL,
`TRIGGER_NAME` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
`TRIGGER_GROUP` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
`BLOB_DATA` blob,
PRIMARY KEY (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`),
KEY `SCHED_NAME` (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`),
CONSTRAINT `qrtz_blob_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `QRTZ_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- ----------------------------
-- Records of QRTZ_BLOB_TRIGGERS
-- ----------------------------
BEGIN;
COMMIT;
-- ----------------------------
-- Table structure for QRTZ_CALENDARS
-- ----------------------------
DROP TABLE IF EXISTS `QRTZ_CALENDARS`;
CREATE TABLE `QRTZ_CALENDARS` (
`SCHED_NAME` varchar(120) COLLATE utf8mb4_unicode_ci NOT NULL,
`CALENDAR_NAME` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
`CALENDAR` blob NOT NULL,
PRIMARY KEY (`SCHED_NAME`,`CALENDAR_NAME`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- ----------------------------
-- Records of QRTZ_CALENDARS
-- ----------------------------
BEGIN;
COMMIT;
-- ----------------------------
-- Table structure for QRTZ_CRON_TRIGGERS
-- ----------------------------
DROP TABLE IF EXISTS `QRTZ_CRON_TRIGGERS`;
CREATE TABLE `QRTZ_CRON_TRIGGERS` (
`SCHED_NAME` varchar(120) COLLATE utf8mb4_unicode_ci NOT NULL,
`TRIGGER_NAME` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
`TRIGGER_GROUP` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
`CRON_EXPRESSION` varchar(120) COLLATE utf8mb4_unicode_ci NOT NULL,
`TIME_ZONE_ID` varchar(80) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`),
CONSTRAINT `qrtz_cron_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `QRTZ_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- ----------------------------
-- Records of QRTZ_CRON_TRIGGERS
-- ----------------------------
BEGIN;
INSERT INTO `QRTZ_CRON_TRIGGERS` VALUES ('schedulerName', 'payNotifyJob', 'DEFAULT', '* * * * * ?', 'Asia/Shanghai');
INSERT INTO `QRTZ_CRON_TRIGGERS` VALUES ('schedulerName', 'userSessionTimeoutJob', 'DEFAULT', '0 * * * * ? *', 'Asia/Shanghai');
COMMIT;
-- ----------------------------
-- Table structure for QRTZ_FIRED_TRIGGERS
-- ----------------------------
DROP TABLE IF EXISTS `QRTZ_FIRED_TRIGGERS`;
CREATE TABLE `QRTZ_FIRED_TRIGGERS` (
`SCHED_NAME` varchar(120) COLLATE utf8mb4_unicode_ci NOT NULL,
`ENTRY_ID` varchar(95) COLLATE utf8mb4_unicode_ci NOT NULL,
`TRIGGER_NAME` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
`TRIGGER_GROUP` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
`INSTANCE_NAME` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
`FIRED_TIME` bigint NOT NULL,
`SCHED_TIME` bigint NOT NULL,
`PRIORITY` int NOT NULL,
`STATE` varchar(16) COLLATE utf8mb4_unicode_ci NOT NULL,
`JOB_NAME` varchar(190) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`JOB_GROUP` varchar(190) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`IS_NONCONCURRENT` varchar(1) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`REQUESTS_RECOVERY` varchar(1) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (`SCHED_NAME`,`ENTRY_ID`),
KEY `IDX_QRTZ_FT_TRIG_INST_NAME` (`SCHED_NAME`,`INSTANCE_NAME`),
KEY `IDX_QRTZ_FT_INST_JOB_REQ_RCVRY` (`SCHED_NAME`,`INSTANCE_NAME`,`REQUESTS_RECOVERY`),
KEY `IDX_QRTZ_FT_J_G` (`SCHED_NAME`,`JOB_NAME`,`JOB_GROUP`),
KEY `IDX_QRTZ_FT_JG` (`SCHED_NAME`,`JOB_GROUP`),
KEY `IDX_QRTZ_FT_T_G` (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`),
KEY `IDX_QRTZ_FT_TG` (`SCHED_NAME`,`TRIGGER_GROUP`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- ----------------------------
-- Records of QRTZ_FIRED_TRIGGERS
-- ----------------------------
BEGIN;
COMMIT;
-- ----------------------------
-- Table structure for QRTZ_JOB_DETAILS
-- ----------------------------
DROP TABLE IF EXISTS `QRTZ_JOB_DETAILS`;
CREATE TABLE `QRTZ_JOB_DETAILS` (
`SCHED_NAME` varchar(120) COLLATE utf8mb4_unicode_ci NOT NULL,
`JOB_NAME` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
`JOB_GROUP` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
`DESCRIPTION` varchar(250) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`JOB_CLASS_NAME` varchar(250) COLLATE utf8mb4_unicode_ci NOT NULL,
`IS_DURABLE` varchar(1) COLLATE utf8mb4_unicode_ci NOT NULL,
`IS_NONCONCURRENT` varchar(1) COLLATE utf8mb4_unicode_ci NOT NULL,
`IS_UPDATE_DATA` varchar(1) COLLATE utf8mb4_unicode_ci NOT NULL,
`REQUESTS_RECOVERY` varchar(1) COLLATE utf8mb4_unicode_ci NOT NULL,
`JOB_DATA` blob,
PRIMARY KEY (`SCHED_NAME`,`JOB_NAME`,`JOB_GROUP`),
KEY `IDX_QRTZ_J_REQ_RECOVERY` (`SCHED_NAME`,`REQUESTS_RECOVERY`),
KEY `IDX_QRTZ_J_GRP` (`SCHED_NAME`,`JOB_GROUP`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- ----------------------------
-- Records of QRTZ_JOB_DETAILS
-- ----------------------------
BEGIN;
INSERT INTO `QRTZ_JOB_DETAILS` VALUES ('schedulerName', 'payNotifyJob', 'DEFAULT', NULL, 'cn.iocoder.yudao.framework.quartz.core.handler.JobHandlerInvoker', '0', '1', '1', '0', 0xACED0005737200156F72672E71756172747A2E4A6F62446174614D61709FB083E8BFA9B0CB020000787200266F72672E71756172747A2E7574696C732E537472696E674B65794469727479466C61674D61708208E8C3FBC55D280200015A0013616C6C6F77735472616E7369656E74446174617872001D6F72672E71756172747A2E7574696C732E4469727479466C61674D617013E62EAD28760ACE0200025A000564697274794C00036D617074000F4C6A6176612F7574696C2F4D61703B787001737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F4000000000000C770800000010000000027400064A4F425F49447372000E6A6176612E6C616E672E4C6F6E673B8BE490CC8F23DF0200014A000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B020000787000000000000000057400104A4F425F48414E444C45525F4E414D4574000C7061794E6F746966794A6F627800);
INSERT INTO `QRTZ_JOB_DETAILS` VALUES ('schedulerName', 'userSessionTimeoutJob', 'DEFAULT', NULL, 'cn.iocoder.yudao.framework.quartz.core.handler.JobHandlerInvoker', '0', '1', '1', '0', 0xACED0005737200156F72672E71756172747A2E4A6F62446174614D61709FB083E8BFA9B0CB020000787200266F72672E71756172747A2E7574696C732E537472696E674B65794469727479466C61674D61708208E8C3FBC55D280200015A0013616C6C6F77735472616E7369656E74446174617872001D6F72672E71756172747A2E7574696C732E4469727479466C61674D617013E62EAD28760ACE0200025A000564697274794C00036D617074000F4C6A6176612F7574696C2F4D61703B787001737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F4000000000000C770800000010000000027400064A4F425F49447372000E6A6176612E6C616E672E4C6F6E673B8BE490CC8F23DF0200014A000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B0200007870000000000000000D7400104A4F425F48414E444C45525F4E414D457400157573657253657373696F6E54696D656F75744A6F627800);
COMMIT;
-- ----------------------------
-- Table structure for QRTZ_LOCKS
-- ----------------------------
DROP TABLE IF EXISTS `QRTZ_LOCKS`;
CREATE TABLE `QRTZ_LOCKS` (
`SCHED_NAME` varchar(120) COLLATE utf8mb4_unicode_ci NOT NULL,
`LOCK_NAME` varchar(40) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`SCHED_NAME`,`LOCK_NAME`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- ----------------------------
-- Records of QRTZ_LOCKS
-- ----------------------------
BEGIN;
INSERT INTO `QRTZ_LOCKS` VALUES ('schedulerName', 'STATE_ACCESS');
INSERT INTO `QRTZ_LOCKS` VALUES ('schedulerName', 'TRIGGER_ACCESS');
COMMIT;
-- ----------------------------
-- Table structure for QRTZ_PAUSED_TRIGGER_GRPS
-- ----------------------------
DROP TABLE IF EXISTS `QRTZ_PAUSED_TRIGGER_GRPS`;
CREATE TABLE `QRTZ_PAUSED_TRIGGER_GRPS` (
`SCHED_NAME` varchar(120) COLLATE utf8mb4_unicode_ci NOT NULL,
`TRIGGER_GROUP` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`SCHED_NAME`,`TRIGGER_GROUP`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- ----------------------------
-- Records of QRTZ_PAUSED_TRIGGER_GRPS
-- ----------------------------
BEGIN;
COMMIT;
-- ----------------------------
-- Table structure for QRTZ_SCHEDULER_STATE
-- ----------------------------
DROP TABLE IF EXISTS `QRTZ_SCHEDULER_STATE`;
CREATE TABLE `QRTZ_SCHEDULER_STATE` (
`SCHED_NAME` varchar(120) COLLATE utf8mb4_unicode_ci NOT NULL,
`INSTANCE_NAME` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
`LAST_CHECKIN_TIME` bigint NOT NULL,
`CHECKIN_INTERVAL` bigint NOT NULL,
PRIMARY KEY (`SCHED_NAME`,`INSTANCE_NAME`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- ----------------------------
-- Records of QRTZ_SCHEDULER_STATE
-- ----------------------------
BEGIN;
INSERT INTO `QRTZ_SCHEDULER_STATE` VALUES ('schedulerName', 'Yunai.local1635571630493', 1635572537879, 15000);
COMMIT;
-- ----------------------------
-- Table structure for QRTZ_SIMPLE_TRIGGERS
-- ----------------------------
DROP TABLE IF EXISTS `QRTZ_SIMPLE_TRIGGERS`;
CREATE TABLE `QRTZ_SIMPLE_TRIGGERS` (
`SCHED_NAME` varchar(120) COLLATE utf8mb4_unicode_ci NOT NULL,
`TRIGGER_NAME` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
`TRIGGER_GROUP` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
`REPEAT_COUNT` bigint NOT NULL,
`REPEAT_INTERVAL` bigint NOT NULL,
`TIMES_TRIGGERED` bigint NOT NULL,
PRIMARY KEY (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`),
CONSTRAINT `qrtz_simple_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `QRTZ_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- ----------------------------
-- Records of QRTZ_SIMPLE_TRIGGERS
-- ----------------------------
BEGIN;
COMMIT;
-- ----------------------------
-- Table structure for QRTZ_SIMPROP_TRIGGERS
-- ----------------------------
DROP TABLE IF EXISTS `QRTZ_SIMPROP_TRIGGERS`;
CREATE TABLE `QRTZ_SIMPROP_TRIGGERS` (
`SCHED_NAME` varchar(120) COLLATE utf8mb4_unicode_ci NOT NULL,
`TRIGGER_NAME` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
`TRIGGER_GROUP` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
`STR_PROP_1` varchar(512) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`STR_PROP_2` varchar(512) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`STR_PROP_3` varchar(512) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`INT_PROP_1` int DEFAULT NULL,
`INT_PROP_2` int DEFAULT NULL,
`LONG_PROP_1` bigint DEFAULT NULL,
`LONG_PROP_2` bigint DEFAULT NULL,
`DEC_PROP_1` decimal(13,4) DEFAULT NULL,
`DEC_PROP_2` decimal(13,4) DEFAULT NULL,
`BOOL_PROP_1` varchar(1) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`BOOL_PROP_2` varchar(1) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`),
CONSTRAINT `qrtz_simprop_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `QRTZ_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- ----------------------------
-- Records of QRTZ_SIMPROP_TRIGGERS
-- ----------------------------
BEGIN;
COMMIT;
-- ----------------------------
-- Table structure for QRTZ_TRIGGERS
-- ----------------------------
DROP TABLE IF EXISTS `QRTZ_TRIGGERS`;
CREATE TABLE `QRTZ_TRIGGERS` (
`SCHED_NAME` varchar(120) COLLATE utf8mb4_unicode_ci NOT NULL,
`TRIGGER_NAME` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
`TRIGGER_GROUP` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
`JOB_NAME` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
`JOB_GROUP` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
`DESCRIPTION` varchar(250) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`NEXT_FIRE_TIME` bigint DEFAULT NULL,
`PREV_FIRE_TIME` bigint DEFAULT NULL,
`PRIORITY` int DEFAULT NULL,
`TRIGGER_STATE` varchar(16) COLLATE utf8mb4_unicode_ci NOT NULL,
`TRIGGER_TYPE` varchar(8) COLLATE utf8mb4_unicode_ci NOT NULL,
`START_TIME` bigint NOT NULL,
`END_TIME` bigint DEFAULT NULL,
`CALENDAR_NAME` varchar(190) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`MISFIRE_INSTR` smallint DEFAULT NULL,
`JOB_DATA` blob,
PRIMARY KEY (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`),
KEY `IDX_QRTZ_T_J` (`SCHED_NAME`,`JOB_NAME`,`JOB_GROUP`),
KEY `IDX_QRTZ_T_JG` (`SCHED_NAME`,`JOB_GROUP`),
KEY `IDX_QRTZ_T_C` (`SCHED_NAME`,`CALENDAR_NAME`),
KEY `IDX_QRTZ_T_G` (`SCHED_NAME`,`TRIGGER_GROUP`),
KEY `IDX_QRTZ_T_STATE` (`SCHED_NAME`,`TRIGGER_STATE`),
KEY `IDX_QRTZ_T_N_STATE` (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`,`TRIGGER_STATE`),
KEY `IDX_QRTZ_T_N_G_STATE` (`SCHED_NAME`,`TRIGGER_GROUP`,`TRIGGER_STATE`),
KEY `IDX_QRTZ_T_NEXT_FIRE_TIME` (`SCHED_NAME`,`NEXT_FIRE_TIME`),
KEY `IDX_QRTZ_T_NFT_ST` (`SCHED_NAME`,`TRIGGER_STATE`,`NEXT_FIRE_TIME`),
KEY `IDX_QRTZ_T_NFT_MISFIRE` (`SCHED_NAME`,`MISFIRE_INSTR`,`NEXT_FIRE_TIME`),
KEY `IDX_QRTZ_T_NFT_ST_MISFIRE` (`SCHED_NAME`,`MISFIRE_INSTR`,`NEXT_FIRE_TIME`,`TRIGGER_STATE`),
KEY `IDX_QRTZ_T_NFT_ST_MISFIRE_GRP` (`SCHED_NAME`,`MISFIRE_INSTR`,`NEXT_FIRE_TIME`,`TRIGGER_GROUP`,`TRIGGER_STATE`),
CONSTRAINT `qrtz_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`) REFERENCES `QRTZ_JOB_DETAILS` (`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- ----------------------------
-- Records of QRTZ_TRIGGERS
-- ----------------------------
BEGIN;
INSERT INTO `QRTZ_TRIGGERS` VALUES ('schedulerName', 'payNotifyJob', 'DEFAULT', 'payNotifyJob', 'DEFAULT', NULL, 1635572540000, 1635572539000, 5, 'WAITING', 'CRON', 1635294882000, 0, NULL, 0, 0xACED0005737200156F72672E71756172747A2E4A6F62446174614D61709FB083E8BFA9B0CB020000787200266F72672E71756172747A2E7574696C732E537472696E674B65794469727479466C61674D61708208E8C3FBC55D280200015A0013616C6C6F77735472616E7369656E74446174617872001D6F72672E71756172747A2E7574696C732E4469727479466C61674D617013E62EAD28760ACE0200025A000564697274794C00036D617074000F4C6A6176612F7574696C2F4D61703B787001737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F4000000000000C770800000010000000037400114A4F425F48414E444C45525F504152414D707400124A4F425F52455452595F494E54455256414C737200116A6176612E6C616E672E496E746567657212E2A0A4F781873802000149000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B02000078700000000074000F4A4F425F52455452595F434F554E5471007E000B7800);
INSERT INTO `QRTZ_TRIGGERS` VALUES ('schedulerName', 'userSessionTimeoutJob', 'DEFAULT', 'userSessionTimeoutJob', 'DEFAULT', NULL, 1643993400000, -1, 5, 'WAITING', 'CRON', 1643993386000, 0, NULL, 0, 0xACED0005737200156F72672E71756172747A2E4A6F62446174614D61709FB083E8BFA9B0CB020000787200266F72672E71756172747A2E7574696C732E537472696E674B65794469727479466C61674D61708208E8C3FBC55D280200015A0013616C6C6F77735472616E7369656E74446174617872001D6F72672E71756172747A2E7574696C732E4469727479466C61674D617013E62EAD28760ACE0200025A000564697274794C00036D617074000F4C6A6176612F7574696C2F4D61703B787001737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F4000000000000C770800000010000000037400114A4F425F48414E444C45525F504152414D707400124A4F425F52455452595F494E54455256414C737200116A6176612E6C616E672E496E746567657212E2A0A4F781873802000149000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B0200007870000007D074000F4A4F425F52455452595F434F554E547371007E0009000000037800);
COMMIT;
SET FOREIGN_KEY_CHECKS = 1;

View File

@ -25,6 +25,7 @@
<mysql.version>5.1.46</mysql.version> <mysql.version>5.1.46</mysql.version>
<druid.version>1.2.8</druid.version> <druid.version>1.2.8</druid.version>
<mybatis-plus.version>3.4.3.4</mybatis-plus.version> <mybatis-plus.version>3.4.3.4</mybatis-plus.version>
<mybatis-plus-generator.version>3.5.2</mybatis-plus-generator.version>
<dynamic-datasource.version>3.5.0</dynamic-datasource.version> <dynamic-datasource.version>3.5.0</dynamic-datasource.version>
<redisson.version>3.17.0</redisson.version> <redisson.version>3.17.0</redisson.version>
<!-- Config 配置中心相关 --> <!-- Config 配置中心相关 -->
@ -45,6 +46,7 @@
<activiti.version>7.1.0.M6</activiti.version> <activiti.version>7.1.0.M6</activiti.version>
<flowable.version>6.7.0</flowable.version> <flowable.version>6.7.0</flowable.version>
<!-- 工具类相关 --> <!-- 工具类相关 -->
<jasypt-spring-boot-starter.version>3.0.4</jasypt-spring-boot-starter.version>
<lombok.version>1.18.20</lombok.version> <lombok.version>1.18.20</lombok.version>
<mapstruct.version>1.4.1.Final</mapstruct.version> <mapstruct.version>1.4.1.Final</mapstruct.version>
<hutool.version>5.6.1</hutool.version> <hutool.version>5.6.1</hutool.version>
@ -192,6 +194,11 @@
<artifactId>mybatis-plus-boot-starter</artifactId> <artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version> <version>${mybatis-plus.version}</version>
</dependency> </dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId> <!-- 代码生成器,使用它解析表结构 -->
<version>${mybatis-plus-generator.version}</version>
</dependency>
<dependency> <dependency>
<groupId>com.baomidou</groupId> <groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId> <!-- 多数据源 --> <artifactId>dynamic-datasource-spring-boot-starter</artifactId> <!-- 多数据源 -->
@ -428,6 +435,12 @@
<version>${revision}</version> <version>${revision}</version>
</dependency> </dependency>
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId> <!-- 加解密 -->
<version>${jasypt-spring-boot-starter.version}</version>
</dependency>
<dependency> <dependency>
<groupId>cn.iocoder.boot</groupId> <groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-excel</artifactId> <artifactId>yudao-spring-boot-starter-excel</artifactId>

View File

@ -4,29 +4,40 @@ import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.tenant.config.TenantProperties; import cn.iocoder.yudao.framework.tenant.config.TenantProperties;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler; import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
import lombok.AllArgsConstructor;
import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.LongValue; import net.sf.jsqlparser.expression.LongValue;
import java.util.HashSet;
import java.util.Set;
/** /**
* 基于 MyBatis Plus 多租户的功能实现 DB 层面的多租户的功能 * 基于 MyBatis Plus 多租户的功能实现 DB 层面的多租户的功能
* *
* @author 芋道源码 * @author 芋道源码
*/ */
@AllArgsConstructor
public class TenantDatabaseInterceptor implements TenantLineHandler { public class TenantDatabaseInterceptor implements TenantLineHandler {
private final TenantProperties properties; private final Set<String> ignoreTables = new HashSet<>();
public TenantDatabaseInterceptor(TenantProperties properties) {
// 不同 DB 大小写的习惯不同所以需要都添加进去
properties.getIgnoreTables().forEach(table -> {
ignoreTables.add(table.toLowerCase());
ignoreTables.add(table.toUpperCase());
});
// OracleKeyGenerator 生成主键时会查询这个表查询这个表后会自动拼接 TENANT_ID 导致报错
ignoreTables.add("DUAL");
}
@Override @Override
public Expression getTenantId() { public Expression getTenantId() {
return new LongValue( TenantContextHolder.getRequiredTenantId()); return new LongValue(TenantContextHolder.getRequiredTenantId());
} }
@Override @Override
public boolean ignoreTable(String tableName) { public boolean ignoreTable(String tableName) {
return TenantContextHolder.isIgnore() // 情况一全局忽略多租户 return TenantContextHolder.isIgnore() // 情况一全局忽略多租户
|| CollUtil.contains(properties.getIgnoreTables(), tableName); // 情况二忽略多租户的表 || CollUtil.contains(ignoreTables, tableName); // 情况二忽略多租户的表
} }
} }

View File

@ -15,12 +15,12 @@ import java.util.List;
public interface ConfigFrameworkDAO { public interface ConfigFrameworkDAO {
/** /**
* 查询是否存在比 maxUpdateTime 更新记录更晚的配置 * 查询是否存在比 maxUpdateTime 的更新记录数量
* *
* @param maxUpdateTime 最大更新时间 * @param maxUpdateTime 最大更新时间
* @return 是否存在 * @return 是否存在
*/ */
boolean selectExistsByUpdateTimeAfter(Date maxUpdateTime); int selectCountByUpdateTimeGt(Date maxUpdateTime);
/** /**
* 查询配置列表 * 查询配置列表

View File

@ -24,7 +24,6 @@ import java.util.List;
import java.util.Properties; import java.util.Properties;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.function.Predicate;
@Slf4j @Slf4j
public class DBConfigRepository extends AbstractConfigRepository { public class DBConfigRepository extends AbstractConfigRepository {
@ -172,7 +171,7 @@ public class DBConfigRepository extends AbstractConfigRepository {
if (maxUpdateTime == null) { // 如果更新时间为空说明 DB 一定有新数据 if (maxUpdateTime == null) { // 如果更新时间为空说明 DB 一定有新数据
log.info("[loadConfigIfUpdate][首次加载全量配置]"); log.info("[loadConfigIfUpdate][首次加载全量配置]");
} else { // 判断数据库中是否有更新的配置 } else { // 判断数据库中是否有更新的配置
if (!configFrameworkDAO.selectExistsByUpdateTimeAfter(maxUpdateTime)) { if (configFrameworkDAO.selectCountByUpdateTimeGt(maxUpdateTime) == 0) {
return null; return null;
} }
log.info("[loadConfigIfUpdate][增量加载全量配置]"); log.info("[loadConfigIfUpdate][增量加载全量配置]");

View File

@ -36,7 +36,6 @@
<artifactId>jakarta.validation-api</artifactId> <artifactId>jakarta.validation-api</artifactId>
</dependency> </dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -38,6 +38,15 @@
<artifactId>mysql-connector-java</artifactId> <artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version> <version>${mysql.version}</version>
</dependency> </dependency>
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<dependency> <dependency>
<groupId>com.alibaba</groupId> <groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId> <artifactId>druid-spring-boot-starter</artifactId>

View File

@ -0,0 +1,105 @@
package cn.iocoder.yudao.framework.mybatis.config;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
import cn.iocoder.yudao.framework.mybatis.core.enums.SqlConstants;
import cn.iocoder.yudao.framework.mybatis.core.util.JdbcUtils;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.env.ConfigurableEnvironment;
import java.util.Set;
/**
* IdType {@link IdType#NONE} 根据 PRIMARY 数据源所使用的数据库自动设置
*
* @author 芋道源码
*/
@Slf4j
public class IdTypeEnvironmentPostProcessor implements EnvironmentPostProcessor {
private static final String ID_TYPE_KEY = "mybatis-plus.global-config.db-config.id-type";
private static final String DATASOURCE_DYNAMIC_KEY = "spring.datasource.dynamic";
private static final String QUARTZ_JOB_STORE_DRIVER_KEY = "spring.quartz.properties.org.quartz.jobStore.driverDelegateClass";
private static final Set<DbType> INPUT_ID_TYPES = SetUtils.asSet(DbType.ORACLE, DbType.ORACLE_12C,
DbType.POSTGRE_SQL, DbType.KINGBASE_ES, DbType.DB2, DbType.H2);
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
// 如果获取不到 DbType则不进行处理
DbType dbType = getDbType(environment);
if (dbType == null) {
return;
}
// 设置 Quartz JobStore 对应的 Driver
// TODO 芋艿暂时没有找到特别合适的地方先放在这里
setJobStoreDriverIfPresent(environment, dbType);
// 初始化 SQL 静态变量
SqlConstants.init(dbType);
// 如果非 NONE则不进行处理
IdType idType = getIdType(environment);
if (idType != IdType.NONE) {
return;
}
// 情况一用户输入 ID适合 OraclePostgreSQLKingbaseDB2H2 数据库
if (INPUT_ID_TYPES.contains(dbType)) {
setIdType(environment, IdType.INPUT);
return;
}
// 情况二自增 ID适合 MySQL 等直接自增的数据库
setIdType(environment, IdType.AUTO);
}
public IdType getIdType(ConfigurableEnvironment environment) {
return environment.getProperty(ID_TYPE_KEY, IdType.class);
}
public void setIdType(ConfigurableEnvironment environment, IdType idType) {
environment.getSystemProperties().put(ID_TYPE_KEY, idType);
log.info("[setIdType][修改 MyBatis Plus 的 idType 为({})]", idType);
}
public void setJobStoreDriverIfPresent(ConfigurableEnvironment environment, DbType dbType) {
String driverClass = environment.getProperty(QUARTZ_JOB_STORE_DRIVER_KEY);
if (StrUtil.isNotEmpty(driverClass)) {
return;
}
// 根据 dbType 类型获取对应的 driverClass
switch (dbType) {
case POSTGRE_SQL:
driverClass = "org.quartz.impl.jdbcjobstore.PostgreSQLDelegate";
break;
case ORACLE:
case ORACLE_12C:
driverClass = "org.quartz.impl.jdbcjobstore.oracle.OracleDelegate";
break;
}
// 设置 driverClass 变量
if (StrUtil.isNotEmpty(driverClass)) {
environment.getSystemProperties().put(QUARTZ_JOB_STORE_DRIVER_KEY, driverClass);
}
}
public static DbType getDbType(ConfigurableEnvironment environment) {
String primary = environment.getProperty(DATASOURCE_DYNAMIC_KEY + "." + "primary");
if (StrUtil.isEmpty(primary)) {
return null;
}
String url = environment.getProperty(DATASOURCE_DYNAMIC_KEY + ".datasource." + primary + ".url");
if (StrUtil.isEmpty(url)) {
return null;
}
return JdbcUtils.getDbType(url);
}
}

View File

@ -1,13 +1,22 @@
package cn.iocoder.yudao.framework.mybatis.config; package cn.iocoder.yudao.framework.mybatis.config;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.mybatis.core.handler.DefaultDBFieldHandler; import cn.iocoder.yudao.framework.mybatis.core.handler.DefaultDBFieldHandler;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.core.incrementer.IKeyGenerator;
import com.baomidou.mybatisplus.extension.incrementer.H2KeyGenerator;
import com.baomidou.mybatisplus.extension.incrementer.KingbaseKeyGenerator;
import com.baomidou.mybatisplus.extension.incrementer.OracleKeyGenerator;
import com.baomidou.mybatisplus.extension.incrementer.PostgreKeyGenerator;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.mybatis.spring.annotation.MapperScan; import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.ConfigurableEnvironment;
/** /**
* MyBaits 配置类 * MyBaits 配置类
@ -31,4 +40,25 @@ public class YudaoMybatisAutoConfiguration {
return new DefaultDBFieldHandler(); // 自动填充参数类 return new DefaultDBFieldHandler(); // 自动填充参数类
} }
@Bean
@ConditionalOnProperty(prefix = "mybatis-plus.global-config.db-config", name = "id-type", havingValue = "INPUT")
public IKeyGenerator keyGenerator(ConfigurableEnvironment environment) {
DbType dbType = IdTypeEnvironmentPostProcessor.getDbType(environment);
if (dbType != null) {
switch (dbType) {
case POSTGRE_SQL:
return new PostgreKeyGenerator();
case ORACLE:
case ORACLE_12C:
return new OracleKeyGenerator();
case H2:
return new H2KeyGenerator();
case KINGBASE_ES:
return new KingbaseKeyGenerator();
}
}
// 找不到合适的 IKeyGenerator 实现类
throw new IllegalArgumentException(StrUtil.format("DbType{} 找不到合适的 IKeyGenerator 实现类", dbType));
}
} }

View File

@ -3,8 +3,8 @@ package cn.iocoder.yudao.framework.mybatis.core.dataobject;
import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableLogic; import com.baomidou.mybatisplus.annotation.TableLogic;
import lombok.Builder;
import lombok.Data; import lombok.Data;
import org.apache.ibatis.type.JdbcType;
import java.io.Serializable; import java.io.Serializable;
import java.util.Date; import java.util.Date;
@ -32,14 +32,14 @@ public abstract class BaseDO implements Serializable {
* *
* 使用 String 类型的原因是未来可能会存在非数值的情况留好拓展性 * 使用 String 类型的原因是未来可能会存在非数值的情况留好拓展性
*/ */
@TableField(fill = FieldFill.INSERT) @TableField(fill = FieldFill.INSERT, jdbcType = JdbcType.VARCHAR)
private String creator; private String creator;
/** /**
* 更新者目前使用 SysUser id 编号 * 更新者目前使用 SysUser id 编号
* *
* 使用 String 类型的原因是未来可能会存在非数值的情况留好拓展性 * 使用 String 类型的原因是未来可能会存在非数值的情况留好拓展性
*/ */
@TableField(fill = FieldFill.INSERT_UPDATE) @TableField(fill = FieldFill.INSERT_UPDATE, jdbcType = JdbcType.VARCHAR)
private String updater; private String updater;
/** /**
* 是否删除 * 是否删除

View File

@ -1,11 +1,21 @@
package cn.iocoder.yudao.framework.mybatis.core.enums; package cn.iocoder.yudao.framework.mybatis.core.enums;
import com.baomidou.mybatisplus.annotation.DbType;
/** /**
* SQL相关常量类 * SQL相关常量类
*
* @author 芋道源码
*/ */
public interface SqlConstants { public class SqlConstants {
/**
* 数据库的类型
*/
public static DbType DB_TYPE;
String LIMIT1 = "LIMIT 1"; public static void init(DbType dbType) {
DB_TYPE = dbType;
}
} }

View File

@ -1,5 +1,7 @@
package cn.iocoder.yudao.framework.mybatis.core.query; package cn.iocoder.yudao.framework.mybatis.core.query;
import cn.hutool.core.lang.Assert;
import cn.iocoder.yudao.framework.mybatis.core.enums.SqlConstants;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ArrayUtils; import com.baomidou.mybatisplus.core.toolkit.ArrayUtils;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
@ -124,4 +126,24 @@ public class QueryWrapperX<T> extends QueryWrapper<T> {
return this; return this;
} }
/**
* 设置只返回最后一条
*
* TODO 芋艿不是完美解需要在思考下如果使用多数据源并且数据源是多种类型时可能会存在问题实现之返回一条的语法不同
*
* @return this
*/
public QueryWrapperX<T> limit1() {
Assert.notNull(SqlConstants.DB_TYPE, "获取不到数据库的类型");
switch (SqlConstants.DB_TYPE) {
case ORACLE:
case ORACLE_12C:
super.eq("ROWNUM", 1);
break;
default:
super.last("LIMIT 1");
}
return this;
}
} }

View File

@ -0,0 +1,42 @@
package cn.iocoder.yudao.framework.mybatis.core.util;
import com.baomidou.mybatisplus.annotation.DbType;
import java.sql.Connection;
import java.sql.DriverManager;
/**
* JDBC 工具类
*
* @author 芋道源码
*/
public class JdbcUtils {
/**
* 判断连接是否正确
*
* @param url 数据源连接
* @param username 账号
* @param password 密码
* @return 是否正确
*/
public static boolean isConnectionOK(String url, String username, String password) {
try (Connection ignored = DriverManager.getConnection(url, username, password)) {
return true;
} catch (Exception ex) {
return false;
}
}
/**
* 获得 URL 对应的 DB 类型
*
* @param url URL
* @return DB 类型
*/
public static DbType getDbType(String url) {
String name = com.alibaba.druid.util.JdbcUtils.getDbType(url, null);
return DbType.getDbType(name);
}
}

View File

@ -1,3 +1,5 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.iocoder.yudao.framework.datasource.config.YudaoDataSourceAutoConfiguration,\ cn.iocoder.yudao.framework.datasource.config.YudaoDataSourceAutoConfiguration,\
cn.iocoder.yudao.framework.mybatis.config.YudaoMybatisAutoConfiguration cn.iocoder.yudao.framework.mybatis.config.YudaoMybatisAutoConfiguration
org.springframework.boot.env.EnvironmentPostProcessor=\
cn.iocoder.yudao.framework.mybatis.config.IdTypeEnvironmentPostProcessor

View File

@ -3,12 +3,8 @@ package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Map;
@ApiModel("管理后台 - 通过流程任务的 Request VO") @ApiModel("管理后台 - 通过流程任务的 Request VO")
@Data @Data
@ -20,6 +16,6 @@ public class BpmTaskApproveReqVO {
@ApiModelProperty(value = "审批意见", required = true, example = "不错不错!") @ApiModelProperty(value = "审批意见", required = true, example = "不错不错!")
@NotEmpty(message = "审批意见不能为空") @NotEmpty(message = "审批意见不能为空")
private String comment; private String reason;
} }

View File

@ -22,6 +22,6 @@ public class BpmTaskDonePageItemRespVO extends BpmTaskTodoPageItemRespVO {
@ApiModelProperty(value = "任务结果", required = true, notes = "参见 bpm_process_instance_result", example = "2") @ApiModelProperty(value = "任务结果", required = true, notes = "参见 bpm_process_instance_result", example = "2")
private Integer result; private Integer result;
@ApiModelProperty(value = "审批建议", required = true, example = "不请假了!") @ApiModelProperty(value = "审批建议", required = true, example = "不请假了!")
private String comment; private String reason;
} }

View File

@ -16,6 +16,6 @@ public class BpmTaskRejectReqVO {
@ApiModelProperty(value = "审批意见", required = true, example = "不错不错!") @ApiModelProperty(value = "审批意见", required = true, example = "不错不错!")
@NotEmpty(message = "审批意见不能为空") @NotEmpty(message = "审批意见不能为空")
private String comment; private String reason;
} }

View File

@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.bpm.dal.dataobject.definition; package cn.iocoder.yudao.module.bpm.dal.dataobject.definition;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; 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.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
@ -16,6 +17,7 @@ import java.util.List;
* @author 芋道源码 * @author 芋道源码
*/ */
@TableName(value = "bpm_form", autoResultMap = true) @TableName(value = "bpm_form", autoResultMap = true)
@KeySequence("bpm_form_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true) @ToString(callSuper = true)

View File

@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.bpm.dal.dataobject.definition;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum; import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
@ -17,6 +18,7 @@ import java.util.List;
* @author 芋道源码 * @author 芋道源码
*/ */
@TableName(value = "bpm_process_definition_ext", autoResultMap = true) @TableName(value = "bpm_process_definition_ext", autoResultMap = true)
@KeySequence("bpm_process_definition_ext_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true) @ToString(callSuper = true)

View File

@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.framework.mybatis.core.type.JsonLongSetTypeHandler; import cn.iocoder.yudao.framework.mybatis.core.type.JsonLongSetTypeHandler;
import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum;
import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum; import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
@ -21,6 +22,7 @@ import java.util.Set;
* @author 芋道源码 * @author 芋道源码
*/ */
@TableName(value = "bpm_task_assign_rule", autoResultMap = true) @TableName(value = "bpm_task_assign_rule", autoResultMap = true)
@KeySequence("bpm_task_assign_rule_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true) @ToString(callSuper = true)
@ -31,8 +33,9 @@ public class BpmTaskAssignRuleDO extends BaseDO {
/** /**
* {@link #processDefinitionId} 空串用于标识属于流程模型而不属于流程定义 * {@link #processDefinitionId} 空串用于标识属于流程模型而不属于流程定义
* 不使用空串的原因Oracle 针对空串会处理成 null进而导致无法检索
*/ */
public static final String PROCESS_DEFINITION_ID_NULL = ""; public static final String PROCESS_DEFINITION_ID_NULL = "DEFAULT";
/** /**
* 编号 * 编号
@ -64,7 +67,6 @@ public class BpmTaskAssignRuleDO extends BaseDO {
* *
* 枚举 {@link BpmTaskAssignRuleTypeEnum} * 枚举 {@link BpmTaskAssignRuleTypeEnum}
*/ */
@TableField("`type`")
private Integer type; private Integer type;
/** /**
* 规则值数组一般关联指定表的编号 * 规则值数组一般关联指定表的编号

View File

@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.bpm.dal.dataobject.definition;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.framework.mybatis.core.type.JsonLongSetTypeHandler; import cn.iocoder.yudao.framework.mybatis.core.type.JsonLongSetTypeHandler;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
@ -16,6 +17,7 @@ import java.util.Set;
* @author 芋道源码 * @author 芋道源码
*/ */
@TableName(value = "bpm_user_group", autoResultMap = true) @TableName(value = "bpm_user_group", autoResultMap = true)
@KeySequence("bpm_user_group_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true) @ToString(callSuper = true)

View File

@ -1,10 +1,13 @@
package cn.iocoder.yudao.module.bpm.dal.dataobject.oa; package cn.iocoder.yudao.module.bpm.dal.dataobject.oa;
import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
import lombok.*;
import java.util.*;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; 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.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
import java.util.Date;
/** /**
* OA 请假申请 DO * OA 请假申请 DO
@ -15,6 +18,7 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
* @author 芋道源码 * @author 芋道源码
*/ */
@TableName("bpm_oa_leave") @TableName("bpm_oa_leave")
@KeySequence("bpm_oa_leave_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true) @ToString(callSuper = true)
@ -37,8 +41,7 @@ public class BpmOALeaveDO extends BaseDO {
/** /**
* 请假类型 * 请假类型
*/ */
@TableField("`type`") private Integer type;
private String type;
/** /**
* 原因 * 原因
*/ */

View File

@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.bpm.dal.dataobject.task;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum; import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
@ -21,6 +22,7 @@ import java.util.Map;
* @author 芋道源码 * @author 芋道源码
*/ */
@TableName(value = "bpm_process_instance_ext", autoResultMap = true) @TableName(value = "bpm_process_instance_ext", autoResultMap = true)
@KeySequence("bpm_process_instance_ext_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true) @ToString(callSuper = true)

View File

@ -2,6 +2,8 @@ package cn.iocoder.yudao.module.bpm.dal.dataobject.task;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; 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.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data; import lombok.Data;
@ -17,6 +19,7 @@ import java.util.Date;
* @author 芋道源码 * @author 芋道源码
*/ */
@TableName(value = "bpm_task_ext", autoResultMap = true) @TableName(value = "bpm_task_ext", autoResultMap = true)
@KeySequence("bpm_task_ext_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true) @ToString(callSuper = true)
@ -60,7 +63,7 @@ public class BpmTaskExtDO extends BaseDO {
/** /**
* 审批建议 * 审批建议
*/ */
private String comment; private String reason;
/** /**
* 任务的结束时间 * 任务的结束时间
* *

View File

@ -1,11 +1,11 @@
package cn.iocoder.yudao.module.bpm.dal.mysql.definition; package cn.iocoder.yudao.module.bpm.dal.mysql.definition;
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormPageReqVO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 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.bpm.controller.admin.definition.vo.form.BpmFormPageReqVO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
/** /**
@ -17,9 +17,9 @@ import org.apache.ibatis.annotations.Mapper;
public interface BpmFormMapper extends BaseMapperX<BpmFormDO> { public interface BpmFormMapper extends BaseMapperX<BpmFormDO> {
default PageResult<BpmFormDO> selectPage(BpmFormPageReqVO reqVO) { default PageResult<BpmFormDO> selectPage(BpmFormPageReqVO reqVO) {
return selectPage(reqVO, new QueryWrapperX<BpmFormDO>() return selectPage(reqVO, new LambdaQueryWrapperX<BpmFormDO>()
.likeIfPresent("name", reqVO.getName()) .likeIfPresent(BpmFormDO::getName, reqVO.getName())
.orderByDesc("id")); .orderByDesc(BpmFormDO::getId));
} }
} }

View File

@ -1,8 +1,7 @@
package cn.iocoder.yudao.module.bpm.dal.mysql.definition; package cn.iocoder.yudao.module.bpm.dal.mysql.definition;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import java.util.Collection; import java.util.Collection;
@ -12,11 +11,11 @@ import java.util.List;
public interface BpmProcessDefinitionExtMapper extends BaseMapperX<BpmProcessDefinitionExtDO> { public interface BpmProcessDefinitionExtMapper extends BaseMapperX<BpmProcessDefinitionExtDO> {
default List<BpmProcessDefinitionExtDO> selectListByProcessDefinitionIds(Collection<String> processDefinitionIds) { default List<BpmProcessDefinitionExtDO> selectListByProcessDefinitionIds(Collection<String> processDefinitionIds) {
return selectList("process_definition_id", processDefinitionIds); return selectList(BpmProcessDefinitionExtDO::getProcessDefinitionId, processDefinitionIds);
} }
default BpmProcessDefinitionExtDO selectByProcessDefinitionId(String processDefinitionId) { default BpmProcessDefinitionExtDO selectByProcessDefinitionId(String processDefinitionId) {
return selectOne("process_definition_id", processDefinitionId); return selectOne(BpmProcessDefinitionExtDO::getProcessDefinitionId, processDefinitionId);
} }
} }

View File

@ -1,8 +1,8 @@
package cn.iocoder.yudao.module.bpm.dal.mysql.definition; package cn.iocoder.yudao.module.bpm.dal.mysql.definition;
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 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.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
@ -13,23 +13,23 @@ public interface BpmTaskAssignRuleMapper extends BaseMapperX<BpmTaskAssignRuleDO
default List<BpmTaskAssignRuleDO> selectListByProcessDefinitionId(String processDefinitionId, default List<BpmTaskAssignRuleDO> selectListByProcessDefinitionId(String processDefinitionId,
@Nullable String taskDefinitionKey) { @Nullable String taskDefinitionKey) {
return selectList(new QueryWrapperX<BpmTaskAssignRuleDO>() return selectList(new LambdaQueryWrapperX<BpmTaskAssignRuleDO>()
.eq("process_definition_id", processDefinitionId) .eq(BpmTaskAssignRuleDO::getProcessDefinitionId, processDefinitionId)
.eqIfPresent("task_definition_key", taskDefinitionKey)); .eqIfPresent(BpmTaskAssignRuleDO::getTaskDefinitionKey, taskDefinitionKey));
} }
default List<BpmTaskAssignRuleDO> selectListByModelId(String modelId) { default List<BpmTaskAssignRuleDO> selectListByModelId(String modelId) {
return selectList(new QueryWrapperX<BpmTaskAssignRuleDO>() return selectList(new LambdaQueryWrapperX<BpmTaskAssignRuleDO>()
.eq("model_id", modelId) .eq(BpmTaskAssignRuleDO::getModelId, modelId)
.eq("process_definition_id", BpmTaskAssignRuleDO.PROCESS_DEFINITION_ID_NULL)); .eq(BpmTaskAssignRuleDO::getProcessDefinitionId, BpmTaskAssignRuleDO.PROCESS_DEFINITION_ID_NULL));
} }
default BpmTaskAssignRuleDO selectListByModelIdAndTaskDefinitionKey(String modelId, default BpmTaskAssignRuleDO selectListByModelIdAndTaskDefinitionKey(String modelId,
String taskDefinitionKey) { String taskDefinitionKey) {
return selectOne(new QueryWrapperX<BpmTaskAssignRuleDO>() return selectOne(new LambdaQueryWrapperX<BpmTaskAssignRuleDO>()
.eq("model_id", modelId) .eq(BpmTaskAssignRuleDO::getModelId, modelId)
.eq("process_definition_id", BpmTaskAssignRuleDO.PROCESS_DEFINITION_ID_NULL) .eq(BpmTaskAssignRuleDO::getProcessDefinitionId, BpmTaskAssignRuleDO.PROCESS_DEFINITION_ID_NULL)
.eq("task_definition_key", taskDefinitionKey)); .eq(BpmTaskAssignRuleDO::getTaskDefinitionKey, taskDefinitionKey));
} }
} }

View File

@ -1,35 +1,34 @@
package cn.iocoder.yudao.module.bpm.dal.mysql.task; package cn.iocoder.yudao.module.bpm.dal.mysql.task;
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceMyPageReqVO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 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 com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceMyPageReqVO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
@Mapper @Mapper
public interface BpmProcessInstanceExtMapper extends BaseMapperX<BpmProcessInstanceExtDO> { public interface BpmProcessInstanceExtMapper extends BaseMapperX<BpmProcessInstanceExtDO> {
default PageResult<BpmProcessInstanceExtDO> selectPage(Long userId, BpmProcessInstanceMyPageReqVO reqVO) { default PageResult<BpmProcessInstanceExtDO> selectPage(Long userId, BpmProcessInstanceMyPageReqVO reqVO) {
return selectPage(reqVO, new QueryWrapperX<BpmProcessInstanceExtDO>() return selectPage(reqVO, new LambdaQueryWrapperX<BpmProcessInstanceExtDO>()
.eqIfPresent("start_user_id", userId) .eqIfPresent(BpmProcessInstanceExtDO::getStartUserId, userId)
.likeIfPresent("name", reqVO.getName()) .likeIfPresent(BpmProcessInstanceExtDO::getName, reqVO.getName())
.eqIfPresent("process_definition_id", reqVO.getProcessDefinitionId()) .eqIfPresent(BpmProcessInstanceExtDO::getProcessDefinitionId, reqVO.getProcessDefinitionId())
.eqIfPresent("category", reqVO.getCategory()) .eqIfPresent(BpmProcessInstanceExtDO::getCategory, reqVO.getCategory())
.eqIfPresent("status", reqVO.getStatus()) .eqIfPresent(BpmProcessInstanceExtDO::getStatus, reqVO.getStatus())
.eqIfPresent("result", reqVO.getResult()) .eqIfPresent(BpmProcessInstanceExtDO::getResult, reqVO.getResult())
.betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime()) .betweenIfPresent(BpmProcessInstanceExtDO::getCreateTime, reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
.orderByDesc("id")); .orderByDesc(BpmProcessInstanceExtDO::getId));
} }
default BpmProcessInstanceExtDO selectByProcessInstanceId(String processDefinitionId) { default BpmProcessInstanceExtDO selectByProcessInstanceId(String processDefinitionId) {
return selectOne("process_instance_id", processDefinitionId); return selectOne(BpmProcessInstanceExtDO::getProcessInstanceId, processDefinitionId);
} }
default void updateByProcessInstanceId(BpmProcessInstanceExtDO updateObj) { default void updateByProcessInstanceId(BpmProcessInstanceExtDO updateObj) {
update(updateObj, new QueryWrapper<BpmProcessInstanceExtDO>() update(updateObj, new LambdaQueryWrapperX<BpmProcessInstanceExtDO>()
.eq("process_instance_id", updateObj.getProcessInstanceId())); .eq(BpmProcessInstanceExtDO::getProcessInstanceId, updateObj.getProcessInstanceId()));
} }
} }

View File

@ -1,7 +1,7 @@
package cn.iocoder.yudao.module.bpm.dal.mysql.task; package cn.iocoder.yudao.module.bpm.dal.mysql.task;
import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
@ -20,6 +20,6 @@ public interface BpmTaskExtMapper extends BaseMapperX<BpmTaskExtDO> {
} }
default List<BpmTaskExtDO> selectListByProcessInstanceId(String processInstanceId) { default List<BpmTaskExtDO> selectListByProcessInstanceId(String processInstanceId) {
return selectList("process_instance_id", processInstanceId); return selectList(BpmTaskExtDO::getProcessInstanceId, processInstanceId);
} }
} }

View File

@ -44,7 +44,7 @@ public class BpmMessageServiceImpl implements BpmMessageService {
public void sendMessageWhenProcessInstanceReject(BpmMessageSendWhenProcessInstanceRejectReqDTO reqDTO) { public void sendMessageWhenProcessInstanceReject(BpmMessageSendWhenProcessInstanceRejectReqDTO reqDTO) {
Map<String, Object> templateParams = new HashMap<>(); Map<String, Object> templateParams = new HashMap<>();
templateParams.put("processInstanceName", reqDTO.getProcessInstanceName()); templateParams.put("processInstanceName", reqDTO.getProcessInstanceName());
templateParams.put("comment", reqDTO.getComment()); templateParams.put("reason", reqDTO.getReason());
templateParams.put("detailUrl", getProcessInstanceDetailUrl(reqDTO.getProcessInstanceId())); templateParams.put("detailUrl", getProcessInstanceDetailUrl(reqDTO.getProcessInstanceId()));
smsSendApi.sendSingleSmsToAdmin(BpmMessageConvert.INSTANCE.convert(reqDTO.getStartUserId(), smsSendApi.sendSingleSmsToAdmin(BpmMessageConvert.INSTANCE.convert(reqDTO.getStartUserId(),
BpmMessageEnum.PROCESS_INSTANCE_REJECT.getSmsTemplateCode(), templateParams)); BpmMessageEnum.PROCESS_INSTANCE_REJECT.getSmsTemplateCode(), templateParams));

View File

@ -28,6 +28,6 @@ public class BpmMessageSendWhenProcessInstanceRejectReqDTO {
* 不通过理由 * 不通过理由
*/ */
@NotEmpty(message = "不通过理由不能为空") @NotEmpty(message = "不通过理由不能为空")
private String comment; private String reason;
} }

View File

@ -116,10 +116,10 @@ public interface BpmProcessInstanceConvert {
return event; return event;
} }
default BpmMessageSendWhenProcessInstanceRejectReqDTO convert(ProcessInstance processInstance, String comment) { default BpmMessageSendWhenProcessInstanceRejectReqDTO convert(ProcessInstance processInstance, String reason) {
BpmMessageSendWhenProcessInstanceRejectReqDTO reqDTO = new BpmMessageSendWhenProcessInstanceRejectReqDTO(); BpmMessageSendWhenProcessInstanceRejectReqDTO reqDTO = new BpmMessageSendWhenProcessInstanceRejectReqDTO();
copyTo(processInstance, reqDTO); copyTo(processInstance, reqDTO);
reqDTO.setComment(comment); reqDTO.setReason(reason);
return reqDTO; return reqDTO;
} }
@Mapping(source = "name", target = "processInstanceName") @Mapping(source = "name", target = "processInstanceName")

View File

@ -158,8 +158,8 @@ public interface BpmProcessInstanceService {
* 更新 ProcessInstance 拓展记录为不通过 * 更新 ProcessInstance 拓展记录为不通过
* *
* @param id 流程编号 * @param id 流程编号
* @param comment 理由例如说审批不通过时需要传递该值 * @param reason 理由例如说审批不通过时需要传递该值
*/ */
void updateProcessInstanceExtReject(String id, String comment); void updateProcessInstanceExtReject(String id, String reason);
} }

View File

@ -285,11 +285,11 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
} }
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void updateProcessInstanceExtReject(String id, String comment) { public void updateProcessInstanceExtReject(String id, String reason) {
// 需要主动查询因为 instance 只有 id 属性 // 需要主动查询因为 instance 只有 id 属性
ProcessInstance processInstance = getProcessInstance(id); ProcessInstance processInstance = getProcessInstance(id);
// 删除流程实例以实现驳回任务时取消整个审批流程 // 删除流程实例以实现驳回任务时取消整个审批流程
deleteProcessInstance(id, StrUtil.format(BpmProcessInstanceDeleteReasonEnum.REJECT_TASK.format(comment))); deleteProcessInstance(id, StrUtil.format(BpmProcessInstanceDeleteReasonEnum.REJECT_TASK.format(reason)));
// 更新 status + result // 更新 status + result
// 注意不能和上面的逻辑更换位置因为 deleteProcessInstance 会触发流程的取消进而调用 updateProcessInstanceExtCancel 方法 // 注意不能和上面的逻辑更换位置因为 deleteProcessInstance 会触发流程的取消进而调用 updateProcessInstanceExtCancel 方法
@ -300,7 +300,7 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO); processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO);
// 发送流程被不通过的消息 // 发送流程被不通过的消息
messageService.sendMessageWhenProcessInstanceReject(BpmProcessInstanceConvert.INSTANCE.convert(processInstance, comment)); messageService.sendMessageWhenProcessInstanceReject(BpmProcessInstanceConvert.INSTANCE.convert(processInstance, reason));
// 发送流程实例的状态事件 // 发送流程实例的状态事件
processInstanceResultEventPublisher.sendProcessInstanceResultEvent( processInstanceResultEventPublisher.sendProcessInstanceResultEvent(

View File

@ -226,7 +226,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
taskService.complete(task.getId(), instance.getProcessVariables()); // TODO 芋艿variables 的选择 taskService.complete(task.getId(), instance.getProcessVariables()); // TODO 芋艿variables 的选择
// 更新任务拓展表为通过 // 更新任务拓展表为通过
taskExtMapper.updateByTaskId(new BpmTaskExtDO().setTaskId(task.getId()) taskExtMapper.updateByTaskId(new BpmTaskExtDO().setTaskId(task.getId())
.setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()).setComment(reqVO.getComment())); .setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()).setReason(reqVO.getReason()));
// TODO 芋艿添加评论 // TODO 芋艿添加评论
// taskService.addComment(task.getId(), task.getProcessInstanceId(), reqVO.getComment()); // taskService.addComment(task.getId(), task.getProcessInstanceId(), reqVO.getComment());
@ -250,11 +250,11 @@ public class BpmTaskServiceImpl implements BpmTaskService {
} }
// 更新流程实例为不通过 // 更新流程实例为不通过
processInstanceService.updateProcessInstanceExtReject(instance.getProcessInstanceId(), reqVO.getComment()); processInstanceService.updateProcessInstanceExtReject(instance.getProcessInstanceId(), reqVO.getReason());
// 更新任务拓展表为不通过 // 更新任务拓展表为不通过
taskExtMapper.updateByTaskId(new BpmTaskExtDO().setTaskId(task.getId()) taskExtMapper.updateByTaskId(new BpmTaskExtDO().setTaskId(task.getId())
.setResult(BpmProcessInstanceResultEnum.REJECT.getResult()).setComment(reqVO.getComment())); .setResult(BpmProcessInstanceResultEnum.REJECT.getResult()).setReason(reqVO.getReason()));
// TODO 芋艿添加评论 // TODO 芋艿添加评论
// taskService.addComment(task.getId(), task.getProcessInstanceId(), reqVO.getComment()); // taskService.addComment(task.getId(), task.getProcessInstanceId(), reqVO.getComment());

View File

@ -18,12 +18,10 @@ import org.flowable.task.api.Task;
import org.mapstruct.Mapper; import org.mapstruct.Mapper;
import org.mapstruct.Mapping; import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget; import org.mapstruct.MappingTarget;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers; import org.mapstruct.factory.Mappers;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
/** /**
* 流程实例 Convert * 流程实例 Convert
@ -105,11 +103,11 @@ public interface BpmProcessInstanceConvert {
.setProcessInstanceName(instance.getName()); .setProcessInstanceName(instance.getName());
} }
default BpmMessageSendWhenProcessInstanceRejectReqDTO convert2RejectReq(ProcessInstance instance, String comment) { default BpmMessageSendWhenProcessInstanceRejectReqDTO convert2RejectReq(ProcessInstance instance, String reason) {
return new BpmMessageSendWhenProcessInstanceRejectReqDTO() return new BpmMessageSendWhenProcessInstanceRejectReqDTO()
.setProcessInstanceName(instance.getName()) .setProcessInstanceName(instance.getName())
.setProcessInstanceId(instance.getId()) .setProcessInstanceId(instance.getId())
.setComment(comment) .setReason(reason)
.setStartUserId(NumberUtils.parseLong(instance.getStartUserId())); .setStartUserId(NumberUtils.parseLong(instance.getStartUserId()));
} }

View File

@ -141,9 +141,9 @@ public interface BpmProcessInstanceService {
* 更新 ProcessInstance 拓展记录为不通过 * 更新 ProcessInstance 拓展记录为不通过
* *
* @param id 流程编号 * @param id 流程编号
* @param comment 理由例如说审批不通过时需要传递该值 * @param reason 理由例如说审批不通过时需要传递该值
*/ */
void updateProcessInstanceExtReject(String id, String comment); void updateProcessInstanceExtReject(String id, String reason);
} }

View File

@ -250,11 +250,11 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
} }
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void updateProcessInstanceExtReject(String id, String comment) { public void updateProcessInstanceExtReject(String id, String reason) {
// 需要主动查询因为 instance 只有 id 属性 // 需要主动查询因为 instance 只有 id 属性
ProcessInstance processInstance = getProcessInstance(id); ProcessInstance processInstance = getProcessInstance(id);
// 删除流程实例以实现驳回任务时取消整个审批流程 // 删除流程实例以实现驳回任务时取消整个审批流程
deleteProcessInstance(id, StrUtil.format(BpmProcessInstanceDeleteReasonEnum.REJECT_TASK.format(comment))); deleteProcessInstance(id, StrUtil.format(BpmProcessInstanceDeleteReasonEnum.REJECT_TASK.format(reason)));
// 更新 status + result // 更新 status + result
// 注意不能和上面的逻辑更换位置因为 deleteProcessInstance 会触发流程的取消进而调用 updateProcessInstanceExtCancel 方法 // 注意不能和上面的逻辑更换位置因为 deleteProcessInstance 会触发流程的取消进而调用 updateProcessInstanceExtCancel 方法
@ -265,7 +265,7 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO); processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO);
// 发送流程被不通过的消息 // 发送流程被不通过的消息
messageService.sendMessageWhenProcessInstanceReject(BpmProcessInstanceConvert.INSTANCE.convert2RejectReq(processInstance, comment)); messageService.sendMessageWhenProcessInstanceReject(BpmProcessInstanceConvert.INSTANCE.convert2RejectReq(processInstance, reason));
// 发送流程实例的状态事件 // 发送流程实例的状态事件
processInstanceResultEventPublisher.sendProcessInstanceResultEvent( processInstanceResultEventPublisher.sendProcessInstanceResultEvent(

View File

@ -182,7 +182,7 @@ public class BpmTaskServiceImpl implements BpmTaskService{
taskService.complete(task.getId(), instance.getProcessVariables()); taskService.complete(task.getId(), instance.getProcessVariables());
// 更新任务拓展表为通过 // 更新任务拓展表为通过
taskExtMapper.updateByTaskId(new BpmTaskExtDO().setTaskId(task.getId()) taskExtMapper.updateByTaskId(new BpmTaskExtDO().setTaskId(task.getId())
.setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()).setComment(reqVO.getComment())); .setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()).setReason(reqVO.getReason()));
} }
@Override @Override
@ -196,11 +196,11 @@ public class BpmTaskServiceImpl implements BpmTaskService{
} }
// 更新流程实例为不通过 // 更新流程实例为不通过
processInstanceService.updateProcessInstanceExtReject(instance.getProcessInstanceId(), reqVO.getComment()); processInstanceService.updateProcessInstanceExtReject(instance.getProcessInstanceId(), reqVO.getReason());
// 更新任务拓展表为不通过 // 更新任务拓展表为不通过
taskExtMapper.updateByTaskId(new BpmTaskExtDO().setTaskId(task.getId()) taskExtMapper.updateByTaskId(new BpmTaskExtDO().setTaskId(task.getId())
.setResult(BpmProcessInstanceResultEnum.REJECT.getResult()).setComment(reqVO.getComment())); .setResult(BpmProcessInstanceResultEnum.REJECT.getResult()).setReason(reqVO.getReason()));
} }
@Override @Override

View File

@ -13,7 +13,7 @@ public interface ErrorCodeConstants {
ErrorCode CONFIG_NOT_EXISTS = new ErrorCode(1001000001, "参数配置不存在"); ErrorCode CONFIG_NOT_EXISTS = new ErrorCode(1001000001, "参数配置不存在");
ErrorCode CONFIG_KEY_DUPLICATE = new ErrorCode(1001000002, "参数配置 key 重复"); ErrorCode CONFIG_KEY_DUPLICATE = new ErrorCode(1001000002, "参数配置 key 重复");
ErrorCode CONFIG_CAN_NOT_DELETE_SYSTEM_TYPE = new ErrorCode(1001000003, "不能删除类型为系统内置的参数配置"); 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 ========== // ========== 定时任务 1001001000 ==========
ErrorCode JOB_NOT_EXISTS = new ErrorCode(1001001000, "定时任务不存在"); ErrorCode JOB_NOT_EXISTS = new ErrorCode(1001001000, "定时任务不存在");
@ -36,11 +36,12 @@ public interface ErrorCodeConstants {
ErrorCode CODEGEN_TABLE_EXISTS = new ErrorCode(1003001000, "表定义已经存在"); ErrorCode CODEGEN_TABLE_EXISTS = new ErrorCode(1003001000, "表定义已经存在");
ErrorCode CODEGEN_IMPORT_TABLE_NULL = new ErrorCode(1003001001, "导入的表不存在"); ErrorCode CODEGEN_IMPORT_TABLE_NULL = new ErrorCode(1003001001, "导入的表不存在");
ErrorCode CODEGEN_IMPORT_COLUMNS_NULL = new ErrorCode(1003001002, "导入的字段不存在"); 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_TABLE_NOT_EXISTS = new ErrorCode(1003001004, "表定义不存在");
ErrorCode CODEGEN_COLUMN_NOT_EXISTS = new ErrorCode(1003001005, "字段义不存在"); ErrorCode CODEGEN_COLUMN_NOT_EXISTS = new ErrorCode(1003001005, "字段义不存在");
ErrorCode CODEGEN_SYNC_COLUMNS_NULL = new ErrorCode(1003001006, "同步的字段不存在"); ErrorCode CODEGEN_SYNC_COLUMNS_NULL = new ErrorCode(1003001006, "同步的字段不存在");
ErrorCode CODEGEN_SYNC_NONE_CHANGE = new ErrorCode(1003001007, "同步失败,不存在改变"); ErrorCode CODEGEN_SYNC_NONE_CHANGE = new ErrorCode(1003001007, "同步失败,不存在改变");
ErrorCode CODEGEN_TABLE_INFO_TABLE_COMMENT_IS_NULL = new ErrorCode(1003001008, "数据库的表注释未填写");
ErrorCode CODEGEN_TABLE_INFO_COLUMN_COMMENT_IS_NULL = new ErrorCode(1003001009, "数据库的表字段({})注释未填写");
// ========== 字典类型测试1001005000 ========== // ========== 字典类型测试1001005000 ==========
ErrorCode TEST_DEMO_NOT_EXISTS = new ErrorCode(1001005000, "测试示例不存在"); ErrorCode TEST_DEMO_NOT_EXISTS = new ErrorCode(1001005000, "测试示例不存在");
@ -49,4 +50,8 @@ public interface ErrorCodeConstants {
ErrorCode FILE_CONFIG_NOT_EXISTS = new ErrorCode(1001006000, "文件配置不存在"); ErrorCode FILE_CONFIG_NOT_EXISTS = new ErrorCode(1001006000, "文件配置不存在");
ErrorCode FILE_CONFIG_DELETE_FAIL_MASTER = new ErrorCode(1001006001, "该文件配置不允许删除,原因:它是主配置,删除会导致无法上传文件"); ErrorCode FILE_CONFIG_DELETE_FAIL_MASTER = new ErrorCode(1001006001, "该文件配置不允许删除,原因:它是主配置,删除会导致无法上传文件");
// ========== 数据源配置 1001007000 ==========
ErrorCode DATA_SOURCE_CONFIG_NOT_EXISTS = new ErrorCode(1001007000, "数据源配置不存在");
ErrorCode DATA_SOURCE_CONFIG_NOT_OK = new ErrorCode(1001007001, "数据源配置不正确,无法进行连接");
} }

View File

@ -47,6 +47,10 @@
<groupId>cn.iocoder.boot</groupId> <groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-mybatis</artifactId> <artifactId>yudao-spring-boot-starter-mybatis</artifactId>
</dependency> </dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId> <!-- 代码生成器,使用它解析表结构 -->
</dependency>
<dependency> <dependency>
<groupId>cn.iocoder.boot</groupId> <groupId>cn.iocoder.boot</groupId>
@ -79,6 +83,11 @@
</dependency> </dependency>
<!-- 工具类相关 --> <!-- 工具类相关 -->
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId> <!-- 加解密 -->
</dependency>
<dependency> <dependency>
<groupId>cn.iocoder.boot</groupId> <groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-excel</artifactId> <artifactId>yudao-spring-boot-starter-excel</artifactId>

View File

@ -4,19 +4,18 @@ import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.ZipUtil; import cn.hutool.core.util.ZipUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenCreateListReqVO;
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenDetailRespVO; import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenDetailRespVO;
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenPreviewRespVO; import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenPreviewRespVO;
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenUpdateReqVO; import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenUpdateReqVO;
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.CodegenTablePageReqVO; import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.CodegenTablePageReqVO;
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.CodegenTableRespVO; import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.CodegenTableRespVO;
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.SchemaTableRespVO; import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.DatabaseTableRespVO;
import cn.iocoder.yudao.module.infra.convert.codegen.CodegenConvert; import cn.iocoder.yudao.module.infra.convert.codegen.CodegenConvert;
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO; 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.dataobject.codegen.CodegenTableDO;
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.SchemaTableDO;
import cn.iocoder.yudao.module.infra.service.codegen.CodegenService; import cn.iocoder.yudao.module.infra.service.codegen.CodegenService;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiImplicitParams;
@ -33,7 +32,6 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
@ -50,19 +48,16 @@ public class CodegenController {
@GetMapping("/db/table/list") @GetMapping("/db/table/list")
@ApiOperation(value = "获得数据库自带的表定义列表", notes = "会过滤掉已经导入 Codegen 的表") @ApiOperation(value = "获得数据库自带的表定义列表", notes = "会过滤掉已经导入 Codegen 的表")
@ApiImplicitParams({ @ApiImplicitParams({
@ApiImplicitParam(name = "tableName", value = "表名,模糊匹配", required = true, example = "yudao", dataTypeClass = String.class), @ApiImplicitParam(name = "dataSourceConfigId", value = "数据源配置的编号", required = true, example = "1", dataTypeClass = Long.class),
@ApiImplicitParam(name = "tableComment", value = "描述,模糊匹配", required = true, example = "芋道", dataTypeClass = String.class) @ApiImplicitParam(name = "name", value = "表名,模糊匹配", example = "yudao", dataTypeClass = String.class),
@ApiImplicitParam(name = "comment", value = "描述,模糊匹配", example = "芋道", dataTypeClass = String.class)
}) })
@PreAuthorize("@ss.hasPermission('infra:codegen:query')") @PreAuthorize("@ss.hasPermission('infra:codegen:query')")
public CommonResult<List<SchemaTableRespVO>> getSchemaTableList( public CommonResult<List<DatabaseTableRespVO>> getDatabaseTableList(
@RequestParam(value = "tableName", required = false) String tableName, @RequestParam(value = "dataSourceConfigId") Long dataSourceConfigId,
@RequestParam(value = "tableComment", required = false) String tableComment) { @RequestParam(value = "name", required = false) String name,
// 获得数据库自带的表定义列表 @RequestParam(value = "comment", required = false) String comment) {
List<SchemaTableDO> schemaTables = codegenService.getSchemaTableList(tableName, tableComment); return success(codegenService.getDatabaseTableList(dataSourceConfigId, name, comment));
// 移除在 Codegen 已经存在的
Set<String> existsTables = CollectionUtils.convertSet(codegenService.getCodeGenTableList(), CodegenTableDO::getTableName);
schemaTables.removeIf(table -> existsTables.contains(table.getTableName()));
return success(CodegenConvert.INSTANCE.convertList04(schemaTables));
} }
@GetMapping("/table/page") @GetMapping("/table/page")
@ -85,19 +80,10 @@ public class CodegenController {
} }
@ApiOperation("基于数据库的表结构,创建代码生成器的表和字段定义") @ApiOperation("基于数据库的表结构,创建代码生成器的表和字段定义")
@ApiImplicitParam(name = "tableNames", value = "表名数组", required = true, example = "sys_user", dataTypeClass = List.class) @PostMapping("/create-list")
@PostMapping("/create-list-from-db")
@PreAuthorize("@ss.hasPermission('infra:codegen:create')") @PreAuthorize("@ss.hasPermission('infra:codegen:create')")
public CommonResult<List<Long>> createCodegenListFromDB(@RequestParam("tableNames") List<String> tableNames) { public CommonResult<List<Long>> createCodegenList(@Valid @RequestBody CodegenCreateListReqVO reqVO) {
return success(codegenService.createCodegenListFromDB(getLoginUserId(), tableNames)); return success(codegenService.createCodegenList(getLoginUserId(), reqVO));
}
@ApiOperation("基于 SQL 建表语句,创建代码生成器的表和字段定义")
@ApiImplicitParam(name = "sql", value = "SQL 建表语句", required = true, example = "sql", dataTypeClass = String.class)
@PostMapping("/create-list-from-sql")
@PreAuthorize("@ss.hasPermission('infra:codegen:create')")
public CommonResult<Long> createCodegenListFromSQL(@RequestParam("sql") String sql) {
return success(codegenService.createCodegenListFromSQL(getLoginUserId(), sql));
} }
@ApiOperation("更新数据库的表和字段定义") @ApiOperation("更新数据库的表和字段定义")
@ -117,19 +103,6 @@ public class CodegenController {
return success(true); return success(true);
} }
@ApiOperation("基于 SQL 建表语句,同步数据库的表和字段定义")
@PutMapping("/sync-from-sql")
@ApiImplicitParams({
@ApiImplicitParam(name = "tableId", value = "表编号", required = true, example = "1024", dataTypeClass = Long.class),
@ApiImplicitParam(name = "sql", value = "SQL 建表语句", required = true, example = "sql", dataTypeClass = String.class)
})
@PreAuthorize("@ss.hasPermission('infra:codegen:update')")
public CommonResult<Boolean> syncCodegenFromSQL(@RequestParam("tableId") Long tableId,
@RequestParam("sql") String sql) {
codegenService.syncCodegenFromSQL(tableId, sql);
return success(true);
}
@ApiOperation("删除数据库的表和字段定义") @ApiOperation("删除数据库的表和字段定义")
@DeleteMapping("/delete") @DeleteMapping("/delete")
@ApiImplicitParam(name = "tableId", value = "表编号", required = true, example = "1024", dataTypeClass = Long.class) @ApiImplicitParam(name = "tableId", value = "表编号", required = true, example = "1024", dataTypeClass = Long.class)

View File

@ -0,0 +1,22 @@
package cn.iocoder.yudao.module.infra.controller.admin.codegen.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.util.List;
@ApiModel("管理后台 - 基于数据库的表结构,创建代码生成器的表和字段定义 Request VO")
@Data
public class CodegenCreateListReqVO {
@ApiModelProperty(value = "数据源配置的编号", required = true, example = "1")
@NotNull(message = "数据源配置的编号不能为空")
private Long dataSourceConfigId;
@ApiModelProperty(value = "表名数组", required = true, example = "[1, 2, 3]")
@NotNull(message = "表名数组不能为空")
private List<String> tableNames;
}

View File

@ -22,7 +22,7 @@ public class CodegenColumnBaseVO {
@ApiModelProperty(value = "字段类型", required = true, example = "int(11)") @ApiModelProperty(value = "字段类型", required = true, example = "int(11)")
@NotNull(message = "字段类型不能为空") @NotNull(message = "字段类型不能为空")
private String columnType; private String dataType;
@ApiModelProperty(value = "字段描述", required = true, example = "年龄") @ApiModelProperty(value = "字段描述", required = true, example = "年龄")
@NotNull(message = "字段描述不能为空") @NotNull(message = "字段描述不能为空")

View File

@ -12,10 +12,6 @@ import javax.validation.constraints.NotNull;
@Data @Data
public class CodegenTableBaseVO { public class CodegenTableBaseVO {
@ApiModelProperty(value = "导入类型", required = true, example = "1", notes = "参见 CodegenImportTypeEnum 枚举")
@NotNull(message = "导入类型不能为空")
private Integer importType;
@ApiModelProperty(value = "生成场景", required = true, example = "1", notes = "参见 CodegenSceneEnum 枚举") @ApiModelProperty(value = "生成场景", required = true, example = "1", notes = "参见 CodegenSceneEnum 枚举")
@NotNull(message = "导入类型不能为空") @NotNull(message = "导入类型不能为空")
private Integer scene; private Integer scene;

View File

@ -17,6 +17,9 @@ public class CodegenTableRespVO extends CodegenTableBaseVO {
@ApiModelProperty(value = "编号", required = true, example = "1") @ApiModelProperty(value = "编号", required = true, example = "1")
private Long id; private Long id;
@ApiModelProperty(value = "主键编号", required = true, example = "1024")
private Integer dataSourceConfigId;
@ApiModelProperty(value = "创建时间", required = true) @ApiModelProperty(value = "创建时间", required = true)
private Date createTime; private Date createTime;

View File

@ -0,0 +1,17 @@
package cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ApiModel("管理后台 - 数据库的表定义 Response VO")
@Data
public class DatabaseTableRespVO {
@ApiModelProperty(value = "表名称", required = true, example = "yuanma")
private String name;
@ApiModelProperty(value = "表描述", required = true, example = "芋道源码")
private String comment;
}

View File

@ -1,25 +0,0 @@
package cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
@ApiModel("管理后台 - 数据字典的表定义 Response VO")
@Data
public class SchemaTableRespVO {
@ApiModelProperty(value = "数据库", required = true, example = "yudao")
private String tableSchema;
@ApiModelProperty(value = "表名称", required = true, example = "yuanma")
private String tableName;
@ApiModelProperty(value = "表描述", required = true, example = "芋道源码")
private String tableComment;
@ApiModelProperty(value = "创建时间", required = true)
private Date createTime;
}

View File

@ -68,15 +68,15 @@ public class ConfigController {
} }
@GetMapping(value = "/get-value-by-key") @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) @ApiImplicitParam(name = "key", value = "参数键", required = true, example = "yunai.biz.username", dataTypeClass = String.class)
public CommonResult<String> getConfigKey(@RequestParam("key") String key) { public CommonResult<String> getConfigKey(@RequestParam("key") String key) {
ConfigDO config = configService.getConfigByKey(key); ConfigDO config = configService.getConfigByKey(key);
if (config == null) { if (config == null) {
return null; return null;
} }
if (config.getSensitive()) { if (config.getVisible()) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.CONFIG_GET_VALUE_ERROR_IF_SENSITIVE); throw ServiceExceptionUtil.exception(ErrorCodeConstants.CONFIG_GET_VALUE_ERROR_IF_VISIBLE);
} }
return success(config.getValue()); return success(config.getValue());
} }

View File

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

View File

@ -18,7 +18,7 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
@ToString(callSuper = true) @ToString(callSuper = true)
public class ConfigPageReqVO extends PageParam { public class ConfigPageReqVO extends PageParam {
@ApiModelProperty(value = "数名称", example = "模糊匹配") @ApiModelProperty(value = "据源名称", example = "模糊匹配")
private String name; private String name;
@ApiModelProperty(value = "参数键名", example = "yunai.db.username", notes = "模糊匹配") @ApiModelProperty(value = "参数键名", example = "yunai.db.username", notes = "模糊匹配")

View File

@ -0,0 +1,73 @@
package cn.iocoder.yudao.module.infra.controller.admin.db;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.infra.controller.admin.db.vo.DataSourceConfigCreateReqVO;
import cn.iocoder.yudao.module.infra.controller.admin.db.vo.DataSourceConfigRespVO;
import cn.iocoder.yudao.module.infra.controller.admin.db.vo.DataSourceConfigUpdateReqVO;
import cn.iocoder.yudao.module.infra.convert.db.DataSourceConfigConvert;
import cn.iocoder.yudao.module.infra.dal.dataobject.db.DataSourceConfigDO;
import cn.iocoder.yudao.module.infra.service.db.DataSourceConfigService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@Api(tags = "管理后台 - 数据源配置")
@RestController
@RequestMapping("/infra/data-source-config")
@Validated
public class DataSourceConfigController {
@Resource
private DataSourceConfigService dataSourceConfigService;
@PostMapping("/create")
@ApiOperation("创建数据源配置")
@PreAuthorize("@ss.hasPermission('infra:data-source-config:create')")
public CommonResult<Long> createDataSourceConfig(@Valid @RequestBody DataSourceConfigCreateReqVO createReqVO) {
return success(dataSourceConfigService.createDataSourceConfig(createReqVO));
}
@PutMapping("/update")
@ApiOperation("更新数据源配置")
@PreAuthorize("@ss.hasPermission('infra:data-source-config:update')")
public CommonResult<Boolean> updateDataSourceConfig(@Valid @RequestBody DataSourceConfigUpdateReqVO updateReqVO) {
dataSourceConfigService.updateDataSourceConfig(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@ApiOperation("删除数据源配置")
@ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('infra:data-source-config:delete')")
public CommonResult<Boolean> deleteDataSourceConfig(@RequestParam("id") Long id) {
dataSourceConfigService.deleteDataSourceConfig(id);
return success(true);
}
@GetMapping("/get")
@ApiOperation("获得数据源配置")
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('infra:data-source-config:query')")
public CommonResult<DataSourceConfigRespVO> getDataSourceConfig(@RequestParam("id") Long id) {
DataSourceConfigDO dataSourceConfig = dataSourceConfigService.getDataSourceConfig(id);
return success(DataSourceConfigConvert.INSTANCE.convert(dataSourceConfig));
}
@GetMapping("/list")
@ApiOperation("获得数据源配置列表")
@PreAuthorize("@ss.hasPermission('infra:data-source-config:query')")
public CommonResult<List<DataSourceConfigRespVO>> getDataSourceConfigList() {
List<DataSourceConfigDO> list = dataSourceConfigService.getDataSourceConfigList();
return success(DataSourceConfigConvert.INSTANCE.convertList(list));
}
}

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.infra.controller.admin.doc; package cn.iocoder.yudao.module.infra.controller.admin.db;
import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
@ -30,7 +30,7 @@ import java.util.Arrays;
@Api(tags = "管理后台 - 数据库文档") @Api(tags = "管理后台 - 数据库文档")
@RestController @RestController
@RequestMapping("/infra/db-doc") @RequestMapping("/infra/db-doc")
public class DbDocController { public class DatabaseDocController {
@Resource @Resource
private DynamicDataSourceProperties dynamicDataSourceProperties; private DynamicDataSourceProperties dynamicDataSourceProperties;

View File

@ -0,0 +1,27 @@
package cn.iocoder.yudao.module.infra.controller.admin.db.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
import javax.validation.constraints.*;
/**
* 数据源配置 Base VO提供给添加修改详细的子 VO 使用
* 如果子 VO 存在差异的字段请不要添加到这里影响 Swagger 文档生成
*/
@Data
public class DataSourceConfigBaseVO {
@ApiModelProperty(value = "数据源名称", required = true, example = "test")
@NotNull(message = "数据源名称不能为空")
private String name;
@ApiModelProperty(value = "数据源连接", required = true, example = "jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro")
@NotNull(message = "数据源连接不能为空")
private String url;
@ApiModelProperty(value = "用户名", required = true, example = "root")
@NotNull(message = "用户名不能为空")
private String username;
}

View File

@ -0,0 +1,18 @@
package cn.iocoder.yudao.module.infra.controller.admin.db.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
import javax.validation.constraints.*;
@ApiModel("管理后台 - 数据源配置创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class DataSourceConfigCreateReqVO extends DataSourceConfigBaseVO {
@ApiModelProperty(value = "密码", required = true, example = "123456")
@NotNull(message = "密码不能为空")
private String password;
}

View File

@ -0,0 +1,19 @@
package cn.iocoder.yudao.module.infra.controller.admin.db.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
@ApiModel("管理后台 - 数据源配置 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class DataSourceConfigRespVO extends DataSourceConfigBaseVO {
@ApiModelProperty(value = "主键编号", required = true, example = "1024")
private Integer id;
@ApiModelProperty(value = "创建时间", required = true)
private Date createTime;
}

View File

@ -0,0 +1,22 @@
package cn.iocoder.yudao.module.infra.controller.admin.db.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
import javax.validation.constraints.*;
@ApiModel("管理后台 - 数据源配置更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class DataSourceConfigUpdateReqVO extends DataSourceConfigBaseVO {
@ApiModelProperty(value = "主键编号", required = true, example = "1024")
@NotNull(message = "主键编号不能为空")
private Long id;
@ApiModelProperty(value = "密码", required = true, example = "123456")
@NotNull(message = "密码不能为空")
private String password;
}

View File

@ -6,12 +6,14 @@ import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenPreviewR
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenUpdateReqVO; import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenUpdateReqVO;
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.column.CodegenColumnRespVO; import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.column.CodegenColumnRespVO;
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.CodegenTableRespVO; import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.CodegenTableRespVO;
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.SchemaTableRespVO; import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.DatabaseTableRespVO;
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO; 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.dataobject.codegen.CodegenTableDO;
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.SchemaColumnDO; import com.baomidou.mybatisplus.generator.config.po.TableField;
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.SchemaTableDO; import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import org.mapstruct.Mapper; import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers; import org.mapstruct.factory.Mappers;
import java.util.List; import java.util.List;
@ -23,13 +25,27 @@ public interface CodegenConvert {
CodegenConvert INSTANCE = Mappers.getMapper(CodegenConvert.class); CodegenConvert INSTANCE = Mappers.getMapper(CodegenConvert.class);
// ========== InformationSchemaTableDO InformationSchemaColumnDO 相关 ========== // ========== TableInfo 相关 ==========
CodegenTableDO convert(SchemaTableDO bean); @Mappings({
@Mapping(source = "name", target = "tableName"),
@Mapping(source = "comment", target = "tableComment"),
})
CodegenTableDO convert(TableInfo bean);
List<CodegenColumnDO> convertList(List<SchemaColumnDO> list); List<CodegenColumnDO> convertList(List<TableField> list);
CodegenTableRespVO convert(SchemaColumnDO bean); @Mappings({
@Mapping(source = "name", target = "columnName"),
@Mapping(source = "type", target = "dataType"),
@Mapping(source = "comment", target = "columnComment"),
@Mapping(source = "metaInfo.nullable", target = "nullable"),
@Mapping(source = "keyFlag", target = "primaryKey"),
@Mapping(source = "keyIdentityFlag", target = "autoIncrement"),
@Mapping(source = "columnType.type", target = "javaType"),
@Mapping(source = "propertyName", target = "javaField"),
})
CodegenColumnDO convert(TableField bean);
// ========== CodegenTableDO 相关 ========== // ========== CodegenTableDO 相关 ==========
@ -47,7 +63,7 @@ public interface CodegenConvert {
List<CodegenColumnDO> convertList03(List<CodegenUpdateReqVO.Column> columns); List<CodegenColumnDO> convertList03(List<CodegenUpdateReqVO.Column> columns);
List<SchemaTableRespVO> convertList04(List<SchemaTableDO> list); List<DatabaseTableRespVO> convertList04(List<TableInfo> list);
// ========== 其它 ========== // ========== 其它 ==========

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

View File

@ -0,0 +1,30 @@
package cn.iocoder.yudao.module.infra.convert.db;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import cn.iocoder.yudao.module.infra.controller.admin.db.vo.*;
import cn.iocoder.yudao.module.infra.dal.dataobject.db.DataSourceConfigDO;
/**
* 数据源配置 Convert
*
* @author 芋道源码
*/
@Mapper
public interface DataSourceConfigConvert {
DataSourceConfigConvert INSTANCE = Mappers.getMapper(DataSourceConfigConvert.class);
DataSourceConfigDO convert(DataSourceConfigCreateReqVO bean);
DataSourceConfigDO convert(DataSourceConfigUpdateReqVO bean);
DataSourceConfigRespVO convert(DataSourceConfigDO bean);
List<DataSourceConfigRespVO> convertList(List<DataSourceConfigDO> list);
}

View File

@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.infra.dal.dataobject.codegen;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenColumnHtmlTypeEnum; import cn.iocoder.yudao.module.infra.enums.codegen.CodegenColumnHtmlTypeEnum;
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenColumnListConditionEnum; import cn.iocoder.yudao.module.infra.enums.codegen.CodegenColumnListConditionEnum;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data; import lombok.Data;
@ -15,6 +16,7 @@ import lombok.experimental.Accessors;
* @author 芋道源码 * @author 芋道源码
*/ */
@TableName(value = "infra_codegen_column", autoResultMap = true) @TableName(value = "infra_codegen_column", autoResultMap = true)
@KeySequence("infra_codegen_column_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data @Data
@Accessors(chain = true) @Accessors(chain = true)
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ -41,7 +43,7 @@ public class CodegenColumnDO extends BaseDO {
/** /**
* 字段类型 * 字段类型
*/ */
private String columnType; private String dataType;
/** /**
* 字段描述 * 字段描述
*/ */
@ -74,7 +76,6 @@ public class CodegenColumnDO extends BaseDO {
/** /**
* Java 属性名 * Java 属性名
*/ */
// @NotBlank(message = "Java属性不能为空")
private String javaField; private String javaField;
/** /**
* 字典类型 * 字典类型

View File

@ -1,8 +1,10 @@
package cn.iocoder.yudao.module.infra.dal.dataobject.codegen; package cn.iocoder.yudao.module.infra.dal.dataobject.codegen;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.infra.dal.dataobject.db.DataSourceConfigDO;
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenSceneEnum; import cn.iocoder.yudao.module.infra.enums.codegen.CodegenSceneEnum;
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenTemplateTypeEnum; import cn.iocoder.yudao.module.infra.enums.codegen.CodegenTemplateTypeEnum;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@ -14,6 +16,7 @@ import lombok.experimental.Accessors;
* @author 芋道源码 * @author 芋道源码
*/ */
@TableName(value = "infra_codegen_table", autoResultMap = true) @TableName(value = "infra_codegen_table", autoResultMap = true)
@KeySequence("infra_codegen_table_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data @Data
@Accessors(chain = true) @Accessors(chain = true)
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ -25,11 +28,11 @@ public class CodegenTableDO extends BaseDO {
private Long id; private Long id;
/** /**
* 导入类型 * 数据源编号
* *
* 枚举 {@link CodegenTemplateTypeEnum} * 关联 {@link DataSourceConfigDO#getId()}
*/ */
private Integer importType; private Long dataSourceConfigId;
/** /**
* 生成场景 * 生成场景
* *

View File

@ -1,54 +0,0 @@
package cn.iocoder.yudao.module.infra.dal.dataobject.codegen;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Builder;
import lombok.Data;
/**
* MySQL 数据库中的 column 字段定义
*
* @author 芋道源码
*/
@TableName(value = "information_schema.columns", autoResultMap = true)
@Data
@Builder
public class SchemaColumnDO {
/**
* 表名称
*/
private String tableName;
/**
* 字段名
*/
private String columnName;
/**
* 字段类型
*/
private String columnType;
/**
* 字段描述
*/
private String columnComment;
/**
* 是否允许为空
*/
@TableField("case when is_nullable = 'yes' then '1' else '0' end")
private Boolean nullable;
/**
* 是否主键
*/
@TableField("case when column_key = 'PRI' then '1' else '0' end")
private Boolean primaryKey;
/**
* 是否自增
*/
@TableField("case when extra = 'auto_increment' then '1' else '0' end")
private Boolean autoIncrement;
/**
* 排序字段
*/
private Integer ordinalPosition;
}

View File

@ -1,36 +0,0 @@
package cn.iocoder.yudao.module.infra.dal.dataobject.codegen;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Builder;
import lombok.Data;
import java.util.Date;
/**
* MySQL 数据库中的 table 表定义
*
* @author 芋道源码
*/
@TableName(value = "information_schema.tables", autoResultMap = true)
@Data
@Builder
public class SchemaTableDO {
/**
* 数据库
*/
private String tableSchema;
/**
* 表名称
*/
private String tableName;
/**
* 表描述
*/
private String tableComment;
/**
* 创建时间
*/
private Date createTime;
}

View File

@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.infra.dal.dataobject.config;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.infra.enums.config.ConfigTypeEnum; import cn.iocoder.yudao.module.infra.enums.config.ConfigTypeEnum;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data; import lombok.Data;
@ -15,6 +15,7 @@ import lombok.ToString;
* @author 芋道源码 * @author 芋道源码
*/ */
@TableName("infra_config") @TableName("infra_config")
@KeySequence("infra_config_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true) @ToString(callSuper = true)
@ -26,19 +27,19 @@ public class ConfigDO extends BaseDO {
@TableId @TableId
private Long id; private Long id;
/** /**
* 参数分 * 参数分
*/ */
@TableField("`group`") private String category;
private String group;
/** /**
* 参数名称 * 参数名称
*/ */
private String name; private String name;
/** /**
* 参数键名 * 参数键名
*
* 支持多 DB 类型时无法直接使用 key + @TableField("config_key") 来实现转换原因是 "config_key" AS key 而存在报错
*/ */
@TableField("`key`") private String configKey;
private String key;
/** /**
* 参数键值 * 参数键值
*/ */
@ -48,15 +49,13 @@ public class ConfigDO extends BaseDO {
* *
* 枚举 {@link ConfigTypeEnum} * 枚举 {@link ConfigTypeEnum}
*/ */
@TableField("`type`")
private Integer type; private Integer type;
/** /**
* 是否敏感 * 是否可见
* *
* 对于敏感配置需要管理权限才能查看 * 不可见的参数一般是敏感参数前端不可获取
*/ */
@TableField("`sensitive`") private Boolean visible;
private Boolean sensitive;
/** /**
* 备注 * 备注
*/ */

View File

@ -0,0 +1,45 @@
package cn.iocoder.yudao.module.infra.dal.dataobject.db;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
/**
* 数据源配置
*
* @author 芋道源码
*/
@TableName("infra_data_source_config")
@KeySequence("infra_data_source_config_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data
public class DataSourceConfigDO extends BaseDO {
/**
* 主键编号 - Master 数据源
*/
public static final Long ID_MASTER = 0L;
/**
* 主键编号
*/
private Long id;
/**
* 连接名
*/
private String name;
/**
* 数据源连接
*/
private String url;
/**
* 用户名
*/
private String username;
/**
* 密码
*/
private String password;
}

View File

@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.infra.dal.dataobject.file;
import cn.iocoder.yudao.framework.file.core.client.FileClientConfig; import cn.iocoder.yudao.framework.file.core.client.FileClientConfig;
import cn.iocoder.yudao.framework.file.core.enums.FileStorageEnum; import cn.iocoder.yudao.framework.file.core.enums.FileStorageEnum;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; 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.TableField;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
@ -13,8 +14,9 @@ import lombok.*;
* *
* @author 芋道源码 * @author 芋道源码
*/ */
@Data
@TableName(value = "infra_file_config", autoResultMap = true) @TableName(value = "infra_file_config", autoResultMap = true)
@KeySequence("infra_file_config_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true) @ToString(callSuper = true)
@Builder @Builder

View File

@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.infra.dal.dataobject.file;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*; import lombok.*;
@ -13,8 +14,9 @@ import lombok.*;
* *
* @author 芋道源码 * @author 芋道源码
*/ */
@Data
@TableName("infra_file_content") @TableName("infra_file_content")
@KeySequence("infra_file_content_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true) @ToString(callSuper = true)
@Builder @Builder

View File

@ -1,7 +1,7 @@
package cn.iocoder.yudao.module.infra.dal.dataobject.file; package cn.iocoder.yudao.module.infra.dal.dataobject.file;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*; import lombok.*;
@ -13,8 +13,9 @@ import java.io.InputStream;
* *
* @author 芋道源码 * @author 芋道源码
*/ */
@Data
@TableName("infra_file") @TableName("infra_file")
@KeySequence("infra_file_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true) @ToString(callSuper = true)
@Builder @Builder
@ -45,7 +46,6 @@ public class FileDO extends BaseDO {
* *
* 通过 {@link cn.hutool.core.io.FileTypeUtil#getType(InputStream)} 获取 * 通过 {@link cn.hutool.core.io.FileTypeUtil#getType(InputStream)} 获取
*/ */
@TableField(value = "`type`")
private String type; private String type;
/** /**
* 文件大小 * 文件大小

View File

@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.infra.dal.dataobject.job;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.infra.enums.job.JobStatusEnum; import cn.iocoder.yudao.module.infra.enums.job.JobStatusEnum;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*; import lombok.*;
@ -12,6 +13,7 @@ import lombok.*;
* @author 芋道源码 * @author 芋道源码
*/ */
@TableName("infra_job") @TableName("infra_job")
@KeySequence("infra_job_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true) @ToString(callSuper = true)

View File

@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.infra.dal.dataobject.job;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler; import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler;
import cn.iocoder.yudao.module.infra.enums.job.JobLogStatusEnum; import cn.iocoder.yudao.module.infra.enums.job.JobLogStatusEnum;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*; import lombok.*;
@ -14,6 +15,7 @@ import java.util.Date;
* @author 芋道源码 * @author 芋道源码
*/ */
@TableName("infra_job_log") @TableName("infra_job_log")
@KeySequence("infra_job_log_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true) @ToString(callSuper = true)

View File

@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.infra.dal.dataobject.logger;
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*; import lombok.*;
@ -15,6 +16,7 @@ import java.util.Date;
* @author 芋道源码 * @author 芋道源码
*/ */
@TableName("infra_api_access_log") @TableName("infra_api_access_log")
@KeySequence(value = "infra_api_access_log_seq")
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true) @ToString(callSuper = true)

View File

@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.infra.dal.dataobject.logger;
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.infra.enums.logger.ApiErrorLogProcessStatusEnum; import cn.iocoder.yudao.module.infra.enums.logger.ApiErrorLogProcessStatusEnum;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*; import lombok.*;
@ -21,6 +22,7 @@ import java.util.Date;
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@KeySequence(value = "infra_api_error_log_seq")
public class ApiErrorLogDO extends BaseDO { public class ApiErrorLogDO extends BaseDO {
/** /**

View File

@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.infra.dal.dataobject.test; package cn.iocoder.yudao.module.infra.dal.dataobject.test;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*; import lombok.*;
@ -11,6 +12,7 @@ import lombok.*;
* @author 芋道源码 * @author 芋道源码
*/ */
@TableName("infra_test_demo") @TableName("infra_test_demo")
@KeySequence("infra_test_demo_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true) @ToString(callSuper = true)

View File

@ -1,8 +1,8 @@
package cn.iocoder.yudao.module.infra.dal.mysql.codegen; package cn.iocoder.yudao.module.infra.dal.mysql.codegen;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO; import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import java.util.List; import java.util.List;
@ -11,12 +11,14 @@ import java.util.List;
public interface CodegenColumnMapper extends BaseMapperX<CodegenColumnDO> { public interface CodegenColumnMapper extends BaseMapperX<CodegenColumnDO> {
default List<CodegenColumnDO> selectListByTableId(Long tableId) { default List<CodegenColumnDO> selectListByTableId(Long tableId) {
return selectList(new QueryWrapper<CodegenColumnDO>().eq("table_id", tableId) return selectList(new LambdaQueryWrapperX<CodegenColumnDO>()
.orderByAsc("ordinal_position")); .eq(CodegenColumnDO::getTableId, tableId)
.orderByAsc(CodegenColumnDO::getId));
} }
default void deleteListByTableId(Long tableId) { default void deleteListByTableId(Long tableId) {
delete(new QueryWrapper<CodegenColumnDO>().eq("table_id", tableId)); delete(new LambdaQueryWrapperX<CodegenColumnDO>()
.eq(CodegenColumnDO::getTableId, tableId));
} }
} }

View File

@ -2,24 +2,30 @@ package cn.iocoder.yudao.module.infra.dal.mysql.codegen;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 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.infra.dal.dataobject.codegen.CodegenTableDO;
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.CodegenTablePageReqVO; import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.CodegenTablePageReqVO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper @Mapper
public interface CodegenTableMapper extends BaseMapperX<CodegenTableDO> { public interface CodegenTableMapper extends BaseMapperX<CodegenTableDO> {
default CodegenTableDO selectByTableName(String tableName) { default CodegenTableDO selectByTableNameAndDataSourceConfigId(String tableName, Long dataSourceConfigId) {
return selectOne(new QueryWrapper<CodegenTableDO>().eq("table_name", tableName)); return selectOne(CodegenTableDO::getTableName, tableName,
CodegenTableDO::getDataSourceConfigId, dataSourceConfigId);
} }
default PageResult<CodegenTableDO> selectPage(CodegenTablePageReqVO pageReqVO) { default PageResult<CodegenTableDO> selectPage(CodegenTablePageReqVO pageReqVO) {
return selectPage(pageReqVO, new QueryWrapperX<CodegenTableDO>() return selectPage(pageReqVO, new LambdaQueryWrapperX<CodegenTableDO>()
.likeIfPresent("table_name", pageReqVO.getTableName()) .likeIfPresent(CodegenTableDO::getTableName, pageReqVO.getTableName())
.likeIfPresent("table_comment", pageReqVO.getTableComment()) .likeIfPresent(CodegenTableDO::getTableComment, pageReqVO.getTableComment())
.betweenIfPresent("create_time", pageReqVO.getBeginCreateTime(), pageReqVO.getEndCreateTime())); .betweenIfPresent(CodegenTableDO::getCreateTime, pageReqVO.getBeginCreateTime(), pageReqVO.getEndCreateTime()));
}
default List<CodegenTableDO> selectListByDataSourceConfigId(Long dataSourceConfigId) {
return selectList(CodegenTableDO::getDataSourceConfigId, dataSourceConfigId);
} }
} }

View File

@ -1,19 +0,0 @@
package cn.iocoder.yudao.module.infra.dal.mysql.codegen;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.SchemaColumnDO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface SchemaColumnMapper extends BaseMapperX<SchemaColumnDO> {
default List<SchemaColumnDO> selectListByTableName(String tableSchema, String tableName) {
return selectList(new QueryWrapper<SchemaColumnDO>().eq("table_name", tableName)
.eq("table_schema", tableSchema)
.orderByAsc("ordinal_position"));
}
}

View File

@ -1,26 +0,0 @@
package cn.iocoder.yudao.module.infra.dal.mysql.codegen;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.SchemaTableDO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.ibatis.annotations.Mapper;
import java.util.Collection;
import java.util.List;
@Mapper
public interface SchemaTableMapper extends BaseMapperX<SchemaTableDO> {
default List<SchemaTableDO> selectList(Collection<String> tableSchemas, String tableName, String tableComment) {
return selectList(new QueryWrapperX<SchemaTableDO>().in("table_schema", tableSchemas)
.likeIfPresent("table_name", tableName)
.likeIfPresent("table_comment", tableComment));
}
default SchemaTableDO selectByTableSchemaAndTableName(String tableSchema, String tableName) {
return selectOne(new QueryWrapper<SchemaTableDO>().eq("table_schema",tableSchema)
.eq("table_name", tableName));
}
}

View File

@ -2,12 +2,10 @@ package cn.iocoder.yudao.module.infra.dal.mysql.config;
import cn.iocoder.yudao.framework.apollo.internals.ConfigFrameworkDAO; import cn.iocoder.yudao.framework.apollo.internals.ConfigFrameworkDAO;
import cn.iocoder.yudao.framework.apollo.internals.dto.ConfigRespDTO; import cn.iocoder.yudao.framework.apollo.internals.dto.ConfigRespDTO;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.springframework.jdbc.datasource.DriverManagerDataSource;
import javax.sql.DataSource; import javax.sql.DataSource;
import java.sql.ResultSet;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
@ -26,14 +24,18 @@ public class ConfigDAOImpl implements ConfigFrameworkDAO {
} }
@Override @Override
public boolean selectExistsByUpdateTimeAfter(Date maxUpdateTime) { public int selectCountByUpdateTimeGt(Date maxUpdateTime) {
return jdbcTemplate.query("SELECT id FROM infra_config WHERE update_time > ? LIMIT 1", return jdbcTemplate.queryForObject("SELECT COUNT(*) FROM infra_config WHERE update_time > ?",
ResultSet::next, maxUpdateTime); Integer.class, maxUpdateTime);
} }
@Override @Override
public List<ConfigRespDTO> selectList() { public List<ConfigRespDTO> selectList() {
return jdbcTemplate.query("SELECT `key`, `value`, update_time, deleted FROM infra_config", new BeanPropertyRowMapper<>(ConfigRespDTO.class)); return jdbcTemplate.query("SELECT config_key, value, update_time, deleted FROM infra_config",
(rs, rowNum) -> new ConfigRespDTO().setKey(rs.getString("config_key"))
.setValue(rs.getString("value"))
.setUpdateTime(rs.getDate("update_time"))
.setDeleted(rs.getBoolean("deleted")));
} }
} }

View File

@ -2,11 +2,10 @@ package cn.iocoder.yudao.module.infra.dal.mysql.config;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 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.infra.controller.admin.config.vo.ConfigExportReqVO; import cn.iocoder.yudao.module.infra.controller.admin.config.vo.ConfigExportReqVO;
import cn.iocoder.yudao.module.infra.controller.admin.config.vo.ConfigPageReqVO; import cn.iocoder.yudao.module.infra.controller.admin.config.vo.ConfigPageReqVO;
import cn.iocoder.yudao.module.infra.dal.dataobject.config.ConfigDO; import cn.iocoder.yudao.module.infra.dal.dataobject.config.ConfigDO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import java.util.List; import java.util.List;
@ -15,23 +14,23 @@ import java.util.List;
public interface ConfigMapper extends BaseMapperX<ConfigDO> { public interface ConfigMapper extends BaseMapperX<ConfigDO> {
default ConfigDO selectByKey(String key) { default ConfigDO selectByKey(String key) {
return selectOne(new QueryWrapper<ConfigDO>().eq("`key`", key)); return selectOne(ConfigDO::getConfigKey, key);
} }
default PageResult<ConfigDO> selectPage(ConfigPageReqVO reqVO) { default PageResult<ConfigDO> selectPage(ConfigPageReqVO reqVO) {
return selectPage(reqVO, new QueryWrapperX<ConfigDO>() return selectPage(reqVO, new LambdaQueryWrapperX<ConfigDO>()
.likeIfPresent("name", reqVO.getName()) .likeIfPresent(ConfigDO::getName, reqVO.getName())
.likeIfPresent("`key`", reqVO.getKey()) .likeIfPresent(ConfigDO::getConfigKey, reqVO.getKey())
.eqIfPresent("`type`", reqVO.getType()) .eqIfPresent(ConfigDO::getType, reqVO.getType())
.betweenIfPresent("create_time", reqVO.getBeginTime(), reqVO.getEndTime())); .betweenIfPresent(ConfigDO::getCreateTime, reqVO.getBeginTime(), reqVO.getEndTime()));
} }
default List<ConfigDO> selectList(ConfigExportReqVO reqVO) { default List<ConfigDO> selectList(ConfigExportReqVO reqVO) {
return selectList(new QueryWrapperX<ConfigDO>() return selectList(new LambdaQueryWrapperX<ConfigDO>()
.likeIfPresent("name", reqVO.getName()) .likeIfPresent(ConfigDO::getName, reqVO.getName())
.likeIfPresent("`key`", reqVO.getKey()) .likeIfPresent(ConfigDO::getConfigKey, reqVO.getKey())
.eqIfPresent("`type`", reqVO.getType()) .eqIfPresent(ConfigDO::getType, reqVO.getType())
.betweenIfPresent("create_time", reqVO.getBeginTime(), reqVO.getEndTime())); .betweenIfPresent(ConfigDO::getCreateTime, reqVO.getBeginTime(), reqVO.getEndTime()));
} }
} }

View File

@ -0,0 +1,14 @@
package cn.iocoder.yudao.module.infra.dal.mysql.db;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.infra.dal.dataobject.db.DataSourceConfigDO;
import org.apache.ibatis.annotations.Mapper;
/**
* 数据源配置 Mapper
*
* @author 芋道源码
*/
@Mapper
public interface DataSourceConfigMapper extends BaseMapperX<DataSourceConfigDO> {
}

View File

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

View File

@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.infra.dal.mysql.file;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 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.infra.controller.admin.file.vo.file.FilePageReqVO; import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePageReqVO;
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO; import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
@ -16,11 +16,11 @@ import org.apache.ibatis.annotations.Mapper;
public interface FileMapper extends BaseMapperX<FileDO> { public interface FileMapper extends BaseMapperX<FileDO> {
default PageResult<FileDO> selectPage(FilePageReqVO reqVO) { default PageResult<FileDO> selectPage(FilePageReqVO reqVO) {
return selectPage(reqVO, new QueryWrapperX<FileDO>() return selectPage(reqVO, new LambdaQueryWrapperX<FileDO>()
.likeIfPresent("path", reqVO.getPath()) .likeIfPresent(FileDO::getPath, reqVO.getPath())
.likeIfPresent("type", reqVO.getType()) .likeIfPresent(FileDO::getType, reqVO.getType())
.betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime()) .betweenIfPresent(FileDO::getCreateTime, reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
.orderByDesc("create_time")); .orderByDesc(FileDO::getId));
} }
} }

View File

@ -1,23 +0,0 @@
package cn.iocoder.yudao.module.infra.enums.codegen;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 代码生成的导入类型
*
* @author 芋道源码
*/
@AllArgsConstructor
@Getter
public enum CodegenImportTypeEnum {
DB(1), // information_schema table columns 表导入
SQL(2); // 基于建表 SQL 语句导入
/**
* 类型
*/
private final Integer type;
}

View File

@ -1,11 +1,12 @@
package cn.iocoder.yudao.module.infra.service.codegen; package cn.iocoder.yudao.module.infra.service.codegen;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenCreateListReqVO;
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenUpdateReqVO; import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenUpdateReqVO;
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.CodegenTablePageReqVO; import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.CodegenTablePageReqVO;
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.DatabaseTableRespVO;
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO; 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.dataobject.codegen.CodegenTableDO;
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.SchemaTableDO;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -17,32 +18,14 @@ import java.util.Map;
*/ */
public interface CodegenService { public interface CodegenService {
/**
* 基于 SQL 建表语句创建代码生成器的表定义
*
* @param userId 用户编号
* @param sql SQL 建表语句
* @return 创建的表定义的编号
*/
Long createCodegenListFromSQL(Long userId, String sql);
/** /**
* 基于数据库的表结构创建代码生成器的表定义 * 基于数据库的表结构创建代码生成器的表定义
* *
* @param userId 用户编号 * @param userId 用户编号
* @param tableName 表名称 * @param reqVO 表信息
* @return 创建的表定义的编号
*/
Long createCodegen(Long userId, String tableName);
/**
* 基于 {@link #createCodegen(Long, String)} 的批量创建
*
* @param userId 用户编号
* @param tableNames 表名称数组
* @return 创建的表定义的编号数组 * @return 创建的表定义的编号数组
*/ */
List<Long> createCodegenListFromDB(Long userId, List<String> tableNames); List<Long> createCodegenList(Long userId, CodegenCreateListReqVO reqVO);
/** /**
* 更新数据库的表和字段定义 * 更新数据库的表和字段定义
@ -58,14 +41,6 @@ public interface CodegenService {
*/ */
void syncCodegenFromDB(Long tableId); void syncCodegenFromDB(Long tableId);
/**
* 基于 SQL 建表语句同步数据库的表和字段定义
*
* @param tableId 表编号
* @param sql SQL 建表语句
*/
void syncCodegenFromSQL(Long tableId, String sql);
/** /**
* 删除数据库的表和字段定义 * 删除数据库的表和字段定义
* *
@ -89,13 +64,6 @@ public interface CodegenService {
*/ */
CodegenTableDO getCodegenTablePage(Long id); CodegenTableDO getCodegenTablePage(Long id);
/**
* 获得全部表定义
*
* @return 表定义数组
*/
List<CodegenTableDO> getCodeGenTableList();
/** /**
* 获得指定表的字段定义数组 * 获得指定表的字段定义数组
* *
@ -115,10 +83,12 @@ public interface CodegenService {
/** /**
* 获得数据库自带的表定义列表 * 获得数据库自带的表定义列表
* *
* @param tableName 表名称 *
* @param tableComment 表描述 * @param dataSourceConfigId 数据源的配置编号
* @param name 表名称
* @param comment 表描述
* @return 表定义列表 * @return 表定义列表
*/ */
List<SchemaTableDO> getSchemaTableList(String tableName, String tableComment); List<DatabaseTableRespVO> getDatabaseTableList(Long dataSourceConfigId, String name, String comment);
} }

View File

@ -1,26 +1,25 @@
package cn.iocoder.yudao.module.infra.service.codegen; package cn.iocoder.yudao.module.infra.service.codegen;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenCreateListReqVO;
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenUpdateReqVO; import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenUpdateReqVO;
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.CodegenTablePageReqVO; import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.CodegenTablePageReqVO;
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.DatabaseTableRespVO;
import cn.iocoder.yudao.module.infra.convert.codegen.CodegenConvert; import cn.iocoder.yudao.module.infra.convert.codegen.CodegenConvert;
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO; 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.dataobject.codegen.CodegenTableDO;
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.SchemaColumnDO;
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.SchemaTableDO;
import cn.iocoder.yudao.module.infra.dal.mysql.codegen.CodegenColumnMapper; 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.dal.mysql.codegen.CodegenTableMapper;
import cn.iocoder.yudao.module.infra.dal.mysql.codegen.SchemaColumnMapper; import cn.iocoder.yudao.module.infra.enums.codegen.CodegenSceneEnum;
import cn.iocoder.yudao.module.infra.dal.mysql.codegen.SchemaTableMapper;
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenImportTypeEnum;
import cn.iocoder.yudao.module.infra.framework.codegen.config.CodegenProperties;
import cn.iocoder.yudao.module.infra.service.codegen.inner.CodegenBuilder; 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.codegen.inner.CodegenEngine;
import cn.iocoder.yudao.module.infra.service.codegen.inner.CodegenSQLParser; import cn.iocoder.yudao.module.infra.service.db.DatabaseTableService;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import org.apache.commons.collections4.KeyValue; import com.baomidou.mybatisplus.generator.config.po.TableField;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -43,9 +42,8 @@ import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.*;
public class CodegenServiceImpl implements CodegenService { public class CodegenServiceImpl implements CodegenService {
@Resource @Resource
private SchemaTableMapper schemaTableMapper; private DatabaseTableService databaseTableService;
@Resource
private SchemaColumnMapper schemaColumnMapper;
@Resource @Resource
private CodegenTableMapper codegenTableMapper; private CodegenTableMapper codegenTableMapper;
@Resource @Resource
@ -59,68 +57,63 @@ public class CodegenServiceImpl implements CodegenService {
@Resource @Resource
private CodegenEngine codegenEngine; private CodegenEngine codegenEngine;
@Resource @Override
private CodegenProperties codegenProperties; @Transactional(rollbackFor = Exception.class)
public List<Long> createCodegenList(Long userId, CodegenCreateListReqVO reqVO) {
List<Long> ids = new ArrayList<>(reqVO.getTableNames().size());
// 遍历添加虽然效率会低一点但是没必要做成完全批量因为不会这么大量
reqVO.getTableNames().forEach(tableName -> ids.add(createCodegen(userId, reqVO.getDataSourceConfigId(), tableName)));
return ids;
}
private Long createCodegen0(Long userId, CodegenImportTypeEnum importType, public Long createCodegen(Long userId, Long dataSourceConfigId, String tableName) {
SchemaTableDO schemaTable, List<SchemaColumnDO> schemaColumns) { // 从数据库中获得数据库表结构
TableInfo tableInfo = databaseTableService.getTable(dataSourceConfigId, tableName);
// 导入
return createCodegen0(userId, dataSourceConfigId, tableInfo);
}
private Long createCodegen0(Long userId, Long dataSourceConfigId, TableInfo tableInfo) {
// 校验导入的表和字段非空 // 校验导入的表和字段非空
if (schemaTable == null) { checkTableInfo(tableInfo);
throw exception(CODEGEN_IMPORT_TABLE_NULL);
}
if (CollUtil.isEmpty(schemaColumns)) {
throw exception(CODEGEN_IMPORT_COLUMNS_NULL);
}
// 校验是否已经存在 // 校验是否已经存在
if (codegenTableMapper.selectByTableName(schemaTable.getTableName()) != null) { if (codegenTableMapper.selectByTableNameAndDataSourceConfigId(tableInfo.getName(),
dataSourceConfigId) != null) {
throw exception(CODEGEN_TABLE_EXISTS); throw exception(CODEGEN_TABLE_EXISTS);
} }
// 构建 CodegenTableDO 对象插入到 DB // 构建 CodegenTableDO 对象插入到 DB
CodegenTableDO table = codegenBuilder.buildTable(schemaTable); CodegenTableDO table = codegenBuilder.buildTable(tableInfo);
table.setImportType(importType.getType()); table.setDataSourceConfigId(dataSourceConfigId);
table.setScene(CodegenSceneEnum.ADMIN.getScene()); // 默认配置下使用管理后台的模板
table.setAuthor(userApi.getUser(userId).getNickname()); table.setAuthor(userApi.getUser(userId).getNickname());
codegenTableMapper.insert(table); codegenTableMapper.insert(table);
// 构建 CodegenColumnDO 数组插入到 DB // 构建 CodegenColumnDO 数组插入到 DB
List<CodegenColumnDO> columns = codegenBuilder.buildColumns(table.getId(), schemaColumns); List<CodegenColumnDO> columns = codegenBuilder.buildColumns(table.getId(), tableInfo.getFields());
// 如果没有主键则使用第一个字段作为主键
if (!tableInfo.isHavePrimaryKey()) {
columns.get(0).setPrimaryKey(true);
}
codegenColumnMapper.insertBatch(columns); codegenColumnMapper.insertBatch(columns);
return table.getId(); return table.getId();
} }
@Override private void checkTableInfo(TableInfo tableInfo) {
public Long createCodegenListFromSQL(Long userId, String sql) { if (tableInfo == null) {
// SQL 获得数据库表结构 throw exception(CODEGEN_IMPORT_TABLE_NULL);
SchemaTableDO schemaTable;
List<SchemaColumnDO> schemaColumns;
try {
KeyValue<SchemaTableDO, List<SchemaColumnDO>> result = CodegenSQLParser.parse(sql);
schemaTable = result.getKey();
schemaColumns = result.getValue();
} catch (Exception ex) {
throw exception(CODEGEN_PARSE_SQL_ERROR);
} }
// 导入 if (StrUtil.isEmpty(tableInfo.getComment())) {
return this.createCodegen0(userId, CodegenImportTypeEnum.SQL, schemaTable, schemaColumns); throw exception(CODEGEN_TABLE_INFO_TABLE_COMMENT_IS_NULL);
} }
if (CollUtil.isEmpty(tableInfo.getFields())) {
@Override throw exception(CODEGEN_IMPORT_COLUMNS_NULL);
public Long createCodegen(Long userId, String tableName) { }
// 获取当前schema tableInfo.getFields().forEach(field -> {
String tableSchema = codegenProperties.getDbSchemas().iterator().next(); if (StrUtil.isEmpty(field.getComment())) {
// 从数据库中获得数据库表结构 throw exception(CODEGEN_TABLE_INFO_COLUMN_COMMENT_IS_NULL, field.getName());
SchemaTableDO schemaTable = schemaTableMapper.selectByTableSchemaAndTableName(tableSchema, tableName); }
List<SchemaColumnDO> schemaColumns = schemaColumnMapper.selectListByTableName(tableSchema, tableName); });
// 导入
return this.createCodegen0(userId, CodegenImportTypeEnum.DB, schemaTable, schemaColumns);
}
@Override
@Transactional(rollbackFor = Exception.class)
public List<Long> createCodegenListFromDB(Long userId, List<String> tableNames) {
List<Long> ids = new ArrayList<>(tableNames.size());
// 遍历添加虽然效率会低一点但是没必要做成完全批量因为不会这么大量
tableNames.forEach(tableName -> ids.add(createCodegen(userId, tableName)));
return ids;
} }
@Override @Override
@ -147,56 +140,32 @@ public class CodegenServiceImpl implements CodegenService {
if (table == null) { if (table == null) {
throw exception(CODEGEN_TABLE_NOT_EXISTS); throw exception(CODEGEN_TABLE_NOT_EXISTS);
} }
String tableSchema = codegenProperties.getDbSchemas().iterator().next();
// 从数据库中获得数据库表结构 // 从数据库中获得数据库表结构
List<SchemaColumnDO> schemaColumns = schemaColumnMapper.selectListByTableName(tableSchema, table.getTableName()); TableInfo tableInfo = databaseTableService.getTable(table.getDataSourceConfigId(), table.getTableName());
// 执行同步 // 执行同步
this.syncCodegen0(tableId, schemaColumns); syncCodegen0(tableId, tableInfo);
} }
@Override private void syncCodegen0(Long tableId, TableInfo tableInfo) {
@Transactional(rollbackFor = Exception.class) // 校验导入的表和字段非空
public void syncCodegenFromSQL(Long tableId, String sql) { checkTableInfo(tableInfo);
// 校验是否已经存在 List<TableField> tableFields = tableInfo.getFields();
CodegenTableDO table = codegenTableMapper.selectById(tableId);
if (table == null) {
throw exception(CODEGEN_TABLE_NOT_EXISTS);
}
// SQL 获得数据库表结构
List<SchemaColumnDO> schemaColumns;
try {
KeyValue<SchemaTableDO, List<SchemaColumnDO>> result = CodegenSQLParser.parse(sql);
schemaColumns = result.getValue();
} catch (Exception ex) {
throw exception(CODEGEN_PARSE_SQL_ERROR);
}
// 执行同步
this.syncCodegen0(tableId, schemaColumns);
}
private void syncCodegen0(Long tableId, List<SchemaColumnDO> schemaColumns) {
// 校验导入的字段不为空
if (CollUtil.isEmpty(schemaColumns)) {
throw exception(CODEGEN_SYNC_COLUMNS_NULL);
}
Set<String> schemaColumnNames = CollectionUtils.convertSet(schemaColumns, SchemaColumnDO::getColumnName);
// 构建 CodegenColumnDO 数组只同步新增的字段 // 构建 CodegenColumnDO 数组只同步新增的字段
List<CodegenColumnDO> codegenColumns = codegenColumnMapper.selectListByTableId(tableId); List<CodegenColumnDO> codegenColumns = codegenColumnMapper.selectListByTableId(tableId);
Set<String> codegenColumnNames = CollectionUtils.convertSet(codegenColumns, CodegenColumnDO::getColumnName); Set<String> codegenColumnNames = CollectionUtils.convertSet(codegenColumns, CodegenColumnDO::getColumnName);
// 移除已经存在的字段 // 移除已经存在的字段
schemaColumns.removeIf(column -> codegenColumnNames.contains(column.getColumnName())); tableFields.removeIf(column -> codegenColumnNames.contains(column.getColumnName()));
// 计算需要删除的字段 // 计算需要删除的字段
Set<Long> deleteColumnIds = codegenColumns.stream().filter(column -> !schemaColumnNames.contains(column.getColumnName())) Set<String> tableFieldNames = CollectionUtils.convertSet(tableFields, TableField::getName);
Set<Long> deleteColumnIds = codegenColumns.stream().filter(column -> !tableFieldNames.contains(column.getColumnName()))
.map(CodegenColumnDO::getId).collect(Collectors.toSet()); .map(CodegenColumnDO::getId).collect(Collectors.toSet());
if (CollUtil.isEmpty(schemaColumns) && CollUtil.isEmpty(deleteColumnIds)) { if (CollUtil.isEmpty(tableFields) && CollUtil.isEmpty(deleteColumnIds)) {
throw exception(CODEGEN_SYNC_NONE_CHANGE); throw exception(CODEGEN_SYNC_NONE_CHANGE);
} }
// 插入新增的字段 // 插入新增的字段
List<CodegenColumnDO> columns = codegenBuilder.buildColumns(tableId, schemaColumns); List<CodegenColumnDO> columns = codegenBuilder.buildColumns(tableId, tableFields);
codegenColumnMapper.insertBatch(columns); codegenColumnMapper.insertBatch(columns);
// 删除不存在的字段 // 删除不存在的字段
if (CollUtil.isNotEmpty(deleteColumnIds)) { if (CollUtil.isNotEmpty(deleteColumnIds)) {
@ -228,11 +197,6 @@ public class CodegenServiceImpl implements CodegenService {
return codegenTableMapper.selectById(id); return codegenTableMapper.selectById(id);
} }
@Override
public List<CodegenTableDO> getCodeGenTableList() {
return codegenTableMapper.selectList();
}
@Override @Override
public List<CodegenColumnDO> getCodegenColumnListByTableId(Long tableId) { public List<CodegenColumnDO> getCodegenColumnListByTableId(Long tableId) {
return codegenColumnMapper.selectListByTableId(tableId); return codegenColumnMapper.selectListByTableId(tableId);
@ -255,13 +219,18 @@ public class CodegenServiceImpl implements CodegenService {
} }
@Override @Override
public List<SchemaTableDO> getSchemaTableList(String tableName, String tableComment) { public List<DatabaseTableRespVO> getDatabaseTableList(Long dataSourceConfigId, String name, String comment) {
List<SchemaTableDO> tables = schemaTableMapper.selectList(codegenProperties.getDbSchemas(), tableName, tableComment); List<TableInfo> tables = databaseTableService.getTableList(dataSourceConfigId, name, comment);
// TODO 强制移除 Quartz 的表未来做成可配置 // 移除置顶前缀的表名 // TODO 未来做成可配置
tables.removeIf(table -> table.getTableName().startsWith("QRTZ_")); tables.removeIf(table -> table.getName().toUpperCase().startsWith("QRTZ_"));
tables.removeIf(table -> table.getTableName().startsWith("ACT_")); tables.removeIf(table -> table.getName().toUpperCase().startsWith("ACT_"));
tables.removeIf(table -> table.getTableName().startsWith("FLW_")); tables.removeIf(table -> table.getName().toUpperCase().startsWith("FLW_"));
return tables; // 移除已经生成的表
// 移除在 Codegen 已经存在的
Set<String> existsTables = CollectionUtils.convertSet(
codegenTableMapper.selectListByDataSourceConfigId(dataSourceConfigId), CodegenTableDO::getTableName);
tables.removeIf(table -> existsTables.contains(table.getName()));
return CodegenConvert.INSTANCE.convertList04(tables);
} }
} }

View File

@ -7,23 +7,22 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.infra.convert.codegen.CodegenConvert; import cn.iocoder.yudao.module.infra.convert.codegen.CodegenConvert;
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO; 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.dataobject.codegen.CodegenTableDO;
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.SchemaColumnDO;
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.SchemaTableDO;
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenColumnHtmlTypeEnum; import cn.iocoder.yudao.module.infra.enums.codegen.CodegenColumnHtmlTypeEnum;
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenColumnListConditionEnum; import cn.iocoder.yudao.module.infra.enums.codegen.CodegenColumnListConditionEnum;
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenTemplateTypeEnum; import cn.iocoder.yudao.module.infra.enums.codegen.CodegenTemplateTypeEnum;
import com.baomidou.mybatisplus.generator.config.po.TableField;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.util.*; import java.util.*;
import static cn.hutool.core.text.CharSequenceUtil.*; import static cn.hutool.core.text.CharSequenceUtil.*;
/** /**
* 代码生成器的 Builder负责 * 代码生成器的 Builder负责
* 1. 将数据库的表 {@link SchemaTableDO} 定义构建成 {@link CodegenTableDO} * 1. 将数据库的表 {@link TableInfo} 定义构建成 {@link CodegenTableDO}
* 2. 将数据库的列 {@link SchemaColumnDO} 构定义建成 {@link CodegenColumnDO} * 2. 将数据库的列 {@link TableField} 构定义建成 {@link CodegenColumnDO}
*/ */
@Component @Component
public class CodegenBuilder { public class CodegenBuilder {
@ -82,21 +81,6 @@ public class CodegenBuilder {
*/ */
private static final Set<String> LIST_OPERATION_RESULT_EXCLUDE_COLUMN = Sets.newHashSet(); private static final Set<String> LIST_OPERATION_RESULT_EXCLUDE_COLUMN = Sets.newHashSet();
/**
* Java 类型与 MySQL 类型的映射关系
*/
private static final Map<String, Set<String>> javaTypeMappings = MapUtil.<String, Set<String>>builder()
.put(Boolean.class.getSimpleName(), Sets.newHashSet("bit"))
.put(Integer.class.getSimpleName(), Sets.newHashSet("tinyint", "smallint", "mediumint", "int"))
.put(Long.class.getSimpleName(), Collections.singleton("bigint"))
.put(Double.class.getSimpleName(), Sets.newHashSet("float", "double"))
.put(BigDecimal.class.getSimpleName(), Sets.newHashSet("decimal", "numeric"))
.put(String.class.getSimpleName(), Sets.newHashSet("tinytext", "text", "mediumtext", "longtext", // 长文本
"char", "varchar", "nvarchar", "varchar2")) // 短文本
.put(Date.class.getSimpleName(), Sets.newHashSet("datetime", "time", "date", "timestamp"))
.put("byte[]", Sets.newHashSet("blob"))
.build();
static { static {
Arrays.stream(ReflectUtil.getFields(BaseDO.class)).forEach(field -> BASE_DO_FIELDS.add(field.getName())); Arrays.stream(ReflectUtil.getFields(BaseDO.class)).forEach(field -> BASE_DO_FIELDS.add(field.getName()));
BASE_DO_FIELDS.add(TENANT_ID_FIELD); BASE_DO_FIELDS.add(TENANT_ID_FIELD);
@ -109,8 +93,8 @@ public class CodegenBuilder {
LIST_OPERATION_RESULT_EXCLUDE_COLUMN.remove("createTime"); // 创建时间还是需要返回的 LIST_OPERATION_RESULT_EXCLUDE_COLUMN.remove("createTime"); // 创建时间还是需要返回的
} }
public CodegenTableDO buildTable(SchemaTableDO schemaTable) { public CodegenTableDO buildTable(TableInfo tableInfo) {
CodegenTableDO table = CodegenConvert.INSTANCE.convert(schemaTable); CodegenTableDO table = CodegenConvert.INSTANCE.convert(tableInfo);
initTableDefault(table); initTableDefault(table);
return table; return table;
} }
@ -121,57 +105,33 @@ public class CodegenBuilder {
* @param table 表定义 * @param table 表定义
*/ */
private void initTableDefault(CodegenTableDO table) { private void initTableDefault(CodegenTableDO table) {
// system_dept 举例子moduleName systembusinessName deptclassName SystemDept // system_dept 举例子moduleName systembusinessName deptclassName Dept
// 如果不希望 System 前缀则可以手动在代码生成 - 修改生成配置 - 基本信息将实体类名称改为 Dept 即可 // 如果希望以 System 前缀则可以手动在代码生成 - 修改生成配置 - 基本信息将实体类名称改为 SystemDept 即可
table.setModuleName(subBefore(table.getTableName(), '_', false)); // 第一个 _ 前缀的前面作为 module 名字 String tableName = table.getTableName().toLowerCase();
table.setBusinessName(toCamelCase(subAfter(table.getTableName(), // 第一步_ 前缀的前面作为 module 名字第二步moduleName 必须小写
'_', false))); // 第一步第一个 _ 前缀的后面作为 module 名字; 第二步可能存在多个 _ 的情况转换成驼峰 table.setModuleName(subBefore(tableName, '_', false).toLowerCase());
table.setClassName(upperFirst(toCamelCase( // 驼峰 + 首字母大写 // 第一步第一个 _ 前缀的后面作为 module 名字; 第二步可能存在多个 _ 的情况转换成驼峰; 第三步businessName 必须小写
subAfter(table.getTableName(), '_', false)))); // 第一个 _ 前缀的前面作为 class 名字 table.setBusinessName(toCamelCase(subAfter(tableName, '_', false)).toLowerCase());
table.setClassComment(subBefore(table.getTableComment(), // 去除结尾的表作为类描述 // 驼峰 + 首字母大写第一步第一个 _ 前缀的后面作为 class 名字第二步驼峰命名
'表', true)); table.setClassName(upperFirst(toCamelCase(subAfter(tableName, '_', false))));
// 去除结尾的表作为类描述
table.setClassComment(StrUtil.removeSuffixIgnoreCase(table.getTableComment(), ""));
table.setTemplateType(CodegenTemplateTypeEnum.CRUD.getType()); table.setTemplateType(CodegenTemplateTypeEnum.CRUD.getType());
} }
public List<CodegenColumnDO> buildColumns(Long tableId, List<SchemaColumnDO> schemaColumns) { public List<CodegenColumnDO> buildColumns(Long tableId, List<TableField> tableFields) {
List<CodegenColumnDO> columns = CodegenConvert.INSTANCE.convertList(schemaColumns); List<CodegenColumnDO> columns = CodegenConvert.INSTANCE.convertList(tableFields);
int index = 1;
for (CodegenColumnDO column : columns) { for (CodegenColumnDO column : columns) {
column.setTableId(tableId); column.setTableId(tableId);
initColumnDefault(column); column.setOrdinalPosition(index++);
// 初始化 Column 列的默认字段
processColumnOperation(column); // 处理 CRUD 相关的字段的默认值
processColumnUI(column); // 处理 UI 相关的字段的默认值
} }
return columns; return columns;
} }
/**
* 初始化 Column 列的默认字段
*
* @param column 列定义
*/
private void initColumnDefault(CodegenColumnDO column) {
// 处理 Java 相关的字段的默认值
processColumnJava(column);
// 处理 CRUD 相关的字段的默认值
processColumnOperation(column);
// 处理 UI 相关的字段的默认值
processColumnUI(column);
}
private void processColumnJava(CodegenColumnDO column) {
// 处理 javaField 字段
column.setJavaField(toCamelCase(column.getColumnName()));
// 处理 dictType 字段暂无
// 处理 javaType 字段(兼容无符号类型)
String dbType = replaceIgnoreCase(subBefore(column.getColumnType(), '(', false),
" UNSIGNED", "");
javaTypeMappings.entrySet().stream()
.filter(entry -> entry.getValue().contains(dbType))
.findFirst().ifPresent(entry -> column.setJavaType(entry.getKey()));
if (column.getJavaType() == null) {
throw new IllegalStateException(String.format("column(%s) 的数据库类型(%s) 找不到匹配的 Java 类型",
column.getColumnName(), column.getColumnType()));
}
}
private void processColumnOperation(CodegenColumnDO column) { private void processColumnOperation(CodegenColumnDO column) {
// 处理 createOperation 字段 // 处理 createOperation 字段
column.setCreateOperation(!CREATE_OPERATION_EXCLUDE_COLUMN.contains(column.getJavaField()) column.setCreateOperation(!CREATE_OPERATION_EXCLUDE_COLUMN.contains(column.getJavaField())

View File

@ -1,117 +0,0 @@
package cn.iocoder.yudao.module.infra.service.codegen.inner;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.SchemaColumnDO;
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.SchemaTableDO;
import com.alibaba.druid.DbType;
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLPrimaryKey;
import com.alibaba.druid.sql.ast.statement.SQLTableElement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateTableStatement;
import com.alibaba.druid.sql.repository.SchemaRepository;
import org.apache.commons.collections4.KeyValue;
import org.apache.commons.collections4.keyvalue.DefaultKeyValue;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import static com.alibaba.druid.sql.SQLUtils.normalize;
/**
* SQL 解析器将创建表的 SQL解析成 {@link SchemaTableDO} {@link SchemaColumnDO} 对象
* 后续可以基于它们生成代码~
*
* @author 芋道源码
*/
public class CodegenSQLParser {
/**
* 解析建表 SQL 语句返回 {@link SchemaTableDO} {@link SchemaColumnDO} 对象
*
* @param sql 建表 SQL 语句
* @return 解析结果
*/
public static KeyValue<SchemaTableDO, List<SchemaColumnDO>> parse(String sql) {
// 解析 SQL Statement
SQLCreateTableStatement statement = parseCreateSQL(sql);
// 解析 Table
SchemaTableDO table = parseTable(statement);
// 解析 Column 字段
List<SchemaColumnDO> columns = parseColumns(statement);
columns.forEach(column -> column.setTableName(table.getTableName()));
// 返回
return new DefaultKeyValue<>(table, columns);
}
/**
* 使用 Druid 工具建表 SQL 语句
*
* @param sql 建表 SQL 语句
* @return 创建 Statement
*/
private static SQLCreateTableStatement parseCreateSQL(String sql) {
// 解析 SQL
SchemaRepository repository = new SchemaRepository(DbType.mysql);
repository.console(sql);
// 获得该表对应的 MySqlCreateTableStatement 对象
String tableName = CollUtil.getFirst(repository.getDefaultSchema().getObjects()).getName();
return (MySqlCreateTableStatement) repository.findTable(tableName).getStatement();
}
private static SchemaTableDO parseTable(SQLCreateTableStatement statement) {
return SchemaTableDO.builder()
.tableName(statement.getTableSource().getTableName(true))
.tableComment(getCommentText(statement))
.build();
}
private static String getCommentText(SQLCreateTableStatement statement) {
if (statement == null || statement.getComment() == null) {
return "";
}
return ((SQLCharExpr) statement.getComment()).getText();
}
private static List<SchemaColumnDO> parseColumns(SQLCreateTableStatement statement) {
List<SchemaColumnDO> columns = new ArrayList<>();
statement.getTableElementList().forEach(element -> parseColumn(columns, element));
return columns;
}
private static void parseColumn(List<SchemaColumnDO> columns, SQLTableElement element) {
// 处理主键
if (element instanceof SQLPrimaryKey) {
parsePrimaryKey(columns, (SQLPrimaryKey) element);
return;
}
// 处理字段定义
if (element instanceof SQLColumnDefinition) {
parseColumnDefinition(columns, (SQLColumnDefinition) element);
}
}
private static void parsePrimaryKey(List<SchemaColumnDO> columns, SQLPrimaryKey primaryKey) {
String columnName = normalize(primaryKey.getColumns().get(0).toString()); // 暂时不考虑联合主键
// 匹配 columns 主键字段设置为 primary
columns.stream().filter(column -> column.getColumnName().equals(columnName))
.forEach(column -> column.setPrimaryKey(true));
}
private static void parseColumnDefinition(List<SchemaColumnDO> columns, SQLColumnDefinition definition) {
String text = definition.toString().toUpperCase();
columns.add(SchemaColumnDO.builder()
.columnName(normalize(definition.getColumnName()))
.columnType(definition.getDataType().toString())
.columnComment(Objects.isNull(definition.getComment()) ? ""
: normalize(definition.getComment().toString()))
.nullable(!text.contains(" NOT NULL"))
.primaryKey(false)
.autoIncrement(text.contains("AUTO_INCREMENT"))
.ordinalPosition(columns.size() + 1)
.build());
}
}

View File

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

View File

@ -0,0 +1,54 @@
package cn.iocoder.yudao.module.infra.service.db;
import cn.iocoder.yudao.module.infra.controller.admin.db.vo.DataSourceConfigCreateReqVO;
import cn.iocoder.yudao.module.infra.controller.admin.db.vo.DataSourceConfigUpdateReqVO;
import cn.iocoder.yudao.module.infra.dal.dataobject.db.DataSourceConfigDO;
import javax.validation.Valid;
import java.util.List;
/**
* 数据源配置 Service 接口
*
* @author 芋道源码
*/
public interface DataSourceConfigService {
/**
* 创建数据源配置
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createDataSourceConfig(@Valid DataSourceConfigCreateReqVO createReqVO);
/**
* 更新数据源配置
*
* @param updateReqVO 更新信息
*/
void updateDataSourceConfig(@Valid DataSourceConfigUpdateReqVO updateReqVO);
/**
* 删除数据源配置
*
* @param id 编号
*/
void deleteDataSourceConfig(Long id);
/**
* 获得数据源配置
*
* @param id 编号
* @return 数据源配置
*/
DataSourceConfigDO getDataSourceConfig(Long id);
/**
* 获得数据源配置列表
*
* @return 数据源配置列表
*/
List<DataSourceConfigDO> getDataSourceConfigList();
}

View File

@ -0,0 +1,118 @@
package cn.iocoder.yudao.module.infra.service.db;
import cn.iocoder.yudao.framework.mybatis.core.util.JdbcUtils;
import cn.iocoder.yudao.module.infra.controller.admin.db.vo.DataSourceConfigCreateReqVO;
import cn.iocoder.yudao.module.infra.controller.admin.db.vo.DataSourceConfigUpdateReqVO;
import cn.iocoder.yudao.module.infra.convert.db.DataSourceConfigConvert;
import cn.iocoder.yudao.module.infra.dal.dataobject.db.DataSourceConfigDO;
import cn.iocoder.yudao.module.infra.dal.mysql.db.DataSourceConfigMapper;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties;
import org.jasypt.encryption.StringEncryptor;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.DATA_SOURCE_CONFIG_NOT_EXISTS;
import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.DATA_SOURCE_CONFIG_NOT_OK;
/**
* 数据源配置 Service 实现类
*
* @author 芋道源码
*/
@Service
@Validated
public class DataSourceConfigServiceImpl implements DataSourceConfigService {
@Resource
private DataSourceConfigMapper dataSourceConfigMapper;
@Resource
private StringEncryptor stringEncryptor;
@Resource
private DynamicDataSourceProperties dynamicDataSourceProperties;
@Override
public Long createDataSourceConfig(DataSourceConfigCreateReqVO createReqVO) {
DataSourceConfigDO dataSourceConfig = DataSourceConfigConvert.INSTANCE.convert(createReqVO);
checkConnectionOK(dataSourceConfig);
// 插入
dataSourceConfig.setPassword(stringEncryptor.encrypt(createReqVO.getPassword()));
dataSourceConfigMapper.insert(dataSourceConfig);
// 返回
return dataSourceConfig.getId();
}
@Override
public void updateDataSourceConfig(DataSourceConfigUpdateReqVO updateReqVO) {
// 校验存在
validateDataSourceConfigExists(updateReqVO.getId());
DataSourceConfigDO updateObj = DataSourceConfigConvert.INSTANCE.convert(updateReqVO);
checkConnectionOK(updateObj);
// 更新
updateObj.setPassword(stringEncryptor.encrypt(updateObj.getPassword()));
dataSourceConfigMapper.updateById(updateObj);
}
@Override
public void deleteDataSourceConfig(Long id) {
// 校验存在
validateDataSourceConfigExists(id);
// 删除
dataSourceConfigMapper.deleteById(id);
}
private void validateDataSourceConfigExists(Long id) {
if (dataSourceConfigMapper.selectById(id) == null) {
throw exception(DATA_SOURCE_CONFIG_NOT_EXISTS);
}
}
@Override
public DataSourceConfigDO getDataSourceConfig(Long id) {
// 如果 id 0默认为 master 的数据源
if (Objects.equals(id, DataSourceConfigDO.ID_MASTER)) {
return buildMasterDataSourceConfig();
}
// DB 中读取
DataSourceConfigDO dataSourceConfig = dataSourceConfigMapper.selectById(id);
try {
dataSourceConfig.setPassword(stringEncryptor.decrypt(dataSourceConfig.getPassword()));
} catch (Exception ignore) { // 解码失败则不解码
}
return dataSourceConfig;
}
@Override
public List<DataSourceConfigDO> getDataSourceConfigList() {
List<DataSourceConfigDO> result = dataSourceConfigMapper.selectList();
// 补充 master 数据源
result.add(0, buildMasterDataSourceConfig());
return result;
}
private void checkConnectionOK(DataSourceConfigDO config) {
boolean success = JdbcUtils.isConnectionOK(config.getUrl(), config.getUsername(), config.getPassword());
if (!success) {
throw exception(DATA_SOURCE_CONFIG_NOT_OK);
}
}
private DataSourceConfigDO buildMasterDataSourceConfig() {
String primary = dynamicDataSourceProperties.getPrimary();
DataSourceProperty dataSourceProperty = dynamicDataSourceProperties.getDatasource().get(primary);
return new DataSourceConfigDO().setId(DataSourceConfigDO.ID_MASTER).setName(primary)
.setUrl(dataSourceProperty.getUrl())
.setUsername(dataSourceProperty.getUsername())
.setPassword(dataSourceProperty.getPassword());
}
}

View File

@ -0,0 +1,33 @@
package cn.iocoder.yudao.module.infra.service.db;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import java.util.List;
/**
* 数据库表 Service
*
* @author 芋道源码
*/
public interface DatabaseTableService {
/**
* 获得表列表基于表名称 + 表描述进行模糊匹配
*
* @param dataSourceConfigId 数据源配置的编号
* @param nameLike 表名称模糊匹配
* @param commentLike 表描述模糊匹配
* @return 表列表
*/
List<TableInfo> getTableList(Long dataSourceConfigId, String nameLike, String commentLike);
/**
* 获得指定表名
*
* @param dataSourceConfigId 数据源配置的编号
* @param tableName 表名称
* @return
*/
TableInfo getTable(Long dataSourceConfigId, String tableName);
}

View File

@ -0,0 +1,65 @@
package cn.iocoder.yudao.module.infra.service.db;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.module.infra.dal.dataobject.db.DataSourceConfigDO;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
/**
* 数据库表 Service 实现类
*
* @author 芋道源码
*/
@Service
public class DatabaseTableServiceImpl implements DatabaseTableService {
@Resource
private DataSourceConfigService dataSourceConfigService;
@Override
public List<TableInfo> getTableList(Long dataSourceConfigId, String nameLike, String commentLike) {
List<TableInfo> tables = getTableList0(dataSourceConfigId, null);
return tables.stream().filter(tableInfo -> (StrUtil.isEmpty(nameLike) || tableInfo.getName().contains(nameLike))
&& (StrUtil.isEmpty(commentLike) || tableInfo.getComment().contains(commentLike)))
.collect(Collectors.toList());
}
@Override
public TableInfo getTable(Long dataSourceConfigId, String name) {
return CollUtil.getFirst(getTableList0(dataSourceConfigId, name));
}
public List<TableInfo> getTableList0(Long dataSourceConfigId, String name) {
// 获得数据源配置
DataSourceConfigDO config = dataSourceConfigService.getDataSourceConfig(dataSourceConfigId);
Assert.notNull(config, "数据源({}) 不存在!", dataSourceConfigId);
// 使用 MyBatis Plus Generator 解析表结构
DataSourceConfig dataSourceConfig = new DataSourceConfig.Builder(config.getUrl(), config.getUsername(),
config.getPassword()).build();
StrategyConfig.Builder strategyConfig = new StrategyConfig.Builder();
if (StrUtil.isNotEmpty(name)) {
strategyConfig.addInclude(name);
}
GlobalConfig globalConfig = new GlobalConfig.Builder().dateType(DateType.ONLY_DATE).build(); // 只使用 Date 类型不使用 LocalDate
ConfigBuilder builder = new ConfigBuilder(null, dataSourceConfig, strategyConfig.build(),
null, globalConfig, null);
// 按照名字排序
List<TableInfo> tables = builder.getTableInfoList();
tables.sort(Comparator.comparing(TableInfo::getName));
return tables;
}
}

View File

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

View File

@ -10,7 +10,8 @@ import ${BaseDOClassName};
* *
* @author ${table.author} * @author ${table.author}
*/ */
@TableName("${table.tableName}") @TableName("${table.tableName.toLowerCase()}")
@KeySequence("${table.tableName.toLowerCase()}_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true) @ToString(callSuper = true)

Some files were not shown because too many files have changed in this diff Show More