fix(avatar): repair knowledge reindex action
This commit is contained in:
@@ -32,7 +32,7 @@
|
||||
</div>
|
||||
|
||||
<div v-if="displayDocs.length" class="mobile-card-list">
|
||||
<article v-for="doc in displayDocs" :key="doc.id" class="knowledge-card">
|
||||
<article v-for="doc in displayDocs" :key="doc.id" class="knowledge-card document-card">
|
||||
<div class="card-icon">{{ fileEmoji(doc.fileType) }}</div>
|
||||
<div class="card-content">
|
||||
<div class="card-title-row">
|
||||
@@ -46,9 +46,14 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<button v-if="documentState(doc).tone === 'failed'" class="card-retry" @click="retryDoc(doc.id)">重新索引</button>
|
||||
<button v-if="!doc.localUploading" class="card-delete" @click="removeDoc(doc.id)">{{ doc.localOnly ? '移除' : '删除' }}</button>
|
||||
</div>
|
||||
<div v-if="canRetryDoc(doc)" class="card-retry-area">
|
||||
<span v-if="retryErrors[doc.id]" class="card-retry-error">{{ retryErrors[doc.id] }}</span>
|
||||
<button class="card-retry" :disabled="retryingDocs[doc.id]" @click="retryDoc(doc)">
|
||||
{{ retryingDocs[doc.id] ? '重新索引中…' : '重新索引' }}
|
||||
</button>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
<div v-else class="card-empty">📂 暂无文档,先上传一个知识文件</div>
|
||||
@@ -115,6 +120,8 @@ const uploading = computed(() => pendingUploads.value.some((doc) => doc.localUpl
|
||||
const uploadError = ref('')
|
||||
const dragOver = ref(false)
|
||||
const fileInput = ref<HTMLInputElement | null>(null)
|
||||
const retryingDocs = ref<Record<string, boolean>>({})
|
||||
const retryErrors = ref<Record<string, string>>({})
|
||||
let documentPollingTimer: ReturnType<typeof setInterval> | undefined
|
||||
|
||||
const query = ref('')
|
||||
@@ -250,14 +257,24 @@ const uploadOne = async (file: File, ext: string) => {
|
||||
}
|
||||
}
|
||||
|
||||
const retryDoc = async (id: string) => {
|
||||
if (!avatarId.value) return
|
||||
uploadError.value = ''
|
||||
const canRetryDoc = (doc: any) =>
|
||||
!doc.localOnly && doc.filePresent !== false && documentState(doc).tone === 'failed'
|
||||
|
||||
const retryDoc = async (doc: any) => {
|
||||
if (!avatarId.value || !canRetryDoc(doc) || retryingDocs.value[doc.id]) return
|
||||
retryingDocs.value = { ...retryingDocs.value, [doc.id]: true }
|
||||
retryErrors.value = { ...retryErrors.value, [doc.id]: '' }
|
||||
try {
|
||||
await retryKnowledgeDoc(avatarId.value, id)
|
||||
await loadDocs()
|
||||
const updated: any = await retryKnowledgeDoc(avatarId.value, doc.id)
|
||||
Object.assign(doc, updated)
|
||||
startDocumentPolling()
|
||||
} catch (e: any) {
|
||||
uploadError.value = e?.message || '重新索引失败'
|
||||
retryErrors.value = {
|
||||
...retryErrors.value,
|
||||
[doc.id]: e?.response?.data?.message || e?.response?.data?.detail || e?.message || '重新索引失败'
|
||||
}
|
||||
} finally {
|
||||
retryingDocs.value = { ...retryingDocs.value, [doc.id]: false }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -378,6 +395,7 @@ onUnmounted(stopDocumentPolling)
|
||||
.panel-heading p { margin: -5px 0 0; color: #9398AE; font-size: 12px; }
|
||||
.mobile-card-list { display: grid; grid-template-columns: minmax(0, 1fr); width: 100%; min-width: 0; gap: 10px; }
|
||||
.knowledge-card { display: flex; align-items: center; width: 100%; min-width: 0; box-sizing: border-box; gap: 11px; padding: 14px; background: #fff; border: 1px solid #F1E1D3; border-radius: 16px; box-shadow: 0 5px 16px rgba(112, 62, 22, .04); }
|
||||
.document-card { display: grid; grid-template-columns: 42px minmax(0, 1fr) auto; align-items: center; }
|
||||
.card-icon { flex: 0 0 auto; width: 42px; height: 42px; display: grid; place-items: center; border-radius: 13px; background: #FFF3E6; font-size: 22px; }
|
||||
.card-content { min-width: 0; flex: 1; overflow: hidden; }
|
||||
.card-title-row { display: flex; align-items: center; gap: 8px; min-width: 0; }
|
||||
@@ -388,10 +406,13 @@ onUnmounted(stopDocumentPolling)
|
||||
.card-meta, .card-detail { margin: 5px 0 0; color: #9398AE; font-size: 11px; line-height: 1.4; }.card-detail { color: #8B6B58; }
|
||||
.progress-track { width: 100%; height: 4px; margin-top: 8px; overflow: hidden; border-radius: 999px; background: #FDE7D1; }
|
||||
.progress-fill { display: block; height: 100%; border-radius: inherit; background: linear-gradient(90deg, #FB923C, #F97316); transition: width .25s ease; }
|
||||
.card-actions { flex: 0 0 auto; display: flex; flex-direction: column; align-items: stretch; gap: 6px; }
|
||||
.card-actions { flex: 0 0 auto; display: flex; align-items: center; }
|
||||
.card-delete, .card-retry { align-self: center; border: 0; border-radius: 8px; padding: 7px 9px; font-size: 12px; cursor: pointer; white-space: nowrap; }
|
||||
.card-delete { color: #EF4444; background: #FEF2F2; }
|
||||
.card-retry { color: #C15F18; background: #FFF3E6; }
|
||||
.card-retry:disabled { cursor: wait; opacity: .65; }
|
||||
.card-retry-area { grid-column: 1 / -1; display: flex; align-items: center; justify-content: flex-end; gap: 10px; min-width: 0; }
|
||||
.card-retry-error { min-width: 0; overflow: hidden; color: #DC2626; font-size: 11px; line-height: 1.35; text-overflow: ellipsis; white-space: nowrap; }
|
||||
.card-empty { padding: 42px 16px; border: 1px dashed #F1D9C3; border-radius: 16px; color: #9398AE; background: #fff; font-size: 14px; text-align: center; }
|
||||
.qa-card { align-items: stretch; text-align: left; }.qa-card.qa-disabled { opacity: .58; }
|
||||
.qa-card .card-content,
|
||||
@@ -617,8 +638,11 @@ onUnmounted(stopDocumentPolling)
|
||||
@media (max-width: 520px) {
|
||||
.knowledge-panel { padding: 0 12px; }
|
||||
.knowledge-card { display: grid; grid-template-columns: 42px minmax(0, 1fr); align-items: start; gap: 10px; padding: 13px; }
|
||||
.document-card { grid-template-columns: 42px minmax(0, 1fr) auto; }
|
||||
.card-content { grid-column: 2; }
|
||||
.card-delete { grid-column: 2; justify-self: end; margin-top: -2px; }
|
||||
.card-actions { grid-column: 3; grid-row: 1; }
|
||||
.card-delete { justify-self: end; margin-top: -2px; }
|
||||
.card-retry-area { grid-column: 1 / -1; }
|
||||
.qa-card { display: block; }
|
||||
.qa-card .card-content { width: 100%; grid-column: 1; }
|
||||
.card-title-row { align-items: flex-start; flex-wrap: wrap; gap: 5px 7px; }
|
||||
|
||||
Reference in New Issue
Block a user