# dynamic-api-service **Repository Path**: nicky1224/dynamic-api-service ## Basic Information - **Project Name**: dynamic-api-service - **Description**: No description available - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-02-03 - **Last Updated**: 2026-02-06 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 对外接口服务平台 基于 SpringBoot 3 + MySQL + Redis + SaToken + Freemarker 的动态API服务运行平台。 ## 项目结构 ``` dynamic-api-service/ ├── dynamic-api-common/ # 公共模块 ├── dynamic-api-infrastructure/ # 基础设施模块 ├── dynamic-api-domain/ # 领域模块 ├── dynamic-api-runtime/ # 运行时模块 ├── dynamic-api-admin/ # Admin管理模块 ├── dynamic-api-admin-web/ # Admin前端(Vue 3) └── src/main/resources/sql/init.sql # 数据库初始化脚本 ``` ## 技术栈 - **后端**: SpringBoot 3.2.0, MyBatis Plus, SaToken, Freemarker - **数据库**: MySQL 8.0+ - **缓存**: Redis - **前端**: Vue 3, Element Plus, Vite ## 核心功能 ### 1. 动态数据源管理 - 支持多数据源配置 - 运行时动态创建 JdbcTemplate - 数据源连接测试 ### 2. SQL模板引擎 - 基于 Freemarker 的动态 SQL - 支持 `<#if param??>` 条件判断 - 支持分页查询 ### 3. 动态接口 - 统一返回结构 ResponseEntity - 支持多种结果类型(LIST/MAP/PAGE) - 自动处理分页参数 ### 4. 管理后台 - 数据源管理 - 服务管理 - 接口管理 - SQL模板管理 - 接口调试 ## 快速开始 ### 1. 环境要求 - JDK 17+ - Maven 3.6+ - MySQL 8.0+ - Redis 5.0+ - Node.js 16+ ### 2. 数据库初始化 ```sql -- 执行初始化脚本 source src/main/resources/sql/init.sql ``` ### 3. 配置文件 修改 `dynamic-api-runtime/src/main/resources/application.yml`: ```yaml spring: datasource: url: jdbc:mysql://localhost:3306/dynamic_api username: root password: your_password data: redis: host: localhost port: 6379 ``` ### 4. 启动后端 ```bash # 进入项目目录 cd dynamic-api-service # 编译打包 mvn clean package -DskipTests # 启动运行时模块 cd dynamic-api-runtime/target java -jar dynamic-api-runtime-1.0.0.jar # 或启动Admin模块 cd dynamic-api-admin/target java -jar dynamic-api-admin-1.0.0.jar ``` ### 5. 启动前端 ```bash cd dynamic-api-admin-web # 安装依赖 npm install # 启动开发服务器 npm run dev ``` 访问 http://localhost:3000,默认账号: - 用户名: admin - 密码: admin123 ## 使用示例 ### 1. 创建数据源 在管理后台"数据源管理"中添加数据源配置。 ### 2. 创建服务 在"服务管理"中创建服务并绑定数据源。 ### 3. 创建SQL模板 例如: ```sql SELECT * FROM da_datasource WHERE 1=1 <#if status??>AND status = ${status} <#if dsCode??>AND ds_code LIKE '%${dsCode}%' ``` ### 4. 创建接口 配置接口路径、HTTP方法,绑定SQL模板。 ### 5. 调用接口 ```bash curl http://localhost:8080/api/test/queryDatasource?status=1 ``` ## 接口返回格式 ```json { "code": 200, "message": "成功", "data": [ {"id": 1, "dsCode": "default_ds", ...} ] } ``` 分页返回: ```json { "code": 200, "message": "成功", "data": { "pageNum": 1, "pageSize": 10, "total": 100, "pages": 10, "records": [...] } } ``` ## 开发说明 ### 添加新的数据源类型 1. 在 `DataSourceTypeEnum` 中添加新类型 2. 配置驱动类名和URL模板 3. 更新数据库 `da_datasource` 表的 `ds_type` 字段 ### 扩展SQL模板功能 在 `FreemarkerSqlProcessor` 中添加自定义处理逻辑。 ## License MIT License ## 更新日志 ### 2026-02-05 - SaToken Redis 集成与 URL 格式更新 #### 主要变更 1. **SaToken 跨服务 Redis 集成** - Admin 服务(8081)和 Runtime 服务(8080)现在通过 Redis 共享认证 token - 添加 `sa-token-redis-jackson` 依赖实现分布式 token 存储 - Token 存储在 Redis 中,key 前缀为 `Authorization:` 2. **统一 URL 格式** - 所有 API 路径从 `/api/{serviceCode}/{path}` 改为 `/api/data-service/api-center/dataApi/{apiCode}` - Runtime 服务支持按 `api_code` 查询 API - 数据库已更新所有现有 API 的路径格式 3. **认证鉴权增强** - 所有 Admin 和 Runtime 接口都需要 token 认证 - 请求时需在 Header 中携带 `Authorization: {token}` - 未携带 token 的请求将返回 "暂无权限访问" - 自动放行 OPTIONS 请求以支持 CORS 跨域 #### 技术实现 **依赖更新:** ```xml cn.dev33 sa-token-redis-jackson 1.37.0 ``` **配置更新:** ```yaml # application.yml (Admin & Runtime) sa-token: token-name: Authorization is-share: true # 启用跨服务 token 共享 active-timeout: -1 # 修复配置项名称(原 activity-timeout) ``` **代码更新:** - `InfraApiMapper.java`: 新增 `getByCode()` 方法支持按 api_code 查询 - `SqlExecutor.java`: 增加按 api_code 查询 API 的逻辑 - `SaTokenConfig.java`: 配置拦截器放行 OPTIONS 请求 - `runtime-request.js`: 前端新增专门调用 Runtime API 的 axios 实例 #### 完整认证流程 1. **登录获取 token** ```bash curl -X POST http://localhost:8081/admin/auth/login \ -H "Content-Type: application/json" \ -d '{"username":"admin","password":"admin123"}' ``` 响应: ```json { "code": 200, "msg": "成功", "data": "2cffebea-e22a-40b6-9622-5095f359476c" } ``` 2. **Token 存储到 Redis** ``` Authorization:login:session:1 Authorization:login:token:2cffebea-e22a-40b6-9622-5095f359476c ``` 3. **调用 Runtime API** ```bash curl -X GET "http://localhost:8080/api/data-service/api-center/dataApi/DKJJQTFXLB" \ -H "Authorization: 2cffebea-e22a-40b6-9622-5095f359476c" ``` 4. **Runtime 从 Redis 验证 token 并执行 API** #### 前端调试 前端调试界面已更新,现在: - 显示新的 URL 格式:`http://localhost:8080/api/data-service/api-center/dataApi/{apiCode}` - 自动在请求头中携带 token - 支持新建接口的实时调试 #### 服务端口 - Admin 服务: http://localhost:8081 - Runtime 服务: http://localhost:8080 - 前端界面: http://localhost:3000 - Redis: localhost:6379 #### 注意事项 - 确保 Redis 服务已启动,否则 token 无法跨服务共享 - 所有 API 调用必须携带有效的 token - 新建接口后会在数据库中自动使用新的 URL 格式 - 旧格式 URL 仍然向后兼容 --- ## 开发命令参考 ### 一键停止所有服务 ```bash # 停止后端服务 pkill -f "dynamic-api-(runtime|admin).*\.jar" # 停止前端服务 pkill -f "vite\|npm.*dev" # 或者一键停止所有 pkill -f "dynamic-api-(runtime|admin).*\.jar" && pkill -f "vite\|npm.*dev" ``` ### 后端服务管理 #### 1. 清理并编译 ```bash # 进入项目根目录 cd /path/to/dynamic-api-service # 清理并编译(跳过测试) mvn clean install -DskipTests # 或者编译并运行测试 mvn clean install ``` #### 2. 启动后端服务 **方式一:直接启动(前台运行)** ```bash # 启动 Runtime 服务(端口 8080) java -jar dynamic-api-runtime/target/dynamic-api-runtime-1.0.0.jar # 启动 Admin 服务(端口 8081) java -jar dynamic-api-admin/target/dynamic-api-admin-1.0.0.jar ``` **方式二:后台启动(推荐)** ```bash # 启动 Runtime 服务(后台运行,日志输出到 /tmp/runtime.log) nohup java -jar dynamic-api-runtime/target/dynamic-api-runtime-1.0.0.jar > /tmp/runtime.log 2>&1 & # 启动 Admin 服务(后台运行,日志输出到 /tmp/admin.log) nohup java -jar dynamic-api-admin/target/dynamic-api-admin-1.0.0.jar > /tmp/admin.log 2>&1 & ``` **方式三:一键启动所有后端服务** ```bash nohup java -jar dynamic-api-runtime/target/dynamic-api-runtime-1.0.0.jar > /tmp/runtime.log 2>&1 & \ nohup java -jar dynamic-api-admin/target/dynamic-api-admin-1.0.0.jar > /tmp/admin.log 2>&1 & \ sleep 5 && echo "后端服务已启动" ``` #### 3. 查看后端日志 ```bash # 实时查看 Runtime 服务日志 tail -f /tmp/runtime.log # 实时查看 Admin 服务日志 tail -f /tmp/admin.log # 查看最近 100 行日志 tail -100 /tmp/runtime.log ``` ### 前端服务管理 #### 1. 安装依赖(首次运行) ```bash cd dynamic-api-admin-web npm install ``` #### 2. 启动前端服务 **方式一:直接启动(前台运行)** ```bash cd dynamic-api-admin-web npm run dev ``` **方式二:后台启动(推荐)** ```bash cd dynamic-api-admin-web nohup npm run dev > /tmp/frontend.log 2>&1 & ``` #### 3. 查看前端日志 ```bash # 实时查看前端日志 tail -f /tmp/frontend.log # 查看最近 50 行日志 tail -50 /tmp/frontend.log ``` ### 完整开发流程 #### 场景一:首次启动所有服务 ```bash # 1. 进入项目根目录 cd /path/to/dynamic-api-service # 2. 清理并编译后端 mvn clean install -DskipTests # 3. 安装前端依赖(首次运行) cd dynamic-api-admin-web && npm install && cd .. # 4. 启动后端服务 nohup java -jar dynamic-api-runtime/target/dynamic-api-runtime-1.0.0.jar > /tmp/runtime.log 2>&1 & \ nohup java -jar dynamic-api-admin/target/dynamic-api-admin-1.0.0.jar > /tmp/admin.log 2>&1 & \ sleep 5 # 5. 启动前端服务 cd dynamic-api-admin-web nohup npm run dev > /tmp/frontend.log 2>&1 & ``` #### 场景二:代码修改后重新编译启动 ```bash # 1. 停止所有服务 pkill -f "dynamic-api-(runtime|admin).*\.jar" && pkill -f "vite\|npm.*dev" sleep 2 # 2. 重新编译 mvn clean install -DskipTests # 3. 重新启动所有服务 nohup java -jar dynamic-api-runtime/target/dynamic-api-runtime-1.0.0.jar > /tmp/runtime.log 2>&1 & \ nohup java -jar dynamic-api-admin/target/dynamic-api-admin-1.0.0.jar > /tmp/admin.log 2>&1 & \ cd dynamic-api-admin-web && \ nohup npm run dev > /tmp/frontend.log 2>&1 & \ sleep 5 && echo "所有服务已重启" ``` #### 场景三:仅前端代码修改 ```bash # 前端使用热重载,修改会自动生效 # 如需重启前端服务: pkill -f "vite\|npm.*dev" cd dynamic-api-admin-web nohup npm run dev > /tmp/frontend.log 2>&1 & ``` ### 服务验证 #### 检查服务状态 ```bash # 检查后端服务是否运行 ps aux | grep "dynamic-api.*jar" | grep -v grep # 检查前端服务是否运行 ps aux | grep "vite\|npm.*dev" | grep -v grep # 统计运行的服务数量 ps aux | grep -E "dynamic-api.*jar|npm.*dev|vite" | grep -v grep | wc -l ``` #### 测试服务接口 ```bash # 测试 Admin 登录接口 curl -X POST http://localhost:8081/admin/auth/login \ -H "Content-Type: application/json" \ -d '{"username":"admin","password":"admin123"}' # 预期响应 # {"code":200,"msg":"成功","data":"token值","success":true} # 检查 Redis 中的 token redis-cli KEYS "Authorization:*" ``` ### 故障排查 #### 1. 端口被占用 ```bash # 查看端口占用 lsof -i :8080 # Runtime 服务 lsof -i :8081 # Admin 服务 lsof -i :3000 # 前端服务 # 杀死占用端口的进程 kill -9 ``` #### 2. 服务启动失败 ```bash # 查看详细错误日志 tail -100 /tmp/runtime.log | grep -i "error\|exception" tail -100 /tmp/admin.log | grep -i "error\|exception" tail -100 /tmp/frontend.log | grep -i "error" ``` #### 3. Redis 连接失败 ```bash # 检查 Redis 是否运行 redis-cli ping # 预期响应 # PONG # 启动 Redis(如果未运行) redis-server ``` #### 4. 数据库连接失败 ```bash # 检查 MySQL 是否运行 mysql -uroot -p -e "SELECT 1" # 测试数据库连接 mysql -uroot -p12345678 -e "USE dynamic_api; SHOW TABLES;" ``` ### 快速参考 | 服务 | 端口 | 日志文件 | 启动命令 | |------|------|---------|---------| | Runtime | 8080 | /tmp/runtime.log | `java -jar dynamic-api-runtime-1.0.0.jar` | | Admin | 8081 | /tmp/admin.log | `java -jar dynamic-api-admin-1.0.0.jar` | | 前端 | 3000 | /tmp/frontend.log | `npm run dev` | | Redis | 6379 | - | `redis-server` | | MySQL | 3306 | - | `systemctl start mysql` | ### 访问地址 - **前端管理界面**: http://localhost:3000 - **Admin API**: http://localhost:8081 - **Runtime API**: http://localhost:8080 - **Swagger 文档**: http://localhost:8081/swagger-ui.html **默认登录账号:** - 用户名: `admin` - 密码: `admin123` --- ## UI/UX 优化 - 2026-02-06 ### 前端列表显示全面优化 #### 主要改进 **1. 视觉层次优化** - 编码/名称使用蓝色加粗显示,突出主键信息 - 类型/方法使用彩色标签,快速识别分类 - 时间信息使用灰色小字体,弱化次要信息 - 移除无意义的ID列,节省表格空间 **2. 表格布局优化** - 固定列宽改为自适应列宽(min-width) - 长文本自动省略 + 悬浮提示(show-overflow-tooltip) - 操作列固定右侧(fixed="right") - 添加创建时间列,便于数据追溯 **3. 交互体验提升** - 添加加载状态(loading 动画) - 空状态友好提示(暂无数据/加载失败) - 操作按钮改为链接式,添加图标(✏️编辑、🗑️删除、🔌测试) - 分页组件右对齐,开启背景模式 **4. 状态标签色彩方案** **HTTP 方法标签:** - GET - 绿色(查询操作) - POST - 蓝色(新增操作) - PUT - 橙色(更新操作) - DELETE - 红色(删除操作) **返回类型标签:** - LIST - 蓝色(列表) - MAP - 绿色(单对象) - PAGE - 橙色(分页) **数据源类型标签:** - MySQL - 蓝色 - PostgreSQL - 绿色 **状态标签:** - 启用 - 绿色(深色效果) - 禁用 - 灰色(深色效果) **5. 信息聚合显示** **数据源:** ``` 连接地址: host:port/database(合并显示) ``` **接口管理:** ``` API路径: /api/data-service/api-center/dataApi/{code}(等宽字体) 服务: 服务名称(黄色标签) SQL模板: 模板名称(绿色标签) ``` **SQL模板:** ``` SQL预览: {SQL内容}(等宽字体,预览前200字符) ``` **6. 日期时间格式化** 统一格式:`YYYY-MM-DD HH:mm:ss` 示例: ``` 2026-02-06 10:30:45 ``` **7. 响应式设计** - 表格列宽自适应屏幕尺寸 - 搜索表单自动换行 - 移动端友好的布局 #### 技术实现 **日期格式化函数:** ```javascript const formatDateTime = (dateTime) => { if (!dateTime) return '-' const date = new Date(dateTime) const year = date.getFullYear() const month = String(date.getMonth() + 1).padStart(2, '0') const day = String(date.getDate()).padStart(2, '0') const hours = String(date.getHours()).padStart(2, '0') const minutes = String(date.getMinutes()).padStart(2, '0') const seconds = String(date.getSeconds()).padStart(2, '0') return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}` } ``` **关联数据获取:** ```javascript const getServiceName = (serviceId) => { if (!serviceId) return '' const service = serviceList.value.find(s => s.id === serviceId) return service ? service.serviceName : '' } ``` **加载状态管理:** ```javascript const loading = ref(false) const emptyText = ref('暂无数据') const loadData = async () => { loading.value = true try { const res = await getList(params) tableData.value = res.records pagination.total = res.total } catch (error) { emptyText.value = '加载失败' } finally { loading.value = false } } ``` #### CSS 样式优化 **表格样式:** ```css :deep(.el-table) { font-size: 13px; } :deep(.el-table th) { background-color: #fafafa; font-weight: 600; color: #333; } :deep(.el-table .el-table__empty-block) { padding: 40px 0; } ``` **分页样式:** ```css :deep(.el-pagination) { display: flex; padding: 0; } :deep(.el-pagination.is-background .el-pager li) { border-radius: 4px; } ``` **标签样式:** ```css :deep(.el-tag--small) { padding: 2px 8px; height: 20px; line-height: 16px; } ``` #### 优化效果对比 | 项目 | 优化前 | 优化后 | |------|--------|--------| | 列宽 | 固定宽度,浪费空间 | 自适应宽度,充分利用 | | 主键列 | ID(无意义) | 编码/名称(蓝色加粗) | | 状态显示 | 普通标签 | 彩色标签 + 深色效果 | | 操作按钮 | 实体按钮(占用空间) | 链接按钮 + 图标(紧凑) | | 加载反馈 | 无 | Loading 动画 | | 空状态 | 默认提示 | 友好的文字提示 | | 时间显示 | 无 | YYYY-MM-DD HH:mm:ss | | 长文本 | 换行显示 | 省略 + Tooltip | #### 优化的页面 - ✅ 数据源管理 - ✅ 服务管理 - ✅ SQL模板管理 - ✅ 接口管理 #### 浏览器兼容性 - Chrome 90+ - Firefox 88+ - Safari 14+ - Edge 90+ #### 注意事项 - 前端使用 Vite 热重载,修改自动生效 - 日期时间字段需要在后端返回时包含 createTime - 关联数据(服务、数据源、模板)需要在 loadOptions 中预先加载 - 等宽字体用于显示代码类信息(API路径、SQL内容) ---