From e834546d230cc57f811965add75937d6c9e16e6a Mon Sep 17 00:00:00 2001 From: let5sne Date: Tue, 14 Jul 2026 12:44:44 +0800 Subject: [PATCH] fix(aihr): clear stale candidate records on fetch failure --- docs/BRD_IMPLEMENTATION_AUDIT.md | 1 + mobile-uni/src/pages/candidate/index/index.vue | 1 + mobile-uni/src/pages/candidate/materials/index.vue | 1 + mobile-uni/src/pages/candidate/progress/index.vue | 6 ++++++ mobile-uni/tests/candidate-view.test.mjs | 12 ++++++++++++ scripts/demo-check.sh | 3 +++ 6 files changed, 24 insertions(+) diff --git a/docs/BRD_IMPLEMENTATION_AUDIT.md b/docs/BRD_IMPLEMENTATION_AUDIT.md index 7c8c087f..9916119c 100644 --- a/docs/BRD_IMPLEMENTATION_AUDIT.md +++ b/docs/BRD_IMPLEMENTATION_AUDIT.md @@ -244,3 +244,4 @@ - 2026-07-14 BRD 6.3 复盘与 SOP 数据来源复核:复盘页在试点指标接口失败时原先用待复盘记录数代替校准样本数,现改为显示未知并持久提示接口不可用;SOP 文档表继续保留断网演示样例,但为内置演示/已上传记录增加来源标识和提示,避免把演示文档或列表数量误当真实库覆盖与 M5 指标。 - 2026-07-14 BRD 6.3 对练记录回退语义复核:管理端三角色对练页原先始终显示三条静态最近记录,未请求真实复盘记录;现改为 API 优先,真实空列表保持为空,只有接口失败才显示演示记录并持续提示。当前会话完成后追加到现有列表,不再重置时覆盖历史记录。 - 2026-07-14 BRD 6.3 管理端记录首屏回退复核:面试、案例和三角色对练页此前在接口结果返回前就初始化内置 `baseRecords`,慢请求期间可能把演示记录误看成真实业务记录;现统一改为加载期间空表加 loading,只有接口明确失败后才展示演示记录并保留持久提示,真实空列表继续保持为空。补充 `demo-check` 静态标记,管理端 ESLint 与构建通过;本轮未发布生产。 +- 2026-07-14 BRD 6.3 候选人记录失效回退复核:首页、进度和资料页刷新接口失败时原先保留上一次成功结果,错误提示出现但旧面试/资料仍可被误读为当前状态;现统一在失败时清空失效数据,登录过期仍沿用原有跳转提示。补充候选端源码回归测试、`demo-check` 标记,`mobile-uni` 单测 `50/50`、类型检查和 H5 构建通过;本轮未发布生产。 diff --git a/mobile-uni/src/pages/candidate/index/index.vue b/mobile-uni/src/pages/candidate/index/index.vue index bec39a0f..1298db7d 100644 --- a/mobile-uni/src/pages/candidate/index/index.vue +++ b/mobile-uni/src/pages/candidate/index/index.vue @@ -168,6 +168,7 @@ const loadPage = async () => { materials.value = nextMaterials; records.value = nextRecords; } catch (error) { + clearData(); refreshAuthState(); if (!loggedIn.value) { clearData(); diff --git a/mobile-uni/src/pages/candidate/materials/index.vue b/mobile-uni/src/pages/candidate/materials/index.vue index 8e3e37f5..21d7c712 100644 --- a/mobile-uni/src/pages/candidate/materials/index.vue +++ b/mobile-uni/src/pages/candidate/materials/index.vue @@ -108,6 +108,7 @@ const loadMaterials = async () => { try { materials.value = await getCandidateMaterials(); } catch (error) { + clearData(); handleRequestError(error, '资料列表加载失败'); } finally { loading.value = false; diff --git a/mobile-uni/src/pages/candidate/progress/index.vue b/mobile-uni/src/pages/candidate/progress/index.vue index 99d2f830..f77c4b71 100644 --- a/mobile-uni/src/pages/candidate/progress/index.vue +++ b/mobile-uni/src/pages/candidate/progress/index.vue @@ -83,6 +83,11 @@ const reviewStatusDescription = computed(() => latestMaterial.value?.status === ? 'HR 已完成 AI 评分与补充资料复核,后续通知会同步更新。' : 'HR 正在复核 AI 评分与补充资料,预计 1-2 个工作日更新。'); +const clearData = () => { + records.value = []; + materials.value = []; +}; + const loadPage = async () => { loggedIn.value = isLoggedIn(); if (!loggedIn.value) { @@ -97,6 +102,7 @@ const loadPage = async () => { ]); message.value = ''; } catch (error) { + clearData(); loggedIn.value = isLoggedIn(); message.value = loggedIn.value ? (error instanceof Error ? error.message : '面试记录加载失败') : '登录已过期,请重新登录'; } diff --git a/mobile-uni/tests/candidate-view.test.mjs b/mobile-uni/tests/candidate-view.test.mjs index 39c76ffa..1c6203be 100644 --- a/mobile-uni/tests/candidate-view.test.mjs +++ b/mobile-uni/tests/candidate-view.test.mjs @@ -85,6 +85,18 @@ test('候选首页只做状态总览和独立页面分流', async () => { assert.doesNotMatch(source, /interviewQuestions/); }); +test('候选端刷新失败不保留上一轮真实记录', async () => { + const [home, materials, progress] = await Promise.all([ + pageSource('../src/pages/candidate/index/index.vue'), + pageSource('../src/pages/candidate/materials/index.vue'), + pageSource('../src/pages/candidate/progress/index.vue') + ]); + + assert.match(home, /catch \(error\) \{\n\s*clearData\(\);/); + assert.match(materials, /catch \(error\) \{\n\s*clearData\(\);/); + assert.match(progress, /catch \(error\) \{\n\s*clearData\(\);/); +}); + test('面试、资料、进度和预习页各自只承载一类真实任务', async () => { const [interview, materials, progress, study] = await Promise.all([ pageSource('../src/pages/candidate/interview/index.vue'), diff --git a/scripts/demo-check.sh b/scripts/demo-check.sh index 7e016824..693c3684 100755 --- a/scripts/demo-check.sh +++ b/scripts/demo-check.sh @@ -375,6 +375,9 @@ contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/control 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 "buildCandidateFlow" +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 "当前摘要不代表正式上岗资格"