# 灵越智报 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推送进度