# ERP API 管理平台实现方案 ## Context **需求背景**:用户需要一个界面来查看和管理 ERP 数据库的定制 API 封装,并提供手动创建 API 的功能。当前 ERP 服务只有少量固定的 API(CustomerController),缺乏灵活的 API 管理能力。 **重要决策**:**完全集成到管理后台(hzhub-admin)中**,作为系统管理的一个新模块,实现统一管理: - 前端界面集成在 hzhub-admin 的标准管理界面中(左侧菜单 + 右侧功能页面) - 通过后端菜单系统动态添加菜单项(类似"系统管理"、"工具"等模块) - 使用统一的权限体系(通过 Sa-Token 和 permission_code) - 使用统一的认证体系(JWT Token 共享) - 与现有的系统管理、代码生成器等模块保持一致的界面风格和操作体验 **设计目标**: 1. 查看 ERP 数据库中的所有表结构 2. 从数据库表一键生成 API 配置 3. 手动创建和编辑 API(配置 SQL、参数、权限等) 4. API 测试功能(在线测试执行) 5. API 文档预览 6. API 调用统计和监控(完整功能) 7. Redis 缓存支持(完整功能) 8. 版本管理支持(完整功能) **参考架构**: - 基于代码生成器(gen_table + gen_table_column)的两表元数据管理模式 - 使用 JdbcTemplate 执行动态 SQL(安全、简单) - 参考 Vben Admin 的标准 CRUD 界面模式 --- ## 一、架构设计 ### 1.1 数据库表设计 创建两张元数据表存储 API 配置: **erp_api_config(API 配置主表)**: ```sql CREATE TABLE erp_api_config ( api_id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT 'API ID', api_name VARCHAR(100) NOT NULL COMMENT 'API名称', api_path VARCHAR(200) NOT NULL COMMENT 'API路径(如 /erp/dynamic/customer/list)', api_method VARCHAR(10) NOT NULL DEFAULT 'GET' COMMENT 'HTTP方法(GET/POST)', api_desc VARCHAR(500) COMMENT 'API描述', api_version VARCHAR(10) DEFAULT 'v1' COMMENT 'API版本号(v1/v2)', -- 数据源配置 data_source VARCHAR(50) DEFAULT 'erp' COMMENT '数据源名称', -- SQL配置 sql_template TEXT NOT NULL COMMENT 'SQL模板(支持参数占位符 #{paramName})', result_type VARCHAR(20) NOT NULL DEFAULT 'LIST' COMMENT '结果类型(LIST/SINGLE/COUNT)', -- 分页配置 support_pagination TINYINT(1) DEFAULT 0 COMMENT '是否支持分页', page_param_name VARCHAR(50) DEFAULT 'pageNum' COMMENT '页码参数名', size_param_name VARCHAR(50) DEFAULT 'pageSize' COMMENT '页大小参数名', -- 权限配置 require_auth TINYINT(1) DEFAULT 0 COMMENT '是否需要认证', permission_code VARCHAR(100) COMMENT '权限标识(如 erp:customer:list)', -- 缓存配置 enable_cache TINYINT(1) DEFAULT 0 COMMENT '是否启用缓存', cache_key_template VARCHAR(200) COMMENT '缓存键模板(支持参数占位符)', cache_ttl INT DEFAULT 300 COMMENT '缓存过期时间(秒)', -- 来源表信息 source_table VARCHAR(100) COMMENT '来源表名', source_table_comment VARCHAR(500) COMMENT '来源表描述', -- 状态 status TINYINT(1) DEFAULT 1 COMMENT '状态(0禁用 1启用)', create_time DATETIME DEFAULT CURRENT_TIMESTAMP, update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, create_by VARCHAR(50), update_by VARCHAR(50), remark VARCHAR(500) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='ERP动态API配置表'; CREATE INDEX idx_api_path_method ON erp_api_config(api_path, api_method, api_version); CREATE INDEX idx_status ON erp_api_config(status); ``` **erp_api_param(API 参数配置表)**: ```sql CREATE TABLE erp_api_param ( param_id BIGINT PRIMARY KEY AUTO_INCREMENT, api_id BIGINT NOT NULL COMMENT '所属API ID', -- 参数基本信息 param_name VARCHAR(100) NOT NULL COMMENT '参数名称', param_desc VARCHAR(500) COMMENT '参数描述', param_type VARCHAR(20) NOT NULL DEFAULT 'String' COMMENT '参数类型(String/Integer/Long/Date/Boolean)', -- 参数位置 param_position VARCHAR(20) NOT NULL DEFAULT 'QUERY' COMMENT '参数位置(QUERY/BODY)', -- 参数验证 is_required TINYINT(1) DEFAULT 0 COMMENT '是否必填', default_value VARCHAR(200) COMMENT '默认值', -- SQL映射 sql_param_name VARCHAR(100) COMMENT 'SQL参数名', -- 排序 sort INT DEFAULT 0, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='ERP动态API参数配置表'; CREATE INDEX idx_api_id ON erp_api_param(api_id); ALTER TABLE erp_api_param ADD CONSTRAINT fk_api_param_api FOREIGN KEY (api_id) REFERENCES erp_api_config(api_id) ON DELETE CASCADE; ``` **erp_api_stats(API 调用统计表)**: ```sql CREATE TABLE erp_api_stats ( stats_id BIGINT PRIMARY KEY AUTO_INCREMENT, api_id BIGINT NOT NULL COMMENT 'API ID', -- 调用信息 call_time DATETIME NOT NULL COMMENT '调用时间', call_params TEXT COMMENT '调用参数(JSON)', response_time INT COMMENT '响应时间(ms)', call_status VARCHAR(10) COMMENT '调用状态(SUCCESS/ERROR)', -- 错误信息 error_message TEXT COMMENT '错误消息', error_stack TEXT COMMENT '错误堆栈', -- 客户端信息 client_ip VARCHAR(50) COMMENT '客户端IP', user_id VARCHAR(50) COMMENT '用户ID', create_time DATETIME DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='ERP动态API调用统计表'; CREATE INDEX idx_api_id_time ON erp_api_stats(api_id, call_time); CREATE INDEX idx_call_status ON erp_api_stats(call_status); ``` ### 1.2 核心技术选型 **动态 SQL 执行**:JdbcTemplate - 优点:简单、安全、支持 PreparedStatement 参数绑定 - 避免复杂的 MyBatis 动态 SQL(不适合动态生成场景) **参数类型转换**:自定义 ParamTypeConverter - 支持 String、Integer、Long、Date、Boolean 类型 - 自动转换前端参数到 SQL 参数类型 **结果映射**:动态 RowMapper → Map - 避免硬编码 VO 类,灵活适配不同表结构 **安全防护**: - SQL 注入防护:强制 PreparedStatement 参数绑定(#{param} → ?) - SQL 关键字白名单:只允许 SELECT、FROM、WHERE、AND、OR、ORDER、BY 等安全关键字 - 禁止危险操作:DROP、DELETE、TRUNCATE、ALTER、CREATE 等 - 可选权限控制:通过 Sa-Token 的 permission_code 验证 ### 1.3 后端架构 **文件结构**: ``` hzhub-erp/src/main/java/org/hzhub/erp/ ├── controller/ │ ├── ErpApiController.java # API 配置管理 CRUD │ └── DynamicApiController.java # 动态 API 执行入口(通配符路由) ├── service/ │ ├── IErpApiService.java # API 配置 Service 接口 │ ├── impl/ │ │ ├── ErpApiServiceImpl.java # API 配置管理 + 从表导入 │ │ ├── DynamicApiExecutor.java # 核心 SQL 执行引擎 │ │ ├── ApiCacheService.java # Redis 缓存服务 │ │ └── ApiMonitorService.java # 监控统计服务 │ └── ParamTypeConverter.java # 参数类型转换器 ├── domain/ │ ├── ErpApiConfig.java # API 配置实体 │ ├── ErpApiParam.java # API 参数实体 │ └── vo/ │ │ ├── ErpApiConfigVO.java # API 配置 VO │ │ └── ApiTestResultVO.java # API 测试结果 VO ├── mapper/ │ ├── ErpApiConfigMapper.java # API 配置 Mapper │ ├── ErpApiParamMapper.java # API 参数 Mapper │ └── ErpApiStatsMapper.java # API 统计 Mapper └── util/ └── SqlValidator.java # SQL 安全验证工具 ``` **关键模块设计**: 1. **DynamicApiExecutor(核心执行引擎)**: - 处理 SQL 模板:将 #{param} 转换为 ? 占位符 - 参数绑定:按照参数顺序提取值并绑定到 PreparedStatement - 分页处理:自动添加 OFFSET FETCH(SQL Server 语法) - 结果封装:LIST → TableDataInfo,SINGLE → R,COUNT → R - 缓存检查:检查 Redis 缓存,如果存在直接返回 - 统计记录:记录执行时间、调用参数到 erp_api_stats 2. **ApiCacheService(缓存服务)**: - 缓存键生成:根据 cache_key_template 和参数生成缓存键 - 缓存操作:get、set、delete、clear - 缓存过期处理:支持 TTL 配置 - 缓存命中率统计:记录缓存命中和未命中次数 3. **ApiMonitorService(监控服务)**: - 调用记录:记录每次调用到 erp_api_stats - 统计查询:按 API ID、时间段查询调用统计 - 错误分析:查询错误日志、错误率统计 - 性能分析:响应时间趋势、慢查询告警 4. **ErpApiController(配置管理)**: - CRUD 接口:list、getInfo、add、edit、remove - 从表导入:importFromTable(调用 ErpExploreController 获取表结构) - API 测试:testApi(执行并返回结果 + 执行时间) - 状态切换:changeStatus - 统计查询:getApiStats、getApiErrorLog - 版本管理:支持 v1/v2 版本号,路径自动包含版本(/erp/dynamic/v1/xxx) 5. **DynamicApiController(动态路由)**: - 通配符路径:`@GetMapping("/erp/dynamic/{version}/{apiPath}")` - 根据请求路径、版本和方法查询 API 配置 - 权限检查(如果 require_auth = 1) - 参数验证和类型转换 - 缓存检查(如果 enable_cache = 1) - 调用 DynamicApiExecutor 执行 - 记录统计信息 --- ## 二、功能模块详细设计 ### 2.1 API 配置管理(CRUD) **后端接口**: | Method | Path | 功能 | |--------|------|------| | GET | `/erp/api/config/list` | 分页查询 API 配置列表 | | GET | `/erp/api/config/{apiId}` | 获取配置详情(含参数列表) | | POST | `/erp/api/config` | 新增 API 配置 | | PUT | `/erp/api/config` | 修改 API 配置 | | DELETE | `/erp/api/config/{apiIds}` | 删除配置 | | PUT | `/erp/api/config/changeStatus` | 启用/禁用 | | POST | `/erp/api/config/importFromTable` | 从表导入 | | GET | `/erp/api/config/syncTable/{apiId}` | 同步表结构 | | POST | `/erp/api/config/test/{apiId}` | API 测试 | | GET | `/erp/api/config/preview/{apiId}` | API 文档预览 | | GET | `/erp/api/config/stats/{apiId}` | 查询调用统计 | | GET | `/erp/api/config/errorLog/{apiId}` | 查询错误日志 | | DELETE | `/erp/api/config/cache/{apiId}` | 清除缓存 | ### 2.2 从数据库表导入 **流程**: 1. 前端调用 ErpExploreController 获取表列表(`/erp/test/explore`) 2. 用户选择要导入的表(多选) 3. 后端 `importFromTable` 方法: - 查询表的列信息(调用 `/erp/test/explore/table?tableName=xxx`) - 生成默认查询 SQL:`SELECT * FROM tableName WHERE 1=1` - 为每个列创建参数配置(paramName、paramType、paramDesc) - 保存到 erp_api_config 和 erp_api_param **自动生成逻辑**: - API 名称:`{tableName}列表查询` - API 路径:`/erp/dynamic/{tableName}` - SQL 类型:根据列数据类型推断 Java 类型(varchar → String, int → Integer, datetime → Date) - 支持分页:默认启用 ### 2.3 API 测试功能 **设计**: - 输入:apiId + testParams(Map) - 输出:ApiTestResultVO(包含执行结果、执行时间、SQL、错误信息) **ApiTestResultVO 结构**: ```java public class ApiTestResultVO { private String apiPath; private String testMethod; private Map requestParams; private Boolean success; private Object data; // 执行结果 private Long executionTime; // 执行时间(ms) private String executedSql; // 实际执行的 SQL private String errorMessage; // 错误信息(如果失败) private String errorStack; // 错误堆栈 } ``` ### 2.4 API 文档预览 **生成内容**: - 基本信息:API 名称、路径、方法、描述 - 参数说明表:参数名、类型、必填、默认值、描述 - SQL 模板说明 - 响应格式示例 - 使用示例(请求 URL + 参数示例) --- ## 三、前端界面设计 ### 3.1 文件结构 ``` hzhub-admin/apps/web-antd/src/ ├── api/erp/ │ ├── api/ │ │ ├── index.ts # API 函数定义 │ │ └── model.d.ts # TypeScript 类型 │ └── explore/ │ │ ├── index.ts # 数据库探查 API │ │ └── model.d.ts ├── views/erp/api/ │ ├── index.vue # API 配置列表页 │ ├── data.tsx # 列定义、搜索表单 schema │ ├── edit-api.vue # 编辑页(两 Tab) │ ├── edit-tabs/ │ │ ├── basic-setting.vue # 基础设置 Tab │ │ └── params-config.vue # 参数配置 Tab(VxeGrid inline-editable) │ ├── table-import-modal.vue # 从表导入弹窗 │ ├── test-modal.vue # API 测试弹窗 │ ├── doc-preview-modal.vue # 文档预览弹窗 │ └── stats-modal.vue # 统计监控弹窗 ``` ### 3.2 列表页(index.vue) **参考**:tenant/index.vue(完整 CRUD) **功能**: - VxeGrid 表格展示 API 配置(apiName、apiPath、apiMethod、status、createTime) - 搜索表单:apiName、apiPath、status - 操作列:测试、编辑、删除、启用/禁用、查看统计 - 工具栏:从表导入、新增 API ### 3.3 编辑页(edit-api.vue) **参考**:generator/edit-gen.vue(两 Tab 设计) **Tab 1 - 基础设置**: - API 名称、路径、方法(下拉选择 GET/POST) - SQL 模板(使用 CodeMirror 编辑器,支持 SQL Server 语法高亮) - 数据源(下拉选择) - 结果类型(LIST/SINGLE/COUNT) - 分页配置(是否支持分页、参数名) - 权限配置(是否需要认证、权限标识) - 缓存配置(是否启用缓存、缓存键模板、TTL) - 版本号(下拉选择 v1/v2) - 来源表信息(只读,显示来源表名和描述) **Tab 2 - 参数配置**: - VxeGrid inline-editable 表格 - 列:paramName、paramType(下拉)、paramPosition(下拉)、isRequired(复选框)、defaultValue、paramDesc - 工具栏:新增参数、删除参数、同步表结构 ### 3.4 从表导入弹窗(table-import-modal.vue) **参考**:generator/table-import-modal.vue **功能**: - 调用 `/erp/test/explore` 获取表列表 - VxeGrid 表格展示:tableName、schemaName、rowCount、columnCount、hasPrimaryKey - 多选框选择要导入的表 - 确认导入:调用 `/erp/api/config/importFromTable` ### 3.5 API 测试弹窗(test-modal.vue) **设计**: - 上半部分:参数输入表单(根据参数配置动态生成) - 下半部分:执行结果展示 - 元信息:执行时间、状态(成功/失败) - 结果数据:JSON 格式化展示(使用 CodeMirror) - 错误信息:如果失败,显示错误消息和堆栈 ### 3.6 文档预览弹窗(doc-preview-modal.vue) **参考**:generator/code-preview-modal.vue(多 Tab 展示) **Tab 内容**: - API 说明:名称、路径、方法、描述 - 参数说明:表格形式展示参数列表 - SQL 模板:代码高亮显示 - 响应示例:JSON 示例 - 使用示例:完整的请求 URL 和参数示例 ### 3.7 统计监控弹窗(stats-modal.vue) **设计**: - 上部分:统计概览(总调用次数、平均响应时间、错误率) - 中部分:调用次数趋势图(使用 Charts) - 下部分:响应时间趋势图 - 错误日志列表:最近的错误调用记录 --- ## 四、SQL 模板设计 ### 4.1 参数占位符语法 使用 `#{paramName}` 作为参数占位符,自动转换为 PreparedStatement 的 `?`: **示例 SQL 模板**: ```sql -- 简单查询 SELECT * FROM customer WHERE #{customerCode} IS NOT NULL THEN customer_code = #{customerCode} AND #{companyCode} IS NOT NULL THEN company_code = #{companyCode} -- 带分页查询 SELECT customer_code, customer_name, company_code FROM customer WHERE #{keyword} IS NOT NULL THEN customer_name LIKE '%#{keyword}%' ORDER BY customer_code -- 分页参数自动添加:OFFSET #{pageNum} ROWS FETCH NEXT #{pageSize} ROWS ONLY -- 聚合查询 SELECT COUNT(*) AS total FROM customer WHERE #{salesAreaCode} IS NOT NULL THEN sales_area_code = #{salesAreaCode} ``` ### 4.2 SQL 安全验证 **白名单关键字**: ```java Set ALLOWED_KEYWORDS = Set.of( "SELECT", "FROM", "WHERE", "AND", "OR", "ORDER", "BY", "GROUP", "HAVING", "OFFSET", "FETCH", "NEXT", "ROWS", "ONLY", "AS", "COUNT", "SUM", "AVG" ); ``` **禁止关键字**: ```java Set DANGEROUS_KEYWORDS = Set.of( "DROP", "DELETE", "TRUNCATE", "ALTER", "CREATE", "GRANT", "INSERT", "UPDATE" ); ``` --- ## 五、安全考虑 ### 5.1 SQL 注入防护 1. **强制参数绑定**:禁止拼接 SQL,必须使用 PreparedStatement 2. **关键字验证**:执行前验证 SQL 只包含白名单关键字 3. **参数值验证**:基于配置的正则表达式验证参数格式 ### 5.2 权限控制 1. **可选认证**:通过 `require_auth` 字段控制 2. **权限标识**:通过 `permission_code` 配置(如 `erp:customer:list`) 3. **Sa-Token 验证**: ```java if (config.getRequireAuth() == 1) { StpUtil.checkPermission(config.getPermissionCode()); } ``` ### 5.3 访问控制 - 所有动态 API 默认需要通过网关验证(`X-Gateway-Verified` header) - 可选启用 Sa-Token 权限检查 - 支持 RateLimiter 限流(后续添加) --- ## 六、实现步骤(分阶段) 根据用户确认的设计决策: - **路由机制**:使用通配符路由(`/erp/dynamic/{version}/{apiPath}`) - **SQL 编辑器**:基础版本(CodeMirror + 语法高亮) - **高级功能**:第一版实现完整功能(缓存、监控、版本管理) ### Phase 1:核心功能 + 基础增强(第 1-2 周) **目标**:实现最小可用版本 + 基础高级功能 1. **数据库表创建**(hzhub-erp): - 创建 erp_api_config 和 erp_api_param 表(包含缓存、版本字段) - 创建 erp_api_stats 表(监控统计) - 添加索引和外键约束 2. **后端基础架构**: - 创建 Domain 实体类(ErpApiConfig、ErpApiParam、ErpApiStats) - 创建 Mapper 接口和 XML(基础 CRUD) - 创建 Service 接口和实现(ErpApiServiceImpl) - 创建 DynamicApiExecutor(核心 SQL 执行引擎) - 创建 ParamTypeConverter(参数类型转换) - 创建 ApiCacheService(Redis 缓存服务) - 创建 ApiMonitorService(调用统计服务) 3. **Controller 实现**: - ErpApiController(CRUD 接口 + 缓存配置 + 版本管理) - DynamicApiController(通配符路由 + 缓存检查 + 统计记录) 4. **前端基础页面**: - 列表页(index.vue) - 基础的增删改查功能 - CodeMirror SQL 编辑器(语法高亮) ### Phase 2:导入和编辑功能 + 版本管理(第 3 周) **目标**:完善配置管理功能 + 版本支持 1. **从表导入**: - Service:importFromTable 方法 - SQL 模板自动生成 - 参数自动生成 2. **编辑页**: - 两 Tab 设计(基础设置 + 参数配置) - VxeGrid inline-editable 参数编辑 - SQL 编辑器(CodeMirror + SQL Server 语法高亮) - 版本管理字段(api_version,支持 v1/v2) 3. **前端弹窗**: - 从表导入弹窗 - 基础设置表单(包含缓存配置) - 版本选择下拉框 ### Phase 3:测试和文档 + 监控统计(第 4 周) **目标**:增强可用性 + 监控功能 1. **API 测试功能**: - Service:testApi 方法 - 执行日志和错误处理 - 前端测试弹窗 2. **API 文档预览**: - Service:generateApiDoc 方法 - 前端文档预览弹窗 3. **监控统计功能**: - 创建 erp_api_stats 表(记录调用次数、响应时间、错误率) - ApiMonitorService:记录每次调用(调用时间、参数、响应时间) - 统计接口:getApiStats、getApiErrorLog - 前端统计页面:调用次数图表、响应时间趋势 4. **优化体验**: - JSON 格式化展示 - 执行时间统计 - 调用统计可视化 ### Phase 4:安全增强和稳定性(第 5 周) **目标**:提升安全性和稳定性 1. **安全增强**: - SQL 安全验证(SqlValidator) - 权限控制集成 - 参数验证 2. **缓存优化**: - Redis 缓存键生成策略 - 缓存过期处理(TTL) - 缓存命中率统计 3. **同步表结构**: - syncTableStructure 方法 4. **状态管理**: - 启用/禁用功能 - API 状态验证 5. **监控告警**: - 响应时间阈值告警 - 错误率告警 - 调用异常记录 --- ## 七、关键文件清单 ### 后端关键文件(需创建) 1. `/data/hzhub/hzhub-erp/src/main/java/org/hzhub/erp/service/impl/DynamicApiExecutor.java` - 核心 SQL 执行引擎 2. `/data/hzhub/hzhub-erp/src/main/java/org/hzhub/erp/service/impl/ApiCacheService.java` - Redis 缓存服务 3. `/data/hzhub/hzhub-erp/src/main/java/org/hzhub/erp/service/impl/ApiMonitorService.java` - 监控统计服务 4. `/data/hzhub/hzhub-erp/src/main/java/org/hzhub/erp/controller/DynamicApiController.java` - 动态路由入口 5. `/data/hzhub/hzhub-erp/src/main/java/org/hzhub/erp/service/impl/ErpApiServiceImpl.java` - API 配置管理核心业务 6. `/data/hzhub/hzhub-erp/src/main/java/org/hzhub/erp/controller/ErpApiController.java` - API 配置管理 Controller 7. `/data/hzhub/hzhub-erp/src/main/java/org/hzhub/erp/util/SqlValidator.java` - SQL 安全验证工具 ### 前端关键文件(需创建) 1. `/data/hzhub/hzhub-admin/apps/web-antd/src/views/erp/api/index.vue` - API 配置列表页 2. `/data/hzhub/hzhub-admin/apps/web-antd/src/views/erp/api/edit-api.vue` - 编辑页(两 Tab) 3. `/data/hzhub/hzhub-admin/apps/web-antd/src/views/erp/api/test-modal.vue` - API 测试弹窗 4. `/data/hzhub/hzhub-admin/apps/web-antd/src/views/erp/api/stats-modal.vue` - 统计监控弹窗 5. `/data/hzhub/hzhub-admin/apps/web-antd/src/api/erp/api/index.ts` - API 函数定义 ### 需复用的现有文件 - `/data/hzhub/hzhub-erp/src/main/java/org/hzhub/erp/controller/ErpExploreController.java` - 数据库探查功能 - `/data/hzhub/hzhub-admin/apps/web-antd/src/views/tool/gen/edit-gen.vue` - 编辑页设计参考 - `/data/hzhub/hzhub-admin/apps/web-antd/src/views/system/tenant/index.vue` - CRUD 页面参考 --- ## 八、验证方式 ### 8.1 后端测试 1. **单元测试**: - DynamicApiExecutor SQL 执行测试 - ParamTypeConverter 类型转换测试 - SqlValidator 安全验证测试 2. **集成测试**: - 从表导入流程测试 - API 执行流程测试(完整流程) - 权限控制测试 3. **手动测试**: - 启动 hzhub-erp 服务 - 访问 Actuator 健康检查:`curl http://localhost:8082/actuator/health` - 测试动态 API:`curl http://localhost:8082/erp/dynamic/v1/customer/list?pageNum=1&pageSize=10` ### 8.2 前端测试 1. **页面功能测试**: - 启动前端:`cd hzhub-admin && pnpm dev` - 访问 API 管理页面:`http://localhost:5666/#/erp/api` - 测试列表查询、新增、编辑、删除功能 - 测试从表导入功能 - 测试 API 测试功能 2. **API 执行测试**: - 创建一个测试 API - 输入参数执行测试 - 查看执行结果和执行时间 - 测试错误场景(错误的 SQL、缺少参数) ### 8.3 端到端测试 1. 通过网关访问动态 API: - 先登录获取 Token - 访问:`http://localhost:8080/erp/dynamic/v1/customer/list?pageNum=1&pageSize=10` - 验证返回数据格式和分页信息 2. 权限测试: - 创建一个需要权限的 API(require_auth=1, permission_code='erp:test:list') - 未登录访问应该返回 401 - 无权限用户访问应该返回 403 --- ## 九、用户确认的设计决策 根据用户反馈,最终确定的设计决策: 1. **动态路由机制**:使用通配符路由(`/erp/dynamic/{version}/{apiPath}`) - 简单稳定,所有动态 API 共享统一前缀 - 支持版本号(v1/v2),路径自动包含版本 2. **SQL 编辑器**:基础版本(CodeMirror + SQL Server 语法高亮) - 第一版使用代码编辑器 + 语法高亮 - 快速实现核心功能,后续可扩展可视化构建器 3. **高级功能**:第一版实现完整功能 - Redis 缓存:支持缓存配置、缓存键模板、TTL、缓存清除 - API 监控:调用统计、响应时间记录、错误日志 - 版本管理:支持 v1/v2 版本号,可同时运行多版本 API - 统计可视化:调用次数图表、响应时间趋势、错误率统计 这些决策已整合到实现步骤和数据库表设计中。 --- ## 十、集成到管理后台的具体方案 ### 10.1 菜单配置 需要在 hzhub-system 的菜单表中添加 ERP 管理菜单(通过 SQL 插入): ```sql -- ERP 管理菜单(一级菜单) INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, remark) VALUES ('ERP管理', 0, 5, '/erp', NULL, 1, 0, 'M', '0', '0', '', 'monitor', 'admin', NOW(), 'ERP API管理目录'); -- API 配置管理菜单(二级菜单) INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, remark) VALUES ('API配置', (SELECT menu_id FROM sys_menu WHERE menu_name='ERP管理'), 1, 'api', 'erp/api/index', 1, 0, 'C', '0', '0', 'erp:api:list', 'tool', 'admin', NOW(), 'API配置管理菜单'); -- API 配置按钮权限 INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time) VALUES ('API查询', (SELECT menu_id FROM sys_menu WHERE menu_name='API配置'), 1, '', NULL, 1, 0, 'F', '0', '0', 'erp:api:query', '#', 'admin', NOW()); INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time) VALUES ('API新增', (SELECT menu_id FROM sys_menu WHERE menu_name='API配置'), 2, '', NULL, 1, 0, 'F', '0', '0', 'erp:api:add', '#', 'admin', NOW()); INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time) VALUES ('API修改', (SELECT menu_id FROM sys_menu WHERE menu_name='API配置'), 3, '', NULL, 1, 0, 'F', '0', '0', 'erp:api:edit', '#', 'admin', NOW()); INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time) VALUES ('API删除', (SELECT menu_id FROM sys_menu WHERE menu_name='API配置'), 4, '', NULL, 1, 0, 'F', '0', '0', 'erp:api:remove', '#', 'admin', NOW()); INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time) VALUES ('API测试', (SELECT menu_id FROM sys_menu WHERE menu_name='API配置'), 5, '', NULL, 1, 0, 'F', '0', '0', 'erp:api:test', '#', 'admin', NOW()); -- API 监控统计菜单(二级菜单) INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, remark) VALUES ('API监控', (SELECT menu_id FROM sys_menu WHERE menu_name='ERP管理'), 2, 'stats', 'erp/stats/index', 1, 0, 'C', '0', '0', 'erp:api:stats', 'monitor', 'admin', NOW(), 'API调用统计监控'); ``` ### 10.2 权限体系集成 - 所有 API 配置管理接口都需要权限验证(通过 Sa-Token) - 前端按钮使用 `v-access:code="['erp:api:add']"` 控制权限 - 动态 API 本身的权限通过配置表的 `require_auth` 和 `permission_code` 字段控制 - 与现有的系统管理、监控等模块共享统一的 JWT Token ### 10.3 组件复用 复用 hzhub-admin 的标准组件和适配器: - `useVbenVxeGrid` - 表格组件(列表页) - `useVbenForm` - 表单组件(搜索、编辑) - `useVbenDrawer` / `useVbenModal` - 抽屉/弹窗组件 - `TableSwitch` - 状态切换组件 - `CodeMirror` - SQL 编辑器(复用代码生成器的编辑器) ### 10.4 API 函数集成 在 `/data/hzhub/hzhub-admin/apps/web-antd/src/api/erp/` 目录下新增 API 模块,遵循现有的 API 定义模式: - 使用 `requestClient` 统一请求客户端 - 使用 `postWithMsg` / `putWithMsg` / `deleteWithMsg` 自动提示消息 - 定义 TypeScript 类型(model.d.ts) --- 本方案提供了一个完整的 ERP API 管理平台设计,**完全集成到管理后台中**,实现统一管理。从数据库表设计、后端架构、前端界面到安全防护都有详细规划,包含缓存、监控、版本管理等完整功能。实现步骤按优先级分阶段推进,确保核心功能优先完成,逐步增强功能和安全性。