fix(personal): align assistant citations and UI state
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
<view v-else-if="message && !items.length" class="panel"><text class="status-message">{{ message }}</text><button class="secondary-button retry" @click="refresh">重试</button></view>
|
||||
<view v-else-if="!items.length" class="panel empty">还没有个人资料,先收藏一条文字、文件或网页。</view>
|
||||
<view v-else class="item-list">
|
||||
<text v-if="message" class="status-message">{{ message }}</text>
|
||||
<button v-for="item in items" :key="item.id" class="item-card employee-card" @click="openItem(item.id)">
|
||||
<view class="item-head"><text class="source-badge">{{ sourceText(item.sourceType) }}</text><text class="status-badge" :class="item.status.toLowerCase()">{{ statusText(item.status) }}</text></view>
|
||||
<text class="item-title">{{ item.title || '未命名资料' }}</text>
|
||||
@@ -39,7 +40,7 @@
|
||||
import { computed, ref } from 'vue';
|
||||
import { onShow } from '@dcloudio/uni-app';
|
||||
import type { PersonalItem, PersonalItemSourceType, PersonalItemStatus, PersonalSpace } from '@/types/api';
|
||||
import { loadPersonalItems, loadPersonalSpace } from '@/services/personal-assistant';
|
||||
import { loadPersonalItems, loadPersonalSpace, mergePersonalRows } from '@/services/personal-assistant';
|
||||
|
||||
const pageNum = ref(1);
|
||||
const pageSize = 10;
|
||||
@@ -51,14 +52,15 @@ const status = ref<PersonalItemStatus | ''>('');
|
||||
const keyword = ref('');
|
||||
const loading = ref(false);
|
||||
const message = ref('');
|
||||
let requestGeneration = 0;
|
||||
const sourceOptions = [{ label: '全部来源', value: '' }, { label: '文字', value: 'TEXT' }, { label: '文件', value: 'FILE' }, { label: '网页', value: 'URL' }] as const;
|
||||
const statusOptions = [{ label: '全部状态', value: '' }, { label: '等待处理', value: 'QUEUED' }, { label: '解析中', value: 'PARSING' }, { label: '可检索', value: 'READY' }, { label: '失败', value: 'FAILED' }] as const;
|
||||
const sourceLabel = computed(() => sourceOptions.find((item) => item.value === sourceType.value)?.label || '全部来源');
|
||||
const statusLabel = computed(() => statusOptions.find((item) => item.value === status.value)?.label || '全部状态');
|
||||
const usagePercent = computed(() => Math.min(100, Math.round(((space.value?.usedBytes || 0) / Math.max(1, space.value?.quotaBytes || 1)) * 100)));
|
||||
|
||||
const load = async (append = false) => {
|
||||
if (loading.value) return;
|
||||
const load = async (append = false, pageSnapshot = pageNum.value) => {
|
||||
const generation = ++requestGeneration;
|
||||
loading.value = true;
|
||||
message.value = '';
|
||||
try {
|
||||
@@ -66,15 +68,25 @@ const load = async (append = false) => {
|
||||
loadPersonalItems({ pageNum: pageNum.value, pageSize, sourceType: sourceType.value, status: status.value, keyword: keyword.value.trim() }),
|
||||
loadPersonalSpace()
|
||||
]);
|
||||
items.value = append ? [...items.value, ...page.rows] : page.rows;
|
||||
if (generation !== requestGeneration || pageSnapshot !== pageNum.value) return;
|
||||
items.value = append ? mergePersonalRows(items.value, page.rows) : page.rows;
|
||||
total.value = page.total;
|
||||
space.value = latestSpace;
|
||||
} catch (error) {
|
||||
if (generation !== requestGeneration) return;
|
||||
if (append) pageNum.value = Math.max(1, pageSnapshot - 1);
|
||||
message.value = error instanceof Error ? error.message : '资料加载失败';
|
||||
} finally { loading.value = false; }
|
||||
} finally {
|
||||
if (generation === requestGeneration) loading.value = false;
|
||||
}
|
||||
};
|
||||
const refresh = () => { pageNum.value = 1; void load(); };
|
||||
const loadMore = () => { pageNum.value += 1; void load(true); };
|
||||
const loadMore = () => {
|
||||
if (loading.value) return;
|
||||
const nextPage = pageNum.value + 1;
|
||||
pageNum.value = nextPage;
|
||||
void load(true, nextPage);
|
||||
};
|
||||
const changeSource = (event: { detail: { value: string | number } }) => { sourceType.value = sourceOptions[Number(event.detail.value)]?.value || ''; refresh(); };
|
||||
const changeStatus = (event: { detail: { value: string | number } }) => { status.value = statusOptions[Number(event.detail.value)]?.value || ''; refresh(); };
|
||||
const sourceText = (value: PersonalItemSourceType) => ({ TEXT: '文字', FILE: '文件', URL: '外部网页' })[value];
|
||||
|
||||
Reference in New Issue
Block a user