## 新增服务模块 ### 1. ERP服务 (hzhub-erp) - 新增独立的ERP数据适配服务 - 支持SQL Server 2008 R2数据源 - 提供动态API配置管理系统 - 包含客户管理、销售数据等业务接口 ### 2. 系统服务 (hzhub-system) - 新增独立的系统管理服务 - 用户、角色、权限、部门、菜单管理 - 租户管理、操作日志、在线用户监控 - 工作流引擎(warm-flow)集成 - 企业微信审批同步功能 ### 3. API网关 (hzhub-gateway) - 新增Spring Cloud Gateway网关服务 - JWT认证、路由分发、限流熔断 - XSS防护、请求日志记录 - 统一入口端口8080 ## 后台管理功能增强 ### ERP动态API管理 - 新增动态API配置管理界面 - API测试、文档预览、统计监控 - 错误日志查看、缓存管理 - 从数据库表自动导入API配置 ### 系统管理增强 - 企业微信配置管理 - 企业微信审批同步配置 - 部门和用户管理优化 ## 员工门户功能完善 ### 业务页面 - 审批中心:工作流审批、待办任务 - CRM管理:客户关系管理 - 经销商管理:经销商数据展示 - 供应链管理:采购、库存、销售 - BI报表:数据可视化分析 - ERP数据探索:SQL Server数据查询 ### 个人中心 - 基本设置:个人信息管理 - 安全设置:密码修改、登录日志 - 锁屏功能:自动锁屏、手动锁屏 ### 其他功能 - 标签页管理:多标签页导航 - 页面缓存:keepAlive缓存机制 - 会话超时:自动检测并提示 ## 经销商门户 ### 页面路由 - 新增经销商管理页面路由 - AI聊天界面完善 ## 文档更新 - ERP API数据库初始化指南 - ERP API前端完整实现文档 - ERP API测试和验证指南 - Gateway路由迁移计划 - 项目配置文档更新 ## 部署脚本 - 统一启动/停止/重启脚本 - Docker Compose配置优化 - Nginx配置文件更新 ## 技术栈 - 后端: Spring Boot 3.5.8, Java 17 - 前端: Vue 3, TypeScript, Element Plus, Vben Admin - 工作流: warm-flow 1.8.2 - 网关: Spring Cloud Gateway - 数据库: MySQL 8.0, SQL Server 2008 R2 - 缓存: Redis 7 - 向量库: Weaviate 1.25.0 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
743 lines
29 KiB
Markdown
743 lines
29 KiB
Markdown
# 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<String, Object>
|
||
- 避免硬编码 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<Long>
|
||
- 缓存检查:检查 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<String, Object>)
|
||
- 输出:ApiTestResultVO(包含执行结果、执行时间、SQL、错误信息)
|
||
|
||
**ApiTestResultVO 结构**:
|
||
```java
|
||
public class ApiTestResultVO {
|
||
private String apiPath;
|
||
private String testMethod;
|
||
private Map<String, Object> 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<String> ALLOWED_KEYWORDS = Set.of(
|
||
"SELECT", "FROM", "WHERE", "AND", "OR", "ORDER", "BY", "GROUP", "HAVING",
|
||
"OFFSET", "FETCH", "NEXT", "ROWS", "ONLY", "AS", "COUNT", "SUM", "AVG"
|
||
);
|
||
```
|
||
|
||
**禁止关键字**:
|
||
```java
|
||
Set<String> 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 管理平台设计,**完全集成到管理后台中**,实现统一管理。从数据库表设计、后端架构、前端界面到安全防护都有详细规划,包含缓存、监控、版本管理等完整功能。实现步骤按优先级分阶段推进,确保核心功能优先完成,逐步增强功能和安全性。 |