Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2423ffd7ae | ||
|
|
6cf3c47d09 | ||
|
|
6e2a0e2cb3 | ||
|
|
6d83e16b1c | ||
|
|
25b991c13a | ||
|
|
32b1c1045b | ||
|
|
458266297c | ||
|
|
4139d5bd7b | ||
|
|
8b09976db3 | ||
|
|
8e61b43c3f | ||
|
|
b2f2772a17 | ||
|
|
4314d3410f | ||
|
|
a2a07a2549 | ||
|
|
25c6b49775 | ||
|
|
ee9e51947e | ||
|
|
49e05081f9 | ||
|
|
9420a17bcc | ||
|
|
3b6a95c731 | ||
|
|
c59192c144 | ||
|
|
299bec29e0 | ||
|
|
86bb9c2f2a | ||
|
|
121b6653ab | ||
|
|
9fc3990411 | ||
|
|
7a53390946 | ||
|
|
2e8a930b16 | ||
|
|
444c288079 |
No files matched your search
+1
-1
@@ -45,12 +45,12 @@ buildNumber.properties
|
||||
####################### svn ##############################
|
||||
.svn
|
||||
|
||||
|
||||
####################### eclipse ##############################
|
||||
.project
|
||||
.settings
|
||||
bin/
|
||||
logs/
|
||||
db/
|
||||
.classpath
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
# AGENTS.md - Coding Guidelines for crabc-api
|
||||
|
||||
## Project Overview
|
||||
|
||||
A Java Spring Boot API development platform with multi-module Maven architecture for dynamic SQL-based API generation.
|
||||
|
||||
## Build Commands
|
||||
|
||||
```bash
|
||||
# Compile all modules
|
||||
mvn clean compile
|
||||
|
||||
# Run tests (no tests currently exist)
|
||||
mvn test
|
||||
|
||||
# Run a single test class (when tests are added)
|
||||
mvn test -Dtest=ClassName
|
||||
|
||||
# Run a single test method
|
||||
mvn test -Dtest=ClassName#methodName
|
||||
|
||||
# Package application
|
||||
mvn clean package
|
||||
|
||||
# Package without tests
|
||||
mvn clean package -DskipTests
|
||||
|
||||
# Run the application
|
||||
cd crabc-api/crabc-admin && mvn spring-boot:run
|
||||
```
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
cn.crabc
|
||||
├── crabc-api/ # API modules parent
|
||||
│ ├── crabc-admin/ # Boot module (port 9377)
|
||||
│ ├── crabc-core/ # Core business logic
|
||||
│ ├── crabc-datasource/ # Dynamic data sources
|
||||
│ └── crabc-spi/ # Plugin interfaces
|
||||
└── crabc-spring-boot-starter/ # Maven starter (optional)
|
||||
```
|
||||
|
||||
## Technology Stack
|
||||
|
||||
- **Java**: 17
|
||||
- **Spring Boot**: 3.5.9
|
||||
- **MyBatis**: 3.0.5 (with MyBatis-Plus 3.5.15)
|
||||
- **Database**: MySQL 8.0+, Oracle, PostgreSQL, SQL Server, TiDB
|
||||
- **Connection Pool**: Druid 1.2.27
|
||||
- **Cache**: Caffeine
|
||||
- **JSON**: Fastjson 2.0.49
|
||||
- **Auth**: JWT 0.12.5
|
||||
- **Utilities**: Lombok, Apache Commons
|
||||
|
||||
## Code Style Guidelines
|
||||
|
||||
### Naming Conventions
|
||||
|
||||
- **Packages**: `cn.crabc.core.{module}.{layer}` (e.g., `cn.crabc.core.app.controller`)
|
||||
- **Classes**: PascalCase (e.g., `DataSourceController`, `BaseApiService`)
|
||||
- **Interfaces**: PascalCase with `I` prefix (e.g., `IBaseDataService`, `IApiMapper`)
|
||||
- **Methods**: camelCase (e.g., `getDataSourcePage`, `testConnection`)
|
||||
- **Variables**: camelCase (e.g., `dataSourceId`, `pageNum`)
|
||||
- **Constants**: UPPER_SNAKE_CASE (e.g., `CODE_TAG`, `MSG_TAG`)
|
||||
|
||||
### Code Formatting
|
||||
|
||||
- **Indentation**: 4 spaces (no tabs)
|
||||
- **Braces**: Allman style (opening brace on new line for class/method)
|
||||
- **Line endings**: LF
|
||||
- **Encoding**: UTF-8
|
||||
- **Max line length**: 120 characters
|
||||
|
||||
### Import Organization
|
||||
|
||||
1. `java.*` and `javax.*`
|
||||
2. Third-party libraries (Spring, MyBatis, etc.)
|
||||
3. Project internal imports
|
||||
4. Static imports (if any)
|
||||
|
||||
### Documentation
|
||||
|
||||
- All classes must have class-level Javadoc with:
|
||||
- Description in Chinese
|
||||
- `@author yuqf` tag
|
||||
- All public methods should have Javadoc with Chinese descriptions
|
||||
- Use block comments for complex logic sections
|
||||
|
||||
### Dependency Injection
|
||||
|
||||
- Use `@Autowired` for field injection (existing pattern)
|
||||
- Prefer constructor injection for new code when possible
|
||||
|
||||
### REST API Controllers
|
||||
|
||||
- Use `@RestController` annotation
|
||||
- Base path pattern: `/api/box/{module}/{resource}`
|
||||
- Return `Result` wrapper for consistent API responses
|
||||
- HTTP methods:
|
||||
- `GET` for queries with `@GetMapping`
|
||||
- `POST` for create with `@PostMapping`
|
||||
- `PUT` for update with `@PutMapping`
|
||||
- `DELETE` for delete with `@DeleteMapping`
|
||||
|
||||
### Entities and DTOs
|
||||
|
||||
- Use Lombok `@Getter` and `@Setter` annotations
|
||||
- Include `serialVersionUID` for serializable classes
|
||||
- Use `Long` for primary keys
|
||||
- Database column names: use underscores (e.g., `api_id`)
|
||||
- Java field names: use camelCase (e.g., `apiId`)
|
||||
|
||||
### MyBatis Mappers
|
||||
|
||||
- Place XML files in `src/main/resources/mapper/`
|
||||
- Namespace must match mapper interface fully qualified name
|
||||
- Use `<if>` tags for dynamic SQL conditions
|
||||
- Parameter references: `#{fieldName}`
|
||||
- Use `resultType` for selects, `parameterType` for inserts/updates
|
||||
|
||||
### Error Handling
|
||||
|
||||
- Use `Result.error()` for business errors
|
||||
- Return HTTP 200 with error code in response body
|
||||
- Success code: `0`, Error code: `500` or custom
|
||||
|
||||
### Database Guidelines
|
||||
|
||||
- Support multiple database types (MySQL, Oracle, PostgreSQL, etc.)
|
||||
- Use parameterized queries (no string concatenation)
|
||||
- Use PageHelper for pagination
|
||||
|
||||
## Testing
|
||||
|
||||
- Framework: JUnit 4 (from dependencies)
|
||||
- Spring Boot Test for integration tests
|
||||
- Test classes should follow `*Test.java` or `Test*.java` naming
|
||||
- Place tests in `src/test/java` matching package structure
|
||||
|
||||
## Configuration
|
||||
|
||||
- Application config: `application.yml`
|
||||
- MyBatis config: `mybatis-config.xml`
|
||||
- Port: 9377 (development)
|
||||
- Banner mode: off (`banner-mode: off`)
|
||||
|
||||
## Additional Notes
|
||||
|
||||
- This is a Chinese project with Chinese comments and documentation
|
||||
- Licensed under Apache License 2.0
|
||||
- No automated linting tools (checkstyle/spotbugs) currently configured
|
||||
- Focus on dynamic SQL execution and API generation capabilities
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
FROM eclipse-temurin:21-jdk-alpine
|
||||
LABEL version="3.5.2"
|
||||
LABEL version="4.0.0"
|
||||
|
||||
COPY crabc-admin.jar /app.jar
|
||||
ENV LANG="en_US.UTF-8"
|
||||
|
||||
@@ -3,18 +3,19 @@
|
||||
crabc由create + abc 组合而来,意在为项目系统构建的通用的接口底座。
|
||||
|
||||
# 介绍
|
||||
**crabc** 是低代码接口开发平台,企业数据服务平台,深度整合SpringBoot和Mybatis实现动态数据源和动态SQL、函数和存储过程。
|
||||
**crabc-api** 是接口快速开发平台,企业数据服务平台,sql2Api,深度整合SpringBoot和Mybatis实现动态数据源和动态SQL、函数和存储过程。
|
||||
支持接入(mysql、oracle、postgresql、sqlserver、达梦、TiDB、es和hive)等SQL或/NoSQL数据源,
|
||||
在线可视化编写SQL后即可快速生成接口对外提供服务,接口一键上下线。减少通用接口的SQL编写,让开发人员专注更复杂的业务逻辑实现。
|
||||
支持Mybatis中if等标签语法、数据脱敏、数据转换、国密加密、协同开发等功能,可集成微服务网关支持接入第三方接口、权限认证、限流、缓存、告警监控和统一日志等一站式API数据服务,
|
||||
支持Mybatis中if等标签语法、数据脱敏、数据转换、国密加密、协同开发、接口编排等功能,可集成微服务网关支持接入第三方接口、权限认证、限流、缓存、告警监控和统一日志等一站式API数据服务,
|
||||
助力于企业数据资产价值升级,成为企业数字化转型的重要推动力。
|
||||
|
||||

