From d46754ede8c1afd0ccb1988ea649abdbfa3e9b63 Mon Sep 17 00:00:00 2001 From: wangyu <823267011@qq.com> Date: Fri, 12 Jun 2026 10:04:16 +0800 Subject: [PATCH] =?UTF-8?q?AI=E5=AE=A1=E6=A0=B8=E6=94=B9=E4=B8=BA=20?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E9=A1=B5+=E8=AF=A6=E6=83=85=E9=A1=B5=20?= =?UTF-8?q?=E7=BB=93=E6=9E=84=EF=BC=8C=E5=88=97=E8=A1=A8=E5=B8=A6=E5=AE=A1?= =?UTF-8?q?=E6=A0=B8=E6=91=98=E8=A6=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 表 oa_ai_review 增加 summary 列(审核结论摘要,纯文本,列表展示用), 已应用到生产库;分析时由结果 Markdown 提炼前160字纯文本写入 - 列表查询清空大字段 result_md 减小响应体,详情接口仍返回完整结果 - 前端拆分: · index.vue 重写为列表页:搜索(类型/关键字)+表格(类型/文件名/岗位/结论标签/ 审核摘要/时间)+分页,「新增审核」改为弹窗上传(类型/岗位/文件), 审核完成后跳转详情;行可删除 · 新增 detail.vue 详情页:元信息(文件名+下载原件/岗位/模型/时间/审核人) + 结论标签 + 完整 Markdown 结果,返回列表按钮 · router 增加 /hint/aiReview/detail/:id 隐藏路由 - 原件已通过 OSS 留存,详情页可下载,下次可直接查看 Co-Authored-By: Claude Fable 5 --- .../java/com/ruoyi/oa/domain/OaAiReview.java | 3 + .../com/ruoyi/oa/domain/vo/OaAiReviewVo.java | 1 + .../service/impl/OaAiReviewServiceImpl.java | 15 + ruoyi-ui/src/router/index.js | 6 + ruoyi-ui/src/views/oa/aiReview/detail.vue | 110 ++++++ ruoyi-ui/src/views/oa/aiReview/index.vue | 362 ++++++++---------- sql/oa_ai_review.sql | 4 + 7 files changed, 293 insertions(+), 208 deletions(-) create mode 100644 ruoyi-ui/src/views/oa/aiReview/detail.vue diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/OaAiReview.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/OaAiReview.java index ef071fd..a11215b 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/OaAiReview.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/OaAiReview.java @@ -41,6 +41,9 @@ public class OaAiReview extends BaseEntity { /** 合同总体风险评级:高/中/低(简历为空) */ private String riskLevel; + /** AI 审核结论摘要(列表展示,纯文本) */ + private String summary; + /** AI 审核结果(Markdown) */ private String resultMd; diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/OaAiReviewVo.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/OaAiReviewVo.java index d0b8e6f..6c81d32 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/OaAiReviewVo.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/OaAiReviewVo.java @@ -22,6 +22,7 @@ public class OaAiReviewVo implements Serializable { private String position; private Integer matchScore; private String riskLevel; + private String summary; private String resultMd; private String model; private Integer tokens; diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/OaAiReviewServiceImpl.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/OaAiReviewServiceImpl.java index fa9d229..14c2005 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/OaAiReviewServiceImpl.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/OaAiReviewServiceImpl.java @@ -121,6 +121,7 @@ public class OaAiReviewServiceImpl implements IOaAiReviewService { entity.setFileUrl(fileUrl); entity.setPosition(position); entity.setResultMd(result); + entity.setSummary(buildSummary(result)); entity.setModel(miMoProps.getModel()); if ("resume".equals(reviewType)) { entity.setMatchScore(parseInt(SCORE_PATTERN, result, 100)); @@ -137,6 +138,16 @@ public class OaAiReviewServiceImpl implements IOaAiReviewService { return text.length() > MAX_TEXT_LEN ? text.substring(0, MAX_TEXT_LEN) : text; } + /** 从 Markdown 结果里提炼一段纯文本摘要,供列表展示 */ + private String buildSummary(String md) { + if (StringUtils.isBlank(md)) return null; + String text = md.replaceAll("(?m)^#+\\s*", "") // 标题符号 + .replaceAll("[*`>#\\-]", " ") // markdown 符号 + .replaceAll("\\s+", " ") // 折叠空白 + .trim(); + return text.length() > 160 ? text.substring(0, 160) : text; + } + private Integer parseInt(Pattern p, String text, int max) { Matcher m = p.matcher(text == null ? "" : text); if (m.find()) { @@ -194,6 +205,10 @@ public class OaAiReviewServiceImpl implements IOaAiReviewService { } lqw.orderByDesc(OaAiReview::getCreateTime); Page page = baseMapper.selectVoPage(pageQuery.build(), lqw); + // 列表只需 summary,清空大字段 resultMd 减小响应体 + if (page.getRecords() != null) { + page.getRecords().forEach(v -> v.setResultMd(null)); + } return TableDataInfo.build(page); } diff --git a/ruoyi-ui/src/router/index.js b/ruoyi-ui/src/router/index.js index 620375f..a72563d 100644 --- a/ruoyi-ui/src/router/index.js +++ b/ruoyi-ui/src/router/index.js @@ -177,6 +177,12 @@ export const constantRoutes = [ name: "editMeetingMinutes", meta: { title: "编辑会议纪要", activeMenu: "/hint/meeting" }, }, + { + path: "aiReview/detail/:id(\\d+)", + component: () => import("@/views/oa/aiReview/detail"), + name: "aiReviewDetail", + meta: { title: "审核详情", activeMenu: "/hint/aiReview" }, + }, ], }, { diff --git a/ruoyi-ui/src/views/oa/aiReview/detail.vue b/ruoyi-ui/src/views/oa/aiReview/detail.vue new file mode 100644 index 0000000..b5d0a70 --- /dev/null +++ b/ruoyi-ui/src/views/oa/aiReview/detail.vue @@ -0,0 +1,110 @@ + + + + + diff --git a/ruoyi-ui/src/views/oa/aiReview/index.vue b/ruoyi-ui/src/views/oa/aiReview/index.vue index 45bd9be..13d8bff 100644 --- a/ruoyi-ui/src/views/oa/aiReview/index.vue +++ b/ruoyi-ui/src/views/oa/aiReview/index.vue @@ -1,155 +1,189 @@ diff --git a/sql/oa_ai_review.sql b/sql/oa_ai_review.sql index 8e2c747..e06f76e 100644 --- a/sql/oa_ai_review.sql +++ b/sql/oa_ai_review.sql @@ -17,6 +17,7 @@ CREATE TABLE IF NOT EXISTS `oa_ai_review` ( `position` varchar(255) DEFAULT NULL COMMENT '简历目标岗位', `match_score` int(11) DEFAULT NULL COMMENT '简历匹配度评分 0-100', `risk_level` varchar(10) DEFAULT NULL COMMENT '合同风险评级 高/中/低', + `summary` varchar(500) DEFAULT NULL COMMENT 'AI审核结论摘要(列表展示)', `result_md` longtext COMMENT 'AI 审核结果(Markdown)', `model` varchar(50) DEFAULT NULL COMMENT '使用的模型', `tokens` int(11) DEFAULT NULL COMMENT '消耗 token', @@ -30,6 +31,9 @@ CREATE TABLE IF NOT EXISTS `oa_ai_review` ( KEY `idx_create_time` (`create_time`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='AI 审核记录(合同/简历)'; +-- 若表已存在(旧版本),补加 summary 列(MySQL 不支持 ADD COLUMN IF NOT EXISTS,重复执行报错可忽略): +-- ALTER TABLE `oa_ai_review` ADD COLUMN `summary` varchar(500) DEFAULT NULL COMMENT 'AI审核结论摘要(列表展示)' AFTER `risk_level`; + -- ---------------- 菜单:信息 > AI审核 ---------------- -- 父菜单 1774989374680858626 = 「信息」 INSERT IGNORE INTO `sys_menu`