751 lines
64 KiB
Bash
Executable File
751 lines
64 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
set -euo pipefail
|
||
|
||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||
FRONTEND_URL="${FRONTEND_URL:-https://wygj-admin.localhost}"
|
||
MOBILE_URL="${MOBILE_URL:-https://wygj-mobile-uni.localhost}"
|
||
|
||
cd "$ROOT_DIR"
|
||
|
||
fail() {
|
||
echo "FAIL: $*" >&2
|
||
exit 1
|
||
}
|
||
|
||
need() {
|
||
command -v "$1" >/dev/null || fail "missing command: $1"
|
||
}
|
||
|
||
contains() {
|
||
local file="$1"
|
||
local text="$2"
|
||
grep -Fq "$text" "$file" || fail "$file missing marker: $text"
|
||
}
|
||
|
||
check_url() {
|
||
local name="$1"
|
||
local url="$2"
|
||
local code
|
||
code="$(curl -k -sS -o /tmp/wygj-demo-check.body -w '%{http_code}' "$url")"
|
||
[[ "$code" == "200" ]] || fail "$name returned HTTP $code"
|
||
echo "OK: $name"
|
||
}
|
||
|
||
check_mobile_h5_shell() {
|
||
local html href icon_url code
|
||
html="$(curl -k -fsS "$MOBILE_URL/h5/")"
|
||
[[ "$html" != *"tongji-collector"* && "$html" != *"WebTrack.gif"* && "$html" != *"uni-stat"* ]] || fail "mobile H5 includes uni statistics runtime"
|
||
[[ "$html" != *"/h5/h5/"* ]] || fail "mobile H5 has duplicated /h5 base path"
|
||
href="$(printf '%s' "$html" | sed -nE 's/.*<link rel="icon" href="([^"]+)".*/\1/p' | head -n 1)"
|
||
[[ -n "$href" ]] || fail "mobile H5 missing favicon link"
|
||
[[ "$href" == /* ]] || fail "mobile H5 favicon must use an absolute path"
|
||
icon_url="${MOBILE_URL%/}${href}"
|
||
code="$(curl -k -sS -o /tmp/wygj-demo-check.favicon -w '%{http_code}' "$icon_url")"
|
||
[[ "$code" == "200" ]] || fail "mobile H5 favicon returned HTTP $code: $icon_url"
|
||
contains mobile-uni/src/manifest.json '"enable": false'
|
||
echo "OK: mobile H5 shell"
|
||
}
|
||
|
||
pilot_sql_scalar() {
|
||
local database="${AIHR_PILOT_DB:-ry-vue}"
|
||
[[ "$database" =~ ^[A-Za-z0-9_-]+$ ]] || fail "invalid AIHR_PILOT_DB: $database"
|
||
docker exec wygj-mysql mysql -uroot -proot --default-character-set=utf8mb4 -N -B -D "$database" -e "$1" 2>/dev/null
|
||
}
|
||
|
||
check_pilot_samples() {
|
||
if ! command -v docker >/dev/null || ! docker ps --format '{{.Names}}' | grep -qx 'wygj-mysql'; then
|
||
[[ "${AIHR_PILOT_STRICT:-false}" != "true" ]] || fail "pilot DB sample counts unavailable (wygj-mysql not running)"
|
||
echo "SKIP: pilot DB sample counts (wygj-mysql not running)"
|
||
return
|
||
fi
|
||
|
||
if ! pilot_sql_scalar "SELECT 1" >/dev/null; then
|
||
[[ "${AIHR_PILOT_STRICT:-false}" != "true" ]] || fail "pilot DB sample counts unavailable (database connection failed)"
|
||
echo "SKIP: pilot DB sample counts (database connection failed)"
|
||
return
|
||
fi
|
||
|
||
if [[ "${AIHR_PILOT_STRICT:-false}" == "true" ]] && {
|
||
[[ -z "${AIHR_PILOT_START_DATE:-}" ]] || [[ -z "${AIHR_PILOT_END_DATE:-}" ]]
|
||
}; then
|
||
fail "strict pilot check requires AIHR_PILOT_START_DATE and AIHR_PILOT_END_DATE"
|
||
fi
|
||
|
||
local pilot_start="${AIHR_PILOT_START_DATE:-$(date +%F)}"
|
||
local pilot_end="${AIHR_PILOT_END_DATE:-$pilot_start}"
|
||
local pilot_tenant="${AIHR_PILOT_TENANT_ID:-000000}"
|
||
[[ "$pilot_tenant" =~ ^[A-Za-z0-9_-]+$ ]] || fail "invalid AIHR_PILOT_TENANT_ID: $pilot_tenant"
|
||
[[ "$pilot_start" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]] || fail "invalid AIHR_PILOT_START_DATE: $pilot_start"
|
||
[[ "$pilot_end" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]] || fail "invalid AIHR_PILOT_END_DATE: $pilot_end"
|
||
[[ "$(pilot_sql_scalar "SELECT DATE('$pilot_start') IS NOT NULL")" == "1" ]] || fail "invalid AIHR_PILOT_START_DATE: $pilot_start"
|
||
[[ "$(pilot_sql_scalar "SELECT DATE('$pilot_end') IS NOT NULL")" == "1" ]] || fail "invalid AIHR_PILOT_END_DATE: $pilot_end"
|
||
[[ "$pilot_start" > "$pilot_end" ]] && fail "pilot start date must not be after end date"
|
||
|
||
local scenario_count scenario_service_promotion_count scenario_daily_service_count rubric_expected_count rubric_five_dimension_count completed_people pilot_people org_active org_phone_linked org_hire_date_linked org_pilot_people org_pilot_projects org_completed_people audio_table_count audio_upload_table_count case_media_schema_count practice_session_schema_count daily_drill_schema_count prompt_version_schema_count requester_identity_schema_count hire_date_schema_count sop_document_count case_stored_count case_unmasked_count
|
||
local calibration_stats calibration_count calibration_matched sop_total sop_usable sop_pending satisfaction_count satisfaction_average
|
||
local org_identity_cte="
|
||
WITH active_org AS (
|
||
SELECT DISTINCT ext_party_id, project_code, person_phone
|
||
FROM aihr_org_snapshot
|
||
WHERE tenant_id = '$pilot_tenant' AND employment_status = 'active'
|
||
AND person_phone IS NOT NULL AND person_phone <> ''
|
||
), all_org_keys AS (
|
||
SELECT ext_party_id AS identity_key, ext_party_id
|
||
FROM active_org
|
||
WHERE ext_party_id IS NOT NULL AND ext_party_id <> ''
|
||
UNION ALL
|
||
SELECT person_phone AS identity_key, ext_party_id
|
||
FROM active_org
|
||
), conflict_keys AS (
|
||
SELECT identity_key
|
||
FROM all_org_keys
|
||
GROUP BY identity_key
|
||
HAVING COUNT(DISTINCT ext_party_id) > 1
|
||
), unsafe_org AS (
|
||
SELECT DISTINCT k.ext_party_id
|
||
FROM all_org_keys k
|
||
JOIN conflict_keys c ON c.identity_key = k.identity_key
|
||
), safe_org AS (
|
||
SELECT o.ext_party_id, o.project_code, o.person_phone
|
||
FROM active_org o
|
||
LEFT JOIN unsafe_org u ON u.ext_party_id = o.ext_party_id
|
||
WHERE u.ext_party_id IS NULL
|
||
), org_key_candidates AS (
|
||
SELECT ext_party_id AS identity_key, ext_party_id
|
||
FROM safe_org
|
||
WHERE ext_party_id IS NOT NULL AND ext_party_id <> ''
|
||
UNION ALL
|
||
SELECT person_phone AS identity_key, ext_party_id
|
||
FROM safe_org
|
||
), org_identity AS (
|
||
SELECT identity_key, MIN(ext_party_id) AS ext_party_id
|
||
FROM org_key_candidates
|
||
GROUP BY identity_key
|
||
HAVING COUNT(DISTINCT ext_party_id) = 1
|
||
)"
|
||
scenario_count="$(pilot_sql_scalar "SELECT COUNT(*) FROM aihr_practice_scenario WHERE tenant_id = '$pilot_tenant' AND position = '生活顾问' AND enabled = 1")"
|
||
# ponytail: presence-only core-flow gate; content quality and SOP applicability still require HR review.
|
||
scenario_service_promotion_count="$(pilot_sql_scalar "SELECT COUNT(*) FROM aihr_practice_scenario WHERE tenant_id = '$pilot_tenant' AND position = '生活顾问' AND enabled = 1 AND (scenario_type LIKE '%推介%' OR scenario_type LIKE '%增值%' OR scenario_name LIKE '%推介%' OR scenario_name LIKE '%增值%')")"
|
||
scenario_daily_service_count="$(pilot_sql_scalar "SELECT COUNT(*) FROM aihr_practice_scenario WHERE tenant_id = '$pilot_tenant' AND position = '生活顾问' AND enabled = 1 AND (scenario_type LIKE '%日常%' OR scenario_name LIKE '%日常%')")"
|
||
rubric_expected_count="$(pilot_sql_scalar "SELECT COUNT(*) FROM aihr_practice_rubric r JOIN aihr_practice_scenario s ON s.tenant_id = r.tenant_id AND s.scenario_code = r.scenario_code WHERE r.tenant_id = '$pilot_tenant' AND s.position = '生活顾问' AND s.enabled = 1 AND r.enabled = 1")"
|
||
rubric_five_dimension_count="$(pilot_sql_scalar "
|
||
SELECT COUNT(*)
|
||
FROM (
|
||
SELECT r.rubric_code
|
||
FROM aihr_practice_rubric r
|
||
JOIN aihr_practice_scenario s ON s.tenant_id = r.tenant_id AND s.scenario_code = r.scenario_code
|
||
JOIN aihr_practice_rubric_dimension d ON d.tenant_id = r.tenant_id AND d.rubric_code = r.rubric_code
|
||
WHERE r.tenant_id = '$pilot_tenant' AND s.position = '生活顾问' AND s.enabled = 1 AND r.enabled = 1
|
||
GROUP BY r.rubric_code
|
||
HAVING COUNT(*) = 5 AND ABS(SUM(d.weight) - 1.00) < 0.001
|
||
) ready_rubrics")"
|
||
audio_table_count="$(pilot_sql_scalar "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name = 'aihr_practice_audio'")"
|
||
audio_upload_table_count="$(pilot_sql_scalar "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name = 'aihr_practice_audio_upload'")"
|
||
case_media_schema_count="$(pilot_sql_scalar "SELECT COUNT(*) FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'aihr_case_record' AND column_name IN ('media_oss_id','media_url')")"
|
||
practice_session_schema_count="$(pilot_sql_scalar "SELECT COUNT(*) FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'aihr_practice_session' AND column_name IN ('dim_task_completion','dim_response_timeliness','response_latency_ms','annotations_json','review_advice','incentive_point','satisfaction_score','satisfaction_comment')")"
|
||
daily_drill_schema_count="$(pilot_sql_scalar "SELECT COUNT(*) FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'aihr_practice_assignment' AND column_name IN ('answer_text','feedback','correct','finished_time','score','score_mode')")"
|
||
prompt_version_schema_count="$(pilot_sql_scalar "SELECT COUNT(*) FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'aihr_sop_answer_review' AND column_name = 'prompt_version'")"
|
||
requester_identity_schema_count="$(pilot_sql_scalar "SELECT COUNT(*) FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'aihr_sop_answer_review' AND column_name = 'requester_ext_party_id'")"
|
||
hire_date_schema_count="$(pilot_sql_scalar "SELECT COUNT(*) FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'aihr_org_snapshot' AND column_name = 'hire_date'")"
|
||
sop_document_count="$(pilot_sql_scalar "SELECT COUNT(*) FROM aihr_knowledge_attach WHERE tenant_id = '$pilot_tenant' AND type = 'sop' AND status = 2")"
|
||
case_stored_count="$(pilot_sql_scalar "SELECT COUNT(*) FROM aihr_case_record WHERE tenant_id = '$pilot_tenant' AND status = '已入库'")"
|
||
case_unmasked_count="$(pilot_sql_scalar "SELECT COUNT(*) FROM aihr_case_record WHERE tenant_id = '$pilot_tenant' AND status = '已入库' AND CONCAT_WS(' ', title, transcript, summary) REGEXP '1[3-9][0-9]{9}|[[:alnum:]._%+-]+@[[:alnum:].-]+\\.[[:alpha:]]{2,}|[0-9]{1,2}(栋|幢|号楼|单元)[0-9]{3,4}|[0-9]{1,2}[--][0-9]{3,4}'")"
|
||
completed_people="$(pilot_sql_scalar "
|
||
SELECT COUNT(*)
|
||
FROM (
|
||
SELECT ext_party_id
|
||
FROM aihr_practice_session
|
||
WHERE tenant_id = '$pilot_tenant' AND mode = 'mobile'
|
||
AND finished_time >= '${pilot_start} 00:00:00'
|
||
AND finished_time < DATE_ADD('${pilot_end}', INTERVAL 1 DAY)
|
||
GROUP BY ext_party_id
|
||
HAVING COUNT(*) >= 10
|
||
) completed_people")"
|
||
pilot_people="$(pilot_sql_scalar "
|
||
SELECT COUNT(*)
|
||
FROM (
|
||
SELECT ext_party_id
|
||
FROM aihr_practice_session
|
||
WHERE tenant_id = '$pilot_tenant' AND mode = 'mobile'
|
||
AND finished_time >= '${pilot_start} 00:00:00'
|
||
AND finished_time < DATE_ADD('${pilot_end}', INTERVAL 1 DAY)
|
||
UNION
|
||
SELECT ext_party_id
|
||
FROM aihr_practice_assignment
|
||
WHERE tenant_id = '$pilot_tenant'
|
||
AND create_time >= '${pilot_start} 00:00:00'
|
||
AND create_time < DATE_ADD('${pilot_end}', INTERVAL 1 DAY)
|
||
) pilot_people")"
|
||
org_active="$(pilot_sql_scalar "SELECT COUNT(*) FROM aihr_org_snapshot WHERE tenant_id = '$pilot_tenant' AND employment_status = 'active'")"
|
||
org_phone_linked="$(pilot_sql_scalar "$org_identity_cte
|
||
SELECT COUNT(DISTINCT ext_party_id)
|
||
FROM safe_org")"
|
||
if (( hire_date_schema_count == 1 )); then
|
||
org_hire_date_linked="$(pilot_sql_scalar "$org_identity_cte
|
||
SELECT COUNT(DISTINCT s.ext_party_id)
|
||
FROM safe_org s
|
||
JOIN aihr_org_snapshot o ON o.tenant_id = '$pilot_tenant' AND o.ext_party_id = s.ext_party_id
|
||
WHERE o.employment_status = 'active' AND o.hire_date IS NOT NULL")"
|
||
else
|
||
org_hire_date_linked=0
|
||
fi
|
||
org_pilot_people="$(pilot_sql_scalar "
|
||
$org_identity_cte,
|
||
pilot_identity AS (
|
||
SELECT ext_party_id identity_key
|
||
FROM aihr_practice_session
|
||
WHERE tenant_id = '$pilot_tenant' AND mode = 'mobile'
|
||
AND finished_time >= '${pilot_start} 00:00:00'
|
||
AND finished_time < DATE_ADD('${pilot_end}', INTERVAL 1 DAY)
|
||
UNION
|
||
SELECT ext_party_id identity_key
|
||
FROM aihr_practice_assignment
|
||
WHERE tenant_id = '$pilot_tenant'
|
||
AND create_time >= '${pilot_start} 00:00:00'
|
||
AND create_time < DATE_ADD('${pilot_end}', INTERVAL 1 DAY)
|
||
)
|
||
SELECT COUNT(DISTINCT o.ext_party_id)
|
||
FROM pilot_identity p
|
||
JOIN org_identity o ON o.identity_key = p.identity_key")"
|
||
org_pilot_projects="$(pilot_sql_scalar "
|
||
$org_identity_cte,
|
||
pilot_identity AS (
|
||
SELECT ext_party_id identity_key
|
||
FROM aihr_practice_session
|
||
WHERE tenant_id = '$pilot_tenant' AND mode = 'mobile'
|
||
AND finished_time >= '${pilot_start} 00:00:00'
|
||
AND finished_time < DATE_ADD('${pilot_end}', INTERVAL 1 DAY)
|
||
UNION
|
||
SELECT ext_party_id identity_key
|
||
FROM aihr_practice_assignment
|
||
WHERE tenant_id = '$pilot_tenant'
|
||
AND create_time >= '${pilot_start} 00:00:00'
|
||
AND create_time < DATE_ADD('${pilot_end}', INTERVAL 1 DAY)
|
||
), pilot_org AS (
|
||
SELECT DISTINCT o.ext_party_id
|
||
FROM pilot_identity p
|
||
JOIN org_identity o ON o.identity_key = p.identity_key
|
||
)
|
||
SELECT COUNT(DISTINCT o.project_code)
|
||
FROM pilot_org p
|
||
JOIN safe_org o ON o.ext_party_id = p.ext_party_id
|
||
WHERE o.project_code IS NOT NULL AND o.project_code <> ''")"
|
||
org_completed_people="$(pilot_sql_scalar "
|
||
$org_identity_cte,
|
||
session_identity AS (
|
||
SELECT ext_party_id AS identity_key, COUNT(*) AS session_count
|
||
FROM aihr_practice_session
|
||
WHERE tenant_id = '$pilot_tenant' AND mode = 'mobile'
|
||
AND finished_time >= '${pilot_start} 00:00:00'
|
||
AND finished_time < DATE_ADD('${pilot_end}', INTERVAL 1 DAY)
|
||
GROUP BY ext_party_id
|
||
), completed_org AS (
|
||
SELECT o.ext_party_id
|
||
FROM session_identity s
|
||
JOIN org_identity o ON o.identity_key = s.identity_key
|
||
GROUP BY o.ext_party_id
|
||
HAVING SUM(s.session_count) >= 10
|
||
)
|
||
SELECT COUNT(*)
|
||
FROM completed_org")"
|
||
calibration_stats="$(pilot_sql_scalar "
|
||
$org_identity_cte,
|
||
formal_sessions AS (
|
||
SELECT s.session_id
|
||
FROM aihr_practice_session s
|
||
JOIN org_identity o ON o.identity_key = s.ext_party_id
|
||
WHERE s.tenant_id = '$pilot_tenant' AND s.mode = 'mobile'
|
||
AND s.finished_time >= '${pilot_start} 00:00:00'
|
||
AND s.finished_time < DATE_ADD('${pilot_end}', INTERVAL 1 DAY)
|
||
), latest_calibration AS (
|
||
SELECT c.session_id, MAX(c.id) AS id
|
||
FROM aihr_practice_calibration c
|
||
JOIN formal_sessions s ON s.session_id = c.session_id
|
||
WHERE c.tenant_id = '$pilot_tenant' AND c.original_score IS NOT NULL AND c.corrected_score IS NOT NULL
|
||
AND c.create_time >= '${pilot_start} 00:00:00'
|
||
AND c.create_time < DATE_ADD('${pilot_end}', INTERVAL 1 DAY)
|
||
GROUP BY c.session_id
|
||
)
|
||
SELECT COUNT(*) AS total,
|
||
COALESCE(SUM(CASE
|
||
WHEN (CASE WHEN c.original_score < 60 THEN 0 WHEN c.original_score < 75 THEN 1 WHEN c.original_score < 90 THEN 2 ELSE 3 END)
|
||
= (CASE WHEN c.corrected_score < 60 THEN 0 WHEN c.corrected_score < 75 THEN 1 WHEN c.corrected_score < 90 THEN 2 ELSE 3 END)
|
||
THEN 1 ELSE 0 END), 0) AS matched
|
||
FROM aihr_practice_calibration c
|
||
JOIN latest_calibration latest ON latest.id = c.id
|
||
WHERE c.tenant_id = '$pilot_tenant'")"
|
||
read -r calibration_count calibration_matched <<<"$calibration_stats"
|
||
sop_total="$(pilot_sql_scalar "SELECT COUNT(*) FROM aihr_sop_answer_review r WHERE r.tenant_id = '$pilot_tenant' AND r.status = '已评审' AND NULLIF(TRIM(r.requester_ext_party_id), '') IS NOT NULL AND EXISTS (SELECT 1 FROM aihr_org_snapshot o WHERE o.tenant_id = r.tenant_id AND o.employment_status = 'active' AND (o.ext_party_id = r.requester_ext_party_id OR o.person_phone = r.requester_ext_party_id)) AND (LOWER(TRIM(COALESCE(r.category, ''))) = 'sop' OR r.category LIKE '%SOP%') AND r.reviewed_time >= '${pilot_start} 00:00:00' AND r.reviewed_time < DATE_ADD('${pilot_end}', INTERVAL 1 DAY)")"
|
||
sop_usable="$(pilot_sql_scalar "SELECT COALESCE(SUM(CASE WHEN r.usable = 1 THEN 1 ELSE 0 END), 0) FROM aihr_sop_answer_review r WHERE r.tenant_id = '$pilot_tenant' AND r.status = '已评审' AND NULLIF(TRIM(r.requester_ext_party_id), '') IS NOT NULL AND EXISTS (SELECT 1 FROM aihr_org_snapshot o WHERE o.tenant_id = r.tenant_id AND o.employment_status = 'active' AND (o.ext_party_id = r.requester_ext_party_id OR o.person_phone = r.requester_ext_party_id)) AND (LOWER(TRIM(COALESCE(r.category, ''))) = 'sop' OR r.category LIKE '%SOP%') AND r.reviewed_time >= '${pilot_start} 00:00:00' AND r.reviewed_time < DATE_ADD('${pilot_end}', INTERVAL 1 DAY)")"
|
||
sop_pending="$(pilot_sql_scalar "SELECT COUNT(*) FROM aihr_sop_answer_review r WHERE r.tenant_id = '$pilot_tenant' AND r.status <> '已评审' AND NULLIF(TRIM(r.requester_ext_party_id), '') IS NOT NULL AND EXISTS (SELECT 1 FROM aihr_org_snapshot o WHERE o.tenant_id = r.tenant_id AND o.employment_status = 'active' AND (o.ext_party_id = r.requester_ext_party_id OR o.person_phone = r.requester_ext_party_id)) AND (LOWER(TRIM(COALESCE(r.category, ''))) = 'sop' OR r.category LIKE '%SOP%') AND r.create_time >= '${pilot_start} 00:00:00' AND r.create_time < DATE_ADD('${pilot_end}', INTERVAL 1 DAY)")"
|
||
satisfaction_count="$(pilot_sql_scalar "
|
||
$org_identity_cte,
|
||
formal_sessions AS (
|
||
SELECT s.satisfaction_score
|
||
FROM aihr_practice_session s
|
||
JOIN org_identity o ON o.identity_key = s.ext_party_id
|
||
WHERE s.tenant_id = '$pilot_tenant' AND s.mode = 'mobile'
|
||
AND s.finished_time >= '${pilot_start} 00:00:00'
|
||
AND s.finished_time < DATE_ADD('${pilot_end}', INTERVAL 1 DAY)
|
||
)
|
||
SELECT COUNT(*) FROM formal_sessions WHERE satisfaction_score IS NOT NULL")"
|
||
satisfaction_average="$(pilot_sql_scalar "
|
||
$org_identity_cte,
|
||
formal_sessions AS (
|
||
SELECT s.satisfaction_score
|
||
FROM aihr_practice_session s
|
||
JOIN org_identity o ON o.identity_key = s.ext_party_id
|
||
WHERE s.tenant_id = '$pilot_tenant' AND s.mode = 'mobile'
|
||
AND s.finished_time >= '${pilot_start} 00:00:00'
|
||
AND s.finished_time < DATE_ADD('${pilot_end}', INTERVAL 1 DAY)
|
||
)
|
||
SELECT COALESCE(ROUND(AVG(satisfaction_score), 1), 0) FROM formal_sessions WHERE satisfaction_score IS NOT NULL")"
|
||
echo "OK: pilot gates window=${pilot_start}..${pilot_end} scenarios=${scenario_count}/12 rubric_five_dimensions=${rubric_five_dimension_count}/${rubric_expected_count} core_flow=service_promotion:${scenario_service_promotion_count} daily_service:${scenario_daily_service_count} sop_docs=${sop_document_count}/5 stored_cases=${case_stored_count}/20 case_unmasked=${case_unmasked_count} ten_sessions=${completed_people}/${pilot_people} org_identity=${org_phone_linked}/${org_active} org_hire_date=${org_hire_date_linked}/${org_active} org_pilot=${org_pilot_people}/20 projects=${org_pilot_projects}/1-2 org_ten_sessions=${org_completed_people}/${org_pilot_people} calibration=${calibration_count}/20 consistency=${calibration_matched}/${calibration_count} sop_usable=${sop_usable}/${sop_total} sop_pending=${sop_pending} satisfaction=${satisfaction_average}/5 responses=${satisfaction_count} audio_schema=${audio_table_count} audio_upload_schema=${audio_upload_table_count} case_media_schema=${case_media_schema_count}/2 practice_session_schema=${practice_session_schema_count}/8 daily_drill_schema=${daily_drill_schema_count}/6 prompt_version_schema=${prompt_version_schema_count} requester_identity_schema=${requester_identity_schema_count} hire_date_schema=${hire_date_schema_count}"
|
||
|
||
[[ "${AIHR_PILOT_STRICT:-false}" != "true" ]] || {
|
||
(( scenario_count >= 12 )) || fail "pilot enabled scenarios ${scenario_count}/12"
|
||
(( rubric_expected_count >= scenario_count && rubric_five_dimension_count >= rubric_expected_count )) || fail "pilot five-dimension rubrics ${rubric_five_dimension_count}/${rubric_expected_count}"
|
||
(( scenario_service_promotion_count > 0 )) || fail "pilot service-promotion scenarios missing"
|
||
(( scenario_daily_service_count > 0 )) || fail "pilot daily-service scenarios missing"
|
||
(( sop_document_count >= 5 )) || fail "pilot residential SOP documents ${sop_document_count}/5"
|
||
(( case_stored_count >= 20 )) || fail "pilot stored cases ${case_stored_count}/20"
|
||
(( case_unmasked_count == 0 )) || fail "pilot stored cases contain unmasked known PII (${case_unmasked_count})"
|
||
(( audio_table_count == 1 )) || fail "pilot audio schema unavailable (aihr_practice_audio missing)"
|
||
(( audio_upload_table_count == 1 )) || fail "pilot audio staging schema unavailable (aihr_practice_audio_upload missing)"
|
||
(( case_media_schema_count == 2 )) || fail "pilot case media schema unavailable (aihr_case_record.media_oss_id/media_url missing)"
|
||
(( practice_session_schema_count == 8 )) || fail "pilot practice session schema incomplete (${practice_session_schema_count}/8)"
|
||
(( daily_drill_schema_count == 6 )) || fail "pilot daily drill schema incomplete (${daily_drill_schema_count}/6)"
|
||
(( prompt_version_schema_count == 1 )) || fail "pilot RAG traceability schema unavailable (aihr_sop_answer_review.prompt_version missing)"
|
||
(( requester_identity_schema_count == 1 )) || fail "pilot SOP requester identity schema unavailable (aihr_sop_answer_review.requester_ext_party_id missing)"
|
||
(( hire_date_schema_count == 1 )) || fail "pilot org hire_date schema unavailable"
|
||
(( org_phone_linked >= 20 )) || fail "pilot mobile-login org members ${org_phone_linked}/20 (active org ${org_active})"
|
||
(( org_hire_date_linked >= 20 )) || fail "pilot org hire_date identities ${org_hire_date_linked}/20"
|
||
(( org_pilot_people >= 20 )) || fail "pilot activity matched to active org ${org_pilot_people}/20"
|
||
(( org_pilot_projects >= 1 && org_pilot_projects <= 2 )) || fail "pilot project scope must be 1-2 projects (actual ${org_pilot_projects})"
|
||
(( org_completed_people * 100 >= org_pilot_people * 80 )) || fail "pilot org members with at least 10 completed sessions below 80% (${org_completed_people}/${org_pilot_people})"
|
||
(( calibration_count >= 20 )) || fail "pilot calibration samples ${calibration_count}/20"
|
||
(( calibration_matched * 100 >= calibration_count * 70 )) || fail "pilot AI/human band consistency below 70%"
|
||
(( sop_total > 0 )) || fail "pilot SOP review samples missing"
|
||
(( sop_usable * 100 >= sop_total * 80 )) || fail "pilot SOP usable rate below 80%"
|
||
(( satisfaction_count > 0 )) || fail "pilot satisfaction responses missing"
|
||
awk -v average="$satisfaction_average" 'BEGIN { exit !(average >= 4.0) }' || fail "pilot satisfaction average below 4/5"
|
||
}
|
||
}
|
||
|
||
if [[ "${AIHR_DEMO_CHECK_LIBRARY_ONLY:-false}" == "true" ]]; then
|
||
[[ "${AIHR_PILOT_STRICT:-false}" != "true" ]] || fail "AIHR_DEMO_CHECK_LIBRARY_ONLY cannot bypass strict pilot checks"
|
||
return 0 2>/dev/null || exit 0
|
||
fi
|
||
|
||
need curl
|
||
|
||
check_url "frontend" "$FRONTEND_URL/"
|
||
check_url "mobile-uni" "$MOBILE_URL/h5/"
|
||
check_mobile_h5_shell
|
||
contains docs/DEMO_ACCEPTANCE.md "capture-demo-screenshots.mjs"
|
||
contains scripts/capture-demo-screenshots.mjs "Page.captureScreenshot"
|
||
contains scripts/capture-demo-screenshots.mjs "wygj-ai-interview-flow.png"
|
||
|
||
tenant_payload="$(curl -k -fsS "$FRONTEND_URL/dev-api/auth/tenant/list")"
|
||
[[ "$tenant_payload" == *'"tenantId":"000000"'* ]] || fail "tenant list missing tenant 000000"
|
||
echo "OK: tenant list"
|
||
|
||
code_payload="$(curl -k -fsS "$FRONTEND_URL/dev-api/auth/code")"
|
||
[[ "$code_payload" == *'"uuid"'* ]] || fail "captcha response missing uuid"
|
||
echo "OK: captcha"
|
||
|
||
contains frontend/src/router/index.ts "/recruit/interview"
|
||
contains frontend/src/router/index.ts "/train/practice"
|
||
contains frontend/src/router/index.ts "/knowledge/cases"
|
||
contains frontend/src/router/index.ts "/knowledge/sop"
|
||
contains frontend/src/router/index.ts "/system/model"
|
||
contains frontend/src/router/index.ts "/admin/org-permission"
|
||
contains frontend/src/views/admin/org-permission.vue "dryRun ? '同步预检' : '执行同步'"
|
||
contains frontend/src/views/admin/org-permission.vue "组织同步接口不可用,请检查外部同步配置"
|
||
contains frontend/src/views/admin/org-permission.vue "row.personName || row.extPartyId"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrOrgSyncService.java "storeDisplayFields"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrOrgSyncService.java "rows.stream().filter(OrgRow::suspectText)"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrOrgSyncService.java "boolean suspectText = hasQuestionMark(projectName)"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrOrgSyncService.java "组织同步必须明确传 dryRun"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrOrgSyncController.java "@RequestBody(required = true)"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/test/java/org/dromara/aihr/service/AihrOrgSyncServiceTest.java "syncRequiresExplicitDryRunMode"
|
||
contains backend/ruoyi-admin/src/main/resources/application-prod.yml "store-display-fields: false"
|
||
|
||
contains mobile-uni/package.json "aihr-mobile-uni"
|
||
contains mobile-uni/src/pages.json "pages/user/today/index"
|
||
contains mobile-uni/src/pages.json "pages/user/learning/index"
|
||
contains mobile-uni/src/pages.json "pages/supervisor/index/index"
|
||
contains mobile-uni/src/pages.json "pages/candidate/index/index"
|
||
contains mobile-uni/src/pages.json "pages/candidate/interview/index"
|
||
contains mobile-uni/src/pages.json "pages/candidate/materials/index"
|
||
contains mobile-uni/src/pages.json "pages/candidate/progress/index"
|
||
contains mobile-uni/src/pages.json "pages/candidate/study/index"
|
||
contains mobile-uni/src/pages/auth/login/index.vue "/resource/sms/code"
|
||
contains mobile-uni/src/pages/auth/login/index.vue "/auth/mobile/sms-login"
|
||
contains mobile-uni/src/services/home.ts "/api/aihr/mobile/home/"
|
||
contains mobile-uni/src/services/home.ts "auth: isLoggedIn()"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrMobileSeedService.java "public HomeResponse publicHome(String role)"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrMobileController.java "return R.ok(mobileSeedService.publicHome(role))"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrMobileController.java "mobileSeedService.home(role, identity)"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrMobileController.java "!UserType.APP_USER.getUserType().equals(loginUser.getUserType())"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrMobileController.java "无权访问该录音"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrMobileController.java "supervisorRoleRequested"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "public MobileTeamMetrics mobileTeamMetrics(String supervisorExtPartyId)"
|
||
contains mobile-uni/src/services/practice.ts "/api/train/practice/start"
|
||
contains mobile-uni/src/services/practice.ts "/api/aihr/mobile/practice/history"
|
||
contains mobile-uni/src/services/practice.ts "/api/aihr/mobile/profile/promotion-evidence"
|
||
contains mobile-uni/src/pages/user/practice/index.vue "训练完成,主管端待复盘已更新"
|
||
contains mobile-uni/src/pages/user/profile/index.vue "人工贡献分"
|
||
contains mobile-uni/src/services/knowledge.ts "/api/knowledge/answer-feedback"
|
||
contains mobile-uni/src/pages/user/sop/index.vue "有帮助"
|
||
contains mobile-uni/src/pages/user/sop/index.vue "没解决"
|
||
contains mobile-uni/src/services/knowledge.ts "/api/knowledge/summary-card"
|
||
contains mobile-uni/src/services/knowledge.ts "/api/knowledge/position-sop"
|
||
contains mobile-uni/src/services/position.ts "removeStorageSync(roleKey)"
|
||
contains mobile-uni/src/services/position.ts "/api/aihr/mobile/me"
|
||
contains mobile-uni/src/services/position.ts "role === 'user' && isSupervisorRoute(requested)"
|
||
contains mobile-uni/src/services/case.ts "/api/knowledge/case/upload"
|
||
contains mobile-uni/src/services/case.ts "/api/knowledge/case/capabilities"
|
||
contains mobile-uni/src/services/case.ts "/api/knowledge/case/records/"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrCaseController.java "/records/{caseId}"
|
||
contains mobile-uni/src/services/candidate.ts "/api/recruit/interview/start"
|
||
contains mobile-uni/src/services/candidate.ts "/api/aihr/mobile/candidate/materials"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrCandidateMaterialController.java "候选人登录态无效"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrCandidateMaterialController.java "@SaCheckLogin"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrCandidateMaterialController.java "review(id, request, operator)"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrCandidateMaterialService.java "SUPPORTED_MATERIAL_EXTENSIONS"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrCandidateMaterialService.java "审核接口必须明确提交"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrCaseService.java "SUPPORTED_AUDIO_EXTENSIONS"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrInterviewController.java "@SaCheckLogin"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrSpeechController.java "@SaCheckLogin"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrCaseController.java "@SaCheckLogin"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrSopController.java "restrictDemoVerificationSource(request)"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrSopController.java "StpUtil.hasRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)"
|
||
contains mobile-uni/src/pages/candidate/interview/index.vue "startCandidateInterview"
|
||
contains mobile-uni/src/pages/candidate/materials/index.vue "uploadCandidateMaterial"
|
||
contains mobile-uni/src/pages/candidate/progress/index.vue "const loadPage = async () =>"
|
||
contains mobile-uni/src/pages/candidate/index/index.vue "clearData();"
|
||
contains mobile-uni/src/pages/candidate/materials/index.vue "clearData();"
|
||
contains mobile-uni/src/pages/candidate/progress/index.vue "const clearData = () =>"
|
||
contains mobile-uni/src/pages/candidate/study/index.vue "searchKnowledge"
|
||
contains mobile-uni/src/pages/user/learning/index.vue "岗位 SOP"
|
||
contains mobile-uni/src/pages/user/learning/index.vue "当前摘要不代表正式上岗资格"
|
||
contains mobile-uni/src/pages/user/learning/index.vue "岗位学习范围加载失败"
|
||
contains mobile-uni/src/pages/user/learning/index.vue "getPracticeAssignments"
|
||
contains mobile-uni/src/pages/user/learning/index.vue "searchKnowledge"
|
||
contains mobile-uni/src/pages/user/learning/index.vue "getPracticePrepCard"
|
||
contains frontend/src/views/recruit/interview.vue "建议复试"
|
||
contains frontend/src/views/recruit/interview.vue 'v-loading="recordsLoading"'
|
||
contains frontend/src/views/recruit/interview.vue "const recordsLoading = ref(true)"
|
||
contains frontend/src/views/train/practice.vue "导师改写"
|
||
contains frontend/src/views/train/practice.vue 'v-loading="recordsLoading"'
|
||
contains frontend/src/views/train/practice.vue "const records = ref<Array<(typeof baseRecords)[number]>>([])"
|
||
contains frontend/src/views/knowledge/cases.vue "真实语音"
|
||
contains frontend/src/views/knowledge/cases.vue 'v-loading="recordsLoading"'
|
||
contains frontend/src/views/knowledge/cases.vue "const records = ref<CaseRecord[]>([])"
|
||
contains frontend/src/views/knowledge/cases.vue "案例所属项目"
|
||
contains frontend/src/views/knowledge/cases.vue "请先选择案例所属项目"
|
||
contains backend/script/sql/update/aihr_20260714_case_media_mysql8.sql "media_oss_id"
|
||
contains backend/script/sql/update/aihr_20260714_case_media_mysql8.sql "media_url"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrCaseService.java "系统用户上传案例必须明确所属项目"
|
||
contains frontend/src/views/index.vue "核心流程覆盖待内容确认"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrDashboardService.java "核心流程覆盖待内容确认"
|
||
contains frontend/src/views/index.vue "不等于端到端验收"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrDashboardService.java "不等于端到端验收"
|
||
contains frontend/src/views/index.vue "正式试点身份待核对"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrDashboardService.java "正式试点身份待核对"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "TenantHelper.getTenantId()"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrOrgSyncService.java "TenantHelper.getTenantId()"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/test/java/org/dromara/aihr/service/AihrTenantContextContractTest.java "businessServicesUseDynamicTenantContext"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrDashboardService.java "String traineeExpression = storeDisplayFields"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "String nameExpression = !storeDisplayFields"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "PILOT_SESSION_ROWS_SQL.formatted(storeDisplayFields"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "private String persistedTraineeName"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "persistedTraineeName(extPartyId.matches"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "if (!orgSnapshotTableExists() && !isDemoProfile())"
|
||
contains frontend/src/views/index.vue "待同步"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrDashboardService.java "核心流程待确认"
|
||
contains frontend/src/views/knowledge/sop.vue "训练题已生成"
|
||
contains frontend/src/views/knowledge/sop.vue "不代表这些文档已真实入库"
|
||
contains frontend/src/views/knowledge/sop.vue "内置演示"
|
||
contains frontend/src/views/knowledge/sop.vue "apiResult.value?.records"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/domain/AihrSopDto.java "String source"
|
||
contains frontend/src/views/knowledge/processing.vue "当前显示演示数据,不代表真实库统计"
|
||
contains frontend/src/views/knowledge/cases.vue "不代表真实案例库数据"
|
||
contains frontend/src/views/recruit/interview.vue "不代表真实面试数据"
|
||
contains frontend/src/views/system/model/index.vue "调用优先级"
|
||
contains frontend/src/views/system/model/index.vue "提示词模板"
|
||
contains frontend/src/views/system/model/index.vue "不代表真实租户配置"
|
||
contains frontend/src/views/system/model/index.vue "不代表真实租户模板数据"
|
||
contains frontend/src/views/system/prompts.vue "保存并启用"
|
||
contains frontend/src/views/competency/growth.vue "学分规则(待 HR 配置)"
|
||
contains frontend/src/views/competency/growth.vue "规划参考,当前不生效"
|
||
contains frontend/src/views/competency/growth.vue "训练画像等级(参考)"
|
||
contains frontend/src/views/competency/growth.vue "人工贡献分"
|
||
contains frontend/src/views/train/reviews.vue "人工贡献分"
|
||
contains frontend/src/views/train/reviews.vue "incentivePoint: null as number | null"
|
||
contains frontend/src/views/train/reviews.vue "incentivePoint: reviewForm.incentivePoint ?? undefined"
|
||
contains frontend/src/views/competency/growth.vue "person.personName || person.extPartyId"
|
||
contains mobile-uni/src/pages/user/profile/index.vue "成长证据包(待人工复核)"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "训练画像参考等级"
|
||
contains frontend/src/router/index.ts "/system/prompts"
|
||
contains frontend/src/api/aihr/interview.ts "/api/recruit/interview/start"
|
||
contains frontend/src/api/aihr/interview.ts "/api/recruit/interview/candidate-links"
|
||
contains frontend/src/api/aihr/interview.ts "/records/\${encodeURIComponent(sessionId)}/review"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrInterviewController.java "/api/recruit/interview"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrInterviewController.java "无权查看面试记录"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrInterviewController.java "/records/{sessionId}/review"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrInterviewService.java "reviewed_score"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrInterviewController.java "interviewService.answer(request, currentAppUsername())"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrInterviewController.java "interviewService.finish(request, currentAppUsername())"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrInterviewService.java "面试会话不存在或无权访问"
|
||
contains frontend/src/views/recruit/interview.vue "人工复核 AI 面试结果"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrInterviewController.java "@SaCheckRole"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrInterviewService.java "aihr_candidate_employee_link"
|
||
contains frontend/src/api/aihr/practice.ts "/api/train/practice/start"
|
||
contains frontend/src/api/aihr/practice.ts "/api/aihr/prompt-templates"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrPracticeController.java "/api/train/practice"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrPracticeController.java "practiceSeedService.turn(request, currentAppUsername(), currentAppUserId())"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrPracticeController.java "practiceSeedService.finish(request, currentAppUsername())"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "训练会话不存在或无权访问"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "finished_time IS NOT NULL"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "人工校准必须明确填写总分"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrInterviewService.java "finished_time IS NOT NULL AND total_score IS NOT NULL"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrInterviewService.java "reviewed_score = NULL"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrInterviewService.java "请先完成全部面试回答"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrInterviewService.java "面试题不存在"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "noneMatch(AihrPracticeSeedService::canSeeProject)"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrPracticeController.java "@SaCheckLogin"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrPracticeController.java "sessions/{sessionId}/annotations"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrPracticeController.java "bindCalibrationReviewer(request)"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrMobileController.java "bindReviewOperator(request)"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrPromptTemplateController.java "/api/aihr/prompt-templates"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrPromptTemplateController.java "public R<List<PromptTemplateResponse>> list"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "mobileCompletedCount"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "任务完成度"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "响应时效"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "new DimensionResponse(\"响应时效\", \"待采集\""
|
||
contains frontend/src/views/train/practice.vue "label: '任务完成度'"
|
||
contains backend/script/sql/aihr_practice_mysql8.sql "task_completion"
|
||
contains backend/script/sql/update/aihr_20260714_practice_five_dimensions_mysql8.sql "aihr_brd_rubric_codes"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/domain/AihrPracticeDto.java "MistakeAggregateResponse"
|
||
contains mobile-uni/src/pages/supervisor/team/index.vue "团队错题本"
|
||
contains mobile-uni/src/types/api.ts "PracticeMistakeAggregate"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrMobileController.java "/practice/mistakes"
|
||
contains mobile-uni/src/pages/user/learning/index.vue "错题本"
|
||
contains mobile-uni/src/pages/user/learning/index.vue "mistakeFilters"
|
||
contains mobile-uni/src/pages/user/profile/index.vue "AI训练综合分仅作训练参考"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "aihr_practice_session"
|
||
contains backend/script/sql/aihr_practice_mysql8.sql "aihr_practice_scenario"
|
||
contains backend/script/sql/update/aihr_20260714_practice_catalog_schema_mysql8.sql "aihr_practice_rubric_dimension"
|
||
contains backend/script/sql/update/aihr_20260714_practice_brd_scenarios_mysql8.sql "service-promotion-needs"
|
||
contains backend/script/sql/update/aihr_20260714_practice_brd_scenarios_mysql8.sql "daily-service-followup"
|
||
contains backend/script/sql/update/aihr_20260714_brd_sop_seed_mysql8.sql "sop_service_promotion_v1"
|
||
contains backend/script/sql/update/aihr_20260714_brd_sop_seed_mysql8.sql "sop_daily_service_v1"
|
||
contains backend/script/sql/update/aihr_20260714_prompt_template_seed_mysql8.sql "summary_card"
|
||
contains backend/script/sql/aihr_practice_mysql8.sql "aihr_prompt_template"
|
||
contains backend/script/sql/aihr_practice_mysql8.sql "summary_card"
|
||
contains frontend/src/views/train/practice.vue "训练前预习卡"
|
||
contains frontend/src/views/train/practice.vue "Rubric 预览"
|
||
contains frontend/src/views/train/practice.vue "提示词模板"
|
||
contains frontend/src/views/train/practice.vue "导出试点CSV"
|
||
contains frontend/src/views/train/practice.vue "训练记录接口暂不可用,当前显示演示记录"
|
||
contains frontend/src/views/train/practice.vue "listPracticeReviews"
|
||
contains frontend/src/views/train/reviews.vue "导出试点 CSV"
|
||
contains frontend/src/views/train/reviews.vue "人工校准总分"
|
||
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 backend/script/sql/update/aihr_20260714_practice_evidence_mysql8.sql "aihr_practice_audio"
|
||
contains backend/script/sql/update/aihr_20260714_practice_evidence_mysql8.sql "aihr_practice_audio_upload"
|
||
contains backend/script/sql/update/aihr_20260714_practice_evidence_mysql8.sql "aihr_practice_calibration"
|
||
contains backend/script/sql/aihr_org_snapshot_mysql8.sql "hire_date"
|
||
contains backend/script/sql/update/aihr_20260714_org_hire_date_mysql8.sql "hire_date"
|
||
contains backend/script/sql/update/aihr_20260714_org_hire_date_mysql8.sql "aihr_org_snapshot_table_exists"
|
||
contains backend/script/sql/update/aihr_20260714_sop_requester_identity_mysql8.sql "aihr_sop_source_exists"
|
||
contains backend/script/sql/update/aihr_20260714_sop_requester_identity_mysql8.sql "aihr_sop_prompt_version_exists"
|
||
contains scripts/tests/aihr-schema-migrations.test.sh "AIHR legacy schema migrations are idempotent"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrOrgSyncService.java "hireDate"
|
||
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/controller/AihrModelController.java "@SaCheckRole"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrSopController.java "@SaCheckRole"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/domain/AihrSopDto.java "String position"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrSopController.java "/position-sop"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrSopController.java "@SaIgnore"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrDashboardController.java "@SaCheckLogin"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrDashboardController.java "@SaCheckRole"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrSopSeedService.java 'firstNonBlank(position, "生活顾问")'
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrSopSeedService.java "normalizeSearchSource"
|
||
contains frontend/src/views/train/practice.vue "practice_help"
|
||
contains mobile-uni/src/pages/user/practice/index.vue "loadHelp"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "turnEvidence"
|
||
contains mobile-uni/src/pages/user/practice/index.vue "每日三题"
|
||
contains mobile-uni/src/pages/user/practice/index.vue "每日一练语音已转成文字"
|
||
contains mobile-uni/src/pages/user/practice/index.vue "dailyAudioOssIds"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "answer_audio_oss_id"
|
||
contains backend/script/sql/aihr_practice_mysql8.sql "answer_audio_url"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "pilot_metric_ready"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrMobileController.java "/practice/satisfaction"
|
||
contains backend/script/sql/aihr_practice_mysql8.sql "satisfaction_score"
|
||
contains mobile-uni/src/services/practice.ts "/api/aihr/mobile/practice/satisfaction"
|
||
contains mobile-uni/src/pages/user/practice/index.vue "本次训练体验如何"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "incentive_point"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrModelSeedService.java "cost-guard-fallback"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrSpeechService.java "Duration.ofSeconds(5)"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrMobileSeedService.java "待复盘对练"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrMobileController.java "/practice/reviews"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrMobileController.java "StpUtil.hasRoleOr(TenantConstants.SUPER_ADMIN_ROLE_KEY, \"hr_operator\")"
|
||
contains mobile-uni/src/pages/supervisor/review/index.vue "人工贡献分"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrMobileController.java "/practice/reviews/{id}/reviewed"
|
||
contains mobile-uni/src/pages/supervisor/review/index.vue "标记已复盘"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "source = 'retry'"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "score_mode"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeLlmService.java "scoreDailyDrill"
|
||
contains backend/script/sql/update/aihr_20260714_daily_drill_score_mode_mysql8.sql "score_mode"
|
||
contains backend/script/sql/update/aihr_20260714_daily_drill_score_mode_mysql8.sql "ADD COLUMN score int"
|
||
contains mobile-uni/src/pages/user/practice/index.vue "AI语义评估"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java 'String source = "manual"'
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "训练场景已停用,无法开始"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "public PrepCardResponse prepCard(String scenarioId)"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "scenario.id(), scenario.name(), source"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "return rows;"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "isWithinNewHireWindow"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "allow-legacy-daily-drill-fallback"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "isLegacyDailyDrillFallbackEnabled"
|
||
contains backend/ruoyi-admin/src/main/resources/application-dev.yml "allow-legacy-daily-drill-fallback: true"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrOrgSyncService.java "instr(coalesce(person_name, '')"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "maskSensitiveText"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "validateAudioOwnership"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "d.answer_audio_oss_id = ?"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "stagePracticeAudio"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "cleanupExpiredPracticeAudioUploads"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrSpeechController.java "stagePracticeAudio"
|
||
contains mobile-uni/src/services/practice.ts "/api/aihr/mobile/practice/assignments"
|
||
contains mobile-uni/src/services/practice.ts "/api/train/practice/scenarios?position="
|
||
contains mobile-uni/src/pages/supervisor/assign/index.vue "scenarioOptions"
|
||
contains mobile-uni/src/pages/supervisor/assign/index.vue "暂无可派发的已启用场景"
|
||
contains mobile-uni/src/pages/supervisor/review/index.vue "scenarioOptions"
|
||
contains frontend/src/api/aihr/case.ts "/api/knowledge/case/upload"
|
||
contains frontend/src/api/aihr/case.ts "/api/knowledge/case/records?limit="
|
||
contains frontend/src/api/aihr/case.ts "/api/knowledge/case/records/"
|
||
contains frontend/src/views/knowledge/cases.vue "loadCaseRecords"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrCaseController.java "currentProjectScopes"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrCaseService.java "projectScopesForAppUser"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrCaseController.java "/api/knowledge/case"
|
||
contains frontend/src/api/aihr/sop.ts "/api/knowledge/search"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrSopController.java "@SaCheckLogin"
|
||
contains frontend/src/api/aihr/sop.ts "/api/knowledge/doc/upload"
|
||
contains frontend/src/api/aihr/sop.ts "/api/knowledge/reviews"
|
||
contains frontend/src/api/aihr/sop.ts "/api/knowledge/answer-feedback"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrSopController.java "reviewAnswerFeedback(id, operator)"
|
||
contains frontend/src/views/knowledge/sop.vue "SOP 问答评审已记录"
|
||
contains frontend/src/views/knowledge/sop.vue "答案待复核"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrSopController.java "/api/knowledge"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrSopController.java "/doc/upload"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrSopSeedService.java "仅支持 txt/md/markdown/pdf/doc/docx/xls/xlsx/ppt/pptx/图片文件"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrSopSeedService.java "/embeddings"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrSopSeedService.java "aihr_knowledge_gap"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrMultipartFiles.java "withOriginalFilename"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrCandidateMaterialService.java "AihrMultipartFiles.withOriginalFilename"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrCandidateMaterialService.java "deleteUploadedOssQuietly"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrCaseService.java "AihrMultipartFiles.withOriginalFilename"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrCaseService.java "cleanupFailedUpload"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrSopSeedService.java "AihrMultipartFiles.withOriginalFilename"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrSopSeedService.java "deleteUploadedOssQuietly"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrSpeechController.java "AihrMultipartFiles.withOriginalFilename"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrSopSeedService.java "o.tenant_id = a.tenant_id"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrSopSeedService.java "where tenant_id = ? and oss_id = ? limit 1"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrSopSeedService.java "deleteQdrantTenantPoints()"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrSopSeedService.java "/points/count"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrInterviewService.java "requireSessionTenant(session, tenantId())"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrInterviewService.java "private record InterviewSession(String tenantId"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "canReadPracticeAudioForTenant"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrMobileController.java "mobileSeedService.canReadPracticeAudioForTenant(ossId)"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrSpeechController.java "oss.getOssId(), \"\")"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrSpeechController.java "asr audio upload failed(处理错误已隐藏)"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrModelSeedService.java "visionAllowed"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrSopSeedService.java "!modelService.visionAllowed()"
|
||
contains backend/ruoyi-admin/src/main/java/org/dromara/web/controller/CaptchaController.java '!environment.acceptsProfiles(Profiles.of("prod"))'
|
||
contains backend/ruoyi-admin/src/test/java/org/dromara/web/controller/CaptchaControllerSecurityTest.java "CaptchaControllerSecurityTest"
|
||
contains backend/ruoyi-admin/src/main/resources/application-dev.yml "AIHR_MYSQL_PORT:13306"
|
||
contains backend/ruoyi-admin/src/main/resources/application-dev.yml "AIHR_REDIS_PORT:16379"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrOrgSyncService.java "person_phone like ?"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/test/java/org/dromara/aihr/service/AihrOrgSyncServiceTest.java "hiddenDisplayFieldsStillAllowIdentitySearchByPhone"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrSopSeedService.java "requester_ext_party_id"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrSopController.java "currentRequesterExtPartyId"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrSopSeedService.java "hasExplicitSopReviewDecision"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrSopSeedService.java "validateFeedbackFragmentOwnership"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrSopSeedService.java "normalizeFeedbackReviewId"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrSopSeedService.java "AND query_text = ?"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrVideoService.java "处理输出已隐藏"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrUploadQueueService.java "资料加工失败,请重试或联系管理员"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrSopSeedService.java "目录导入失败,请重试或联系管理员"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrSopSeedService.java "文件处理失败,请重试或联系管理员"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrCaseService.java "case audio upload failed(处理错误已隐藏)"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrSpeechController.java "tts audio upload failed(处理错误已隐藏)"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrSensitiveText.java "外部 AI 模型前"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrModelSeedService.java "AihrSensitiveText.forModel(prompt)"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrModelSeedService.java "外部响应体已隐藏"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrSopSeedService.java "AihrSensitiveText.forModel(renderPrompt"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrSpeechService.java "AihrSensitiveText.forModel(text.trim())"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrSpeechService.java "asr http {}(外部响应体已隐藏)"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrVideoService.java "AihrSensitiveText.forModel(fileName)"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrOrgSyncService.java "外部响应体已隐藏"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrCaseController.java "仅项目负责人或主管可提交案例素材"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrCaseController.java "@GetMapping(\"/capabilities\")"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrCaseController.java "StpUtil.hasRoleOr"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrCaseController.java "private boolean canViewCases()"
|
||
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 backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrInterviewService.java "候选人不存在,请先创建或完成一次面试记录"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrSopController.java "reviewSearch(id, request, operator)"
|
||
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"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrSopSeedService.java "prompt_version"
|
||
contains backend/script/sql/aihr_practice_mysql8.sql "prompt_version"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrSopSeedService.java "review_id"
|
||
contains mobile-uni/src/services/knowledge.ts "reviewId: params.reviewId"
|
||
contains backend/script/sql/aihr_knowledge_mysql8.sql "embedding_json"
|
||
contains frontend/src/views/knowledge/sop.vue "上传文档"
|
||
contains frontend/src/views/knowledge/sop.vue ".pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx"
|
||
contains docs/RUOYI_AI_INCREMENTAL_MIGRATION.md "ruoyi-ai"
|
||
contains docs/RUOYI_AI_INCREMENTAL_MIGRATION.md "POST /api/knowledge/doc/upload"
|
||
contains backend/script/sql/aihr_knowledge_mysql8.sql "aihr_knowledge_fragment"
|
||
contains backend/script/sql/aihr_model_mysql8.sql "aihr_model_config"
|
||
contains backend/script/sql/aihr_practice_mysql8.sql "aihr_practice_session"
|
||
contains backend/script/sql/aihr_practice_mysql8.sql "dialogue_json"
|
||
contains backend/script/sql/aihr_practice_mysql8.sql "incentive_point"
|
||
contains backend/script/sql/aihr_model_mysql8.sql "api_key"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrModelController.java "/api/aihr/model"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrModelController.java "/providers/{providerCode}"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrModelController.java "/configs/{id}/enabled"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrModelSeedService.java "aihr_model_provider"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrModelSeedService.java "模型调用失败,已回退内置兜底"
|
||
contains frontend/src/api/aihr/model.ts "/api/aihr/model/providers"
|
||
contains frontend/src/api/aihr/model.ts "/api/aihr/model/configs"
|
||
contains frontend/src/views/system/model/index.vue "submitProvider"
|
||
contains frontend/src/views/system/model/index.vue "submitModel"
|
||
contains backend/ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java "/mobile/sms-login"
|
||
contains backend/ruoyi-admin/src/main/java/org/dromara/web/controller/CaptchaController.java "aihr.sms.login-template-id"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrMobileController.java "/api/aihr/mobile"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrMobileController.java "@SaCheckLogin"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrMobileController.java "mobile identity lookup failed, fallback to employee role"
|
||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrMobileSeedService.java "candidateHome"
|
||
|
||
echo "OK: demo routes and real-flow markers"
|
||
echo "OK: AI interview API markers"
|
||
echo "OK: AI practice API markers"
|
||
echo "OK: AI case API markers"
|
||
echo "OK: AI SOP API markers"
|
||
echo "OK: ruoyi-ai incremental migration markers"
|
||
echo "OK: AI model migration markers"
|
||
echo "OK: AI model config page markers"
|
||
echo "OK: AI mobile role home markers"
|
||
check_pilot_samples
|
||
echo "PASS: demo preflight"
|