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`