feat(keywords): rename brand-question terminology to search-keyword + add entity exclusion
- Rename UI/prompt labels: "品牌主问题" → "优化关键词", "搜索问题" → "搜索词" - Add brand/competitor entity exclusion filter in question expansion (AI distill path) - Refactor combination question text normalization, remove manual question-mark appending - Update prompts to emphasize commercial-intent search queries over editorial phrasing - Sync prompt changes across server/configs, deploy, and k3s configs - Update i18n, frontend views (BrandQuestionCreate, TemplateWizard), and test fixtures Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -286,6 +286,12 @@ const templateMeta = computed(() => {
|
||||
const selectedBrand = computed(
|
||||
() => brandsQuery.data.value?.find((brand) => brand.id === selectedBrandId.value) ?? null,
|
||||
)
|
||||
const brandNameOptions = computed(() =>
|
||||
(brandsQuery.data.value ?? []).map((item) => ({
|
||||
label: item.name,
|
||||
value: item.name,
|
||||
})),
|
||||
)
|
||||
|
||||
function findQuestionById(id: number | null): Question | null {
|
||||
if (!id) {
|
||||
@@ -654,6 +660,23 @@ watch(supplementalQuestionIds, (ids) => {
|
||||
}
|
||||
})
|
||||
|
||||
function handleBrandNameInput(value: string): void {
|
||||
brandName.value = value
|
||||
const matchedBrand = brandsQuery.data.value?.find((item) => item.name === value)
|
||||
selectedBrandId.value = matchedBrand?.id ?? null
|
||||
}
|
||||
|
||||
function handleBrandNameSelect(value: string): void {
|
||||
const brand = brandsQuery.data.value?.find((item) => item.name === value)
|
||||
if (!brand) {
|
||||
selectedBrandId.value = null
|
||||
brandName.value = value
|
||||
return
|
||||
}
|
||||
selectedBrandId.value = brand.id
|
||||
brandName.value = brand.name
|
||||
}
|
||||
|
||||
watch(selectedBrandId, async (brandId) => {
|
||||
if (restoringDraft.value) {
|
||||
return
|
||||
@@ -1192,8 +1215,9 @@ function sanitizeLegacyKeywordCopy(copy: TemplateCardCopy): TemplateCardCopy {
|
||||
|
||||
function sanitizeLegacyKeywordText(value: string | undefined): string {
|
||||
return (value || '')
|
||||
.replace(/核心关键词/g, '品牌主问题')
|
||||
.replace(/关键词/g, '品牌问题')
|
||||
.replace(/品牌主问题/g, '优化关键词')
|
||||
.replace(/补充覆盖问题/g, '补充关键词')
|
||||
.replace(/核心关键词/g, '优化关键词')
|
||||
.replace(/标题生成/g, '后续生成')
|
||||
}
|
||||
|
||||
@@ -2392,29 +2416,17 @@ function onStructureDragEnd(): void {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="field-item">
|
||||
<label>{{ t('templates.wizard.sections.brandLibrary') }}</label>
|
||||
<a-select
|
||||
v-model:value="selectedBrandId"
|
||||
allow-clear
|
||||
show-search
|
||||
:placeholder="t('templates.wizard.placeholders.brandLibrary')"
|
||||
:options="
|
||||
(brandsQuery.data.value || []).map((item) => ({
|
||||
label: item.name,
|
||||
value: item.id,
|
||||
}))
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="field-item">
|
||||
<label class="required-asterisk">
|
||||
{{ t('templates.wizard.sections.brandName') }}
|
||||
</label>
|
||||
<a-input
|
||||
<a-auto-complete
|
||||
v-model:value="brandName"
|
||||
allow-clear
|
||||
:options="brandNameOptions"
|
||||
:placeholder="t('templates.wizard.placeholders.brandName')"
|
||||
@change="handleBrandNameInput"
|
||||
@select="handleBrandNameSelect"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user