feat: add brand library management features

- Introduced BrandLibrarySummary type to encapsulate brand library limits and usage.
- Updated Brand interface to include keyword_count and question_count fields.
- Implemented brand library limits in the backend, including max brands, keywords, and questions per keyword.
- Added API endpoint to retrieve brand library summary.
- Enhanced BrandsView.vue to display brand library usage and limits.
- Implemented computed properties to manage brand, keyword, and question limits in the UI.
- Updated mutation handlers to invalidate relevant queries upon creating/updating brands, keywords, and questions.
- Added visual indicators for brand, keyword, and question limits in the UI.
- Enhanced error handling for exceeding brand and keyword limits during creation.
This commit is contained in:
2026-04-16 21:01:40 +08:00
parent 27389164b0
commit 41f3060e00
15 changed files with 731 additions and 44 deletions
+20
View File
@@ -811,6 +811,23 @@ const enUS = {
keywords: "Keywords",
competitors: "Competitors",
},
quota: {
plan: "Current plan",
planHint: "Brand library limits are enforced from the active plan.",
brands: "Brand companies",
brandsHint: "Free defaults to 1 and paid defaults to 2.",
keywords: "Total keywords",
keywordsHint: "The total number of keywords this account can bind.",
questions: "Questions per keyword",
questionsHint: "The maximum number of questions allowed under one keyword.",
},
meta: {
keywordCount: "{count} keywords",
questionCount: "{count} questions",
brandKeywordCount: "{count} keywords under this brand",
globalKeywordUsage: "Total keywords used {used} / {total}",
keywordQuestionUsage: "Questions {used} / {total}",
},
sections: {
keywords: "Keywords",
questions: "Question set",
@@ -855,6 +872,9 @@ const enUS = {
deleteCompetitor: "Competitor deleted.",
chooseBrand: "Please choose a brand first.",
chooseKeyword: "Please choose a keyword first.",
brandLimitReached: "Your current plan allows up to {limit} brand companies.",
keywordLimitReached: "This account allows up to {limit} keywords.",
questionLimitReached: "This keyword allows up to {limit} questions.",
},
},
custom: {
+20
View File
@@ -818,6 +818,23 @@ const zhCN = {
keywords: "关键词",
competitors: "竞品库",
},
quota: {
plan: "当前套餐",
planHint: "品牌词库额度会按套餐实时生效。",
brands: "品牌公司",
brandsHint: "免费版默认 1 个,付费版默认 2 个。",
keywords: "关键词总量",
keywordsHint: "当前用户可绑定的关键词总数。",
questions: "每个关键词问题数",
questionsHint: "单个关键词下最多可维护的问题数。",
},
meta: {
keywordCount: "{count} 个关键词",
questionCount: "{count} 个问题",
brandKeywordCount: "当前品牌已绑定 {count} 个关键词",
globalKeywordUsage: "总关键词已用 {used} / {total}",
keywordQuestionUsage: "问题 {used} / {total}",
},
sections: {
keywords: "关键词",
questions: "问题集",
@@ -862,6 +879,9 @@ const zhCN = {
deleteCompetitor: "竞品已删除",
chooseBrand: "请先选择品牌",
chooseKeyword: "请先选择关键词",
brandLimitReached: "当前套餐最多可绑定 {limit} 个品牌公司",
keywordLimitReached: "当前账号最多可绑定 {limit} 个关键词",
questionLimitReached: "当前关键词下最多可维护 {limit} 个问题",
},
},
custom: {