diff --git a/docs/BRD_IMPLEMENTATION_AUDIT.md b/docs/BRD_IMPLEMENTATION_AUDIT.md index 3fdf9ad2..606c5def 100644 --- a/docs/BRD_IMPLEMENTATION_AUDIT.md +++ b/docs/BRD_IMPLEMENTATION_AUDIT.md @@ -268,3 +268,4 @@ - 2026-07-14 BRD 4.3.4 每日三题生产 profile 硬门禁:旧回退即使被环境变量显式打开,仍可能在生产 profile 生效;现仅允许 `dev/local` profile 使用训练次数兼容回退,`prod` 或混合 profile 强制关闭。新增 profile 边界测试和 `demo-check` marker;未修改数据库结构或生产数据。 - 2026-07-14 BRD 6.3 SOP 来源标识修复:SOP 检索成功时前端原先忽略 API 返回的 `records`,后端返回的内置记录也没有来源字段,可能把演示文档显示成真实知识库;现 API 成功态只使用响应记录,内置记录明确标记 `source=demo`,失败/未检索态继续保留已有回退提示。未修改知识库数据或生产环境。 - 2026-07-14 当前线上资源复核:生产根站、`/h5/` 和 `/prod-api/auth/tenant/list` 均返回 `200`;线上管理端 `index-CJZ3Ax3Z.js` SHA-256 为 `8b9278a26ccb760abce489b12a20b221748c64d4c4153613d2511777bb9677bc`,当前分支构建 `index-B3bSjqdi.js` SHA-256 为 `2ff13b11307631f9cd672247d6d08e395fb674ac5b9c6f7c4fb27832eacdf075`;线上 H5 `index-D4-NrEpb.js` SHA-256 为 `ab15bfd17cabe58e2f34b0ac61ee198a837128ed85dc6bb0ddf77bc3e22dcd9c`,当前分支构建 `index-8gZKJTho.js` SHA-256 为 `c6b01faeba4198cb7ff9f5c2ffa88f1cc97c8ecdf20be86f432ca7a1d673f3e1`。本轮只读核验,未执行生产静态资源同步、后端重启或业务数据写入。 +- 2026-07-14 BRD 4.4 场景派发覆盖复核:数据库已有 12 个生活顾问场景,但移动端主管“指派专项”和“复盘后再练”此前只提供 3 个静态场景,导致其余已启用场景无法从主管入口使用;现改为 API 优先加载已启用场景,失败时保留 3 个本地兜底。BRD 所称 7–14 天专项训练营目前仍只有 `source='camp'` 标签,没有训练营计划、天数、每日任务、进度和完成规则,需 HR 确认内容与运营口径后再实现,不以标签冒充训练营闭环。 diff --git a/mobile-uni/src/pages/supervisor/assign/index.vue b/mobile-uni/src/pages/supervisor/assign/index.vue index c916579c..148bfb9b 100644 --- a/mobile-uni/src/pages/supervisor/assign/index.vue +++ b/mobile-uni/src/pages/supervisor/assign/index.vue @@ -122,7 +122,7 @@ import { onLoad, onShow } from '@dcloudio/uni-app'; import type { PracticeAlert, PracticeAssignment } from '@/types/api'; import { clearAuth, isLoggedIn, rememberLoginRedirect } from '@/services/auth'; import { resetPageScroll } from '@/services/navigation'; -import { createPracticeAssignment, getPracticeAlerts, getPracticeTeamSnapshot } from '@/services/practice'; +import { createPracticeAssignment, getPracticeAlerts, getPracticeScenarios, getPracticeTeamSnapshot } from '@/services/practice'; import SupervisorTabBar from '@/components/SupervisorTabBar.vue'; import { createAsyncGenerationGuard, @@ -130,6 +130,7 @@ import { isSupervisorAccessDenied, manualPracticeAssignments, supervisorScenarioOptions, + type SupervisorScenarioOption, type SupervisorScenarioId } from '@/services/supervisor-view'; @@ -137,6 +138,7 @@ const basePath = '/pages/supervisor/assign/index'; const targetExtPartyId = ref(''); const targetName = ref(''); const assignmentScenarioId = ref('fee-parking'); +const scenarioOptions = ref([...supervisorScenarioOptions]); const assignmentReason = ref(''); const assignments = ref([]); const alerts = ref([]); @@ -174,7 +176,7 @@ const queryText = (value: unknown) => { }; const isScenarioId = (value: string): value is SupervisorScenarioId => - supervisorScenarioOptions.some((item) => item.id === value); + scenarioOptions.value.some((item) => item.id === value); const refreshAuthState = () => { loggedIn.value = isLoggedIn(); @@ -240,6 +242,31 @@ const loadAssignments = async (force = false) => { } }; +const loadScenarioOptions = async () => { + try { + const rows = await getPracticeScenarios('生活顾问'); + const nextOptions = rows + .filter((item) => item.enabled !== false && item.id && item.name) + .map((item) => ({ id: item.id, name: item.name })); + if (nextOptions.length) { + scenarioOptions.value = nextOptions; + if (!isScenarioId(assignmentScenarioId.value)) { + assignmentScenarioId.value = nextOptions[0].id; + } + return; + } + scenarioOptions.value = [...supervisorScenarioOptions]; + if (!isScenarioId(assignmentScenarioId.value)) { + assignmentScenarioId.value = supervisorScenarioOptions[0].id; + } + } catch { + scenarioOptions.value = [...supervisorScenarioOptions]; + if (!isScenarioId(assignmentScenarioId.value)) { + assignmentScenarioId.value = supervisorScenarioOptions[0].id; + } + } +}; + const loadPage = () => { refreshAuthState(); message.value = ''; @@ -247,7 +274,7 @@ const loadPage = () => { clearPrivateState(); return; } - void loadAssignments(); + void Promise.all([loadAssignments(), loadScenarioOptions()]); }; const assignPractice = async () => { @@ -261,7 +288,7 @@ const assignPractice = async () => { assigning.value = true; message.value = ''; try { - const scenario = supervisorScenarioOptions.find((item) => item.id === assignmentScenarioId.value); + const scenario = scenarioOptions.value.find((item) => item.id === assignmentScenarioId.value); await createPracticeAssignment({ extPartyId, traineeName: targetName.value.trim() || `手机用户${extPartyId.slice(-4)}`, @@ -322,9 +349,7 @@ onLoad((query) => { targetName.value = queryText(query?.name); assignmentReason.value = queryText(query?.reason); const requestedScenario = queryText(query?.scenarioId); - assignmentScenarioId.value = isScenarioId(requestedScenario) - ? requestedScenario - : inferSupervisorScenarioId(assignmentReason.value); + assignmentScenarioId.value = requestedScenario || inferSupervisorScenarioId(assignmentReason.value); }); onShow(() => { diff --git a/mobile-uni/src/pages/supervisor/review/index.vue b/mobile-uni/src/pages/supervisor/review/index.vue index 75a26c99..b7ae94de 100644 --- a/mobile-uni/src/pages/supervisor/review/index.vue +++ b/mobile-uni/src/pages/supervisor/review/index.vue @@ -118,7 +118,7 @@ 暂不派发