一、改造背景:为什么要做
旧版查新功能只支持期刊类型,且缓存Key设计有缺陷(临时查新会冲突),数据库字段约束过死(subjectId、projectId必填导致临时查新无法保存)。
业务需要支持成果(achievement)和期刊(periodical)两种命中类型。临时查新(没有subjectId/projectId)需要独立缓存Key,否则会互相覆盖。前端需要统一的文件下载方式,不能直接暴露URL。
二、核心改动:三块一起动
2.1 VO字段重命名(前后端对齐)
| 改动项 | 旧 | 新 | 原因 |
|---|---|---|---|
| 字段名 | periodicalNo | referenceNo | 不再只支持期刊,统一叫"参考文件编号" |
| 新增字段 | 无 | bizFileId | 前端统一用这个字段调下载接口 |
| 删除字段 | url | 无 | 安全考虑,不让前端直接调文件URL |
2.2 缓存Key优化(解决临时查新冲突)
旧逻辑:可能只用某一个ID,临时查新时ID为空,导致Key重复覆盖
新逻辑:三级优先级,有哪个用哪个
java
private String buildCacheId(NoveltyCheckDTO reqDTO) {
if (reqDTO.getProjectId() != null) return String.valueOf(reqDTO.getProjectId());
if (reqDTO.getSubjectId() != null) return String.valueOf(reqDTO.getSubjectId());
return reqDTO.getRequestId(); // 临时查新走这里
}
2.3 数据库表结构调整(放宽约束)
sql
ALTER TABLE `kl_novelty_check`
MODIFY COLUMN `subject_id` bigint NULL COMMENT '查新主体ID(临时查新可为空)',
MODIFY COLUMN `project_id` bigint NULL DEFAULT NULL COMMENT '关联期刊项目ID(临时查新可为空)';
改动原因:临时查新没有subjectId/projectId,强制非空会插入失败。
三、XXXX查新策略完善(核心逻辑)
3.1 支持两种命中类型
| source_type | 处理方式 | 查询逻辑 |
|---|---|---|
| achievement | 通过achievement_id → bkl_file | 直接获取文件名和fileId |
| periodical | 通过project_id → periodical_document | 查询最新版本原始文档 |
3.2 periodical类型的特殊处理
java
List<PeriodicalDocument> documents = periodicalDocumentService.list(
Wrappers.lambdaQuery(PeriodicalDocument.class)
.eq(PeriodicalDocument::getProjectId, projectId)
.eq(PeriodicalDocument::getDocumentType, "origin")
.orderByDesc(PeriodicalDocument::getVersion)
.last("limit 1")
);
关键点 :只取document_type = origin的最新版本。
四、修复的问题清单
| 问题 | 解决方案 |
|---|---|
| createTime类型不匹配 | 统一使用LocalDateTime |
| 查新结果不显示期刊号 | 通过成果ID关联bkl_file |
| 临时查新缓存Key冲突 | 用requestId作为兜底缓存Key |
| periodical类型无法关联文件 | 通过project_id查询periodical_document |
| 文档类型判断混乱 | 区分type=3(期刊)和origin(原始文档) |
五、最终返回结果示例
java
{
"referenceFiles": [
{
"id": "0000001",
"referenceNo": "NO1111111-深度学习的智慧能源管理系统",
"title": "本发明涉及一种基于深度学习的智慧能源管理系统...",
"similarity": 80,
"bizFileId": 1
}
],
"riskLevel": "LOW",
"riskTitle": "存在1件高度相似期刊,建议修改调整",
"aiModificationSuggestion": "⚠️ 一般警示:存在相似期刊..."
}
六、待优化项
-
数据去重:多个项目重复上传相同文件的问题(业务层面)
-
文件名显示:过长时可截断
-
其他查新类型:论文/标准(已预留,暂未实现)
七、涉及的核心文件
| 文件 | 改动内容 |
|---|---|
| NoveltyCheckVO.java | 字段重命名 |
| NoveltyCheckBizServiceImpl.java | 缓存Key优化、临时查新支持 |
| XXXXNoveltyCheckStrategy.java | 完整重写,支持两种类型 |
| NoveltyCheckDataServiceImpl.java | saveNewVersion支持subjectId为空 |
| kl_novelty_check表 | subject_id、project_id改为可空 |
八、底稿收尾落款
本文为《技术底稿》系列第 42 篇,记录查新功能从单一期刊查新升级为通用查新的完整改造过程。
涉及VO字段重命名、缓存Key优先级重构、数据库约束放宽、多源命中策略落地等多个改动点,是一次典型的功能通用化重构实践。
改造完成后,查新功能已支持achievement和periodical两种命中类型,临时查新场景不再有缓存冲突,前端文件下载统一走bizFileId接口,整体安全性和扩展性都有明显提升。
同类功能通用化改造、多类型命中策略设计,可作为参考范本。