设计时间: 2026-02-12
核心变化: 前端只关心"项目"概念,不区分项目/模板/报告
技术栈: Spring Boot 3.x + PostgreSQL + 图数据库架构
lingyue-zhibao-backend/
├── common/ # 公共模块
│ ├── core/ # 核心工具
│ │ ├── exception/ # 统一异常处理
│ │ ├── result/ # 统一返回结果
│ │ ├── config/ # 全局配置
│ │ └── util/ # 工具类
│ ├── security/ # 安全模块
│ │ ├── jwt/ # JWT工具
│ │ ├── filter/ # 安全过滤器
│ │ └── handler/ # 认证处理器
│ └── graph/ # 图数据库基础
│ ├── entity/ # 图实体基类
│ ├── mapper/ # 图Mapper基类
│ └── service/ # 图服务基类
│
├── modules/ # 业务模块
│ ├── system/ # 系统管理模块
│ │ ├── controller/
│ │ │ ├── UserController.java
│ │ │ ├── RoleController.java
│ │ │ ├── PermissionController.java
│ │ │ ├── DictController.java
│ │ │ └── ConfigController.java
│ │ ├── service/
│ │ ├── mapper/
│ │ └── entity/
│ │
│ ├── graph/ # 图数据核心模块 ⭐
│ │ ├── controller/
│ │ │ ├── NodeController.java # 节点通用操作
│ │ │ ├── EdgeController.java # 关系通用操作
│ │ │ └── PropertyController.java # 属性操作
│ │ ├── service/
│ │ │ ├── NodeService.java
│ │ │ ├── EdgeService.java
│ │ │ └── PropertyService.java
│ │ ├── mapper/
│ │ │ ├── NodeMapper.java
│ │ │ ├── EdgeMapper.java
│ │ │ └── PropertyMapper.java
│ │ └── entity/
│ │ ├── Node.java
│ │ ├── Edge.java
│ │ ├── NodeProperty.java
│ │ └── EdgeProperty.java
│ │
│ ├── project/ # 项目管理模块 ⭐⭐⭐
│ │ ├── controller/
│ │ │ ├── ProjectController.java # 项目CRUD
│ │ │ ├── ElementController.java # 要素定义管理
│ │ │ ├── ValueController.java # 要素值管理
│ │ │ └── ProjectExportController.java # 项目导出
│ │ ├── service/
│ │ │ ├── ProjectService.java
│ │ │ ├── ElementService.java
│ │ │ ├── ValueService.java
│ │ │ ├── ProjectCopyService.java
│ │ │ └── ProjectExportService.java
│ │ ├── dto/
│ │ │ ├── ProjectCreateDTO.java
│ │ │ ├── ProjectUpdateDTO.java
│ │ │ ├── ProjectVO.java
│ │ │ ├── ElementDefineDTO.java
│ │ │ └── ValueUpdateDTO.java
│ │ └── enums/
│ │ ├── ProjectStatus.java
│ │ └── ElementType.java # text/paragraph/table
│ │
│ ├── attachment/ # 附件管理模块
│ │ ├── controller/
│ │ │ └── AttachmentController.java
│ │ ├── service/
│ │ │ ├── AttachmentService.java
│ │ │ ├── AttachmentParseService.java
│ │ │ └── AttachmentUploadService.java
│ │ ├── dto/
│ │ │ ├── AttachmentUploadDTO.java
│ │ │ └── AttachmentVO.java
│ │ └── enums/
│ │ ├── AttachmentType.java # pdf/docx/xlsx
│ │ └── ParseStatus.java
│ │
│ ├── entity/ # 实体管理模块(NER结果)
│ │ ├── controller/
│ │ │ └── EntityController.java
│ │ ├── service/
│ │ │ ├── EntityService.java
│ │ │ ├── EntityMergeService.java
│ │ │ └── EntityExtractionService.java
│ │ ├── dto/
│ │ │ ├── EntityCreateDTO.java
│ │ │ ├── EntityMergeDTO.java
│ │ │ └── EntityVO.java
│ │ └── enums/
│ │ ├── EntityType.java # ORG/PERSON/DATE/NUMBER/LOCATION
│ │ └── BusinessLabel.java
│ │
│ ├── rule/ # 规则引擎模块 ⭐
│ │ ├── controller/
│ │ │ └── RuleController.java
│ │ ├── service/
│ │ │ ├── RuleService.java
│ │ │ ├── RuleExecutor.java
│ │ │ └── RuleConfigService.java
│ │ ├── executor/ # 规则执行器
│ │ │ ├── DirectEntityExecutor.java # 直接引用实体
│ │ │ ├── RegexExtractExecutor.java # 正则提取
│ │ │ ├── LLMGenerateExecutor.java # LLM生成
│ │ │ └── TableAggregateExecutor.java # 表格聚合
│ │ ├── dto/
│ │ │ ├── RuleCreateDTO.java
│ │ │ ├── RuleExecuteDTO.java
│ │ │ └── RuleVO.java
│ │ └── enums/
│ │ ├── RuleType.java # direct_entity/extraction/llm/aggregate
│ │ └── ActionType.java
│ │
│ ├── file/ # 文件服务模块
│ │ ├── controller/
│ │ │ ├── FileUploadController.java
│ │ │ └── FileDownloadController.java
│ │ ├── service/
│ │ │ ├── FileStorageService.java
│ │ │ ├── FileParseService.java
│ │ │ └── FilePreviewService.java
│ │ ├── parser/ # 文件解析器
│ │ │ ├── PdfParser.java
│ │ │ ├── DocxParser.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/ # 外部AI服务客户端
│ │ │ ├── OpenAIClient.java
│ │ │ └── NerServiceClient.java
│ │ └── dto/
│ │ ├── NerRequest.java
│ │ ├── NerResult.java
│ │ └── LLMRequest.java
│ │
│ └── websocket/ # WebSocket模块
│ ├── handler/
│ │ ├── ParseProgressHandler.java
│ │ ├── AIAssistantHandler.java
│ │ └── NotificationHandler.java
│ └── config/
│ └── WebSocketConfig.java
│
└── Application.java # 启动类
用户操作: 新建项目
↓
1. 创建 PROJECT 节点
- 可选择预设模板类型
- 或选择"从样本创建"
↓
2. 如果选择预设模板:
- 自动创建要素定义(ELEMENT节点)
- 创建空的要素值(VALUE节点)
- 建立关系: PROJECT --HAS_ELEMENT--> ELEMENT
- 建立关系: PROJECT --HAS_VALUE--> VALUE
↓
3. 如果选择从样本创建:
- 上传样本文档作为附件
- 解析文档,提取要素定义
- 创建ELEMENT和VALUE节点
↓
4. 返回项目ID,跳转到编辑器
接口设计:
POST /api/v1/projects
{
"title": "成都院2024年复审报告",
"description": "成都院电力安全生产标准化复审报告",
"templateType": "电力安全生产标准化复审报告", // 可选
"sampleFileId": null // 或提供样本文件ID
}
Response:
{
"code": 200,
"data": {
"id": 10,
"title": "成都院2024年复审报告",
"status": "draft",
"templateType": "电力安全生产标准化复审报告",
"elementCount": 8,
"filledCount": 1
}
}
用户操作: 上传附件
↓
1. 文件上传到 OSS/本地存储
↓
2. 创建 ATTACHMENT 节点
- 保存文件路径、类型、大小等
- 建立 PROJECT --HAS_ATTACHMENT--> ATTACHMENT
↓
3. 异步解析任务:
a. 文档解析(提取文本)
b. NER实体识别
c. 创建 ENTITY 节点
d. 建立 ATTACHMENT --HAS_ENTITY--> ENTITY
↓
4. WebSocket推送解析进度
↓
5. 解析完成,返回实体列表
接口设计:
POST /api/v1/projects/{projectId}/attachments/upload
Content-Type: multipart/form-data
Response:
{
"code": 200,
"data": {
"id": 400,
"fileName": "复审通知.docx",
"fileType": "docx",
"fileSize": 512000,
"parseStatus": "parsing",
"taskId": "task_20240212_001"
}
}
用户操作: 从附件实体添加规则
↓
1. 选择实体(如"BZ-0092-2024")
2. 选择目标要素(如"项目编号")
↓
3. 创建 RULE 节点:
- rule_type: "direct_entity"
- action_type: "use_entity_value"
↓
4. 建立关系:
- PROJECT --HAS_RULE--> RULE
- RULE --FOR_ELEMENT--> ELEMENT
- RULE --INPUT_FROM--> ENTITY
↓
5. 执行规则:
- 获取 ENTITY.name
- 更新 VALUE 节点的 value_text
- 更新 is_filled = true
↓
6. 返回执行结果
接口设计:
POST /api/v1/projects/{projectId}/rules
{
"elementKey": "basicInfo.projectCode",
"ruleType": "direct_entity",
"actionType": "use_entity_value",
"inputs": [
{
"inputKey": "entity",
"sourceType": "entity",
"sourceId": 502
}
]
}
Response:
{
"code": 200,
"data": {
"id": 600,
"elementKey": "basicInfo.projectCode",
"executeStatus": "success",
"outputValue": "BZ-0092-2024"
}
}
参考原设计文档,包含:
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/v1/projects |
获取项目列表(分页) |
| GET | /api/v1/projects/{id} |
获取项目详情 |
| POST | /api/v1/projects |
创建项目 |
| PUT | /api/v1/projects/{id} |
更新项目 |
| DELETE | /api/v1/projects/{id} |
删除项目 |
| POST | /api/v1/projects/{id}/copy |
复制项目 |
| POST | /api/v1/projects/{id}/archive |
归档项目 |
| POST | /api/v1/projects/{id}/export |
导出项目 |
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/v1/projects/{id}/elements |
获取项目要素列表 |
| POST | /api/v1/projects/{id}/elements |
添加要素定义 |
| PUT | /api/v1/projects/{id}/elements/{key} |
更新要素定义 |
| DELETE | /api/v1/projects/{id}/elements/{key} |
删除要素定义 |
| POST | /api/v1/projects/{id}/elements/parse |
从样本解析要素 |
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/v1/projects/{id}/values |
获取所有要素值 |
| GET | /api/v1/projects/{id}/values/{key} |
获取单个要素值 |
| PUT | /api/v1/projects/{id}/values/{key} |
更新要素值 |
| POST | /api/v1/projects/{id}/values/batch |
批量更新要素值 |
| 方法 | 路径 | 说明 |
|---|---|---|
| POST | /api/v1/projects/{id}/attachments/upload |
上传附件 |
| GET | /api/v1/projects/{id}/attachments |
获取附件列表 |
| GET | /api/v1/attachments/{id} |
获取附件详情 |
| POST | /api/v1/attachments/{id}/parse |
触发附件解析 |
| DELETE | /api/v1/attachments/{id} |
删除附件 |
| GET | /api/v1/attachments/{id}/entities |
获取附件实体列表 |
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/v1/attachments/{attachmentId}/entities |
获取附件实体列表 |
| GET | /api/v1/projects/{projectId}/entities |
获取项目所有实体 |
| GET | /api/v1/entities/{id} |
获取实体详情 |
| PUT | /api/v1/entities/{id} |
更新实体 |
| POST | /api/v1/entities/merge |
合并实体 |
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/v1/projects/{projectId}/rules |
获取项目规则列表 |
| GET | /api/v1/rules/{id} |
获取规则详情 |
| POST | /api/v1/projects/{projectId}/rules |
创建规则 |
| PUT | /api/v1/rules/{id} |
更新规则 |
| DELETE | /api/v1/rules/{id} |
删除规则 |
| POST | /api/v1/rules/{id}/execute |
执行规则 |
| POST | /api/v1/projects/{projectId}/rules/execute-all |
批量执行规则 |
| 方法 | 路径 | 说明 |
|---|---|---|
| POST | /api/v1/ai/ner/extract |
提取实体(同步) |
| POST | /api/v1/ai/ner/extract/async |
异步提取实体 |
| POST | /api/v1/ai/chat |
AI对话 |
| POST | /api/v1/ai/suggest |
AI建议 |
| POST | /api/v1/ai/optimize |
AI优化文本 |
/**
* 节点服务基类
*/
@Service
public class NodeService {
@Autowired
private NodeMapper nodeMapper;
@Autowired
private NodePropertyMapper propertyMapper;
/**
* 创建节点
*/
public Long createNode(String nodeType, String nodeKey, String name, Long createdBy) {
Node node = new Node();
node.setNodeType(nodeType);
node.setNodeKey(nodeKey);
node.setName(name);
node.setCreatedBy(createdBy);
nodeMapper.insert(node);
return node.getId();
}
/**
* 设置节点属性
*/
public void setProperty(Long nodeId, String propKey, Object value) {
NodeProperty property = new NodeProperty();
property.setNodeId(nodeId);
property.setPropKey(propKey);
if (value instanceof String) {
property.setPropValue((String) value);
} else if (value instanceof Number) {
property.setPropNumber(new BigDecimal(value.toString()));
} else if (value instanceof Date) {
property.setPropDate((Date) value);
} else {
property.setPropJson(JSON.toJSONString(value));
}
propertyMapper.insertOrUpdate(property);
}
}
/**
* 项目查询服务(基于视图)
*/
@Service
public class ProjectQueryService {
@Autowired
private ProjectViewMapper projectViewMapper;
/**
* 获取项目列表
*/
public Page<ProjectVO> listProjects(ProjectQueryDTO query) {
return projectViewMapper.selectProjectPage(query);
}
/**
* 获取项目详情
*/
public ProjectDetailVO getProjectDetail(Long projectId) {
// 查询项目基本信息(v_projects视图)
ProjectVO project = projectViewMapper.selectById(projectId);
// 查询要素定义列表(v_project_elements视图)
List<ElementVO> elements = projectViewMapper.selectElementsByProjectId(projectId);
// 查询要素值列表(v_project_values视图)
List<ValueVO> values = projectViewMapper.selectValuesByProjectId(projectId);
// 查询附件列表(v_attachments视图)
List<AttachmentVO> attachments = projectViewMapper.selectAttachmentsByProjectId(projectId);
// 查询规则列表(v_rules视图)
List<RuleVO> rules = projectViewMapper.selectRulesByProjectId(projectId);
// 组装返回
ProjectDetailVO detail = new ProjectDetailVO();
detail.setProject(project);
detail.setElements(elements);
detail.setValues(values);
detail.setAttachments(attachments);
detail.setRules(rules);
return detail;
}
}
| 维度 | 原设计 | 简化设计 |
|---|---|---|
| 概念层级 | 3层(项目/模板/报告) | 1层(项目) |
| 节点类型 | 9种 | 6种 |
| 关系类型 | 11种 | 8种 |
| 核心模块 | 3个(项目/模板/报告) | 1个(项目) |
| 接口数量 | ~100个 | ~80个 |
✅ 用户体验: 概念简单,操作直观
✅ 开发效率: 前后端代码量减少30%
✅ 维护成本: 状态管理简化,Bug更少
✅ 灵活性: 保留图数据库优势,扩展性不减
虽然前端不区分模板,但可以通过以下方式实现模板功能:
is_template=true)这样既简化了用户理解,又保留了模板复用的能力。