fix: improve question selection handling and user interaction feedback
Frontend CI / Frontend (push) Successful in 2m57s
Frontend CI / Frontend (push) Successful in 2m57s
This commit is contained in:
@@ -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"
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user