【同步】与 yudao-boot 版本保持一致!
This commit is contained in:
@@ -15,14 +15,6 @@ public interface ErrorCodeConstants {
|
||||
ErrorCode CONFIG_CAN_NOT_DELETE_SYSTEM_TYPE = new ErrorCode(1_001_000_003, "不能删除类型为系统内置的参数配置");
|
||||
ErrorCode CONFIG_GET_VALUE_ERROR_IF_VISIBLE = new ErrorCode(1_001_000_004, "获取参数配置失败,原因:不允许获取不可见配置");
|
||||
|
||||
// ========== 定时任务 1-001-001-000 ==========
|
||||
ErrorCode JOB_NOT_EXISTS = new ErrorCode(1_001_001_000, "定时任务不存在");
|
||||
ErrorCode JOB_HANDLER_EXISTS = new ErrorCode(1_001_001_001, "定时任务的处理器已经存在");
|
||||
ErrorCode JOB_CHANGE_STATUS_INVALID = new ErrorCode(1_001_001_002, "只允许修改为开启或者关闭状态");
|
||||
ErrorCode JOB_CHANGE_STATUS_EQUALS = new ErrorCode(1_001_001_003, "定时任务已经处于该状态,无需修改");
|
||||
ErrorCode JOB_UPDATE_ONLY_NORMAL_STATUS = new ErrorCode(1_001_001_004, "只有开启状态的任务,才可以修改");
|
||||
ErrorCode JOB_CRON_EXPRESSION_VALID = new ErrorCode(1_001_001_005, "CRON 表达式不正确");
|
||||
|
||||
// ========== API 错误日志 1-001-002-000 ==========
|
||||
ErrorCode API_ERROR_LOG_NOT_FOUND = new ErrorCode(1_001_002_000, "API 错误日志不存在");
|
||||
ErrorCode API_ERROR_LOG_PROCESSED = new ErrorCode(1_001_002_001, "API 错误日志已处理");
|
||||
@@ -45,7 +37,6 @@ public interface ErrorCodeConstants {
|
||||
ErrorCode CODEGEN_MASTER_TABLE_NOT_EXISTS = new ErrorCode(1_001_004_010, "主表(id={})定义不存在,请检查");
|
||||
ErrorCode CODEGEN_SUB_COLUMN_NOT_EXISTS = new ErrorCode(1_001_004_011, "子表的字段(id={})不存在,请检查");
|
||||
ErrorCode CODEGEN_MASTER_GENERATION_FAIL_NO_SUB_TABLE = new ErrorCode(1_001_004_012, "主表生成代码失败,原因:它没有子表");
|
||||
ErrorCode CODEGEN_MASTER_GENERATION_FAIL_NO_SUB_COLUMN = new ErrorCode(1_001_004_013, "主表生成代码失败,原因:它的子表({})没有字段");
|
||||
|
||||
// ========== 文件配置 1-001-006-000 ==========
|
||||
ErrorCode FILE_CONFIG_NOT_EXISTS = new ErrorCode(1_001_006_000, "文件配置不存在");
|
||||
@@ -55,9 +46,6 @@ public interface ErrorCodeConstants {
|
||||
ErrorCode DATA_SOURCE_CONFIG_NOT_EXISTS = new ErrorCode(1_001_007_000, "数据源配置不存在");
|
||||
ErrorCode DATA_SOURCE_CONFIG_NOT_OK = new ErrorCode(1_001_007_001, "数据源配置不正确,无法进行连接");
|
||||
|
||||
// ========== 数据源配置 1-001-107-000 ==========
|
||||
ErrorCode DEMO_STUDENT_NOT_EXISTS = new ErrorCode(1_001_107_000, "学生不存在");
|
||||
|
||||
// ========== 学生 1-001-201-000 ==========
|
||||
ErrorCode DEMO01_CONTACT_NOT_EXISTS = new ErrorCode(1_001_201_000, "示例联系人不存在");
|
||||
ErrorCode DEMO02_CATEGORY_NOT_EXISTS = new ErrorCode(1_001_201_001, "示例分类不存在");
|
||||
|
||||
@@ -117,11 +117,6 @@
|
||||
<artifactId>velocity-engine-core</artifactId> <!-- 实现代码生成 -->
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.smallbun.screw</groupId>
|
||||
<artifactId>screw-core</artifactId> <!-- 实现数据库文档 -->
|
||||
</dependency>
|
||||
|
||||
<!-- 监控相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.cloud</groupId>
|
||||
|
||||
@@ -1,154 +0,0 @@
|
||||
package cn.iocoder.yudao.module.infra.controller.admin.db;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
|
||||
import cn.smallbun.screw.core.Configuration;
|
||||
import cn.smallbun.screw.core.engine.EngineConfig;
|
||||
import cn.smallbun.screw.core.engine.EngineFileType;
|
||||
import cn.smallbun.screw.core.engine.EngineTemplateType;
|
||||
import cn.smallbun.screw.core.execute.DocumentationExecute;
|
||||
import cn.smallbun.screw.core.process.ProcessConfig;
|
||||
import com.baomidou.dynamic.datasource.creator.DataSourceProperty;
|
||||
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties;
|
||||
import com.zaxxer.hikari.HikariConfig;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
@Tag(name = "管理后台 - 数据库文档")
|
||||
@RestController
|
||||
@RequestMapping("/infra/db-doc")
|
||||
public class DatabaseDocController {
|
||||
|
||||
@Resource
|
||||
private DynamicDataSourceProperties dynamicDataSourceProperties;
|
||||
|
||||
private static final String FILE_OUTPUT_DIR = System.getProperty("java.io.tmpdir") + File.separator
|
||||
+ "db-doc";
|
||||
private static final String DOC_FILE_NAME = "数据库文档";
|
||||
private static final String DOC_VERSION = "1.0.0";
|
||||
private static final String DOC_DESCRIPTION = "文档描述";
|
||||
|
||||
@GetMapping("/export-html")
|
||||
@Operation(summary = "导出 html 格式的数据文档")
|
||||
@Parameter(name = "deleteFile", description = "是否删除在服务器本地生成的数据库文档", example = "true")
|
||||
public void exportHtml(@RequestParam(defaultValue = "true") Boolean deleteFile,
|
||||
HttpServletResponse response) throws IOException {
|
||||
doExportFile(EngineFileType.HTML, deleteFile, response);
|
||||
}
|
||||
|
||||
@GetMapping("/export-word")
|
||||
@Operation(summary = "导出 word 格式的数据文档")
|
||||
@Parameter(name = "deleteFile", description = "是否删除在服务器本地生成的数据库文档", example = "true")
|
||||
public void exportWord(@RequestParam(defaultValue = "true") Boolean deleteFile,
|
||||
HttpServletResponse response) throws IOException {
|
||||
doExportFile(EngineFileType.WORD, deleteFile, response);
|
||||
}
|
||||
|
||||
@GetMapping("/export-markdown")
|
||||
@Operation(summary = "导出 markdown 格式的数据文档")
|
||||
@Parameter(name = "deleteFile", description = "是否删除在服务器本地生成的数据库文档", example = "true")
|
||||
public void exportMarkdown(@RequestParam(defaultValue = "true") Boolean deleteFile,
|
||||
HttpServletResponse response) throws IOException {
|
||||
doExportFile(EngineFileType.MD, deleteFile, response);
|
||||
}
|
||||
|
||||
private void doExportFile(EngineFileType fileOutputType, Boolean deleteFile,
|
||||
HttpServletResponse response) throws IOException {
|
||||
String docFileName = DOC_FILE_NAME + "_" + IdUtil.fastSimpleUUID();
|
||||
String filePath = doExportFile(fileOutputType, docFileName);
|
||||
String downloadFileName = DOC_FILE_NAME + fileOutputType.getFileSuffix(); //下载后的文件名
|
||||
try {
|
||||
// 读取,返回
|
||||
ServletUtils.writeAttachment(response, downloadFileName, FileUtil.readBytes(filePath));
|
||||
} finally {
|
||||
handleDeleteFile(deleteFile, filePath);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 输出文件,返回文件路径
|
||||
*
|
||||
* @param fileOutputType 文件类型
|
||||
* @param fileName 文件名, 无需 ".docx" 等文件后缀
|
||||
* @return 生成的文件所在路径
|
||||
*/
|
||||
private String doExportFile(EngineFileType fileOutputType, String fileName) {
|
||||
try (HikariDataSource dataSource = buildDataSource()) {
|
||||
// 创建 screw 的配置
|
||||
Configuration config = Configuration.builder()
|
||||
.version(DOC_VERSION) // 版本
|
||||
.description(DOC_DESCRIPTION) // 描述
|
||||
.dataSource(dataSource) // 数据源
|
||||
.engineConfig(buildEngineConfig(fileOutputType, fileName)) // 引擎配置
|
||||
.produceConfig(buildProcessConfig()) // 处理配置
|
||||
.build();
|
||||
|
||||
// 执行 screw,生成数据库文档
|
||||
new DocumentationExecute(config).execute();
|
||||
|
||||
return FILE_OUTPUT_DIR + File.separator + fileName + fileOutputType.getFileSuffix();
|
||||
}
|
||||
}
|
||||
|
||||
private void handleDeleteFile(Boolean deleteFile, String filePath) {
|
||||
if (!deleteFile) {
|
||||
return;
|
||||
}
|
||||
FileUtil.del(filePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建数据源
|
||||
*/
|
||||
// TODO 芋艿:screw 暂时不支持 druid,尴尬
|
||||
private HikariDataSource buildDataSource() {
|
||||
// 获得 DataSource 数据源,目前只支持首个
|
||||
String primary = dynamicDataSourceProperties.getPrimary();
|
||||
DataSourceProperty dataSourceProperty = dynamicDataSourceProperties.getDatasource().get(primary);
|
||||
// 创建 HikariConfig 配置类
|
||||
HikariConfig hikariConfig = new HikariConfig();
|
||||
hikariConfig.setJdbcUrl(dataSourceProperty.getUrl());
|
||||
hikariConfig.setUsername(dataSourceProperty.getUsername());
|
||||
hikariConfig.setPassword(dataSourceProperty.getPassword());
|
||||
hikariConfig.addDataSourceProperty("useInformationSchema", "true"); // 设置可以获取 tables remarks 信息
|
||||
// 创建数据源
|
||||
return new HikariDataSource(hikariConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建 screw 的引擎配置
|
||||
*/
|
||||
private static EngineConfig buildEngineConfig(EngineFileType fileOutputType, String docFileName) {
|
||||
return EngineConfig.builder()
|
||||
.fileOutputDir(FILE_OUTPUT_DIR) // 生成文件路径
|
||||
.openOutputDir(false) // 打开目录
|
||||
.fileType(fileOutputType) // 文件类型
|
||||
.produceType(EngineTemplateType.velocity) // 文件类型
|
||||
.fileName(docFileName) // 自定义文件名称
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建 screw 的处理配置,一般可忽略
|
||||
* 指定生成逻辑、当存在指定表、指定表前缀、指定表后缀时,将生成指定表,其余表不生成、并跳过忽略表配置
|
||||
*/
|
||||
private static ProcessConfig buildProcessConfig() {
|
||||
return ProcessConfig.builder()
|
||||
.ignoreTablePrefix(Arrays.asList("QRTZ_", "ACT_", "FLW_")) // 忽略表前缀
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -147,6 +147,4 @@ yudao:
|
||||
- ${management.endpoints.web.base-path}/** # 不处理 Actuator 的请求
|
||||
access-log: # 访问日志的配置项
|
||||
enable: false
|
||||
error-code: # 错误码相关配置项
|
||||
enable: false
|
||||
demo: false # 关闭演示模式
|
||||
|
||||
@@ -143,9 +143,6 @@ yudao:
|
||||
base-package: cn.iocoder.yudao
|
||||
db-schemas: ${spring.datasource.dynamic.datasource.master.name}
|
||||
front-type: 10 # 前端模版的类型,参见 CodegenFrontTypeEnum 枚举类
|
||||
error-code: # 错误码相关配置项
|
||||
constants-class-list:
|
||||
- cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants
|
||||
tenant: # 多租户相关配置项
|
||||
enable: true
|
||||
ignore-urls:
|
||||
|
||||
@@ -94,7 +94,7 @@ const { t } = useI18n() // 国际化
|
||||
const message = useMessage() // 消息弹窗
|
||||
|
||||
const props = defineProps<{
|
||||
${subJoinColumn.javaField}: undefined // ${subJoinColumn.columnComment}(主表的关联字段)
|
||||
${subJoinColumn.javaField}?: number // ${subJoinColumn.columnComment}(主表的关联字段)
|
||||
}>()
|
||||
const loading = ref(false) // 列表的加载中
|
||||
const list = ref([]) // 列表的数据
|
||||
@@ -103,17 +103,20 @@ const total = ref(0) // 列表的总页数
|
||||
const queryParams = reactive({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
${subJoinColumn.javaField}: undefined
|
||||
${subJoinColumn.javaField}: undefined as unknown
|
||||
})
|
||||
|
||||
/** 监听主表的关联字段的变化,加载对应的子表数据 */
|
||||
watch(
|
||||
() => props.${subJoinColumn.javaField},
|
||||
(val) => {
|
||||
(val: number) => {
|
||||
if (!val) {
|
||||
return
|
||||
}
|
||||
queryParams.${subJoinColumn.javaField} = val
|
||||
handleQuery()
|
||||
},
|
||||
{ immediate: false }
|
||||
{ immediate: true, deep: true }
|
||||
)
|
||||
#end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user