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

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

相关推荐
Oneslide19 小时前
Ubuntu 26.04 完整安装 Fcitx5 中文拼音输入法指南(适配默认Wayland)
后端
huangdong_20 小时前
电商平台图片URL原图转换技术深度解析:从缩略图到高清原图的完整方案
java·后端·spring
記億揺晃着的那天20 小时前
Java 调用外部 Go 程序的实践:ProcessBuilder 在生产环境中的应用
java·golang·processbuilder
掘金码甲哥20 小时前
3min手搓一个帮助文档站,很合理吧!
后端
JAVA面经实录91720 小时前
Java 数据结构与算法 (终极完整学习文档)
java·数据结构·算法
JAVA面经实录91721 小时前
操作系统面试题
java·服务器·数据库·计算机网络·面试
一杯奶茶¥21 小时前
基于springboot的失物招领管理系统带万字文档 校园失物招领管理系统 失物认领管理系统java springboot vue
java·vue.js·spring boot·java项目
不能只会打代码21 小时前
边缘视频分析平台的架构设计与性能优化——从750ms到190ms的调优之路
java·spring boot·redis·性能优化·边缘计算·物联网竞赛
小刘|1 天前
Spring AI Alibaba 集成和风天气 API 实战
java·服务器·前端
KANGBboy1 天前
java知识五(继承)
java·开发语言