From 4c5c343acaf1a1fd2dd9e3d7573d32b6ccef2d68 Mon Sep 17 00:00:00 2001
From: let5sne
Date: Sat, 4 Jul 2026 23:27:08 +0800
Subject: [PATCH 01/13] feat(aihr): structured digest answer with layered
mobile presentation
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
用户反馈「检索返回一堆文字不便总结」修复。后端:检索命中后新增
RAG 生成环节 searchDigest——chat 模型 temperature=0 把 top5 片段压
成结构化概要(直接回答≤60字+3-6条可执行要点+0-3条注意红线),硬约束
不得编造、片段答不了则明示无依据;模型未配置/超时/解析失败回退
片段原文拼接,15s 超时不拖垮检索。SearchResponse 增 keyPoints/
cautions 字段。移动端:sopPanel 结果改三层——概要卡(回答大字+要点
列表+警示色块)默认唯一展开;「查看依据」折叠原文片段,单条3行截断
点击展开;「听一遍」按钮把概要送 TTS 播报(独立播放状态,关面板即停,
未配 tts 提示降级)。候选人端知识 tab 同套概要卡+依据折叠,消除
原文倾泻。实测:「客服接待基础流程」4s 返回概要+5要点+3红线。
---
.../org/dromara/aihr/domain/AihrSopDto.java | 4 +-
.../aihr/service/AihrSopSeedService.java | 111 ++-
mobile/src/App.vue | 658 +++++++++++++-----
3 files changed, 613 insertions(+), 160 deletions(-)
diff --git a/backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/domain/AihrSopDto.java b/backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/domain/AihrSopDto.java
index a40f67c1..0780b77d 100644
--- a/backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/domain/AihrSopDto.java
+++ b/backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/domain/AihrSopDto.java
@@ -65,7 +65,9 @@ public final class AihrSopDto {
List docs,
List snippets,
List training,
- List records
+ List records,
+ List keyPoints,
+ List cautions
) {
}
diff --git a/backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrSopSeedService.java b/backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrSopSeedService.java
index 60d5424f..1f9a1786 100644
--- a/backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrSopSeedService.java
+++ b/backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrSopSeedService.java
@@ -123,7 +123,9 @@ public class AihrSopSeedService {
seed.docs(),
seed.snippets(),
seed.training(),
- records()
+ records(),
+ List.of(),
+ List.of()
);
}
@@ -1726,7 +1728,7 @@ public class AihrSopSeedService {
}
}
- private static SearchResponse responseFromHits(String category, String queryText, List hits) {
+ private SearchResponse responseFromHits(String category, String queryText, List hits) {
KnowledgeHit first = hits.get(0);
String responseCategory = isBlank(category) ? first.category() : category;
List snippets = hits.stream()
@@ -1736,18 +1738,119 @@ public class AihrSopSeedService {
for (KnowledgeHit hit : hits) {
docs.putIfAbsent(hit.title(), new DocResponse(hit.title(), hit.description(), "命中 " + scoreText(hit.score()), "pill-success"));
}
+ SearchDigest digest = searchDigest(queryText, hits);
return new SearchResponse(
queryText,
responseCategory,
- "根据已入库 SOP:" + first.content(),
+ digest != null ? digest.answer() : "根据已入库 SOP:" + first.content(),
"引用 " + docs.size() + " 份文档 / " + snippets.size() + " 个片段",
List.copyOf(docs.values()),
snippets,
List.of("题 1:请按命中 SOP 复述处理步骤。", "题 2:哪些信息必须留痕并可追溯?"),
- records()
+ records(),
+ digest != null ? digest.keyPoints() : List.of(),
+ digest != null ? digest.cautions() : List.of()
);
}
+ /**
+ * RAG 生成环节:把命中片段交给 chat 模型压成「直接回答+要点+注意事项」结构化概要。
+ * 模型未配置、超时或解析失败返回 null,由调用方回退片段原文拼接——检索永不因概要失败而报错。
+ */
+ private SearchDigest searchDigest(String queryText, List hits) {
+ Optional runtime = chatRuntime();
+ if (runtime.isEmpty()) {
+ return null;
+ }
+ StringBuilder context = new StringBuilder();
+ int index = 1;
+ for (KnowledgeHit hit : hits.stream().limit(5).toList()) {
+ context.append("片段").append(index++).append("(来源:").append(hit.title()).append("):\n")
+ .append(truncate(hit.content(), 1500)).append("\n\n");
+ }
+ try {
+ String content = callDigestModel(runtime.get(), queryText, context.toString());
+ JsonNode root = objectMapper.readTree(jsonObjectText(content));
+ String answer = root.path("answer").asText("");
+ if (isBlank(answer)) {
+ return null;
+ }
+ return new SearchDigest(
+ truncate(answer, 200),
+ jsonStrings(root.path("keyPoints"), 6, 120),
+ jsonStrings(root.path("cautions"), 3, 120)
+ );
+ } catch (Exception e) {
+ log.warn("search digest failed, keep raw answer: {}", e.getMessage());
+ return null;
+ }
+ }
+
+ private String callDigestModel(ChatRuntime runtime, String queryText, String context) throws Exception {
+ ObjectNode body = objectMapper.createObjectNode();
+ body.put("model", runtime.modelName());
+ body.put("temperature", 0);
+ body.put("stream", false);
+
+ ArrayNode messages = body.putArray("messages");
+ ObjectNode system = messages.addObject();
+ system.put("role", "system");
+ system.put("content", "你是物业一线员工的SOP助手。只返回 JSON,不要 markdown。字段固定为 answer, keyPoints, cautions。"
+ + "answer 是对问题的直接回答(不超过60字,含关键数字/时限);keyPoints 是3到6条可执行要点(每条一句话,含具体数字);"
+ + "cautions 是0到3条注意事项或红线。硬约束:只能基于给定片段内容作答,片段中没有的信息不得编造;"
+ + "若片段无法回答问题,answer 固定为「未在已入库 SOP 中找到明确依据」且 keyPoints 为空数组。");
+
+ ObjectNode user = messages.addObject();
+ user.put("role", "user");
+ user.put("content", """
+ 员工的问题:%s
+
+ 检索命中的 SOP 片段:
+ %s
+ """.formatted(queryText, context));
+
+ HttpRequest.Builder builder = HttpRequest.newBuilder()
+ .uri(URI.create(normalizeBaseUrl(runtime.baseUrl()) + "/chat/completions"))
+ .timeout(Duration.ofSeconds(15))
+ .header("Content-Type", "application/json")
+ .POST(HttpRequest.BodyPublishers.ofString(objectMapper.writeValueAsString(body)));
+ if (!isBlank(runtime.apiKey())) {
+ builder.header("Authorization", "Bearer " + runtime.apiKey());
+ }
+ HttpResponse response = HttpClient.newBuilder()
+ .connectTimeout(Duration.ofSeconds(10))
+ .build()
+ .send(builder.build(), HttpResponse.BodyHandlers.ofString());
+ if (!ok(response.statusCode())) {
+ throw new IllegalStateException("digest HTTP " + response.statusCode());
+ }
+ JsonNode choices = objectMapper.readTree(response.body()).path("choices");
+ if (!choices.isArray() || choices.isEmpty()) {
+ throw new IllegalStateException("digest response missing choices");
+ }
+ return choices.get(0).path("message").path("content").asText();
+ }
+
+ private static List jsonStrings(JsonNode node, int maxItems, int maxChars) {
+ if (!node.isArray()) {
+ return List.of();
+ }
+ List values = new ArrayList<>();
+ for (JsonNode item : node) {
+ String text = item.asText("").strip();
+ if (!text.isEmpty()) {
+ values.add(truncate(text, maxChars));
+ }
+ if (values.size() >= maxItems) {
+ break;
+ }
+ }
+ return List.copyOf(values);
+ }
+
+ private record SearchDigest(String answer, List keyPoints, List cautions) {
+ }
+
private static String dbCategory(String category) {
return "sop".equalsIgnoreCase(Optional.ofNullable(category).orElse("").trim()) ? "" : category;
}
diff --git a/mobile/src/App.vue b/mobile/src/App.vue
index 84c89245..17295742 100644
--- a/mobile/src/App.vue
+++ b/mobile/src/App.vue
@@ -52,7 +52,7 @@
-
+
- {{ reviewMessage }}
-
-
-
-
- {{ selectedReview.trainee }} · {{ selectedReview.score }}分
- {{ selectedReview.time }} · {{ selectedReview.scene }}
-
- {{ selectedReview.status }}
-
-
-
-
- {{ item.label }}
- {{ item.value }}
- {{ item.note }}
-
-
-
-
-
- {{ turn.label }}
- {{ turn.text }}
-
-
-
-
-
导师改写
-
{{ selectedReview.mentorRewrite }}
-
AI点评
-
{{ selectedReview.aiComment }}
-
-
-
-
{{ reviewMessage }}
-
@@ -192,7 +154,7 @@
-
+
{{ activeSupervisorPanel === 'assign' ? '建议指派对象' : '待复盘对练' }}
-
暂无待复盘记录
+
暂无待复盘记录
+
{{ reviewMessage }}
+
{{ selectedReview.trainee }} · {{ selectedReview.score }}分
@@ -239,7 +203,7 @@
{{ reviewMessage }}
-
+
专项建议
催费沟通专项
@@ -255,14 +219,26 @@
{{ knowledgeMessage }}
-
{{ knowledgeResult.answer }}
-
{{ knowledgeResult.reference }}
+
+
{{ knowledgeResult.answer }}
+
+ - {{ point }}
+
+
+
{{ knowledgeResult.reference }}
+
-
引用片段
-
- {{ item.title }}
- {{ item.text }}
-
+
+
+
+ {{ item.title }}
+ {{ item.text }}
+
+
@@ -345,44 +321,6 @@
-
-
- 三角色对练
- {{ practiceResult.totalScore }}分
- {{ practiceStatus === 'starting' ? '准备中' : '进行中' }}
-
-
-
-
{{ practiceResult.aiComment }}
-
{{ practiceResult.mentorRewrite }}
-
-
-
-
-
-
-
-
-
- {{ turn.label }}
- {{ turn.text }}
-
-
-
-
-
-
-
-
-
-
-
-
{{ practiceMessage }}
-
@@ -549,6 +487,9 @@
+
-
-
- 综合能力
- {{ competencyProfile.score }}
-
-
- 训练历史
- {{ competencyProfile.completed }}
-
-
- 待复盘
- {{ competencyProfile.pendingReview }}
-
-
-
- {{ item.label }}
- {{ item.value }}
- {{ item.note }}
-
-
-
-
-
-
训练历史
-
-
@@ -882,20 +791,44 @@
{{ sopRecording ? '停止录音' : sopAsrBusy ? '识别中' : sopUseAudioFileFallback ? '选择语音' : '语音提问' }}
-
+
{{ sopMessage }}
-
{{ sopResult.answer }}
-
{{ sopResult.reference }}
+
+
+ {{ sopResult.answer }}
+
+
+
+ - {{ point }}
+
+
+
{{ sopResult.reference }}
+
+
-
引用片段
-
- {{ item.title }}
- {{ item.text }}
-
+
+
+
+ {{ item.title }}
+ {{ item.text }}
+ 点击展开全文
+
+
@@ -1161,6 +1094,8 @@ interface KnowledgeSearchResponse {
snippets: KnowledgeSnippet[];
training: string[];
records: KnowledgeRecord[];
+ keyPoints?: string[];
+ cautions?: string[];
}
interface CaseTag {
@@ -1236,9 +1171,53 @@ const rolePaths: Record = {
supervisor: '/h5/supervisor'
};
+interface MobileRoute {
+ role: RoleKey;
+ page: string;
+ detail: string;
+}
+
+const pathParts = () => window.location.pathname.split('/').filter(Boolean);
const readRole = (): RoleKey => {
- const last = window.location.pathname.split('/').filter(Boolean).at(-1) || 'user';
- return aliases[last] || 'user';
+ const parts = pathParts();
+ const part = parts[0] === 'h5' ? parts[1] : parts.find((item) => aliases[item]);
+ return aliases[part || 'user'] || 'user';
+};
+
+const readRoute = (): MobileRoute => {
+ const parts = pathParts();
+ const offset = parts[0] === 'h5' ? 2 : 1;
+ return { role: readRole(), page: parts[offset] || '', detail: parts[offset + 1] || '' };
+};
+
+const userPanelSegments: Record, string> = {
+ tasks: 'training',
+ sop: 'knowledge',
+ cases: 'cases',
+ submit: 'submit',
+ profile: 'profile',
+ history: 'history',
+ recommend: 'recommend'
+};
+
+const candidatePanelSegments: Record, string> = {
+ tasks: 'interview',
+ sop: 'sop',
+ cases: 'cases',
+ submit: 'materials',
+ profile: 'profile',
+ history: 'history',
+ recommend: 'recommend'
+};
+
+const supervisorPanelSegments: Record, string> = {
+ team: 'team',
+ reviews: 'reviews',
+ assign: 'assign',
+ weakness: 'weakness',
+ case: 'cases',
+ sop: 'sop',
+ profile: 'profile'
};
const clampPercent = (value: number) => `${Math.max(0, Math.min(value, 100))}%`;
@@ -1285,10 +1264,12 @@ const activeUserPanel = ref('');
const activeSupervisorPanel = ref('');
const knowledgeQuery = ref('住宅投诉处理流程');
const knowledgeResult = ref(null);
+const knowledgeSnippetsOpen = ref(false);
const knowledgeLoading = ref(false);
const knowledgeMessage = ref('');
const sopPanelOpen = ref(false);
const sopReturnTabLabel = ref('首页');
+const sopReturnPath = ref(rolePaths[roleKey.value]);
const sopQuery = ref('');
const sopResult = ref(null);
const sopLoading = ref(false);
@@ -1297,6 +1278,11 @@ const sopRecording = ref(false);
const sopAsrBusy = ref(false);
const sopUseAudioFileFallback = ref(false);
const sopAudioInput = ref();
+const sopSnippetsOpen = ref(false);
+const expandedSnippets = ref(new Set());
+const sopSpeaking = ref(false);
+const sopSpeakLoading = ref(false);
+let sopAudio: HTMLAudioElement | null = null;
const materialFile = ref(null);
const materialUploading = ref(false);
const materialMessage = ref('');
@@ -1313,8 +1299,19 @@ let recordedChunks: Blob[] = [];
let sopMediaRecorder: MediaRecorder | null = null;
let sopRecordedChunks: Blob[] = [];
let customerAudio: HTMLAudioElement | null = null;
+let applyingRoute = false;
-const syncPath = () => window.history.pushState({}, '', rolePaths[roleKey.value]);
+const navigatePath = (path: string, replace = false) => {
+ if (window.location.pathname === path) return;
+ window.history[replace ? 'replaceState' : 'pushState']({}, '', path);
+};
+const syncPath = () => navigatePath(rolePaths[roleKey.value]);
+const userPanelPath = (panel: UserPanelKey) =>
+ panel ? `${rolePaths.user}/${userPanelSegments[panel]}` : rolePaths.user;
+const candidatePanelPath = (panel: UserPanelKey) =>
+ panel ? `${rolePaths.candidate}/${candidatePanelSegments[panel]}` : rolePaths.candidate;
+const supervisorPanelPath = (panel: SupervisorPanelKey) =>
+ panel ? `${rolePaths.supervisor}/${supervisorPanelSegments[panel]}` : rolePaths.supervisor;
const scrollToTop = () => {
window.requestAnimationFrame(() => window.scrollTo({ top: 0 }));
};
@@ -1521,18 +1518,23 @@ const transcribeRecording = async (blob: Blob, filename = 'practice.webm') => {
const openSopPanel = () => {
sopReturnTabLabel.value = activeTabLabel.value;
+ sopReturnPath.value = window.location.pathname.endsWith('/sop') ? rolePaths[roleKey.value] : window.location.pathname;
sopPanelOpen.value = true;
sopQuery.value = '';
sopResult.value = null;
sopMessage.value = '';
+ navigatePath(`${rolePaths[roleKey.value]}/sop`);
};
const closeSopPanel = () => {
if (sopRecording.value) {
sopMediaRecorder?.stop();
}
+ stopSopSpeak();
sopPanelOpen.value = false;
activeTabLabel.value = sopReturnTabLabel.value;
+ navigatePath(sopReturnPath.value || rolePaths[roleKey.value]);
+ applyRouteFromLocation();
};
const toggleSopRecording = async () => {
@@ -1593,6 +1595,15 @@ const transcribeSopRecording = async (blob: Blob, filename = 'sop.webm') => {
}
};
+const openUserPracticePanel = () => {
+ activeTabLabel.value = '训练';
+ activeUserPanel.value = 'tasks';
+ userReviewDetail.value = null;
+ userReviewMessage.value = '';
+ navigatePath(userPanelPath('tasks'));
+ scrollToTop();
+};
+
const handlePrimaryAction = () => {
if (roleKey.value === 'candidate') {
void startCandidateInterview();
@@ -1602,9 +1613,55 @@ const handlePrimaryAction = () => {
tap(workerRole.value.primary.cta);
return;
}
+ openUserPracticePanel();
void startMobilePractice();
};
+const toggleSnippet = (index: number) => {
+ const next = new Set(expandedSnippets.value);
+ if (next.has(index)) {
+ next.delete(index);
+ } else {
+ next.add(index);
+ }
+ expandedSnippets.value = next;
+};
+
+const stopSopSpeak = () => {
+ sopAudio?.pause();
+ sopAudio = null;
+ sopSpeaking.value = false;
+};
+
+const toggleSopSpeak = async () => {
+ if (sopSpeaking.value) {
+ stopSopSpeak();
+ return;
+ }
+ const result = sopResult.value;
+ if (!result) return;
+ // 播报文本 = 直接回答 + 要点,TTS 上限 300 字,留余量截 280
+ const speech = [result.answer, ...(result.keyPoints || []).map((point, i) => `${i + 1}、${point}`)].join('。').slice(0, 280);
+ sopSpeakLoading.value = true;
+ try {
+ const data = await readApi<{ audioUrl: string }>(
+ await fetch('/dev-api/api/ai/tts', {
+ method: 'POST',
+ headers: apiHeaders(),
+ body: JSON.stringify({ text: speech, voice: '' })
+ })
+ );
+ sopAudio = new Audio(data.audioUrl);
+ sopAudio.onended = () => stopSopSpeak();
+ sopSpeaking.value = true;
+ void sopAudio.play().catch(() => stopSopSpeak());
+ } catch {
+ sopMessage.value = '语音播报暂不可用(需启用 tts 模型),可直接阅读上方概要';
+ } finally {
+ sopSpeakLoading.value = false;
+ }
+};
+
const searchSopKnowledge = async () => {
const cleaned = sopQuery.value.trim();
if (!cleaned) {
@@ -1615,8 +1672,12 @@ const searchSopKnowledge = async () => {
sopLoading.value = true;
sopMessage.value = '';
sopResult.value = null;
+ sopSnippetsOpen.value = false;
+ expandedSnippets.value = new Set();
+ stopSopSpeak();
const controller = new AbortController();
- const timeout = window.setTimeout(() => controller.abort(), 15000);
+ // 概要由 chat 模型生成,比纯检索多几秒,超时放宽到 25s
+ const timeout = window.setTimeout(() => controller.abort(), 25000);
try {
sopResult.value = await readApi(
await fetch('/dev-api/api/knowledge/search', {
@@ -1666,6 +1727,7 @@ const searchKnowledge = async (query = knowledgeQuery.value, category = activeUs
const switchKnowledgePanel = (panel: Extract) => {
activeTabLabel.value = '知识';
activeUserPanel.value = panel;
+ navigatePath(roleKey.value === 'candidate' ? candidatePanelPath(panel) : userPanelPath(panel));
knowledgeQuery.value =
panel === 'cases' ? '投诉接待优秀案例' : roleKey.value === 'candidate' ? '客服接待基础流程' : '住宅投诉处理流程';
void searchKnowledge(knowledgeQuery.value, panel === 'cases' ? 'case' : 'sop');
@@ -1694,6 +1756,7 @@ const openCandidateAction = (panel: UserPanelKey) => {
activeUserPanel.value = panel;
userReviewDetail.value = null;
userReviewMessage.value = '';
+ navigatePath(candidatePanelPath(panel));
scrollToTop();
if (panel === 'sop') {
@@ -1740,6 +1803,7 @@ const openUserAction = (panel: UserPanelKey) => {
activeUserPanel.value = panel;
userReviewDetail.value = null;
userReviewMessage.value = '';
+ navigatePath(userPanelPath(panel));
scrollToTop();
if (panel === 'cases') {
@@ -1786,6 +1850,7 @@ const openUserTool = (item: ToolItem) => {
}
if (item.title === '每日一练') {
+ openUserPracticePanel();
void startMobilePractice();
return;
}
@@ -1817,6 +1882,7 @@ const openSupervisorAction = (panel: SupervisorPanelKey) => {
({ team: '团队', reviews: '团队', assign: '团队', weakness: '团队', case: '案例', sop: '案例', profile: '我的' } as Partial>)[panel] || '首页';
activeSupervisorPanel.value = panel;
activeUserPanel.value = '';
+ navigatePath(supervisorPanelPath(panel));
scrollToTop();
if (panel === 'reviews' || panel === 'assign') {
void fetchPracticeData();
@@ -1863,6 +1929,7 @@ const openTab = (label: string) => {
activeSupervisorPanel.value = '';
activeUserPanel.value = '';
selectedReview.value = null;
+ syncPath();
return;
}
if (label === '团队') {
@@ -1884,6 +1951,7 @@ const openTab = (label: string) => {
activeUserPanel.value = '';
userReviewDetail.value = null;
userReviewMessage.value = '';
+ syncPath();
return;
}
if (label === '面试') {
@@ -1908,13 +1976,11 @@ const openTab = (label: string) => {
activeUserPanel.value = '';
userReviewDetail.value = null;
userReviewMessage.value = '';
+ syncPath();
return;
}
if (label === '训练') {
- activeUserPanel.value = 'tasks';
- userReviewDetail.value = null;
- userReviewMessage.value = '';
- void fetchPracticeData();
+ openUserAction('tasks');
return;
}
if (label === '知识') {
@@ -1928,12 +1994,52 @@ const openTab = (label: string) => {
tap(label);
};
+const loadUserReviewDetail = async (id: number) => {
+ userReviewDetail.value = null;
+ userReviewMessage.value = '';
+ try {
+ userReviewDetail.value = await readApi(
+ await fetch(`/dev-api/api/aihr/mobile/practice/reviews/${id}`, { headers: apiHeaders() })
+ );
+ } catch (error) {
+ userReviewMessage.value = error instanceof Error ? error.message : '训练复盘加载失败';
+ }
+};
+
+const reviewDetailFromRecord = (item: PracticeRecord): PracticeReviewDetail => ({
+ ...item,
+ mentorRewrite: `建议复盘时围绕这条记录继续追问:${item.summary}`,
+ aiComment: item.summary,
+ scoreItems: [
+ { label: '总分', value: item.score, note: '本条对练综合评分' }
+ ],
+ dialogue: [
+ { role: 'coach', label: 'AI教练', text: item.summary }
+ ]
+});
+
+const reviewDetailPlaceholder = (id: number): PracticeReviewDetail => ({
+ id,
+ time: '',
+ trainee: '复盘记录',
+ scene: '训练复盘',
+ score: 0,
+ status: '加载中',
+ summary: '正在加载复盘详情',
+ mentorRewrite: '正在加载导师改写',
+ aiComment: '正在加载AI点评',
+ scoreItems: [],
+ dialogue: []
+});
+
+
const openUserHistory = async (item: PracticeRecord) => {
activeTabLabel.value = '我的';
if (!item.id) {
activeUserPanel.value = 'history';
userReviewMessage.value = '这条训练记录暂无复盘详情';
userReviewDetail.value = null;
+ navigatePath(userPanelPath('history'));
scrollToTop();
return;
}
@@ -1941,14 +2047,9 @@ const openUserHistory = async (item: PracticeRecord) => {
activeUserPanel.value = 'history';
userReviewDetail.value = null;
userReviewMessage.value = '';
+ navigatePath(`${userPanelPath('history')}/${item.id}`);
scrollToTop();
- try {
- userReviewDetail.value = await readApi(
- await fetch(`/dev-api/api/aihr/mobile/practice/reviews/${item.id}`, { headers: apiHeaders() })
- );
- } catch (error) {
- userReviewMessage.value = error instanceof Error ? error.message : '训练复盘加载失败';
- }
+ await loadUserReviewDetail(item.id);
};
const handleMaterialFile = (event: Event) => {
@@ -2140,6 +2241,7 @@ const submitMobilePractice = async () => {
const startCandidateInterview = async () => {
activeUserPanel.value = 'tasks';
activeTabLabel.value = '面试';
+ navigatePath(candidatePanelPath('tasks'));
scrollToTop();
interviewStatus.value = 'starting';
interviewSessionId.value = '';
@@ -2203,23 +2305,44 @@ const finishCandidateInterview = async () => {
const goSupervisor = () => {
roleKey.value = 'supervisor';
+ activeTabLabel.value = '首页';
+ activeSupervisorPanel.value = '';
+ activeUserPanel.value = '';
syncPath();
void fetchMobileHome();
};
+const loadSupervisorReviewDetail = async (id: number) => {
+ reviewMessage.value = '';
+ try {
+ selectedReview.value = await readApi(
+ await fetch(`/dev-api/api/aihr/mobile/practice/reviews/${id}`, { headers: apiHeaders() })
+ );
+ } catch (error) {
+ reviewMessage.value = error instanceof Error ? error.message : '复盘详情加载失败';
+ }
+};
+
const openPracticeReview = async (item: PracticeRecord) => {
if (!item.id) {
tap(item.trainee);
return;
}
+ activeTabLabel.value = '团队';
+ activeSupervisorPanel.value = 'reviews';
+ activeUserPanel.value = '';
+ selectedReview.value = reviewDetailFromRecord(item);
reviewMessage.value = '';
- try {
- selectedReview.value = await readApi(
- await fetch(`/dev-api/api/aihr/mobile/practice/reviews/${item.id}`, { headers: apiHeaders() })
- );
- } catch (error) {
- reviewMessage.value = error instanceof Error ? error.message : '复盘详情加载失败';
- }
+ navigatePath(`${supervisorPanelPath('reviews')}/${item.id}`);
+ scrollToTop();
+ await loadSupervisorReviewDetail(item.id);
+};
+
+const closeSupervisorReviewDetail = () => {
+ selectedReview.value = null;
+ reviewMessage.value = '';
+ navigatePath(supervisorPanelPath('reviews'));
+ scrollToTop();
};
const markReviewDone = async () => {
@@ -2304,10 +2427,6 @@ const loginBySms = async () => {
}
};
-window.addEventListener('popstate', () => {
- roleKey.value = readRole();
-});
-
const employeeTabs: TabItem[] = [
{ label: '首页', icon: 'home', active: true },
{ label: '训练', icon: 'graduation', active: false },
@@ -2501,9 +2620,130 @@ const fetchPracticeData = async () => {
}
};
+const applyRouteFromLocation = () => {
+ const route = readRoute();
+ applyingRoute = true;
+ roleKey.value = route.role;
+ activeTabLabel.value = '首页';
+ activeUserPanel.value = '';
+ activeSupervisorPanel.value = '';
+ selectedReview.value = null;
+ userReviewDetail.value = null;
+ reviewMessage.value = '';
+ userReviewMessage.value = '';
+ sopPanelOpen.value = false;
+
+ if (route.role === 'user') {
+ if (route.page === 'training') {
+ activeTabLabel.value = '训练';
+ activeUserPanel.value = 'tasks';
+ void fetchPracticeData();
+ } else if (route.page === 'knowledge') {
+ activeTabLabel.value = '知识';
+ activeUserPanel.value = 'sop';
+ knowledgeQuery.value = '住宅投诉处理流程';
+ void searchKnowledge(knowledgeQuery.value, 'sop');
+ } else if (route.page === 'cases') {
+ activeTabLabel.value = '知识';
+ activeUserPanel.value = 'cases';
+ knowledgeQuery.value = '投诉接待优秀案例';
+ void searchKnowledge(knowledgeQuery.value, 'case');
+ } else if (route.page === 'submit') {
+ activeTabLabel.value = '知识';
+ activeUserPanel.value = 'submit';
+ } else if (route.page === 'profile') {
+ activeTabLabel.value = '我的';
+ activeUserPanel.value = 'profile';
+ void fetchPracticeData();
+ } else if (route.page === 'history') {
+ activeTabLabel.value = '我的';
+ activeUserPanel.value = 'history';
+ void fetchPracticeData();
+ const id = Number(route.detail);
+ if (Number.isFinite(id) && id > 0) void loadUserReviewDetail(id);
+ } else if (route.page === 'recommend') {
+ activeTabLabel.value = '知识';
+ activeUserPanel.value = 'sop';
+ knowledgeQuery.value = '催费沟通专项';
+ void searchKnowledge(knowledgeQuery.value, 'sop');
+ } else if (route.page === 'sop') {
+ sopReturnTabLabel.value = '首页';
+ sopReturnPath.value = rolePaths.user;
+ sopPanelOpen.value = true;
+ }
+ } else if (route.role === 'candidate') {
+ if (route.page === 'interview') {
+ activeTabLabel.value = '面试';
+ activeUserPanel.value = 'tasks';
+ } else if (route.page === 'sop') {
+ activeTabLabel.value = '知识';
+ activeUserPanel.value = 'sop';
+ knowledgeQuery.value = '客服接待基础流程';
+ void searchKnowledge(knowledgeQuery.value, 'sop');
+ } else if (route.page === 'cases') {
+ activeTabLabel.value = '知识';
+ activeUserPanel.value = 'cases';
+ knowledgeQuery.value = '投诉接待优秀案例';
+ void searchKnowledge(knowledgeQuery.value, 'case');
+ } else if (route.page === 'materials') {
+ activeTabLabel.value = '我的';
+ activeUserPanel.value = 'submit';
+ void fetchCandidateMaterials();
+ } else if (route.page === 'profile') {
+ activeTabLabel.value = '我的';
+ activeUserPanel.value = 'profile';
+ void fetchCandidateMaterials();
+ } else if (route.page === 'recommend') {
+ activeTabLabel.value = '知识';
+ activeUserPanel.value = 'sop';
+ knowledgeQuery.value = '投诉接待基础';
+ void searchKnowledge(knowledgeQuery.value, 'sop');
+ }
+ } else if (route.role === 'supervisor') {
+ if (route.page === 'team') {
+ activeTabLabel.value = '团队';
+ activeSupervisorPanel.value = 'team';
+ } else if (route.page === 'reviews') {
+ activeTabLabel.value = '团队';
+ activeSupervisorPanel.value = 'reviews';
+ void fetchPracticeData();
+ const id = Number(route.detail);
+ if (Number.isFinite(id) && id > 0) {
+ selectedReview.value = reviewDetailPlaceholder(id);
+ void loadSupervisorReviewDetail(id);
+ }
+ } else if (route.page === 'assign') {
+ activeTabLabel.value = '团队';
+ activeSupervisorPanel.value = 'assign';
+ void fetchPracticeData();
+ } else if (route.page === 'weakness') {
+ activeTabLabel.value = '团队';
+ activeSupervisorPanel.value = 'weakness';
+ } else if (route.page === 'cases') {
+ activeTabLabel.value = '案例';
+ activeSupervisorPanel.value = 'case';
+ } else if (route.page === 'profile') {
+ activeTabLabel.value = '我的';
+ activeSupervisorPanel.value = 'profile';
+ } else if (route.page === 'sop') {
+ sopReturnTabLabel.value = '案例';
+ sopReturnPath.value = rolePaths.supervisor;
+ sopPanelOpen.value = true;
+ }
+ }
+
+ window.setTimeout(() => {
+ applyingRoute = false;
+ });
+ void fetchMobileHome();
+};
+
+window.addEventListener('popstate', applyRouteFromLocation);
+
watch(
roleKey,
() => {
+ if (applyingRoute) return;
apiHome.value = null;
reviewMessage.value = '';
userReviewMessage.value = '';
@@ -2529,6 +2769,8 @@ watch(
{ immediate: true }
);
+applyRouteFromLocation();
+
const role = computed(() => (apiHome.value?.role === roleKey.value ? apiHome.value : fallbackHomes[roleKey.value]));
const workerRole = computed(
() =>
@@ -3797,6 +4039,101 @@ p {
gap: 8px;
}
+.digest-card {
+ padding: 14px;
+ border-radius: 12px;
+ background: linear-gradient(160deg, rgba(35, 150, 133, 0.08), rgba(35, 150, 133, 0.02));
+ border: 1px solid rgba(35, 150, 133, 0.22);
+}
+
+.digest-head {
+ display: flex;
+ align-items: flex-start;
+ gap: 10px;
+}
+
+.digest-head strong,
+.digest-card > strong {
+ flex: 1;
+ display: block;
+ font-size: 16px;
+ line-height: 1.45;
+ color: var(--text-primary, #16323f);
+}
+
+.digest-speak {
+ flex-shrink: 0;
+ min-height: 32px;
+ padding: 0 12px;
+ border-radius: 16px;
+ border: 1px solid rgba(35, 150, 133, 0.45);
+ background: #ffffff;
+ color: #1f8a76;
+ font-size: 13px;
+ font-weight: 650;
+}
+
+.digest-points {
+ margin: 10px 0 0;
+ padding-left: 20px;
+ display: grid;
+ gap: 6px;
+ font-size: 14px;
+ line-height: 1.5;
+}
+
+.digest-cautions {
+ margin-top: 10px;
+ padding: 8px 10px;
+ border-radius: 8px;
+ background: rgba(240, 160, 32, 0.12);
+ border: 1px solid rgba(240, 160, 32, 0.35);
+}
+
+.digest-cautions p {
+ margin: 0;
+ font-size: 13px;
+ line-height: 1.5;
+ color: #9a6206;
+}
+
+.digest-cautions p + p {
+ margin-top: 4px;
+}
+
+.digest-reference {
+ margin: 10px 0 0;
+ font-size: 12px;
+ color: var(--text-secondary);
+}
+
+.snippet-toggle {
+ width: 100%;
+ min-height: 38px;
+ margin-top: 10px;
+ border-radius: 10px;
+ border: 1px dashed rgba(35, 150, 133, 0.4);
+ background: transparent;
+ color: #1f8a76;
+ font-size: 13px;
+ font-weight: 650;
+}
+
+.sop-result .snippet-list blockquote:not(.expanded) span {
+ display: -webkit-box;
+ -webkit-line-clamp: 3;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+}
+
+.sop-result .snippet-list blockquote em {
+ display: block;
+ margin-top: 6px;
+ font-size: 12px;
+ font-style: normal;
+ color: #1f8a76;
+}
+
.knowledge-tabs {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
@@ -4409,6 +4746,17 @@ p {
gap: 12px;
}
+.detail-back {
+ width: max-content;
+ min-height: 32px;
+ padding: 0 12px;
+ border-radius: 9px;
+ color: var(--primary-teal-active);
+ background: var(--primary-teal-light);
+ font-size: 12px;
+ font-weight: 800;
+}
+
.review-detail-head {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
@@ -4481,7 +4829,7 @@ p {
overflow: auto;
}
-.review-detail > button {
+.review-detail > button:not(.detail-back) {
min-height: 42px;
border-radius: 10px;
color: #ffffff;
@@ -4492,7 +4840,7 @@ p {
transition: var(--transition-spring);
}
-.review-detail > button:disabled {
+.review-detail > button:not(.detail-back):disabled {
color: var(--primary-teal-active);
background: var(--primary-teal-light);
box-shadow: none;
From 7c7a5b05d08a97c2a74c8a3a3852b1822dc2441b Mon Sep 17 00:00:00 2001
From: let5sne
Date: Sat, 4 Jul 2026 23:56:02 +0800
Subject: [PATCH 02/13] docs: capture 2026-07-04 user feedback analysis and
backlog updates
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
新增 feedback/2026070423/ANALYSIS.md:9 张反馈截图逐条解码(信息图
HTML 卡片/按钮触发小窗总结/页面必须切换/可点视觉分化/角色职责地图/
员工五段旅程/主管学习监工/四保一服场景/连贯语音对手戏/动作类知识
视频化/AI 分发决策),拔高为「数字师傅」定位与三个产品跃迁(媒介
匹配/经验资产库/语音对手戏),附行动清单。BACKLOG:B2 增补连贯语音
对手戏与四保一服场景维度,B4 优先级上调(表演型知识主媒介),新增
B8 数字师傅(学习旅程模块化+主管监控面板+个性化分发引擎+知识类型
维度)。
---
docs/BACKLOG.md | 16 ++++
docs/README.md | 3 +-
docs/feedback/2026070423/1.png | Bin 0 -> 588561 bytes
docs/feedback/2026070423/2.png | Bin 0 -> 236107 bytes
docs/feedback/2026070423/3.png | Bin 0 -> 191364 bytes
docs/feedback/2026070423/4.png | Bin 0 -> 140658 bytes
docs/feedback/2026070423/5.png | Bin 0 -> 229012 bytes
docs/feedback/2026070423/6.png | Bin 0 -> 155741 bytes
docs/feedback/2026070423/7.png | Bin 0 -> 350747 bytes
docs/feedback/2026070423/8.png | Bin 0 -> 353412 bytes
docs/feedback/2026070423/9.png | Bin 0 -> 207776 bytes
docs/feedback/2026070423/ANALYSIS.md | 119 +++++++++++++++++++++++++++
12 files changed, 137 insertions(+), 1 deletion(-)
create mode 100644 docs/feedback/2026070423/1.png
create mode 100644 docs/feedback/2026070423/2.png
create mode 100644 docs/feedback/2026070423/3.png
create mode 100644 docs/feedback/2026070423/4.png
create mode 100644 docs/feedback/2026070423/5.png
create mode 100644 docs/feedback/2026070423/6.png
create mode 100644 docs/feedback/2026070423/7.png
create mode 100644 docs/feedback/2026070423/8.png
create mode 100644 docs/feedback/2026070423/9.png
create mode 100644 docs/feedback/2026070423/ANALYSIS.md
diff --git a/docs/BACKLOG.md b/docs/BACKLOG.md
index 06e1429c..4d9da4dc 100644
--- a/docs/BACKLOG.md
+++ b/docs/BACKLOG.md
@@ -28,6 +28,9 @@
- 方言 → 粤语/川话预置音色,或语音克隆接口用 ~15s 真实录音复刻(方言 TTS 本来就在一期集成清单第 4 项)
- 吵架 → `emotion: angry` + `speed: 1.2`
- 求救听不清 → TTS 出 `emotion: sad/fearful` 底音 + ffmpeg 后期加噪/压音量/断续("信道劣化"无现成 API,后期处理最可控)
+- **2026-07-04 反馈增补**(截图见 `feedback/2026070423/`,解读见其 ANALYSIS.md):
+ - **连贯语音对手戏**:对练从"回合制答题"升级为实时情景对话——ASR→LLM(情绪人设+对话记忆)→TTS 低延迟循环,"很凶的老太太吵架"是验收场景;
+ - **场景库分四保一服**:保安/保洁/保绿/保修/客服按岗位出场景,启用 `practice_scenario.position/project_type` 字段,内容不混岗。
### B3. AI 一键生成场景培训图片(优先级 3)
@@ -48,6 +51,7 @@
2. **数字人口播**(案例讲解视频主力):腾讯智影 / 百度曦灵 / 硅基智能,按分钟计费,比文生视频便宜一个量级
3. **文生视频**(片头/场景氛围镜头):可灵 Kling / 火山即梦 Seedance / MiniMax 海螺 / 通义万相
- 选型倾向:二期先只接 **MiniMax 一家**打通(LLM + TTS + 文生图 + 视频一个 key 一套鉴权,对 2 人团队集成量最小,且同时覆盖 B2 语气声);视频质量不满意再单换可灵/即梦——全部封装在自有 provider 抽象后(参照 siliconflow embedding provider 先例)。
+- **2026-07-04 反馈:优先级上调**(解读见 `feedback/2026070423/ANALYSIS.md`)——视频不是"锦上添花的生成玩具",而是**表演型/动作类隐性知识的主传递媒介**(巡逻、查卫生、礼仪、上门催费:"几个人去、带什么、开口怎么说,经验上的东西没办法说,好的领导现场表演一遍,现在都可以用 AI 做出来")。切入点:催费上门等 1-2 条示范视频先行,验证价值再铺量。
### B5. 员工四维画像:训练时长 / 贡献度 / 测评分 / AI 等级
@@ -79,6 +83,18 @@
- 前置:火山引擎开户 + G3/G6 供应商合规评估;图片/视频资料成规模、以图搜图成为真实高频需求。
- 已做的替代缓解(2026-07-04):视频关键帧 caption(vision prompt 带画面描述)+ rerank(bge-reranker-v2-m3)已上线,覆盖大部分检索需求;B7 只补最后一段纯视觉语义。
+### B8. 数字师傅:学习旅程模块化 + 个性化分发引擎(2026-07-04 反馈,方向级)
+
+来源:2026-07-04 用户反馈(截图与完整解读见 `feedback/2026070423/ANALYSIS.md`)。核心洞察:系统的对标物是"会带人的老师傅"——把言传(话术语音)、身教(动作视频)、判断(该学什么)用 AI 规模化。
+
+三个子块,可独立排期:
+
+1. **员工端五段学习旅程模块化**:入职前面试考核 → 岗前培训 → **每日小训(5-10 分钟,独立模块)** → 棘手问题即时求助("发一个语音,给我两三个 SOP 或话术"——检索输出加话术层)→ 场景模拟。角色主页做成"职责地图"(板块化菜单,不是卡片流)。
+2. **主管端学习监控面板**:员工×活动(看了哪些视频/做了哪些互动)×时长×效果,衔接 B5 四维画像与视频观看时长统计(心跳+区间合并方案,见 2026-07-04 会话讨论)。
+3. **个性化分发引擎**(系统的大脑):岗位(四保一服)× 阶段(入职前/岗前/在岗)× 画像短板 → 决定"今天该看什么/练什么";内容多了以后分发比生产更难("用 AI 分析该让他们看到哪些东西")。闭环:AI 生产内容 → AI 匹配媒介 → AI 决定给谁看 → 数据回流画像。
+
+配套知识模型扩容:知识类型维度(SOP=标准 / 案例=参照 / 话术=直接能说 / 经验策略=火候),检索按类型分层供给;案例沉淀链路是隐性知识的采集入口,战略地位上调。
+
## Future Enhancements
### Model Classification Version Governance
diff --git a/docs/README.md b/docs/README.md
index dc2f9db0..899582b6 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -13,7 +13,8 @@
| [AI人力资源系统一期MVP版作战清单.md](AI人力资源系统一期MVP版作战清单.md) | MVP 作战图、切割线、排期、验收承诺 |
| [物业AI人力资源系统业务需求文档BRD.md](物业AI人力资源系统业务需求文档BRD.md) | 业务需求、范围边界、角色、风险与验收 |
| [物业AI人力资源系统开发规格TechSpec.md](物业AI人力资源系统开发规格TechSpec.md) | 工程结构、数据模型、页面路由、API 和核心实现规格 |
-| [BACKLOG.md](BACKLOG.md) | 需求池与延后事项(含 2026-07-03 甲方反馈 B1–B5:数据权限/人设语音/生成图片/生成视频/员工四维画像) |
+| [BACKLOG.md](BACKLOG.md) | 需求池与延后事项(B1–B8:数据权限/人设语音/生成图片/生成视频/员工画像/视觉检索/数字师傅) |
+| [feedback/](feedback/) | 用户反馈原始截图与解读(按日期归档,含 ANALYSIS.md) |
| [CODEBASE_ORIGINS.md](CODEBASE_ORIGINS.md) | 代码库来源与上游仓库说明 |
| [prototypes/ai-hr-dashboard.png](prototypes/ai-hr-dashboard.png) | 后台首页高保真目标图 |
| [prototypes/ai-hr-p0-pages-composite.png](prototypes/ai-hr-p0-pages-composite.png) | P0 四个页面组合高保真原型图 |
diff --git a/docs/feedback/2026070423/1.png b/docs/feedback/2026070423/1.png
new file mode 100644
index 0000000000000000000000000000000000000000..0d47110563b966a1d235eee7526b19d294add112
GIT binary patch
literal 588561
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