fix(backend): return canonical extPartyId in practice review detail

The reviewDetail query referenced a.trainee_name without declaring the
table alias, which 500s whenever org-sync display fields are enabled,
and the mobile payload never exposed extPartyId, so the supervisor
review pages could not resolve organization member names.
This commit is contained in:
2026-07-20 13:16:18 +08:00
parent 0e46591d5f
commit b6a7af9e51
3 changed files with 14 additions and 5 deletions
@@ -433,6 +433,7 @@ public class AihrMobileController {
data.put("aiComment", maskSensitiveText(detail.aiComment())); data.put("aiComment", maskSensitiveText(detail.aiComment()));
data.put("reviewAdvice", maskSensitiveText(detail.reviewAdvice())); data.put("reviewAdvice", maskSensitiveText(detail.reviewAdvice()));
data.put("incentivePoint", detail.incentivePoint()); data.put("incentivePoint", detail.incentivePoint());
data.put("extPartyId", detail.extPartyId());
data.put("scoreItems", detail.scoreItems().stream().map(item -> Map.of( data.put("scoreItems", detail.scoreItems().stream().map(item -> Map.of(
"label", item.label(), "label", item.label(),
"value", item.value(), "value", item.value(),
@@ -229,7 +229,8 @@ public final class AihrPracticeDto {
Integer incentivePoint, Integer incentivePoint,
List<DimensionResponse> scoreItems, List<DimensionResponse> scoreItems,
List<DialogueResponse> dialogue, List<DialogueResponse> dialogue,
List<AnnotationResponse> annotations List<AnnotationResponse> annotations,
String extPartyId
) { ) {
} }
@@ -1504,14 +1504,20 @@ public class AihrPracticeSeedService {
return null; return null;
} }
String nameExpression = !storeDisplayFields ? "'员工'" : "a.trainee_name"; String nameExpression = !storeDisplayFields ? "'员工'" : "a.trainee_name";
boolean hasOrgSnapshot = orgSnapshotTableExists();
boolean hasPhone = hasOrgSnapshot && orgSnapshotColumnExists("person_phone");
String identityExpression = hasOrgSnapshot
? teamCanonicalIdentityExpression("a", hasPhone)
: "a.ext_party_id";
List<ReviewDetailResponse> rows = jdbcTemplate.query(""" List<ReviewDetailResponse> rows = jdbcTemplate.query("""
SELECT id, session_id, finished_time, %s AS trainee_name, scenario_id, scenario_name, total_score, status, SELECT id, session_id, finished_time, %s AS trainee_name, scenario_id, scenario_name, total_score, status,
summary, mentor_rewrite, ai_comment, review_advice, incentive_point, summary, mentor_rewrite, ai_comment, review_advice, incentive_point,
dim_task_completion, dim_response_timeliness, response_latency_ms, dim_task_completion, dim_response_timeliness, response_latency_ms,
dim_compliance, dim_emotion, dim_communication, dim_marketing, dialogue_json, annotations_json dim_compliance, dim_emotion, dim_communication, dim_marketing, dialogue_json, annotations_json,
FROM aihr_practice_session %s AS ext_party_id
FROM aihr_practice_session a
WHERE tenant_id = ? AND mode = 'mobile' AND id = ? WHERE tenant_id = ? AND mode = 'mobile' AND id = ?
""".formatted(nameExpression), this::mapReviewDetail, tenantId(), id); """.formatted(nameExpression, identityExpression), this::mapReviewDetail, tenantId(), id);
return rows.isEmpty() ? null : rows.get(0); return rows.isEmpty() ? null : rows.get(0);
} }
@@ -3770,7 +3776,8 @@ public class AihrPracticeSeedService {
rs.getObject("incentive_point") == null ? null : rs.getInt("incentive_point"), rs.getObject("incentive_point") == null ? null : rs.getInt("incentive_point"),
scoreItems(rs), scoreItems(rs),
dialogue, dialogue,
readAnnotations(rs.getString("annotations_json"), dialogue, scenario) readAnnotations(rs.getString("annotations_json"), dialogue, scenario),
rs.getString("ext_party_id")
); );
} }