《技术底稿 42》查新功能通用化改造:从单一期刊到多源命中,缓存与表结构一次重构

一、改造背景:为什么要做

旧版查新功能只支持期刊类型,且缓存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接口,整体安全性和扩展性都有明显提升。

同类功能通用化改造、多类型命中策略设计,可作为参考范本。

相关推荐
武子康8 分钟前
Java-07 深入浅出 MyBatis数据库一对多关系模型实战:表结构设计与查询实现
java·后端
花椒技术1 小时前
企业内部 Agent 落地复盘:Gateway、Skill 和二次确认如何串起受控业务执行
后端·agent·ai编程
阿杰技术2 小时前
AI 编程助手落地实战:从提效到重构的全场景指南
人工智能·重构
REDcker2 小时前
Linux OverlayFS详解
java·linux·运维
Royzst2 小时前
xml知识点
java·服务器·前端
我是一颗柠檬3 小时前
【MySQL全面教学】MySQL事务与ACID Day9(2026年)
数据库·后端·mysql
橙子圆1233 小时前
Redis知识9之集群
数据库·redis·缓存
枕星而眠3 小时前
数据结构八大排序详解(一):四大简单排序
c语言·数据结构·c++·后端
IT_陈寒3 小时前
React useEffect闭包陷阱差点把我整失业了
前端·人工智能·后端
鱼鳞_3 小时前
苍穹外卖-Day08(缓存套餐)
java·redis·缓存