《技术底稿 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接口,整体安全性和扩展性都有明显提升。

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

相关推荐
吴声子夜歌3 小时前
ApacheCommons——commons-pool2(高性能通用对象池框架)
java·开发语言·apache
mldong7 小时前
C# 开发者也有自己的轻量工作流引擎了:NuGet 装包,5 分钟跑通一条审批流
后端·c#·.net
xcl09258 小时前
幼儿托育系统开发实战:从需求分析到上线全流程指南
java·大数据·需求分析
吴声子夜歌8 小时前
ApacheCommons——commons-cli(命令行参数解析)
java·开发语言·apache
小小猪的春天9 小时前
Java 手写第一个 MCP Server:Spring AI MCP 半小时跑通
java·人工智能·spring boot·ai编程
find1star9 小时前
LeetCode 141:环形链表
java·算法·leetcode·链表
爱学堂IT分享9 小时前
鹤翔老师pmp项目管理培训认证考试课 (直播录播题库送学时证明)【共58课时】-51CTO学堂
后端
今天AI了吗9 小时前
DeepSeek Harness 深度解析:从评测架构到实战落地
java·网络·数据库·人工智能·架构·java-ee
王的宝库9 小时前
Go 项目结构:从单文件到标准工程布局
开发语言·后端·golang
许彰午10 小时前
27-AuthService登录链路
java·低代码·架构