# 灵越智报 2.0 - 后端开发结构文档(定稿)
> **版本**: v1.0-final
> **定稿时间**: 2026-02-12
> **技术栈**: Spring Boot 3.x + MyBatis-Plus + PostgreSQL 15+
> **设计原则**: 简化单层项目结构,前端只关心"项目"概念
---
## 一、技术选型
### 1.1 核心框架
| 组件 | 技术 | 版本 | 说明 |
|------|------|------|------|
| 基础框架 | Spring Boot | 3.2.x | 主框架 |
| ORM | MyBatis-Plus | 3.5.x | 数据访问 |
| 数据库 | PostgreSQL | 15+ | 主数据库 |
| 缓存 | Redis | 7.x | 会话、字典、配置缓存 |
| 安全 | Spring Security + JWT | - | 认证授权 |
| 接口文档 | Knife4j (Swagger) | 4.x | API文档 |
| JSON | Jackson | - | JSON序列化 |
| 日志 | SLF4J + Logback | - | 日志框架 |
### 1.2 文件处理
| 组件 | 技术 | 说明 |
|------|------|------|
| Word解析 | Apache POI | docx读写 |
| PDF解析 | PDFBox | pdf读取 |
| Excel解析 | Apache POI / EasyExcel | xlsx读写 |
| 通用解析 | Apache Tika | 文件类型检测 |
### 1.3 AI与外部服务
| 组件 | 技术 | 说明 |
|------|------|------|
| NER服务 | Python独立服务 | 实体识别(HTTP调用) |
| LLM | OpenAI API | 大模型调用 |
| 规则引擎 | 独立服务(待对接) | DSL规则执行 |
| 服务调用 | RestTemplate / WebClient | HTTP客户端 |
### 1.4 实时通信
| 组件 | 技术 | 说明 |
|------|------|------|
| WebSocket | Spring WebSocket + STOMP | 实时推送 |
### 1.5 文件存储
| 组件 | 技术 | 说明 |
|------|------|------|
| 开发环境 | 本地文件系统 | /uploads/ |
| 生产环境 | MinIO / 阿里云OSS | 对象存储 |
---
## 二、项目结构
### 2.1 Maven模块结构
```
lingyue-zhibao/
├── pom.xml # 父POM
├── lingyue-common/ # 公共模块
│ ├── pom.xml
│ └── src/main/java/com/lingyue/common/
│ ├── core/
│ │ ├── Result.java # 统一返回结果
│ │ ├── PageResult.java # 分页返回结果
│ │ ├── BaseEntity.java # 实体基类
│ │ └── Constants.java # 常量定义
│ ├── exception/
│ │ ├── BusinessException.java # 业务异常
│ │ ├── AuthException.java # 认证异常
│ │ └── GlobalExceptionHandler.java # 全局异常处理
│ ├── config/
│ │ ├── MyBatisPlusConfig.java # MyBatis-Plus配置
│ │ ├── RedisConfig.java # Redis配置
│ │ ├── CorsConfig.java # 跨域配置
│ │ └── JacksonConfig.java # JSON配置
│ ├── security/
│ │ ├── JwtUtil.java # JWT工具类
│ │ ├── JwtAuthFilter.java # JWT认证过滤器
│ │ ├── SecurityConfig.java # Security配置
│ │ ├── UserContext.java # 当前用户上下文
│ │ └── PasswordUtil.java # 密码工具(BCrypt)
│ ├── util/
│ │ ├── DateUtil.java
│ │ ├── StringUtil.java
│ │ ├── JsonUtil.java
│ │ ├── FileUtil.java
│ │ └── IdGenerator.java # ID/编号生成器
│ └── annotation/
│ ├── OperationLog.java # 操作日志注解
│ └── RequirePermission.java # 权限注解
│
├── lingyue-graph/ # 图数据核心模块
│ ├── pom.xml
│ └── src/main/java/com/lingyue/graph/
│ ├── entity/
│ │ ├── Node.java
│ │ ├── Edge.java
│ │ ├── NodeProperty.java
│ │ ├── EdgeProperty.java
│ │ ├── NodeType.java
│ │ └── EdgeType.java
│ ├── mapper/
│ │ ├── NodeMapper.java
│ │ ├── EdgeMapper.java
│ │ ├── NodePropertyMapper.java
│ │ ├── EdgePropertyMapper.java
│ │ └── xml/
│ │ ├── NodeMapper.xml
│ │ ├── EdgeMapper.xml
│ │ ├── NodePropertyMapper.xml
│ │ └── EdgePropertyMapper.xml
│ └── service/
│ ├── NodeService.java # 节点CRUD
│ ├── EdgeService.java # 关系CRUD
│ └── PropertyService.java # 属性CRUD
│
└── lingyue-app/ # 应用主模块
├── pom.xml
└── src/main/java/com/lingyue/app/
├── LingyueApplication.java # 启动类
│
├── system/ # ===== 系统管理模块 =====
│ ├── controller/
│ │ ├── AuthController.java
│ │ ├── UserController.java
│ │ ├── RoleController.java
│ │ ├── PermissionController.java
│ │ ├── DictController.java
│ │ ├── ConfigController.java
│ │ └── LogController.java
│ ├── service/
│ │ ├── AuthService.java
│ │ ├── UserService.java
│ │ ├── RoleService.java
│ │ ├── PermissionService.java
│ │ ├── DictService.java
│ │ ├── ConfigService.java
│ │ └── LogService.java
│ ├── mapper/
│ │ ├── SysUserMapper.java
│ │ ├── SysRoleMapper.java
│ │ ├── SysPermissionMapper.java
│ │ ├── SysDictMapper.java
│ │ ├── SysConfigMapper.java
│ │ └── SysLogMapper.java
│ ├── entity/
│ │ ├── SysUser.java
│ │ ├── SysRole.java
│ │ ├── SysPermission.java
│ │ ├── SysSession.java
│ │ ├── SysConfig.java
│ │ ├── SysDictType.java
│ │ ├── SysDictItem.java
│ │ ├── SysOperationLog.java
│ │ └── SysLoginLog.java
│ └── dto/
│ ├── LoginRequest.java
│ ├── LoginResponse.java
│ ├── UserCreateDTO.java
│ ├── UserUpdateDTO.java
│ ├── UserVO.java
│ ├── RoleVO.java
│ └── PermissionTreeVO.java
│
├── project/ # ===== 项目管理模块 ⭐ =====
│ ├── controller/
│ │ ├── ProjectController.java
│ │ ├── ElementController.java
│ │ ├── ValueController.java
│ │ └── ProjectExportController.java
│ ├── service/
│ │ ├── ProjectService.java
│ │ ├── ProjectQueryService.java
│ │ ├── ElementService.java
│ │ ├── ValueService.java
│ │ ├── ProjectCopyService.java
│ │ └── ProjectExportService.java
│ ├── dto/
│ │ ├── ProjectCreateDTO.java
│ │ ├── ProjectUpdateDTO.java
│ │ ├── ProjectQueryDTO.java
│ │ ├── ProjectVO.java
│ │ ├── ProjectDetailVO.java
│ │ ├── ElementDefineDTO.java
│ │ ├── ElementVO.java
│ │ ├── ValueUpdateDTO.java
│ │ ├── ValueBatchUpdateDTO.java
│ │ └── ValueVO.java
│ ├── enums/
│ │ ├── ProjectStatus.java # draft/in_progress/completed/archived
│ │ └── ElementType.java # text/paragraph/table
│ └── viewmapper/
│ └── ProjectViewMapper.java # 基于视图的查询
│
├── attachment/ # ===== 附件管理模块 =====
│ ├── controller/
│ │ └── AttachmentController.java
│ ├── service/
│ │ ├── AttachmentService.java
│ │ ├── AttachmentUploadService.java
│ │ └── AttachmentParseService.java
│ ├── dto/
│ │ ├── AttachmentVO.java
│ │ └── AttachmentUploadVO.java
│ └── viewmapper/
│ └── AttachmentViewMapper.java
│
├── entity/ # ===== 实体管理模块 =====
│ ├── controller/
│ │ └── EntityController.java
│ ├── service/
│ │ ├── EntityService.java
│ │ └── EntityMergeService.java
│ ├── dto/
│ │ ├── EntityVO.java
│ │ ├── EntityUpdateDTO.java
│ │ └── EntityMergeDTO.java
│ └── viewmapper/
│ └── EntityViewMapper.java
│
├── rule/ # ===== 规则管理模块 =====
│ ├── controller/
│ │ └── RuleController.java
│ ├── service/
│ │ ├── RuleService.java
│ │ └── RuleExecuteService.java
│ ├── executor/
│ │ ├── RuleExecutor.java # 执行器接口
│ │ ├── DirectEntityExecutor.java # 直接引用实体
│ │ ├── RegexExtractExecutor.java # 正则提取
│ │ └── ExternalDSLExecutor.java # 外部规则引擎(预留)
│ ├── dto/
│ │ ├── RuleCreateDTO.java
│ │ ├── RuleUpdateDTO.java
│ │ ├── RuleVO.java
│ │ ├── RuleExecuteRequest.java
│ │ └── RuleExecuteResult.java
│ └── viewmapper/
│ └── RuleViewMapper.java
│
├── file/ # ===== 文件服务模块 =====
│ ├── controller/
│ │ ├── FileUploadController.java
│ │ └── FileDownloadController.java
│ ├── service/
│ │ ├── FileStorageService.java
│ │ └── FilePreviewService.java
│ ├── parser/
│ │ ├── FileParser.java # 解析器接口
│ │ ├── DocxParser.java
│ │ ├── PdfParser.java
│ │ └── XlsxParser.java
│ └── dto/
│ ├── FileUploadVO.java
│ └── FileParseResult.java
│
├── ai/ # ===== AI服务模块 =====
│ ├── controller/
│ │ ├── NerController.java
│ │ ├── LLMController.java
│ │ └── AIAssistantController.java
│ ├── service/
│ │ ├── NerService.java
│ │ ├── LLMService.java
│ │ ├── AIAssistantService.java
│ │ └── PromptService.java
│ ├── client/
│ │ ├── NerServiceClient.java # NER服务HTTP客户端
│ │ ├── LLMClient.java # LLM API客户端
│ │ └── RuleEngineClient.java # 规则引擎客户端(预留)
│ └── dto/
│ ├── NerRequest.java
│ ├── NerResult.java
│ ├── LLMRequest.java
│ ├── LLMResponse.java
│ ├── ChatMessage.java
│ └── AISuggestion.java
│
├── websocket/ # ===== WebSocket模块 =====
│ ├── config/
│ │ └── WebSocketConfig.java
│ ├── handler/
│ │ ├── ParseProgressHandler.java # 解析进度推送
│ │ ├── RuleExecuteHandler.java # 规则执行进度推送
│ │ └── NotificationHandler.java # 通知推送
│ └── dto/
│ └── WsMessage.java
│
└── task/ # ===== 异步任务模块 =====
├── config/
│ └── AsyncConfig.java
├── service/
│ ├── TaskService.java
│ ├── ParseTaskExecutor.java # 文件解析任务
│ ├── NerTaskExecutor.java # NER识别任务
│ └── ExportTaskExecutor.java # 导出任务
└── dto/
└── TaskVO.java
```
---
## 三、接口设计
### 3.1 认证接口(7个)
| # | 方法 | 路径 | 说明 | 认证 |
|---|------|------|------|------|
| 1 | POST | `/api/v1/auth/login` | 用户登录 | 否 |
| 2 | POST | `/api/v1/auth/logout` | 用户登出 | 是 |
| 3 | POST | `/api/v1/auth/refresh` | 刷新Token | 否(需refresh_token) |
| 4 | GET | `/api/v1/auth/captcha` | 获取验证码 | 否 |
| 5 | GET | `/api/v1/auth/me` | 获取当前用户信息 | 是 |
| 6 | PUT | `/api/v1/auth/password` | 修改密码 | 是 |
| 7 | GET | `/api/v1/auth/permissions` | 获取当前用户权限 | 是 |
#### 登录接口详情
```
POST /api/v1/auth/login
Request:
{
"username": "admin",
"password": "123456",
"captchaId": "uuid",
"captchaCode": "abcd"
}
Response:
{
"code": 200,
"data": {
"accessToken": "eyJhbGciOi...",
"refreshToken": "eyJhbGciOi...",
"expiresIn": 7200,
"user": {
"id": 1,
"username": "admin",
"realName": "管理员",
"avatar": null,
"roles": ["admin"]
}
}
}
```
---
### 3.2 用户管理接口(11个)
| # | 方法 | 路径 | 说明 |
|---|------|------|------|
| 1 | GET | `/api/v1/users` | 用户列表(分页) |
| 2 | GET | `/api/v1/users/{id}` | 用户详情 |
| 3 | POST | `/api/v1/users` | 创建用户 |
| 4 | PUT | `/api/v1/users/{id}` | 更新用户 |
| 5 | DELETE | `/api/v1/users/{id}` | 删除用户 |
| 6 | PUT | `/api/v1/users/{id}/status` | 启用/禁用用户 |
| 7 | PUT | `/api/v1/users/{id}/password/reset` | 重置密码 |
| 8 | GET | `/api/v1/users/{id}/roles` | 获取用户角色 |
| 9 | PUT | `/api/v1/users/{id}/roles` | 分配用户角色 |
| 10 | GET | `/api/v1/users/export` | 导出用户列表 |
| 11 | POST | `/api/v1/users/import` | 导入用户 |
#### 用户列表接口详情
```
GET /api/v1/users?page=1&size=20&keyword=张&status=active&department=技术部
Response:
{
"code": 200,
"data": {
"total": 50,
"pages": 3,
"current": 1,
"records": [
{
"id": 1,
"username": "admin",
"realName": "管理员",
"email": "admin@lingyue.com",
"phone": "13800138000",
"department": "技术部",
"position": "系统管理员",
"status": "active",
"roles": [{"id": 1, "roleName": "超级管理员"}],
"lastLoginAt": "2026-02-12T10:00:00",
"createdAt": "2026-01-01T00:00:00"
}
]
}
}
```
---
### 3.3 角色管理接口(8个)
| # | 方法 | 路径 | 说明 |
|---|------|------|------|
| 1 | GET | `/api/v1/roles` | 角色列表 |
| 2 | GET | `/api/v1/roles/{id}` | 角色详情 |
| 3 | POST | `/api/v1/roles` | 创建角色 |
| 4 | PUT | `/api/v1/roles/{id}` | 更新角色 |
| 5 | DELETE | `/api/v1/roles/{id}` | 删除角色 |
| 6 | GET | `/api/v1/roles/{id}/permissions` | 获取角色权限 |
| 7 | PUT | `/api/v1/roles/{id}/permissions` | 分配角色权限 |
| 8 | GET | `/api/v1/roles/{id}/users` | 获取角色下用户 |
---
### 3.4 权限管理接口(4个)
| # | 方法 | 路径 | 说明 |
|---|------|------|------|
| 1 | GET | `/api/v1/permissions/tree` | 权限树 |
| 2 | POST | `/api/v1/permissions` | 创建权限 |
| 3 | PUT | `/api/v1/permissions/{id}` | 更新权限 |
| 4 | DELETE | `/api/v1/permissions/{id}` | 删除权限 |
---
### 3.5 数据字典接口(8个)
| # | 方法 | 路径 | 说明 |
|---|------|------|------|
| 1 | GET | `/api/v1/dicts` | 字典类型列表 |
| 2 | POST | `/api/v1/dicts` | 创建字典类型 |
| 3 | PUT | `/api/v1/dicts/{id}` | 更新字典类型 |
| 4 | DELETE | `/api/v1/dicts/{id}` | 删除字典类型 |
| 5 | GET | `/api/v1/dicts/{code}/items` | 获取字典项列表 |
| 6 | POST | `/api/v1/dicts/{code}/items` | 创建字典项 |
| 7 | PUT | `/api/v1/dicts/items/{id}` | 更新字典项 |
| 8 | DELETE | `/api/v1/dicts/items/{id}` | 删除字典项 |
---
### 3.6 系统配置接口(4个)
| # | 方法 | 路径 | 说明 |
|---|------|------|------|
| 1 | GET | `/api/v1/configs` | 配置列表 |
| 2 | GET | `/api/v1/configs/{key}` | 获取配置 |
| 3 | PUT | `/api/v1/configs/{key}` | 更新配置 |
| 4 | GET | `/api/v1/configs/public` | 获取公开配置(无需认证) |
---
### 3.7 日志接口(4个)
| # | 方法 | 路径 | 说明 |
|---|------|------|------|
| 1 | GET | `/api/v1/logs/operations` | 操作日志列表 |
| 2 | GET | `/api/v1/logs/operations/{id}` | 操作日志详情 |
| 3 | GET | `/api/v1/logs/logins` | 登录日志列表 |
| 4 | DELETE | `/api/v1/logs/operations/clean` | 清理历史日志 |
---
### 3.8 项目管理接口(8个)⭐
| # | 方法 | 路径 | 说明 |
|---|------|------|------|
| 1 | GET | `/api/v1/projects` | 项目列表(分页) |
| 2 | GET | `/api/v1/projects/{id}` | 项目详情(含要素、值、附件、规则) |
| 3 | POST | `/api/v1/projects` | 创建项目 |
| 4 | PUT | `/api/v1/projects/{id}` | 更新项目 |
| 5 | DELETE | `/api/v1/projects/{id}` | 删除项目 |
| 6 | POST | `/api/v1/projects/{id}/copy` | 复制项目 |
| 7 | PUT | `/api/v1/projects/{id}/archive` | 归档项目 |
| 8 | POST | `/api/v1/projects/{id}/export` | 导出项目 |
#### 创建项目接口详情
```
POST /api/v1/projects
Request:
{
"title": "成都院2024年复审报告",
"description": "成都院电力安全生产标准化复审报告",
"templateType": "电力安全生产标准化复审报告",
"fromProjectId": null // 从已有项目复制(可选)
}
Response:
{
"code": 200,
"data": {
"id": 10,
"title": "成都院2024年复审报告",
"projectCode": "PRJ-2024-001",
"status": "draft",
"templateType": "电力安全生产标准化复审报告",
"elementCount": 8,
"filledCount": 1,
"createdAt": "2026-02-12T10:00:00"
}
}
```
#### 项目详情接口详情
```
GET /api/v1/projects/{id}
Response:
{
"code": 200,
"data": {
"project": {
"id": 10,
"title": "成都院2024年复审报告",
"projectCode": "PRJ-2024-001",
"status": "draft",
"description": "成都院电力安全生产标准化复审报告",
"templateType": "电力安全生产标准化复审报告",
"contentHtml": "
...
",
"contentMarkdown": "# ...",
"elementCount": 8,
"attachmentCount": 2,
"ruleCount": 5,
"filledCount": 6,
"createdByName": "admin",
"createdAt": "2026-02-12T10:00:00",
"updatedAt": "2026-02-12T15:00:00"
},
"elements": [
{
"id": 201,
"elementKey": "basicInfo.projectCode",
"elementName": "项目编号",
"elementType": "text",
"namespace": "basicInfo",
"fieldName": "projectCode",
"required": true,
"description": "项目编号,格式如 BZ-0092-2024",
"sortOrder": 1
}
],
"values": [
{
"valueId": 301,
"elementKey": "basicInfo.projectCode",
"valueText": "BZ-0092-2024",
"isFilled": true,
"fillSource": "rule"
}
],
"attachments": [
{
"id": 400,
"displayName": "01-复审通知",
"fileName": "复审通知.docx",
"fileType": "docx",
"fileSize": 512000,
"parseStatus": "completed",
"entityCount": 6,
"sortOrder": 1
}
],
"rules": [
{
"id": 600,
"ruleName": "项目编号-直接引用实体",
"elementKey": "basicInfo.projectCode",
"ruleType": "direct_entity",
"actionType": "use_entity_value",
"lastRunStatus": "success",
"lastOutputText": "BZ-0092-2024"
}
]
}
}
```
#### 项目列表接口详情
```
GET /api/v1/projects?page=1&size=20&status=draft&templateType=电力安全&keyword=成都
Response:
{
"code": 200,
"data": {
"total": 15,
"pages": 1,
"current": 1,
"records": [
{
"id": 10,
"title": "成都院2024年复审报告",
"projectCode": "PRJ-2024-001",
"status": "draft",
"templateType": "电力安全生产标准化复审报告",
"elementCount": 8,
"attachmentCount": 2,
"filledCount": 6,
"createdByName": "admin",
"updatedAt": "2026-02-12T15:00:00"
}
]
}
}
```
---
### 3.9 要素管理接口(5个)
| # | 方法 | 路径 | 说明 |
|---|------|------|------|
| 1 | GET | `/api/v1/projects/{id}/elements` | 获取项目要素列表 |
| 2 | POST | `/api/v1/projects/{id}/elements` | 添加要素定义 |
| 3 | PUT | `/api/v1/projects/{id}/elements/{elementId}` | 更新要素定义 |
| 4 | DELETE | `/api/v1/projects/{id}/elements/{elementId}` | 删除要素定义 |
| 5 | POST | `/api/v1/projects/{id}/elements/parse` | 从样本文件解析要素 |
#### 添加要素定义接口详情
```
POST /api/v1/projects/{id}/elements
Request:
{
"elementKey": "basicInfo.projectCode",
"elementName": "项目编号",
"elementType": "text",
"namespace": "basicInfo",
"fieldName": "projectCode",
"required": true,
"defaultValue": null,
"description": "项目编号,格式如 BZ-0092-2024"
}
Response:
{
"code": 200,
"data": {
"elementId": 201,
"valueId": 301,
"elementKey": "basicInfo.projectCode"
}
}
```
---
### 3.10 要素值接口(4个)
| # | 方法 | 路径 | 说明 |
|---|------|------|------|
| 1 | GET | `/api/v1/projects/{id}/values` | 获取所有要素值 |
| 2 | GET | `/api/v1/projects/{id}/values/{elementKey}` | 获取单个要素值 |
| 3 | PUT | `/api/v1/projects/{id}/values/{elementKey}` | 更新要素值 |
| 4 | POST | `/api/v1/projects/{id}/values/batch` | 批量更新要素值 |
#### 更新要素值接口详情
```
PUT /api/v1/projects/{id}/values/{elementKey}
Request:
{
"valueText": "BZ-0092-2024",
"fillSource": "manual"
}
Response:
{
"code": 200,
"data": {
"valueId": 301,
"elementKey": "basicInfo.projectCode",
"valueText": "BZ-0092-2024",
"isFilled": true,
"fillSource": "manual"
}
}
```
---
### 3.11 附件管理接口(6个)
| # | 方法 | 路径 | 说明 |
|---|------|------|------|
| 1 | POST | `/api/v1/projects/{id}/attachments/upload` | 上传附件 |
| 2 | GET | `/api/v1/projects/{id}/attachments` | 获取附件列表 |
| 3 | GET | `/api/v1/attachments/{id}` | 获取附件详情 |
| 4 | DELETE | `/api/v1/attachments/{id}` | 删除附件 |
| 5 | POST | `/api/v1/attachments/{id}/parse` | 触发附件解析 |
| 6 | PUT | `/api/v1/attachments/{id}/sort` | 调整附件排序 |
#### 上传附件接口详情
```
POST /api/v1/projects/{id}/attachments/upload
Content-Type: multipart/form-data
FormData:
file: (binary)
displayName: "01-复审通知" // 可选
Response:
{
"code": 200,
"data": {
"id": 400,
"displayName": "01-复审通知",
"fileName": "复审通知.docx",
"fileType": "docx",
"fileSize": 512000,
"parseStatus": "pending",
"taskId": "task_20240212_001"
}
}
```
---
### 3.12 实体管理接口(5个)
| # | 方法 | 路径 | 说明 |
|---|------|------|------|
| 1 | GET | `/api/v1/attachments/{attachmentId}/entities` | 获取附件实体列表 |
| 2 | GET | `/api/v1/projects/{projectId}/entities` | 获取项目所有实体 |
| 3 | GET | `/api/v1/entities/{id}` | 获取实体详情 |
| 4 | PUT | `/api/v1/entities/{id}` | 更新实体 |
| 5 | POST | `/api/v1/entities/merge` | 合并实体 |
#### 获取项目所有实体接口详情
```
GET /api/v1/projects/{projectId}/entities?entityType=ORG&keyword=成都
Response:
{
"code": 200,
"data": [
{
"id": 500,
"entityText": "中国电建集团成都勘测设计研究院有限公司",
"entityType": "ORG",
"businessLabel": "评审对象",
"confidence": 0.95,
"occurrenceCount": 5,
"attachmentId": 400,
"attachmentName": "01-复审通知"
}
]
}
```
---
### 3.13 规则管理接口(7个)
| # | 方法 | 路径 | 说明 |
|---|------|------|------|
| 1 | GET | `/api/v1/projects/{projectId}/rules` | 获取项目规则列表 |
| 2 | GET | `/api/v1/rules/{id}` | 获取规则详情(含输入) |
| 3 | POST | `/api/v1/projects/{projectId}/rules` | 创建规则 |
| 4 | PUT | `/api/v1/rules/{id}` | 更新规则 |
| 5 | DELETE | `/api/v1/rules/{id}` | 删除规则 |
| 6 | POST | `/api/v1/rules/{id}/execute` | 执行单个规则 |
| 7 | POST | `/api/v1/projects/{projectId}/rules/execute-all` | 批量执行规则 |
#### 创建规则接口详情
```
POST /api/v1/projects/{projectId}/rules
Request:
{
"elementKey": "basicInfo.projectCode",
"ruleName": "项目编号-直接引用实体",
"ruleType": "direct_entity",
"actionType": "use_entity_value",
"description": "直接使用附件实体值填充项目编号",
"inputs": [
{
"inputKey": "entity",
"inputType": "entity_ref",
"inputName": "项目编号实体",
"sourceNodeId": 502
}
]
}
Response:
{
"code": 200,
"data": {
"id": 600,
"ruleName": "项目编号-直接引用实体",
"ruleType": "direct_entity",
"status": "active"
}
}
```
#### 执行规则接口详情
```
POST /api/v1/rules/{id}/execute
Response:
{
"code": 200,
"data": {
"ruleId": 600,
"status": "success",
"outputText": "BZ-0092-2024",
"elementKey": "basicInfo.projectCode",
"valueUpdated": true,
"duration": 15
}
}
```
---
### 3.14 AI服务接口(5个)
| # | 方法 | 路径 | 说明 |
|---|------|------|------|
| 1 | POST | `/api/v1/ai/ner/extract` | 同步提取实体 |
| 2 | POST | `/api/v1/ai/ner/extract/async` | 异步提取实体 |
| 3 | POST | `/api/v1/ai/chat` | AI对话 |
| 4 | POST | `/api/v1/ai/suggest` | AI建议 |
| 5 | POST | `/api/v1/ai/optimize` | AI优化文本 |
#### AI对话接口详情
```
POST /api/v1/ai/chat
Request:
{
"projectId": 10,
"messages": [
{"role": "user", "content": "帮我总结一下评审结论"}
],
"context": {
"elementKey": "result.conclusion"
}
}
Response:
{
"code": 200,
"data": {
"reply": "根据评审材料,成都院在安全生产标准化方面...",
"suggestions": [
{"type": "fill_element", "elementKey": "result.conclusion", "value": "..."}
]
}
}
```
---
### 3.15 文件服务接口(4个)
| # | 方法 | 路径 | 说明 |
|---|------|------|------|
| 1 | POST | `/api/v1/files/upload` | 通用文件上传 |
| 2 | GET | `/api/v1/files/{fileKey}` | 文件下载 |
| 3 | GET | `/api/v1/files/{fileKey}/preview` | 文件预览 |
| 4 | DELETE | `/api/v1/files/{fileKey}` | 删除文件 |
---
### 3.16 任务接口(3个)
| # | 方法 | 路径 | 说明 |
|---|------|------|------|
| 1 | GET | `/api/v1/tasks/{id}` | 查询任务状态 |
| 2 | GET | `/api/v1/tasks?type=parse&status=running` | 任务列表 |
| 3 | POST | `/api/v1/tasks/{id}/cancel` | 取消任务 |
---
### 3.17 接口统计
| 模块 | 接口数 |
|------|--------|
| 认证 | 7 |
| 用户管理 | 11 |
| 角色管理 | 8 |
| 权限管理 | 4 |
| 数据字典 | 8 |
| 系统配置 | 4 |
| 日志 | 4 |
| **项目管理** | **8** |
| **要素管理** | **5** |
| **要素值** | **4** |
| **附件管理** | **6** |
| **实体管理** | **5** |
| **规则管理** | **7** |
| AI服务 | 5 |
| 文件服务 | 4 |
| 任务 | 3 |
| **合计** | **93** |
---
## 四、核心业务流程
### 4.1 创建项目流程
```
用户点击"新建项目"
│
├─ 选择"空白项目"
│ └─ 创建 PROJECT 节点(status=draft)
│ └─ 返回项目ID,跳转编辑器
│
├─ 选择"从预设模板创建"
│ └─ 创建 PROJECT 节点
│ └─ 根据 templateType 自动创建 ELEMENT 节点
│ └─ 为每个 ELEMENT 创建空的 VALUE 节点
│ └─ 建立所有关系(HAS_ELEMENT, HAS_VALUE, FOR_ELEMENT)
│ └─ 返回项目ID,跳转编辑器
│
└─ 选择"从已有项目复制"
└─ 复制源项目的 ELEMENT 节点和 RULE 节点
└─ 创建新的空 VALUE 节点
└─ 建立 COPIED_FROM 关系
└─ 返回项目ID,跳转编辑器
```
**后端实现要点**:
```java
@Service
public class ProjectService {
@Transactional
public ProjectVO createProject(ProjectCreateDTO dto) {
// 1. 创建 PROJECT 节点
Long projectId = nodeService.createNode("PROJECT", generateProjectCode(), dto.getTitle(), currentUserId());
// 2. 设置属性
propertyService.set(projectId, "title", dto.getTitle());
propertyService.set(projectId, "description", dto.getDescription());
propertyService.set(projectId, "status", "draft");
propertyService.set(projectId, "template_type", dto.getTemplateType());
// 3. 如果有模板类型,初始化要素
if (dto.getTemplateType() != null) {
initializeElements(projectId, dto.getTemplateType());
}
// 4. 如果是复制项目
if (dto.getFromProjectId() != null) {
copyProjectElements(projectId, dto.getFromProjectId());
}
return getProjectVO(projectId);
}
}
```
---
### 4.2 附件上传与解析流程
```
用户上传文件
│
▼
FileUploadController.upload()
│
├─ 1. 保存文件到存储(本地/OSS)
│ └─ 记录到 sys_files 表
│
├─ 2. 创建 ATTACHMENT 节点
│ ├─ 设置属性:file_name, file_path, file_type, file_size
│ ├─ 设置 parse_status = 'pending'
│ └─ 建立 PROJECT --HAS_ATTACHMENT--> ATTACHMENT 关系
│
├─ 3. 创建异步解析任务
│ └─ 记录到 sys_tasks 表
│
└─ 4. 返回附件信息 + taskId
异步任务执行:
│
├─ 5. 文件解析(提取文本)
│ ├─ DocxParser / PdfParser / XlsxParser
│ ├─ 更新 parsed_text 属性
│ └─ WebSocket 推送进度 30%
│
├─ 6. NER实体识别
│ ├─ 调用 NER 服务
│ ├─ 创建 ENTITY 节点
│ ├─ 建立 ATTACHMENT --HAS_ENTITY--> ENTITY 关系
│ └─ WebSocket 推送进度 80%
│
└─ 7. 完成
├─ 更新 parse_status = 'completed'
└─ WebSocket 推送进度 100%
```
---
### 4.3 规则创建与执行流程
```
用户从实体列表拖拽实体到要素
│
▼
RuleController.createRule()
│
├─ 1. 创建 RULE 节点
│ ├─ rule_type = 'direct_entity'
│ ├─ action_type = 'use_entity_value'
│ └─ status = 'active'
│
├─ 2. 建立关系
│ ├─ PROJECT --HAS_RULE--> RULE
│ ├─ RULE --FOR_ELEMENT--> ELEMENT
│ └─ RULE --INPUT_FROM--> ENTITY(带 edge_properties)
│
└─ 3. 自动执行规则
│
▼
RuleExecuteService.execute(ruleId)
│
├─ 4. 获取规则输入(INPUT_FROM 边)
│ └─ 获取 ENTITY 节点的 name
│
├─ 5. 执行规则逻辑
│ └─ DirectEntityExecutor: 直接使用实体值
│
├─ 6. 更新 VALUE 节点
│ ├─ value_text = entity.name
│ ├─ is_filled = 'true'
│ └─ fill_source = 'rule'
│
└─ 7. 更新 RULE 节点
├─ last_output_text = entity.name
├─ last_run_status = 'success'
└─ last_run_time = NOW()
```
---
### 4.4 项目导出流程
```
用户点击"导出"
│
▼
ProjectExportController.export(projectId, format)
│
├─ 1. 查询项目完整数据
│ ├─ 项目基本信息(v_projects)
│ ├─ 要素定义列表(v_project_elements)
│ ├─ 要素值列表(v_project_values)
│ └─ 报告内容(content_html / content_markdown)
│
├─ 2. 渲染模板
│ ├─ Word: Apache POI + 模板文件
│ └─ PDF: iText / PDFBox
│
├─ 3. 替换要素占位符
│ └─ {{basicInfo.projectCode}} → "BZ-0092-2024"
│
└─ 4. 返回文件流
└─ Content-Disposition: attachment; filename="报告.docx"
```
---
## 五、WebSocket 消息设计
### 5.1 连接地址
```
ws://host:port/ws?token={accessToken}
```
### 5.2 消息格式
```json
{
"type": "PARSE_PROGRESS",
"data": {
"taskId": "task_001",
"attachmentId": 400,
"progress": 80,
"stage": "ner_extracting",
"message": "正在识别实体..."
}
}
```
### 5.3 消息类型
| type | 说明 | 触发场景 |
|------|------|----------|
| PARSE_PROGRESS | 解析进度 | 附件解析过程中 |
| PARSE_COMPLETE | 解析完成 | 附件解析完成 |
| PARSE_FAILED | 解析失败 | 附件解析失败 |
| RULE_EXECUTED | 规则执行完成 | 规则执行后 |
| VALUE_UPDATED | 要素值更新 | 要素值被修改后 |
| NOTIFICATION | 通知 | 系统通知 |
---
## 六、统一返回格式
### 6.1 成功响应
```json
{
"code": 200,
"message": "success",
"data": { ... }
}
```
### 6.2 分页响应
```json
{
"code": 200,
"message": "success",
"data": {
"total": 100,
"pages": 5,
"current": 1,
"size": 20,
"records": [ ... ]
}
}
```
### 6.3 错误响应
```json
{
"code": 400,
"message": "参数错误:标题不能为空",
"data": null
}
```
### 6.4 错误码定义
| code | 说明 |
|------|------|
| 200 | 成功 |
| 400 | 参数错误 |
| 401 | 未认证 |
| 403 | 无权限 |
| 404 | 资源不存在 |
| 409 | 资源冲突 |
| 500 | 服务器内部错误 |
---
## 七、规则引擎对接(预留)
### 7.1 当前状态
规则引擎由独立团队开发,将提供接口供本系统调用。接口参数格式待确认。
### 7.2 对接设计
```java
/**
* 规则引擎客户端(预留)
* 待规则引擎接口定义后实现
*/
@Service
public class RuleEngineClient {
/**
* 调用规则引擎执行DSL
* @param dslContent DSL代码
* @param params 参数(节点ID映射)
* @return 执行结果
*/
public RuleExecuteResult executeDSL(String dslContent, Map params) {
// TODO: 待规则引擎接口定义后实现
throw new UnsupportedOperationException("规则引擎接口待对接");
}
}
```
### 7.3 已知信息
根据规则引擎同事提供的DSL示例,对接时需要传递的核心参数为**节点ID**。当前数据库设计中所有业务实体都有唯一的 `nodes.id`,可直接作为参数。
### 7.4 待确认事项
- [ ] 接口请求/响应格式
- [ ] 调用方式(HTTP/gRPC/消息队列)
- [ ] 异步执行和回调机制
- [ ] 错误处理和重试策略
---
## 八、配置文件模板
### 8.1 application.yml
```yaml
server:
port: 8080
servlet:
context-path: /
spring:
datasource:
url: jdbc:postgresql://localhost:5432/lingyue_zhibao
username: postgres
password: ${DB_PASSWORD}
driver-class-name: org.postgresql.Driver
hikari:
maximum-pool-size: 20
minimum-idle: 5
redis:
host: localhost
port: 6379
password: ${REDIS_PASSWORD:}
database: 0
servlet:
multipart:
max-file-size: 100MB
max-request-size: 100MB
mybatis-plus:
mapper-locations: classpath*:mapper/**/*.xml
configuration:
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl
# JWT配置
jwt:
secret: ${JWT_SECRET}
access-token-expire: 7200 # 2小时
refresh-token-expire: 604800 # 7天
# 文件存储配置
file:
storage:
type: local # local / oss / minio
local:
base-path: /data/lingyue/uploads
oss:
endpoint: ${OSS_ENDPOINT:}
access-key: ${OSS_ACCESS_KEY:}
secret-key: ${OSS_SECRET_KEY:}
bucket: ${OSS_BUCKET:}
# NER服务配置
ner:
service:
url: http://localhost:5000
timeout: 30000
# LLM配置
llm:
api-key: ${LLM_API_KEY:}
base-url: ${LLM_BASE_URL:https://api.openai.com/v1}
model: gpt-4
max-tokens: 4096
# 规则引擎配置(预留)
rule-engine:
url: ${RULE_ENGINE_URL:}
timeout: 60000
```
---
## 九、开发优先级
### Phase 1(Week 1-2):基础设施 + 用户系统 + 项目管理
| 优先级 | 模块 | 接口数 |
|--------|------|--------|
| P0 | 项目框架搭建 | - |
| P0 | 数据库初始化 | - |
| P0 | 图数据核心服务(NodeService, EdgeService) | - |
| P0 | 认证接口 | 7 |
| P0 | 用户管理接口 | 11 |
| P0 | 项目管理接口 | 8 |
| P0 | 要素管理接口 | 5 |
| P0 | 要素值接口 | 4 |
### Phase 2(Week 3-4):附件 + 实体 + 规则
| 优先级 | 模块 | 接口数 |
|--------|------|--------|
| P0 | 文件服务接口 | 4 |
| P0 | 附件管理接口 | 6 |
| P0 | 实体管理接口 | 5 |
| P0 | 规则管理接口 | 7 |
| P0 | WebSocket推送 | - |
| P0 | 异步任务 | 3 |
### Phase 3(Week 5-6):AI + 导出 + 系统管理
| 优先级 | 模块 | 接口数 |
|--------|------|--------|
| P1 | AI服务接口 | 5 |
| P0 | 项目导出 | 1 |
| P1 | 角色管理接口 | 8 |
| P1 | 权限管理接口 | 4 |
| P2 | 数据字典接口 | 8 |
| P2 | 系统配置接口 | 4 |
| P2 | 日志接口 | 4 |
---
## 十、总结
### 10.1 核心数据
| 维度 | 数值 |
|------|------|
| Maven模块 | 3个(common, graph, app) |
| 业务模块 | 9个(system, project, attachment, entity, rule, file, ai, websocket, task) |
| 接口总数 | 93个 |
| 数据库表 | 20张 |
| 数据库视图 | 7个 |
| 节点类型 | 6种 |
| 关系类型 | 11种 |
### 10.2 核心设计决策
1. **单层项目结构**: 前端只关心"项目",不区分模板/报告
2. **图数据库架构**: 关系型数据库实现图结构,灵活扩展
3. **视图抽象**: 通过数据库视图简化业务查询
4. **规则引擎预留**: DSL对接接口预留,待规则引擎团队提供接口后实现
5. **异步任务**: 文件解析、NER识别等耗时操作异步执行,WebSocket推送进度