fix(personal): align assistant citations and UI state
This commit is contained in:
@@ -51,7 +51,7 @@
|
||||
<text class="answer-text">{{ answer.answer }}</text>
|
||||
<view v-if="answer.citations?.length" class="citation-list">
|
||||
<text class="citation-heading">引用依据</text>
|
||||
<button v-for="citation in answer.citations" :key="`${citation.domain}-${citation.sourceId}`" class="citation-card" @click="openCitation(citation)">
|
||||
<button v-for="citation in answer.citations" :key="`${citation.domain}-${citation.sourceId}`" class="citation-card" :disabled="!citation.itemId" @click="openCitation(citation)">
|
||||
<view class="citation-head">
|
||||
<text class="domain-badge" :class="citation.domain.toLowerCase()">{{ citationLabel(citation) }}</text>
|
||||
<text class="citation-title">{{ citation.title }}</text>
|
||||
@@ -67,14 +67,14 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue';
|
||||
import type { PersonalAskResponse, PersonalCitation } from '@/types/api';
|
||||
import { askPersonalAssistant, loadPersonalItem, type KnowledgeScope } from '@/services/personal-assistant';
|
||||
import { askPersonalAssistant, type KnowledgeScope } from '@/services/personal-assistant';
|
||||
|
||||
const scopes = ref<KnowledgeScope[]>(['PERSONAL']);
|
||||
const queryText = ref('');
|
||||
const asking = ref(false);
|
||||
const answer = ref<PersonalAskResponse>();
|
||||
const message = ref('');
|
||||
const citationSourceTypes = ref<Record<string, string>>({});
|
||||
let requestGeneration = 0;
|
||||
const enterpriseEnabled = computed(() => scopes.value.includes('ENTERPRISE'));
|
||||
|
||||
const toggleEnterprise = () => {
|
||||
@@ -84,53 +84,45 @@ const toggleEnterprise = () => {
|
||||
const submitQuestion = async () => {
|
||||
const question = queryText.value.trim();
|
||||
if (!question || asking.value) return;
|
||||
const generation = ++requestGeneration;
|
||||
asking.value = true;
|
||||
answer.value = undefined;
|
||||
message.value = '';
|
||||
try {
|
||||
answer.value = await askPersonalAssistant({ queryText: question, scope: scopes.value, outputFormat: 'ACTION_PLAN' });
|
||||
await resolveCitationTypes(answer.value.citations || []);
|
||||
const response = await askPersonalAssistant({ queryText: question, scope: scopes.value, outputFormat: 'ACTION_PLAN' });
|
||||
if (generation !== requestGeneration) return;
|
||||
answer.value = response;
|
||||
} catch (error) {
|
||||
if (generation !== requestGeneration) return;
|
||||
const text = error instanceof Error ? error.message : '提问失败,请稍后重试';
|
||||
if (enterpriseEnabled.value && /ENTERPRISE_SCOPE_FORBIDDEN|企业知识|FORBIDDEN/i.test(text)) {
|
||||
scopes.value = ['PERSONAL'];
|
||||
message.value = '当前岗位没有企业知识权限,已仅查询我的资料。';
|
||||
try {
|
||||
answer.value = await askPersonalAssistant({ queryText: question, scope: ['PERSONAL'], outputFormat: 'ACTION_PLAN' });
|
||||
await resolveCitationTypes(answer.value.citations || []);
|
||||
const personalResponse = await askPersonalAssistant({ queryText: question, scope: ['PERSONAL'], outputFormat: 'ACTION_PLAN' });
|
||||
if (generation !== requestGeneration) return;
|
||||
answer.value = personalResponse;
|
||||
} catch (personalError) {
|
||||
if (generation !== requestGeneration) return;
|
||||
answer.value = undefined;
|
||||
message.value = personalError instanceof Error ? personalError.message : '我的资料查询失败,请稍后重试';
|
||||
}
|
||||
} else {
|
||||
message.value = text;
|
||||
}
|
||||
} finally {
|
||||
asking.value = false;
|
||||
if (generation === requestGeneration) asking.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const resolveCitationTypes = async (citations: PersonalCitation[]) => {
|
||||
const personalIds = Array.from(new Set(citations
|
||||
.filter((citation) => citation.domain === 'PERSONAL' && /^\d+$/.test(citation.sourceId))
|
||||
.map((citation) => citation.sourceId)));
|
||||
const resolved = await Promise.all(personalIds.map(async (id) => {
|
||||
try {
|
||||
const item = await loadPersonalItem(Number(id));
|
||||
return [id, item.sourceType] as const;
|
||||
} catch {
|
||||
return [id, ''] as const;
|
||||
}
|
||||
}));
|
||||
citationSourceTypes.value = Object.fromEntries(resolved);
|
||||
};
|
||||
|
||||
const citationLabel = (citation: PersonalCitation) => {
|
||||
if (citation.domain === 'ENTERPRISE') return '企业 SOP';
|
||||
return /^https?:/i.test(citation.sourceId) || citationSourceTypes.value[citation.sourceId] === 'URL' ? '外部网页' : '我的资料';
|
||||
return citation.sourceType === 'URL' ? '外部网页' : '我的资料';
|
||||
};
|
||||
|
||||
const openCitation = (citation: PersonalCitation) => {
|
||||
if (citation.domain !== 'PERSONAL' || !/^\d+$/.test(citation.sourceId)) return;
|
||||
uni.navigateTo({ url: `/pages/user/assistant/item?id=${encodeURIComponent(citation.sourceId)}` });
|
||||
if (citation.domain !== 'PERSONAL' || !citation.itemId) return;
|
||||
uni.navigateTo({ url: `/pages/user/assistant/item?id=${citation.itemId}` });
|
||||
};
|
||||
|
||||
const goBack = () => uni.navigateBack();
|
||||
|
||||
Reference in New Issue
Block a user