feat(aihr): export human calibration evidence

This commit is contained in:
2026-07-14 03:36:02 +08:00
parent 5e3dfd0085
commit 65e6483d23
7 changed files with 58 additions and 9 deletions
+2
View File
@@ -346,6 +346,8 @@ contains frontend/src/views/train/practice.vue "导出试点CSV"
contains frontend/src/views/train/reviews.vue "导出试点 CSV"
contains frontend/src/views/train/reviews.vue "人工校准总分"
contains frontend/src/api/aihr/practice.ts "/api/train/practice/export"
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "final_adopted_score"
contains backend/script/sql/aihr_practice_mysql8.sql "aihr_practice_calibration"
contains frontend/src/api/aihr/practice.ts '/api/train/practice/scenarios/${id}/enabled'
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrPracticeController.java "/scenarios/{id}/enabled"
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/domain/AihrSopDto.java "String position"
+24 -1
View File
@@ -83,7 +83,13 @@ const DETAIL_HEADERS = [
'finished_time',
'summary',
'review_advice',
'incentive_point'
'incentive_point',
'ai_score',
'calibration_original_score',
'human_score',
'calibration_reviewer',
'calibration_time',
'final_adopted_score'
];
function fail(message) {
@@ -280,6 +286,23 @@ export function verifyPilotExportContract({ csv, startDate, endDate, contentDisp
}
const score = Number(row[5]);
if (!Number.isFinite(score) || score < 0 || score > 100) fail(`detail score ${row[5] || '<missing>'} is invalid`);
if (Number(row[11]) !== score) fail(`detail ai_score ${row[11] || '<missing>'} does not match score ${row[5]}`);
const calibrationOriginal = row[12] === '' ? null : Number(row[12]);
const humanScore = row[13] === '' ? null : Number(row[13]);
for (const [label, value] of [['calibration_original_score', calibrationOriginal], ['human_score', humanScore]]) {
if (value !== null && (!Number.isFinite(value) || value < 0 || value > 100)) {
fail(`detail ${label} ${value} is invalid`);
}
}
const finalAdopted = Number(row[16]);
if (!Number.isFinite(finalAdopted) || finalAdopted < 0 || finalAdopted > 100) {
fail(`detail final_adopted_score ${row[16] || '<missing>'} is invalid`);
}
if (humanScore === null) {
if (row[14] || row[15] || finalAdopted !== score) fail('detail without human score has inconsistent calibration evidence');
} else if (!row[14] || !row[15] || finalAdopted !== humanScore) {
fail('detail human score is missing reviewer/time or final adopted score');
}
scores.push(score);
if (row[6] === '已复盘') reviewed += 1;
if (score < 80 || row[6] === '待复盘') alerts += 1;
+2 -2
View File
@@ -44,8 +44,8 @@ function validCsv() {
pilot_metric_ready: 'false'
};
const lines = ['metric,value', ...Object.entries(metrics).map(([key, value]) => `${key},${value}`)];
lines.push('', 'formal_ext_party_id,project_codes,session_id,trainee,scene,score,status,finished_time,summary,review_advice,incentive_point');
lines.push('FORMAL-1,P1,session-1,员工甲,投诉处理,86,已复盘,2026-07-08 10:00:00,正式记录,保持回访,3');
lines.push('', 'formal_ext_party_id,project_codes,session_id,trainee,scene,score,status,finished_time,summary,review_advice,incentive_point,ai_score,calibration_original_score,human_score,calibration_reviewer,calibration_time,final_adopted_score');
lines.push('FORMAL-1,P1,session-1,员工甲,投诉处理,86,已复盘,2026-07-08 10:00:00,正式记录,保持回访,3,86,86,78,主管甲,2026-07-08 11:00:00,78');
return lines.join('\n');
}