|
||||
## 功能
|
||||
## 社区版功能
|
||||
- **工作台**:可视化编写SQL快速的对外发布成API接口,支持多SQL同时执行、Mybatis标签语法,实现动态SQL和动态标签
|
||||
- **数据源管理**:动态加载数据库,支持多种SQL/NoSQL数据库。
|
||||
- **应用列表**:AppKey认证、签名认证的应用创建管理以及对API调用在线授权。
|
||||
- **接口列表**:查看开发中和已发布的API接口,可进行上下线管理,编辑升级等
|
||||
- **接口文档**:生成在线接口文档,支持在线测试。
|
||||
- **接口日志**:查看发布的接口被调用日志列表和请求详情。
|
||||
|
||||
## 接口开发流程
|
||||
@@ -31,11 +32,11 @@ cn.crabc
|
||||
├── crabc-spring-boot-starter // 第三方项目maven集成依赖包
|
||||
├── db // SQL脚本
|
||||
├──pom.xml // 依赖
|
||||
~~~
|
||||
~~~
|
||||
|
||||
## 版本说明
|
||||
dev分支框架SpringBoot已升级至3.5,jdk需17及以上版本 \
|
||||
2.x分支框架SpringBoot还是2.x
|
||||
jdk8分支框架SpringBoot是2.x + jdk8
|
||||
|
||||
## 企业版
|
||||
https://pingapi.cn
|
||||
@@ -59,9 +60,6 @@ github:https://github.com/pingapi/crabc-api
|
||||
已申请软件著作,开源版仅供个人学习使用 \
|
||||
企业版功能更强大,商用请加群联系\
|
||||
|
||||
## 数据库脚本
|
||||
加群获取最新数据库脚本
|
||||
|
||||
## 源码地址
|
||||
github: https://github.com/pingapi/crabc-api \
|
||||
gitee: https://gitee.com/linebyte/crabc
|
||||
@@ -72,7 +70,7 @@ gitee: https://gitee.com/linebyte/crabc
|
||||
<dependency>
|
||||
<groupId>cn.crabc</groupId>
|
||||
<artifactId>crabc-spring-boot-starter</artifactId>
|
||||
<version>3.5.2</version>
|
||||
<version>4.3.0</version>
|
||||
</dependency>
|
||||
```
|
||||
在程序启动类中添加下面注解
|
||||
@@ -83,8 +81,13 @@ gitee: https://gitee.com/linebyte/crabc
|
||||
|
||||
## Docker启动
|
||||
先执行db/dml.sql脚本,创建库表和初始化数据,建议mysql 8.0+版本
|
||||
|
||||
X86/AMD架构
|
||||
```
|
||||
docker run -p 9377:9377 -e DB_URL=jdbc:mysql://localhost:3306/crabc -e DB_USER=root -e DB_PWD=root -d --name crabc-api crabc/crabc-api:latest
|
||||
```
|
||||
ARM架构
|
||||
```
|
||||
docker pull crabc/crabc-admin:latest
|
||||
docker run -p 9377:9377 -e DB_URL=jdbc:mysql://localhost:3306/crabc -e DB_USER=root -e DB_PWD=root -d --name crabc-admin crabc/crabc-admin:latest
|
||||
```
|
||||
访问地址:http://127.0.0.1:9377
|
||||
@@ -93,7 +96,7 @@ docker run -p 9377:9377 -e DB_URL=jdbc:mysql://localhost:3306/crabc -e DB_USER=r
|
||||
_## Windows桌面运行
|
||||
先执行db/dml.sql脚本,创建库表和初始化数据,建议mysql 8.0+版本
|
||||
```
|
||||
java -jar crabc-admin.jar --spring.datasource.url=jdbc:mysql://127.0.0.1:3306/crabc --spring.datasource.username=root --spring.datasource.password=root
|
||||
java -jar crabc-api.jar --spring.datasource.url=jdbc:mysql://127.0.0.1:3306/crabc --spring.datasource.username=root --spring.datasource.password=root
|
||||
```
|
||||
|
||||
## 效果截图
|
||||
@@ -101,16 +104,16 @@ java -jar crabc-admin.jar --spring.datasource.url=jdbc:mysql://127.0.0.1:3306/cr
|
||||

|
||||
#### 接口属性
|
||||

|
||||
#### 请求参数
|
||||
#### 返回参数
|
||||

|
||||
#### 在线预览
|
||||

|
||||
#### 接口列表
|
||||

|
||||

|
||||
#### 日志管理
|
||||

|
||||
#### 数据库类型
|
||||

|
||||
### 限流熔断
|
||||

|
||||
|
||||
## 交流群
|
||||
**进群前请先点【Star】谢谢**
|
||||
@@ -136,31 +139,33 @@ QQ群(请先Star):748993036
|
||||
| 鹭栖技术信息公司 |
|
||||
| 循脉医疗科技有限公司 |
|
||||
| 云上贵州大数据有限公司 |
|
||||
| 巨元瀚洋有限公司 |
|
||||
|
||||
## 企业版和开源版对比
|
||||
| 功能 | 社区版 | 企业版 |
|
||||
|--------|------------------------------|-----------------------------------------------------------------------------------------------------------------------------|
|
||||
| 架构设计 | 单体 | 微服务 |
|
||||
| 接口创建模式 | SQL脚本 | SQL脚本、图表、接口转发 |
|
||||
| 动态标签 | 支持 | 支持 |
|
||||
| 动态路由 | 不支持 | 支持 |
|
||||
| 数据库 | SQL:mysql/oracle/postgresql/sqlserver <br>TiDB/OpenGauss/Doris | SQL:mysql/oracle/postgresql/sqlserver/tidb<br>/opengauss/doris/oceanbase/dm/gbase <br> NoSQL:es/mongodb <br> TSDB: TDengine |
|
||||
| 认证方式 | 无/Code认证/签名认证 | 无/Code认证/签名认证 |
|
||||
| SQL类型 | 查询SQL | 查询/插入/更新/删除等SQL |
|
||||
| 结果类型 | json | json/Excel |
|
||||
| 接口日志 | 支持 | 支持 |
|
||||
| 数据模型 | 不支持 | 支持 |
|
||||
| 协同开发 | 不支持 | 支持 |
|
||||
| 结果转换 | 不支持 | 支持 |
|
||||
| 接口市场 | 不支持 | 支持 |
|
||||
| 申请审批 | 不支持 | 支持 |
|
||||
| 接口授权 | 不支持 | 支持 |
|
||||
| 系统权限 | 不支持 | 支持 |
|
||||
| 用户管理 | 不支持 | 支持 |
|
||||
| 数据脱敏 | 不支持 | 支持 |
|
||||
| 版本管理 | 不支持 | 支持
|
||||
| 接口缓存 | 不支持 | 支持 |
|
||||
| 限流熔断 | 不支持 | 支持 |
|
||||
| IP控制 | 不支持 | 支持 |
|
||||
| 监控报表 | 支持 | 支持 |
|
||||
| 集群模式 | 不支持 | 支持 |
|
||||
| 功能 | 社区版 | 企业版 |
|
||||
|-------|--------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------|
|
||||
| 架构设计 | 单体 | 微服务 |
|
||||
| 开发模式 | SQL脚本 | SQL脚本、图表、接口转发、原生脚本 |
|
||||
| 接口编排 | 不支持 | 支持 |
|
||||
| 动态标签 | 支持 | 支持 |
|
||||
| 动态路由 | 不支持 | 支持 |
|
||||
| 数据库 | SQL:mysql/oracle/postgresql/sqlserver <br>TiDB/OpenGauss/Doris | SQL:mysql/oracle/postgresql/sqlserver/tidb<br>/opengauss/doris/oceanbase/dm/gbase <br> NoSQL:es/mongodb/hbase <br> TSDB: TDengine |
|
||||
| 认证方式 | 无/Code认证/签名认证 | 无/Code认证/签名认证 |
|
||||
| SQL类型 | 查询SQL | 查询/插入/更新/删除等SQL |
|
||||
| 结果类型 | json | json/Excel |
|
||||
| 接口日志 | 支持 | 支持 |
|
||||
| 数据模型 | 不支持 | 支持 |
|
||||
| 协同开发 | 不支持 | 支持 |
|
||||
| 结果转换 | 不支持 | 支持 |
|
||||
| 接口市场 | 不支持 | 支持 |
|
||||
| 申请审批 | 不支持 | 支持 |
|
||||
| 接口授权 | 不支持 | 支持 |
|
||||
| 系统权限 | 不支持 | 支持 |
|
||||
| 用户管理 | 不支持 | 支持 |
|
||||
| 数据脱敏 | 不支持 | 支持 |
|
||||
| 版本管理 | 不支持 | 支持
|
||||
| 接口缓存 | 不支持 | 支持 |
|
||||
| 限流熔断 | 不支持 | 支持 |
|
||||
| IP控制 | 不支持 | 支持 |
|
||||
| 监控报表 | 支持 | 支持 |
|
||||
| 集群模式 | 不支持 | 支持 |
|
||||
@@ -5,14 +5,14 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>cn.crabc</groupId>
|
||||
<artifactId>crabc-boot</artifactId>
|
||||
<artifactId>crabc-api</artifactId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>crabc-admin</artifactId>
|
||||
<properties>
|
||||
<maven.compiler.source>21</maven.compiler.source>
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
<dependencies>
|
||||
File renamed without changes.
+3
-13
@@ -3,7 +3,7 @@ server:
|
||||
port: 9377
|
||||
spring:
|
||||
application:
|
||||
name: crabc-admin
|
||||
name: crabc-api
|
||||
main:
|
||||
banner-mode: off
|
||||
jackson:
|
||||
@@ -13,7 +13,7 @@ spring:
|
||||
type: com.alibaba.druid.pool.DruidDataSource
|
||||
url: jdbc:mysql://127.0.0.1:3306/crabc?characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true
|
||||
username: root
|
||||
password: root
|
||||
password:
|
||||
# mybatis配置
|
||||
mybatis:
|
||||
# 搜索指定包别名
|
||||
@@ -25,14 +25,4 @@ mybatis:
|
||||
# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||
|
||||
pagehelper:
|
||||
autoRuntimeDialect: true # 开启多数据源分页识别
|
||||
|
||||
# es健康检查
|
||||
management:
|
||||
health:
|
||||
elasticsearch:
|
||||
enabled: false
|
||||
# 签名认证过期时间
|
||||
crabc:
|
||||
auth:
|
||||
expiresTime: 10
|
||||
autoRuntimeDialect: true # 开启多数据源分页识别
|
||||
File renamed without changes.
File renamed without changes.
@@ -3,7 +3,7 @@
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>crabc-boot</artifactId>
|
||||
<artifactId>crabc-api</artifactId>
|
||||
<groupId>cn.crabc</groupId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
@@ -12,8 +12,8 @@
|
||||
<artifactId>crabc-core</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>21</maven.compiler.source>
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
+1
-1
@@ -97,7 +97,7 @@ public class ApiServiceController {
|
||||
Object value = paramMap.get(paramName);
|
||||
|
||||
// 必填参数校验
|
||||
if (param.getRequired() && !paramMap.containsKey(paramName)) {
|
||||
if ("Y".equals(param.getRequired()) && !paramMap.containsKey(paramName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
+3
-2
@@ -1,5 +1,6 @@
|
||||
package cn.crabc.core.app.config;
|
||||
|
||||
import cn.crabc.core.app.entity.dto.ApiInfoDTO;
|
||||
import com.github.benmanes.caffeine.cache.Cache;
|
||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
import org.springframework.cache.CacheManager;
|
||||
@@ -28,9 +29,9 @@ public class CacheConfig {
|
||||
* @return
|
||||
*/
|
||||
@Bean("apiCache")
|
||||
public Cache<String, Object> apiCaffeine() {
|
||||
public Cache<String, ApiInfoDTO> apiCaffeine() {
|
||||
return Caffeine.newBuilder()
|
||||
.expireAfterAccess(10, TimeUnit.HOURS)
|
||||
.expireAfterAccess(1, TimeUnit.MINUTES)
|
||||
.build();
|
||||
}
|
||||
|
||||
+4
-1
@@ -56,7 +56,10 @@ public class DataSourceConfig {
|
||||
dataSource.setTestWhileIdle(true);
|
||||
dataSource.setTestOnBorrow(false);
|
||||
dataSource.setTestOnReturn(false);
|
||||
dataSource.setTestOnReturn(false);
|
||||
// 连接泄漏检测配置
|
||||
dataSource.setRemoveAbandoned(true);
|
||||
dataSource.setRemoveAbandonedTimeout(300);
|
||||
dataSource.setLogAbandoned(true);
|
||||
JdbcDataSourceRouter dynamic = new JdbcDataSourceRouter();
|
||||
dynamic.setTargetDataSources(new HashMap<>());
|
||||
// 设置默认数据源
|
||||
File renamed without changes.
@@ -0,0 +1,91 @@
|
||||
package cn.crabc.core.app.config;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
|
||||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
|
||||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
|
||||
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
/**
|
||||
* Jackson 配置类
|
||||
* 解决时间字段带 T 和科学计数法问题
|
||||
*
|
||||
* @author yuqf
|
||||
*/
|
||||
@Configuration
|
||||
public class JacksonConfig {
|
||||
|
||||
/**
|
||||
* 日期时间格式
|
||||
*/
|
||||
private static final String DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
|
||||
|
||||
/**
|
||||
* 日期格式
|
||||
*/
|
||||
private static final String DATE_PATTERN = "yyyy-MM-dd";
|
||||
|
||||
/**
|
||||
* 时间格式
|
||||
*/
|
||||
private static final String TIME_PATTERN = "HH:mm:ss";
|
||||
|
||||
/**
|
||||
* 配置 Jackson ObjectMapper
|
||||
* 针对 Spring Boot 3 优化
|
||||
*/
|
||||
@Bean
|
||||
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
|
||||
return builder -> {
|
||||
// 注册 JavaTimeModule 处理 Java 8 日期时间类型
|
||||
JavaTimeModule javaTimeModule = new JavaTimeModule();
|
||||
|
||||
// LocalDateTime 序列化格式
|
||||
javaTimeModule.addSerializer(LocalDateTime.class,
|
||||
new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DATETIME_PATTERN)));
|
||||
|
||||
// LocalDate 序列化格式
|
||||
javaTimeModule.addSerializer(LocalDate.class,
|
||||
new LocalDateSerializer(DateTimeFormatter.ofPattern(DATE_PATTERN)));
|
||||
|
||||
// LocalTime 序列化格式
|
||||
javaTimeModule.addSerializer(LocalTime.class,
|
||||
new LocalTimeSerializer(DateTimeFormatter.ofPattern(TIME_PATTERN)));
|
||||
|
||||
builder.modules(javaTimeModule);
|
||||
|
||||
// BigDecimal 使用自定义序列化器,避免科学计数法(包括数值过小的情况)
|
||||
builder.serializerByType(BigDecimal.class, new JsonSerializer<BigDecimal>() {
|
||||
@Override
|
||||
public void serialize(BigDecimal value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
|
||||
// 使用 toPlainString() 确保不会输出科学计数法
|
||||
gen.writeString(value.stripTrailingZeros().toPlainString());
|
||||
}
|
||||
});
|
||||
|
||||
// BigInteger、Long 使用 ToStringSerializer
|
||||
builder.serializerByType(BigInteger.class, ToStringSerializer.instance);
|
||||
builder.serializerByType(Long.class, ToStringSerializer.instance);
|
||||
builder.serializerByType(long.class, ToStringSerializer.instance);
|
||||
|
||||
// 其他配置
|
||||
builder.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
|
||||
builder.featuresToEnable(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN);
|
||||
};
|
||||
}
|
||||
}
|
||||
File renamed without changes.
+1
-3
@@ -15,8 +15,6 @@ import org.springframework.web.bind.annotation.*;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
/**
|
||||
@@ -41,7 +39,7 @@ public class ApiInfoController {
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/page")
|
||||
public Result page(String keyword, String devType, Integer pageNum, Integer pageSize) {
|
||||
public Result page(@RequestParam(required = false) String keyword, String devType, Integer pageNum, Integer pageSize) {
|
||||
PageInfo<BaseApiInfo> page = apiInfoService.getApiPage(keyword, devType, pageNum, pageSize);
|
||||
return Result.success(page);
|
||||
}
|
||||
File renamed without changes.
+7
-6
@@ -74,11 +74,7 @@ public class ApiTestController {
|
||||
);
|
||||
|
||||
// 处理返回结果
|
||||
Map<String, Object> resultMap = new HashMap<>();
|
||||
resultMap.put("code", 0);
|
||||
resultMap.put("data", formatResultData(data, params.getResultType()));
|
||||
|
||||
return Result.success(resultMap);
|
||||
return Result.success(formatResultData(data, params.getResultType()));
|
||||
|
||||
} catch (Exception e) {
|
||||
return Result.error("测试异常,请检查参数或者SQL是否正常!");
|
||||
@@ -94,6 +90,9 @@ public class ApiTestController {
|
||||
// 处理body参数
|
||||
if (params.getBodyData() != null && params.getBodyData().startsWith("{")) {
|
||||
paramsMap = objectMapper.readValue(params.getBodyData(), HashMap.class);
|
||||
}else if (params.getBodyData() != null && params.getBodyData().startsWith("[")) {
|
||||
List list = objectMapper.readValue(params.getBodyData(), List.class);
|
||||
paramsMap.put("list", list);
|
||||
}
|
||||
|
||||
// 处理query参数
|
||||
@@ -110,7 +109,9 @@ public class ApiTestController {
|
||||
List<Map<String,Object>> paramsList = (List<Map<String, Object>>) requestParams;
|
||||
for (Map<String, Object> entry : paramsList) {
|
||||
if (validateParams(entry)) {
|
||||
paramsMap.put(entry.get("name").toString(), entry.get("value"));
|
||||
if (entry.containsKey("name")) {
|
||||
paramsMap.put(entry.get("name").toString(), entry.get("value"));
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException("参数校验失败");
|
||||
}
|
||||
File renamed without changes.
File renamed without changes.
-3
@@ -35,9 +35,6 @@ public class CommonController {
|
||||
public Result detail(Long apiId) {
|
||||
Integer applyCount = 1;
|
||||
BaseApiInfoVO apiDetail = apiInfoService.getApiDetail(apiId);
|
||||
if ("0".equals(apiDetail.getShowSqlScript())){
|
||||
apiDetail.setSqlScript("***");
|
||||
}
|
||||
apiDetail.setApplyed(applyCount);
|
||||
return Result.success(apiDetail);
|
||||
}
|
||||
File renamed without changes.
File renamed without changes.
+20
-1
@@ -4,6 +4,8 @@ import cn.crabc.core.app.entity.BaseUser;
|
||||
import cn.crabc.core.app.entity.param.UserParam;
|
||||
import cn.crabc.core.app.service.system.IBaseUserService;
|
||||
import cn.crabc.core.app.util.*;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.github.benmanes.caffeine.cache.Cache;
|
||||
import org.apache.tomcat.util.codec.binary.Base64;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
@@ -13,6 +15,7 @@ import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
@@ -26,7 +29,8 @@ public class SysUserController {
|
||||
@Autowired
|
||||
@Qualifier("dataCache")
|
||||
Cache<String, Object> caffeineCache;
|
||||
|
||||
@Autowired
|
||||
private ObjectMapper objectMapper;
|
||||
/**
|
||||
* 登录
|
||||
*
|
||||
@@ -75,6 +79,21 @@ public class SysUserController {
|
||||
BaseUser userInfo = iBaseUserService.getUserById(Long.parseLong(UserThreadLocal.getUserId()));
|
||||
return Result.success(userInfo);
|
||||
}
|
||||
/**
|
||||
* 用户菜单
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/menus")
|
||||
public Result userMenus(){
|
||||
// 固定菜单
|
||||
String menus ="[{\"name\":\"API Hub\",\"checked\":null,\"id\":2,\"parentId\":1,\"open\":null,\"path\":null,\"url\":\"/hub\",\"sort\":2,\"menuType\":1,\"code\":\"Home\",\"hidden\":false,\"permission\":\"/api/box/sys/user/info;/api/box/sys/user/menus;/api/box/sys/message/**;/api/box/sys/user/update/pwd\",\"subMenus\":[{\"name\":\"接口详情\",\"checked\":null,\"id\":7,\"parentId\":2,\"open\":null,\"path\":null,\"url\":\"/doc\",\"sort\":6,\"menuType\":1,\"code\":\"DataCatelogApiDetails\",\"hidden\":true,\"permission\":\"doc\",\"subMenus\":[]}]},{\"name\":\"工作台\",\"checked\":null,\"id\":3,\"parentId\":1,\"open\":null,\"path\":null,\"url\":\"/working\",\"sort\":3,\"menuType\":1,\"code\":\"DataService\",\"hidden\":false,\"permission\":\"/api/box/sys/common/**;/api/box/sys/api/info/**;/api/box/sys/metadata/**;/api/box/sys/test/**;/api/box/sys/group/**;/api/box/sys/user/check/name\",\"subMenus\":[]},{\"name\":\"服务台\",\"checked\":null,\"id\":4,\"parentId\":1,\"open\":null,\"path\":null,\"url\":\"/manage\",\"sort\":4,\"menuType\":1,\"code\":\"Manage\",\"hidden\":false,\"permission\":\"manage\",\"subMenus\":[{\"name\":\"应用管理\",\"checked\":null,\"id\":8,\"parentId\":4,\"open\":null,\"path\":null,\"url\":\"/manage/keys\",\"sort\":1,\"menuType\":1,\"code\":\"Application\",\"hidden\":true,\"permission\":\"/api/box/sys/app/**\",\"subMenus\":[]},{\"name\":\"接口列表\",\"checked\":null,\"id\":9,\"parentId\":4,\"open\":null,\"path\":null,\"url\":\"/manage/apis\",\"sort\":1,\"menuType\":1,\"code\":\"MyApi\",\"hidden\":true,\"permission\":\"/api/box/sys/api/info/**\",\"subMenus\":[]},{\"name\":\"日志管理\",\"checked\":null,\"id\":12,\"parentId\":4,\"open\":null,\"path\":null,\"url\":\"/manage/logs\",\"sort\":1,\"menuType\":1,\"code\":\"UseLog\",\"hidden\":true,\"permission\":\"/api/box/sys/api/log/**\",\"subMenus\":[{\"name\":\"日志列表\",\"checked\":null,\"id\":13,\"parentId\":12,\"open\":null,\"path\":null,\"url\":\"/manage/logs/list\",\"sort\":1,\"menuType\":1,\"code\":\"UseLogList\",\"hidden\":true,\"permission\":\"/api/box/sys/api/log/**\",\"subMenus\":[]},{\"name\":\"日志详情\",\"checked\":null,\"id\":14,\"parentId\":12,\"open\":null,\"path\":null,\"url\":\"/manage/logs/detail\",\"sort\":1,\"menuType\":1,\"code\":\"DetailUesLog\",\"hidden\":true,\"permission\":null,\"subMenus\":[]}]},{\"name\":\"分类管理\",\"checked\":null,\"id\":30,\"parentId\":4,\"open\":null,\"path\":null,\"url\":\"/manage/classification\",\"sort\":1,\"menuType\":1,\"code\":\"Classification\",\"hidden\":true,\"permission\":\"manage:classification\",\"subMenus\":[]},{\"name\":\"数据源\",\"checked\":null,\"id\":31,\"parentId\":4,\"open\":null,\"path\":null,\"url\":\"/manage/datasource\",\"sort\":1,\"menuType\":1,\"code\":\"DataSource\",\"hidden\":true,\"permission\":\"/api/box/sys/datasource/**;/api/box/sys/user/pubKey\",\"subMenus\":[]},{\"name\":\"密码重置\",\"checked\":null,\"id\":32,\"parentId\":4,\"open\":null,\"path\":null,\"url\":\"/manage/edit-pwd\",\"sort\":1,\"menuType\":1,\"code\":\"ChangePassword\",\"hidden\":true,\"permission\":\"/api/box/sys/user/update/pwd\",\"subMenus\":[]}]}]";
|
||||
try {
|
||||
List<Map<String, Object>> list = objectMapper.readValue(menus, List.class);
|
||||
return Result.success(list);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改密码
|
||||
+5
-5
@@ -80,11 +80,6 @@ public class BaseApiInfo extends BaseEntity {
|
||||
*/
|
||||
private String sqlScript;
|
||||
|
||||
/**
|
||||
* 是否显示脚本1/0
|
||||
*/
|
||||
private String showSqlScript;
|
||||
|
||||
/**
|
||||
* 分页设置,不分页:0、只分页:page、分页并统计:pageCount
|
||||
*/
|
||||
@@ -104,6 +99,8 @@ public class BaseApiInfo extends BaseEntity {
|
||||
* schema
|
||||
*/
|
||||
private String schemaName;
|
||||
// 表名
|
||||
private String tableName;
|
||||
|
||||
/**
|
||||
* 数据源类型
|
||||
@@ -120,4 +117,7 @@ public class BaseApiInfo extends BaseEntity {
|
||||
*/
|
||||
private Long parentId;
|
||||
|
||||
/** 分组名称 */
|
||||
private String groupName;
|
||||
|
||||
}
|
||||
File renamed without changes.
+1
-1
@@ -40,7 +40,7 @@ public class BaseApiParam {
|
||||
/**
|
||||
* 是否必填
|
||||
*/
|
||||
private Boolean required;
|
||||
private String required;
|
||||
|
||||
/**
|
||||
* 操作
|
||||
+2
@@ -40,6 +40,8 @@ public class BaseApiSql extends BaseEntity {
|
||||
*/
|
||||
private String schemaName;
|
||||
|
||||
private String tableName;
|
||||
|
||||
/**
|
||||
* 数据源类型
|
||||
*/
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+3
@@ -3,6 +3,8 @@ package cn.crabc.core.app.entity.param;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
public class ApiTestParam {
|
||||
@@ -25,4 +27,5 @@ public class ApiTestParam {
|
||||
|
||||
private String bodyData;
|
||||
|
||||
private Map<String,Object> queryParam;
|
||||
}
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
-2
@@ -71,8 +71,6 @@ public class BaseApiInfoVO extends BaseEntity {
|
||||
private Integer pageSetup;
|
||||
|
||||
private String sqlScript;
|
||||
|
||||
private String showSqlScript;
|
||||
/**
|
||||
* 发布时间
|
||||
*/
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+1
@@ -79,6 +79,7 @@ public class ExceptionHandler {
|
||||
@org.springframework.web.bind.annotation.ExceptionHandler(value = HttpMessageNotReadableException.class)
|
||||
@ResponseBody
|
||||
public Result exceptionHandler(HttpServletRequest req, HttpMessageNotReadableException e) {
|
||||
e.printStackTrace();
|
||||
return Result.error(50002, "Body参数异常,请检查Body/json是否正确传参");
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -23,7 +23,7 @@ public class ApiFilter implements Filter {
|
||||
ContentCachingResponseWrapper responseWrapper = null;
|
||||
try {
|
||||
// 包装类
|
||||
if (request.getContentType() != null && request.getContentType().contains(MediaType.APPLICATION_JSON_VALUE)) {
|
||||
if (request.getContentType() == null || request.getContentType().contains(MediaType.APPLICATION_JSON_VALUE)) {
|
||||
BaseRequestWrapper requestWrapper = new BaseRequestWrapper(request);
|
||||
responseWrapper = new ContentCachingResponseWrapper(response);
|
||||
filterChain.doFilter(requestWrapper, responseWrapper);
|
||||
@@ -40,6 +40,7 @@ public class ApiFilter implements Filter {
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
ApiThreadLocal.remove();
|
||||
Filter.super.destroy();
|
||||
}
|
||||
|
||||
+11
-6
@@ -3,13 +3,13 @@ package cn.crabc.core.app.filter;
|
||||
import cn.crabc.core.app.entity.BaseApiLog;
|
||||
import cn.crabc.core.app.entity.BaseApp;
|
||||
import cn.crabc.core.app.entity.dto.ApiInfoDTO;
|
||||
import cn.crabc.core.app.service.system.IBaseApiInfoService;
|
||||
import cn.crabc.core.app.service.system.IBaseApiLogService;
|
||||
import cn.crabc.core.app.util.ApiThreadLocal;
|
||||
import cn.crabc.core.app.util.RequestUtils;
|
||||
import cn.crabc.core.app.util.Result;
|
||||
import cn.crabc.core.app.util.SM3Util;
|
||||
import cn.crabc.core.datasource.enums.ErrorStatusEnum;
|
||||
import cn.crabc.core.datasource.exception.CustomException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.github.benmanes.caffeine.cache.Cache;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
@@ -22,7 +22,6 @@ import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.StreamUtils;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.web.util.ContentCachingResponseWrapper;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -42,25 +41,30 @@ public class AuthInterceptor implements HandlerInterceptor {
|
||||
private static final String API_PRE = "/api/web/";
|
||||
@Autowired
|
||||
private IBaseApiLogService iBaseApiLogService;
|
||||
@Autowired
|
||||
private IBaseApiInfoService iBaseApiInfoService;
|
||||
@Value("${crabc.auth.expiresTime:10}")
|
||||
private Integer expiresTime;
|
||||
@Autowired
|
||||
private ObjectMapper objectMapper;
|
||||
@Autowired
|
||||
@Qualifier("apiCache")
|
||||
private Cache<String, Object> apiCache;
|
||||
private Cache<String, ApiInfoDTO> apiCache;
|
||||
|
||||
private ApiInfoDTO getApiData(String key) {
|
||||
String[] split = key.split("_");
|
||||
return iBaseApiInfoService.getApiInfoCache(split[0], split[1]);
|
||||
}
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||
String path = request.getRequestURI();
|
||||
String method = request.getMethod();
|
||||
|
||||
Object apiData = apiCache.getIfPresent(method + "_" + path.replace(API_PRE, ""));
|
||||
if (apiData == null) {
|
||||
ApiInfoDTO apiInfo = apiCache.get(method + "_" + path.replace(API_PRE, ""), this::getApiData);
|
||||
if (apiInfo == null) {
|
||||
setErrorResponse(request, response,ErrorStatusEnum.API_INVALID.getCode(),ErrorStatusEnum.API_INVALID.getMassage());
|
||||
return false;
|
||||
}
|
||||
ApiInfoDTO apiInfo = (ApiInfoDTO) apiData;
|
||||
if (apiInfo.getEnabled() == 0) {
|
||||
setErrorResponse(request, response,ErrorStatusEnum.API_OFFLINE.getCode(),ErrorStatusEnum.API_OFFLINE.getMassage());
|
||||
return false;
|
||||
@@ -132,6 +136,7 @@ public class AuthInterceptor implements HandlerInterceptor {
|
||||
apiLog.setCostTime(endTime - apiInfo.getRequestTime());
|
||||
}
|
||||
int status = response.getStatus();
|
||||
apiLog.setAppName(RequestUtils.getAppKey(request));
|
||||
apiLog.setApiPath(request.getRequestURI());
|
||||
apiLog.setRequestIp(RequestUtils.getIp(request));
|
||||
apiLog.setResponseTime(new Date());
|
||||
File renamed without changes.
File renamed without changes.
+7
@@ -74,6 +74,13 @@ public interface BaseApiInfoMapper {
|
||||
*/
|
||||
List<ApiInfoDTO> selectApiDetail(@Param("apiId") Long apiId);
|
||||
|
||||
/**
|
||||
* 根据apiId查询信息
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
ApiInfoDTO getApiDetail(@Param("method") String method, @Param("apiPath") String apiPath);
|
||||
|
||||
/**
|
||||
* 插入API
|
||||
*
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+7
-1
@@ -18,7 +18,13 @@ import java.util.List;
|
||||
*/
|
||||
public interface IBaseApiInfoService {
|
||||
|
||||
void initApi();
|
||||
/**
|
||||
* 根据接口url获取API关联数据
|
||||
*
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
ApiInfoDTO getApiInfoCache(String method, String apiPath);
|
||||
|
||||
/**
|
||||
* 获取API关联数据
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+18
-4
@@ -49,11 +49,23 @@ public class BaseApiInfoServiceImpl implements IBaseApiInfoService {
|
||||
private BaseApiParamMapper apiParamMapper;
|
||||
@Autowired
|
||||
@Qualifier("apiCache")
|
||||
Cache<String, Object> apiInfoCache;
|
||||
|
||||
Cache<String, ApiInfoDTO> apiInfoCache;
|
||||
|
||||
|
||||
@Override
|
||||
public void initApi() {
|
||||
updateCache(null);
|
||||
public ApiInfoDTO getApiInfoCache(String method, String apiPath) {
|
||||
ApiInfoDTO apiInfo = apiInfoMapper.getApiDetail(method, apiPath);
|
||||
if (apiInfo == null) {
|
||||
return null;
|
||||
}
|
||||
// 应用
|
||||
List<BaseApp> appApis = baseAppMapper.selectApiApp(apiInfo.getApiId());
|
||||
// 请求参数
|
||||
List<BaseApiParam> baseApiParams = apiParamMapper.selectReqParams(apiInfo.getApiId());
|
||||
|
||||
apiInfo.setAppList(appApis == null ? new ArrayList<>() : appApis);
|
||||
apiInfo.setRequestParams(baseApiParams == null ? new ArrayList<>() : baseApiParams);
|
||||
return apiInfo;
|
||||
}
|
||||
|
||||
public void updateCache(Long apiId) {
|
||||
@@ -150,6 +162,7 @@ public class BaseApiInfoServiceImpl implements IBaseApiInfoService {
|
||||
api.setApiType("SQL");
|
||||
api.setDatasourceId(sql.getDatasourceId());
|
||||
api.setSchemaName(sql.getSchemaName());
|
||||
api.setTableName(sql.getTableName());
|
||||
api.setDatasourceType(sql.getDatasourceType());
|
||||
api.setSqlScript(sql.getSqlScript());
|
||||
api.setCreateTime(date);
|
||||
@@ -183,6 +196,7 @@ public class BaseApiInfoServiceImpl implements IBaseApiInfoService {
|
||||
api.setEnabled(0);
|
||||
api.setDatasourceId(sql.getDatasourceId());
|
||||
api.setSchemaName(sql.getSchemaName());
|
||||
api.setTableName(sql.getTableName());
|
||||
api.setDatasourceType(sql.getDatasourceType());
|
||||
api.setSqlScript(sql.getSqlScript());
|
||||
api.setUpdateTime(updateTime);
|
||||
+3
-3
@@ -62,7 +62,7 @@ public class BaseApiParamServiceImpl implements IBaseApiParamService {
|
||||
responseCode.setParamDesc("状态码:0 成功");
|
||||
responseCode.setParamType("Int");
|
||||
responseCode.setExample("0");
|
||||
responseCode.setRequired("1");
|
||||
responseCode.setRequired("Y");
|
||||
list.add(responseCode);
|
||||
|
||||
RequestParamsVO responseMsg = new RequestParamsVO();
|
||||
@@ -71,7 +71,7 @@ public class BaseApiParamServiceImpl implements IBaseApiParamService {
|
||||
responseMsg.setParamType("String");
|
||||
responseMsg.setExample("");
|
||||
responseMsg.setChildren(null);
|
||||
responseCode.setRequired("1");
|
||||
responseCode.setRequired("Y");
|
||||
list.add(responseMsg);
|
||||
|
||||
RequestParamsVO responseData = new RequestParamsVO();
|
||||
@@ -79,7 +79,7 @@ public class BaseApiParamServiceImpl implements IBaseApiParamService {
|
||||
responseData.setParamDesc("数据");
|
||||
responseData.setParamType("Array");
|
||||
responseData.setExample("");
|
||||
responseCode.setRequired("1");
|
||||
responseCode.setRequired("Y");
|
||||
responseData.setChildren(responseParams);
|
||||
list.add(responseData);
|
||||
return list;
|
||||
File renamed without changes.
+3
-2
@@ -61,7 +61,7 @@ public class BaseDataSourceServiceImpl implements IBaseDataSourceService {
|
||||
public void init() {
|
||||
List<BaseDataSource> baseDataSources = this.getList();
|
||||
for (BaseDataSource dataSource : baseDataSources) {
|
||||
DataSource ds = DataSourceManager.DATA_SOURCE_POOL_JDBC.get(dataSource.getDatasourceId());
|
||||
DataSource ds = DataSourceManager.DATA_SOURCE_POOL_JDBC.get(dataSource.getDatasourceId().toString());
|
||||
try {
|
||||
String jdbcUrl = null;
|
||||
String username = null;
|
||||
@@ -113,6 +113,7 @@ public class BaseDataSourceServiceImpl implements IBaseDataSourceService {
|
||||
dataSource.setClassify("jdbc");
|
||||
dataSource.setCreateBy(UserThreadLocal.getUserId());
|
||||
dataSource.setCreateTime(new Date());
|
||||
dataSource.setUpdateTime(new Date());
|
||||
// 判断是否是自定义
|
||||
if ("custom".equals(dataSource.getDatasourceType())){
|
||||
String dataSourceType = SQLUtil.getDataSourceType(dataSource.getJdbcUrl());
|
||||
@@ -176,7 +177,7 @@ public class BaseDataSourceServiceImpl implements IBaseDataSourceService {
|
||||
byte[] decode = Base64.getDecoder().decode(password);
|
||||
pwd = new String(decode);
|
||||
}else if (dataSource.getDatasourceId() != null){
|
||||
BaseDatasource baseDatasource = dataSourceMapper.selectOne(Integer.parseInt(dataSource.getDatasourceId()));
|
||||
BaseDatasource baseDatasource = dataSourceMapper.selectOne(dataSource.getDatasourceId());
|
||||
byte[] decode = Base64.getDecoder().decode(baseDatasource.getPassword());
|
||||
pwd = new String(decode);
|
||||
}
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+2
-2
@@ -330,10 +330,10 @@ public class SQLUtil {
|
||||
if (reqParams instanceof Map) {
|
||||
Map<String, Object> paramMap = (Map<String, Object>) reqParams;
|
||||
for (BaseApiParam param : paramsConfig) {
|
||||
if (param.getRequired() && !paramMap.containsKey(param.getParamName())) {
|
||||
if ("Y".equals(param.getRequired()) && !paramMap.containsKey(param.getParamName())) {
|
||||
// 必传参数没有传,则报错提示
|
||||
throw new CustomException(52005, "请求参数缺少!");
|
||||
} else if (!param.getRequired() && !paramMap.containsKey(param.getParamName())) {
|
||||
} else if ("N".equals(param.getRequired()) && !paramMap.containsKey(param.getParamName())) {
|
||||
// 非比传参数,去掉SQL中相应的条件
|
||||
sql = regexSql(sql, param.getParamName());
|
||||
}
|
||||
File renamed without changes.
+39
-13
@@ -23,12 +23,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
i.update_by,
|
||||
i.update_time,
|
||||
i.release_time,
|
||||
i.show_sql_script,
|
||||
d.datasource_name
|
||||
g.group_name
|
||||
FROM
|
||||
base_api_info i
|
||||
left join base_datasource d
|
||||
on i.datasource_id = d.datasource_id
|
||||
left join base_group g
|
||||
on i.group_id = g.group_id
|
||||
<where>
|
||||
<if test="apiName !=null and apiName !=''">
|
||||
(i.api_name like concat('%',#{apiName},'%')
|
||||
@@ -90,7 +89,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
remarks,
|
||||
version,
|
||||
page_setup,
|
||||
show_sql_script,
|
||||
datasource_id,
|
||||
datasource_type,
|
||||
schema_name,
|
||||
@@ -106,6 +104,33 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="getApiDetail" resultType="cn.crabc.core.app.entity.dto.ApiInfoDTO">
|
||||
SELECT
|
||||
api_id,
|
||||
api_name,
|
||||
api_path,
|
||||
api_type,
|
||||
api_method,
|
||||
auth_type,
|
||||
api_status,
|
||||
enabled,
|
||||
group_id,
|
||||
tenant_id,
|
||||
remarks,
|
||||
version,
|
||||
page_setup,
|
||||
datasource_id,
|
||||
datasource_type,
|
||||
schema_name,
|
||||
sql_script,
|
||||
sql_type,
|
||||
result_type
|
||||
FROM
|
||||
base_api_info
|
||||
WHERE
|
||||
parent_id = 0 AND api_status ='release' and api_path =#{apiPath} and api_method =#{method}
|
||||
</select>
|
||||
|
||||
<select id="selectApiById" resultType="cn.crabc.core.app.entity.BaseApiInfo">
|
||||
SELECT
|
||||
api_id,
|
||||
@@ -127,8 +152,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
datasource_id,
|
||||
datasource_type,
|
||||
schema_name,
|
||||
table_name,
|
||||
sql_script,
|
||||
show_sql_script,
|
||||
page_setup,
|
||||
sql_type,
|
||||
result_type
|
||||
@@ -153,7 +178,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
b.page_setup,
|
||||
b.create_time,
|
||||
b.sql_script,
|
||||
b.show_sql_script,
|
||||
b.update_time,
|
||||
b.release_time,
|
||||
b.version
|
||||
@@ -186,14 +210,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<if test="sqlType != null and sqlType != ''">sql_type,</if>
|
||||
<if test="resultType != null and resultType != ''">result_type,</if>
|
||||
<if test="sqlScript != null and sqlScript !=''">sql_script,</if>
|
||||
<if test="showSqlScript != null and showSqlScript !=''">show_sql_script,</if>
|
||||
<if test="datasourceId != null and datasourceId != ''">datasource_id,</if>
|
||||
<if test="datasourceType != null and datasourceType != ''">datasource_type,</if>
|
||||
<if test="schemaName != null and schemaName != ''">schema_name,</if>
|
||||
<if test="tableName != null and tableName != ''">table_name,</if>
|
||||
<if test="pageSetup != null">page_setup,</if>
|
||||
enabled,
|
||||
create_by,
|
||||
create_time
|
||||
create_time,
|
||||
update_time
|
||||
)values(
|
||||
<if test="apiName != null and apiName != ''">#{apiName},</if>
|
||||
<if test="apiPath != null and apiPath != ''">#{apiPath},</if>
|
||||
@@ -209,14 +234,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<if test="sqlType != null and sqlType != ''">#{sqlType},</if>
|
||||
<if test="resultType != null and resultType != ''">#{resultType},</if>
|
||||
<if test="sqlScript != null and sqlScript !=''">#{sqlScript},</if>
|
||||
<if test="showSqlScript != null and showSqlScript !=''">#{showSqlScript},</if>
|
||||
<if test="datasourceId != null and datasourceId != ''">#{datasourceId},</if>
|
||||
<if test="datasourceType != null and datasourceType != ''">#{datasourceType},</if>
|
||||
<if test="schemaName != null and schemaName != ''">#{schemaName},</if>
|
||||
<if test="tableName != null and tableName != ''">#{tableName},</if>
|
||||
<if test="pageSetup != null">#{pageSetup},</if>
|
||||
#{enabled},
|
||||
#{createBy},
|
||||
#{createTime}
|
||||
#{createTime},
|
||||
#{updateTime}
|
||||
)
|
||||
</insert>
|
||||
|
||||
@@ -238,10 +264,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<if test="sqlType != null and sqlType != ''">sql_type = #{sqlType},</if>
|
||||
<if test="resultType != null and resultType != ''">result_type = #{resultType},</if>
|
||||
<if test="sqlScript != null and sqlScript !=''">sql_script = #{sqlScript},</if>
|
||||
<if test="showSqlScript != null and showSqlScript !=''">show_sql_script =#{showSqlScript},</if>
|
||||
<if test="datasourceId != null and datasourceId != ''">datasource_id =#{datasourceId},</if>
|
||||
<if test="datasourceType != null and datasourceType != ''">datasource_type =#{datasourceType},</if>
|
||||
<if test="schemaName != null and schemaName != ''">schema_name =#{schemaName},</if>
|
||||
<if test="tableName != null and tableName != ''">table_name =#{tableName},</if>
|
||||
<if test="pageSetup != null">page_setup =#{pageSetup},</if>
|
||||
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
|
||||
update_time = #{updateTime}
|
||||
@@ -262,7 +288,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
</update>
|
||||
|
||||
<delete id="deleteApiInfo">
|
||||
DELETE FROM base_api_info where api_status ='edit' and api_id =#{apiId} and create_by =#{userId}
|
||||
DELETE FROM base_api_info where api_id =#{apiId} and create_by =#{userId}
|
||||
</delete>
|
||||
|
||||
<select id="countApi" resultType="java.lang.Integer">
|
||||
File renamed without changes.
+1
@@ -22,6 +22,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
|
||||
<select id="selectList" resultType="cn.crabc.core.app.entity.BaseApiParam">
|
||||
SELECT
|
||||
param_id,
|
||||
api_id,
|
||||
param_name,
|
||||
column_name,
|
||||
File renamed without changes.
File renamed without changes.
Loaded 100 of 248 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user