fix(aihr): preserve case contributor attribution
This commit is contained in:
+23
-8
@@ -69,7 +69,7 @@ public class AihrCaseService {
|
||||
MediaRef media = storeSourceAudio(file);
|
||||
String caseId = "case-" + UUID.randomUUID();
|
||||
CaseState state = new CaseState(caseId, fileName, scopedProject, transcript, tagsFromText(transcript), null,
|
||||
media.ossId(), media.url());
|
||||
media.ossId(), media.url(), currentCaseOwner());
|
||||
cases.put(caseId, state);
|
||||
saveCase(state, "已转写", caseTitle(List.of(), fileName), transcript);
|
||||
return new UploadResponse(caseId, fileName, transcript, state.tags(), "real-asr", media.url(), media.ossId());
|
||||
@@ -85,7 +85,7 @@ public class AihrCaseService {
|
||||
CaseState state = requireCase(request == null ? null : request.caseId(), projectScopes);
|
||||
CaseSummary summary = organizeWithModel(state).orElseGet(() -> localSummary(state));
|
||||
CaseState next = new CaseState(state.id(), state.fileName(), state.projectExtOrgId(), state.transcript(), summary.tags(), summary.summary(),
|
||||
state.mediaOssId(), state.mediaUrl());
|
||||
state.mediaOssId(), state.mediaUrl(), state.owner());
|
||||
cases.put(state.id(), next);
|
||||
saveCase(next, "已整理", caseTitle(summary.summary(), state.fileName()), summary.aiSummary());
|
||||
return new OrganizeResponse(state.id(), summary.summary(), summary.tags(), summary.aiSummary(), summary.source());
|
||||
@@ -104,7 +104,7 @@ public class AihrCaseService {
|
||||
primaryTag(state.tags()),
|
||||
"已入库",
|
||||
LocalDateTime.now().format(TIME_FORMAT),
|
||||
"培训组",
|
||||
firstNonBlank(state.owner(), "培训组"),
|
||||
detailSummary.isBlank() ? state.transcript() : detailSummary
|
||||
);
|
||||
saveCase(state, "已入库", record.title(), record.summary());
|
||||
@@ -233,7 +233,7 @@ public class AihrCaseService {
|
||||
jdbcTemplate.update("""
|
||||
INSERT INTO aihr_case_record
|
||||
(tenant_id, case_id, file_name, project_ext_org_id, title, type, status, transcript, summary, media_oss_id, media_url, owner, create_time, update_time)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, '培训组', now(), now())
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, now(), now())
|
||||
ON DUPLICATE KEY UPDATE
|
||||
file_name = VALUES(file_name),
|
||||
project_ext_org_id = VALUES(project_ext_org_id),
|
||||
@@ -256,7 +256,8 @@ public class AihrCaseService {
|
||||
truncate(maskSensitiveText(state.transcript()), 4000),
|
||||
truncate(maskSensitiveText(summary), 1000),
|
||||
state.mediaOssId(),
|
||||
truncate(state.mediaUrl(), 500)
|
||||
truncate(state.mediaUrl(), 500),
|
||||
firstNonBlank(state.owner(), "培训组")
|
||||
);
|
||||
}
|
||||
|
||||
@@ -403,7 +404,7 @@ public class AihrCaseService {
|
||||
ensureCaseTable();
|
||||
List<CaseState> persisted = jdbcTemplate.query("""
|
||||
SELECT case_id, file_name, project_ext_org_id, transcript, type
|
||||
, media_oss_id, media_url
|
||||
, media_oss_id, media_url, owner
|
||||
FROM aihr_case_record
|
||||
WHERE tenant_id = ? AND case_id = ?
|
||||
LIMIT 1
|
||||
@@ -415,7 +416,8 @@ public class AihrCaseService {
|
||||
tagsFromText(firstNonBlank(rs.getString("type"), "现场案例")),
|
||||
null,
|
||||
rs.getObject("media_oss_id", Long.class),
|
||||
firstNonBlank(rs.getString("media_url"), "")
|
||||
firstNonBlank(rs.getString("media_url"), ""),
|
||||
firstNonBlank(rs.getString("owner"), "培训组")
|
||||
), tenantId(), normalizedCaseId);
|
||||
state = persisted.stream().findFirst().orElse(null);
|
||||
if (state != null) {
|
||||
@@ -535,6 +537,18 @@ public class AihrCaseService {
|
||||
return clean(AihrSensitiveText.forModel(text));
|
||||
}
|
||||
|
||||
private String currentCaseOwner() {
|
||||
return caseOwner(LoginHelper.getUsername());
|
||||
}
|
||||
|
||||
static String caseOwner(String identity) {
|
||||
String value = clean(identity);
|
||||
if (value.matches("1[3-9]\\d{9}")) {
|
||||
return "员工" + value.substring(value.length() - 4);
|
||||
}
|
||||
return firstNonBlank(value, "培训组");
|
||||
}
|
||||
|
||||
static boolean isSupportedAudioFile(String fileName) {
|
||||
String lower = clean(fileName).toLowerCase(Locale.ROOT);
|
||||
return SUPPORTED_AUDIO_EXTENSIONS.stream().anyMatch(lower::endsWith);
|
||||
@@ -557,7 +571,8 @@ public class AihrCaseService {
|
||||
List<TagResponse> tags,
|
||||
List<SummaryResponse> summary,
|
||||
Long mediaOssId,
|
||||
String mediaUrl
|
||||
String mediaUrl,
|
||||
String owner
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
+8
@@ -163,6 +163,14 @@ class AihrCaseServiceTest {
|
||||
assertFalse(AihrCaseService.isCaseContributorPosition("普通员工", "一线"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Tag("dev")
|
||||
void caseOwnerKeepsAttributionWithoutPersistingRawMobileNumber() {
|
||||
assertEquals("员工1111", AihrCaseService.caseOwner("13900001111"));
|
||||
assertEquals("hr_operator", AihrCaseService.caseOwner("hr_operator"));
|
||||
assertEquals("培训组", AihrCaseService.caseOwner(" "));
|
||||
}
|
||||
|
||||
private static class CaseJdbcTemplate extends JdbcTemplate {
|
||||
private Object[] updateArgs = new Object[0];
|
||||
|
||||
|
||||
@@ -176,3 +176,4 @@
|
||||
- 2026-07-14 BRD G3 音频读取权限复核:发现移动端音频下载接口对已登录 SYS 用户未校验角色,普通后台账号理论上可枚举 `ossId` 读取训练录音;现复用 `superadmin/hr_operator` 门禁,APP 用户继续按本人/主管项目范围校验,其他身份返回 403。AIHR 全量测试 `70/70` 通过,未修改生产环境。
|
||||
- 2026-07-14 BRD 4.4 每日三题资格补强:每日派题现在在组织快照存在 `hire_date` 列时按“入职日期至今不超过 3 个月”判断,边界按自然月且包含当天;旧 Demo 快照没有该列时继续使用“移动端训练记录少于 3 次”的兼容回退。正式试点仍需在外部组织同步落地并校验 `hire_date`,不能把回退口径当成正式新员工资格。
|
||||
- 2026-07-14 BRD G3 候选资料审核状态复核:候选人资料审核接口此前在空请求体时默认写回“待审核”,可能覆盖已有“已通过/已驳回”状态;现要求审核动作显式提交三态之一,空值和未知状态直接拒绝,避免后台误操作回退审核结论。
|
||||
- 2026-07-14 BRD 案例署名复核:案例库已有负责人字段,但此前上传、整理和入库记录都硬编码为“培训组”,无法追溯案例贡献者;现复用既有 `owner` 字段保存首次上传身份,整理和入库阶段保留原署名,手机号身份仅显示员工末四位,避免把原始手机号写入案例展示。
|
||||
|
||||
@@ -514,6 +514,7 @@ contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/control
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrCaseService.java "position_level IN ('主管', '项目经理')"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrCaseService.java "media_oss_id"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrCaseService.java "storeSourceAudio"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrCaseService.java "currentCaseOwner"
|
||||
contains mobile-uni/src/pages/user/cases/index.vue "case-audio"
|
||||
contains frontend/src/views/knowledge/cases.vue "case-audio"
|
||||
contains backend/script/sql/aihr_practice_mysql8.sql "aihr_case_record"
|
||||
|
||||
Reference in New Issue
Block a user