fix: improve question selection handling and user interaction feedback
Frontend CI / Frontend (push) Successful in 2m57s

This commit is contained in:
2026-06-21 17:48:50 +08:00
parent 316aae240e
commit 54c2f92e02
+69 -27
View File
@@ -128,13 +128,21 @@ let questionSelectionSeq = 0
selectedPlatformId.value = normalizeMonitoringPlatformFilter(selectedPlatformId.value) selectedPlatformId.value = normalizeMonitoringPlatformFilter(selectedPlatformId.value)
selectedCitationWindowDays.value = normalizeCitationWindowDays(selectedCitationWindowDays.value) selectedCitationWindowDays.value = normalizeCitationWindowDays(selectedCitationWindowDays.value)
const selectedQuestionSetOptionValue = computed<string | number>({ const isUserQuestionSelectionPending = ref(false)
get: () => selectedQuestionId.value ?? allQuestionOptionValue, const selectedQuestionSetOptionValue = computed<string | number>(
set: (value) => { () => selectedQuestionId.value ?? allQuestionOptionValue,
selectedQuestionId.value = )
typeof value === 'number' && Number.isFinite(value) && value > 0 ? value : null
}, function handleQuestionSetChange(value: string | number): void {
}) const nextQuestionId =
typeof value === 'number' && Number.isFinite(value) && value > 0 ? value : null
if (selectedQuestionId.value === nextQuestionId) {
return
}
questionSelectionSeq += 1
isUserQuestionSelectionPending.value = true
selectedQuestionId.value = nextQuestionId
}
const selectedBrandId = computed(() => companyStore.currentBrandId) const selectedBrandId = computed(() => companyStore.currentBrandId)
const selectedBrand = computed(() => companyStore.currentBrand) const selectedBrand = computed(() => companyStore.currentBrand)
@@ -147,11 +155,11 @@ const questionList = usePaginatedBrandQuestions(selectedBrandId, {
const questionSetOptions = computed(() => questionList.options.value) const questionSetOptions = computed(() => questionList.options.value)
watch( watch(
[selectedBrandId, () => route.query.question_id, selectedQuestionId], [selectedBrandId, () => route.query.question_id],
async ([brandId, requestedQuestionValue, questionId]) => { async ([brandId, requestedQuestionValue]) => {
const requestedQuestionId = parseNumericQuery(requestedQuestionValue) const requestedQuestionId = parseNumericQuery(requestedQuestionValue)
const targetQuestionId = requestedQuestionId ?? questionId if (!brandId || !requestedQuestionId) {
if (!brandId || !targetQuestionId) { questionSelectionSeq += 1
missingRequestedQuestionId.value = null missingRequestedQuestionId.value = null
return return
} }
@@ -165,20 +173,47 @@ watch(
missingRequestedQuestionId.value = null missingRequestedQuestionId.value = null
} }
const question = await questionList.ensureQuestionLoadedById(targetQuestionId) const question = await questionList.ensureQuestionLoadedById(requestedQuestionId)
if (seq !== questionSelectionSeq || brandId !== selectedBrandId.value) { if (seq !== questionSelectionSeq || brandId !== selectedBrandId.value) {
return return
} }
if (question) { if (question) {
selectedQuestionId.value = targetQuestionId selectedQuestionId.value = requestedQuestionId
return return
} }
if (requestedQuestionId === targetQuestionId) { missingRequestedQuestionId.value = requestedQuestionId
missingRequestedQuestionId.value = targetQuestionId if (selectedQuestionId.value === requestedQuestionId) {
selectedQuestionId.value = null
} }
if (selectedQuestionId.value === targetQuestionId) { },
{ immediate: true },
)
watch(
[selectedBrandId, selectedQuestionId],
async ([brandId, questionId]) => {
if (!brandId || !questionId) {
return
}
const requestedQuestionId = parseNumericQuery(route.query.question_id)
if (requestedQuestionId && requestedQuestionId !== questionId) {
return
}
const seq = ++questionSelectionSeq
const question = await questionList.ensureQuestionLoadedById(questionId)
if (
seq !== questionSelectionSeq ||
brandId !== selectedBrandId.value ||
selectedQuestionId.value !== questionId
) {
return
}
if (!question) {
selectedQuestionId.value = null selectedQuestionId.value = null
} }
}, },
@@ -238,7 +273,8 @@ watch(
if ( if (
requestedQuestionId && requestedQuestionId &&
questionId !== requestedQuestionId && questionId !== requestedQuestionId &&
missingQuestionId !== requestedQuestionId missingQuestionId !== requestedQuestionId &&
!isUserQuestionSelectionPending.value
) { ) {
return return
} }
@@ -261,18 +297,23 @@ watch(
currentBusinessDate === nextBusinessDate && currentBusinessDate === nextBusinessDate &&
!hasLegacyCitationDaysQuery !hasLegacyCitationDaysQuery
) { ) {
isUserQuestionSelectionPending.value = false
return return
} }
void router.replace({ void router
name: 'tracking', .replace({
query: { name: 'tracking',
...(nextBrandId ? { brand_id: nextBrandId } : {}), query: {
...(nextQuestionId ? { question_id: nextQuestionId } : {}), ...(nextBrandId ? { brand_id: nextBrandId } : {}),
...(nextPlatformId ? { ai_platform_id: nextPlatformId } : {}), ...(nextQuestionId ? { question_id: nextQuestionId } : {}),
business_date: nextBusinessDate, ...(nextPlatformId ? { ai_platform_id: nextPlatformId } : {}),
}, business_date: nextBusinessDate,
}) },
})
.finally(() => {
isUserQuestionSelectionPending.value = false
})
}, },
) )
@@ -936,7 +977,7 @@ function disableTrackingDate(current: dayjs.Dayjs): boolean {
<div class="tracking-action-item"> <div class="tracking-action-item">
<span class="tracking-action-label">关键词库搜索词</span> <span class="tracking-action-label">关键词库搜索词</span>
<a-select <a-select
v-model:value="selectedQuestionSetOptionValue" :value="selectedQuestionSetOptionValue"
show-search show-search
class="tracking-select tracking-keyword-select" class="tracking-select tracking-keyword-select"
popup-class-name="tracking-keyword-select-dropdown" popup-class-name="tracking-keyword-select-dropdown"
@@ -948,6 +989,7 @@ function disableTrackingDate(current: dayjs.Dayjs): boolean {
" "
:placeholder="t('tracking.keywordPlaceholder')" :placeholder="t('tracking.keywordPlaceholder')"
:options="questionSetOptions" :options="questionSetOptions"
@change="handleQuestionSetChange"
@search="questionList.search" @search="questionList.search"
@popup-scroll="questionList.handlePopupScroll" @popup-scroll="questionList.handlePopupScroll"
/> />