feat: scope articles by brand
This commit is contained in:
@@ -99,7 +99,7 @@ const enUS = {
|
||||
email: 'Email',
|
||||
loginIdentifier: 'Phone / Email',
|
||||
password: 'Password',
|
||||
rememberAccount: 'Remember account',
|
||||
rememberAccount: 'Remember account and password',
|
||||
forgotPassword: 'Forgot password',
|
||||
},
|
||||
membershipBlocked: {
|
||||
@@ -137,6 +137,9 @@ const enUS = {
|
||||
userFallback: 'Admin',
|
||||
logout: 'Logout',
|
||||
planFallback: 'Free Plan',
|
||||
currentCompany: 'Company',
|
||||
currentCompanyPlaceholder: 'Select company',
|
||||
createCompany: 'Create company',
|
||||
openNavigation: 'Open navigation',
|
||||
collapseNavigation: 'Collapse navigation',
|
||||
expandNavigation: 'Expand navigation',
|
||||
@@ -169,6 +172,10 @@ const enUS = {
|
||||
title: 'Welcome back',
|
||||
description: 'Sign in with a real tenant account.',
|
||||
},
|
||||
brandOnboarding: {
|
||||
title: 'Choose a brand',
|
||||
description: 'Create the first brand and initialize its keyword library.',
|
||||
},
|
||||
workspace: {
|
||||
title: 'Workspace',
|
||||
description: 'Template shortcuts, overview data, and recent generations in one place.',
|
||||
@@ -250,6 +257,47 @@ const enUS = {
|
||||
description: 'The link you opened might have moved or no longer exists.',
|
||||
},
|
||||
},
|
||||
onboardingBrand: {
|
||||
eyebrow: 'Brand Onboarding',
|
||||
title: 'Choose a brand or company',
|
||||
subtitle: 'You have access to multiple brands or companies. Choose one to start working.',
|
||||
createBrand: 'Create new brand or company',
|
||||
createHint: 'After creation, keyword initialization starts automatically.',
|
||||
emptyDescription:
|
||||
'New users need to create a brand or company before entering the workspace.',
|
||||
noWebsite: 'No website yet',
|
||||
form: {
|
||||
title: 'Create brand or company',
|
||||
name: 'Brand or company name',
|
||||
namePlaceholder: 'Example: GEO Console / Acme Furniture',
|
||||
website: 'Website (optional)',
|
||||
websitePlaceholder: 'https://example.com',
|
||||
description: 'Description',
|
||||
descriptionPlaceholder: 'Briefly describe the business, products, service area, or core value.',
|
||||
},
|
||||
ai: {
|
||||
title: 'Generating brand or company questions',
|
||||
stages: {
|
||||
fetch: 'Fetching website and business context...',
|
||||
generate: 'Generating candidate search terms for monitoring...',
|
||||
refine: 'Deduplicating and filtering savable questions...',
|
||||
},
|
||||
},
|
||||
questions: {
|
||||
title: 'Select brand or company questions',
|
||||
subtitle:
|
||||
'Choose up to {limit} questions to save to the keyword library. You can add or edit more later.',
|
||||
confirm: 'Save and enter workspace',
|
||||
skip: 'Skip and enter',
|
||||
empty: 'No usable questions were generated. You can enter the workspace and add them manually.',
|
||||
selectionLimit: 'Choose up to {limit} questions.',
|
||||
},
|
||||
messages: {
|
||||
nameRequired: 'Enter a brand or company name.',
|
||||
questionRequired: 'Select at least one question, or skip and add them manually later.',
|
||||
aiCharged: 'This generation consumed {count} AI point.',
|
||||
},
|
||||
},
|
||||
notFound: {
|
||||
title: 'This page got lost',
|
||||
description:
|
||||
@@ -723,7 +771,7 @@ const enUS = {
|
||||
sourceURL: 'Article URL',
|
||||
sourceTitle: 'Source title',
|
||||
language: 'Article language',
|
||||
brandName: 'Brand / subject',
|
||||
brandName: 'Current company',
|
||||
region: 'Region',
|
||||
keywords: 'Optimization keywords',
|
||||
preservePoints: 'Keep / emphasize',
|
||||
@@ -738,17 +786,17 @@ const enUS = {
|
||||
'Selected groups are retrieved in the backend and passed to generation as reference context.',
|
||||
sourceURLPlaceholder: 'https://example.com/article',
|
||||
sourceTitlePlaceholder: 'Optional. Citation titles are prefilled automatically.',
|
||||
brandNamePlaceholder: 'Required. Type the target subject, or choose from the brand library.',
|
||||
brandNamePlaceholder: 'Select the current company in the top bar first.',
|
||||
regionPlaceholder: 'For example: Shanghai, East China, nationwide, North America',
|
||||
keywordsPlaceholder:
|
||||
'Type optimization keywords and press Enter. Brand-library options appear after choosing a subject.',
|
||||
'Type optimization keywords and press Enter. Search-term options appear after selecting the current company.',
|
||||
preservePointsPlaceholder: 'List facts, data, arguments, or examples that must be kept.',
|
||||
avoidPointsPlaceholder: 'List claims, competitors, compliance risks, or wording to avoid.',
|
||||
extraRequirementsPlaceholder:
|
||||
'Add channel, structure, title style, or industry-specific instructions.',
|
||||
queued: 'Rewrite task submitted and queued.',
|
||||
sourceURLRequired: 'Enter the source article URL first.',
|
||||
brandNameRequired: 'Enter the brand / subject first.',
|
||||
brandNameRequired: 'Select the current company in the top bar first.',
|
||||
submitError: 'Failed to submit rewrite task.',
|
||||
backToList: 'Back to rewrites',
|
||||
},
|
||||
@@ -821,7 +869,7 @@ const enUS = {
|
||||
drawerTitle: 'Template generation',
|
||||
steps: {
|
||||
basic: 'Basic info',
|
||||
basicDesc: 'Language, template fields, and brand context',
|
||||
basicDesc: 'Language, template fields, and company context',
|
||||
structure: 'Structure',
|
||||
structureDesc: 'Title and outline',
|
||||
generate: 'Generate',
|
||||
@@ -829,13 +877,13 @@ const enUS = {
|
||||
},
|
||||
sections: {
|
||||
templateFields: 'Template fields',
|
||||
brandContext: 'Brand context',
|
||||
brandContext: 'Company context',
|
||||
language: 'Language',
|
||||
brandInfo: 'Brand',
|
||||
brandLibrary: 'Brand library',
|
||||
brandName: 'Company name',
|
||||
brandInfo: 'Company',
|
||||
brandLibrary: 'Company library',
|
||||
brandName: 'Current company',
|
||||
website: 'Official website',
|
||||
brandSummary: 'AI brand summary',
|
||||
brandSummary: 'AI company summary',
|
||||
keywords: 'Keywords',
|
||||
brandQuestions: 'Keyword library (search terms)',
|
||||
primaryQuestion: 'Optimization keyword',
|
||||
@@ -854,21 +902,21 @@ const enUS = {
|
||||
inputParams: 'Input params',
|
||||
},
|
||||
hints: {
|
||||
brandContext: 'Optional. Selecting a brand pulls in keywords and competitor context.',
|
||||
brandContext: 'The current company pulls in keywords and competitor context.',
|
||||
brandFlow:
|
||||
'You can type a company name or choose one from the brand library. After you choose an optimization keyword, AI will prepare the summary, competitors, and title options.',
|
||||
'Articles use the current company selected in the top bar. After you choose an optimization keyword, AI will prepare the summary, competitors, and title options.',
|
||||
brandSummaryPlaceholder:
|
||||
'After analysis, AI will summarize the brand angle, positioning, and content opportunities here.',
|
||||
'After analysis, AI will summarize the company angle, positioning, and content opportunities here.',
|
||||
keywords:
|
||||
'Type keywords directly or reuse brand-library keywords. AI results will be merged into this list.',
|
||||
brandQuestions:
|
||||
'The optimization keyword controls the article spine; supplemental keywords broaden nearby search intent.',
|
||||
supplementalQuestions:
|
||||
'Choose up to 3 so the article covers related intent without drifting.',
|
||||
questionEmpty: 'No questions are available for this brand yet.',
|
||||
selectBrandFirst: 'Choose a library brand from the company name dropdown first.',
|
||||
questionEmpty: 'No questions are available for this company yet.',
|
||||
selectBrandFirst: 'Select the current company in the top bar first.',
|
||||
competitors:
|
||||
'Competitors stay editable. You can add rows manually; saving to the competitor library is only available after choosing a library brand.',
|
||||
'Competitors stay editable. You can add rows manually; saving to the competitor library is available after selecting the current company.',
|
||||
competitorEmptyEditable:
|
||||
'No competitors yet. Add one manually or let AI fill the list first.',
|
||||
templateFields:
|
||||
@@ -883,7 +931,7 @@ const enUS = {
|
||||
outlinePreview: 'The panel on the right updates from the current outline in real time.',
|
||||
outlineEmpty: 'Generate the outline first to edit the article structure here.',
|
||||
review: 'Check the final setup before creating the generation task.',
|
||||
competitorEmpty: 'No competitors are available under this brand yet.',
|
||||
competitorEmpty: 'No competitors are available under this company yet.',
|
||||
customTitle: 'Use this field if you want to override the title manually.',
|
||||
keyPoints: 'Add any key messages, angles, or style notes here.',
|
||||
async:
|
||||
@@ -904,7 +952,7 @@ const enUS = {
|
||||
review: {
|
||||
templateName: 'Template',
|
||||
articleTitle: 'Article title',
|
||||
brandContext: 'Brand context',
|
||||
brandContext: 'Company context',
|
||||
outline: 'Outline',
|
||||
currentTemplate: 'Current template',
|
||||
promptVisibility: 'Prompt visibility',
|
||||
@@ -922,8 +970,8 @@ const enUS = {
|
||||
actions: 'Actions',
|
||||
},
|
||||
placeholders: {
|
||||
brandLibrary: 'Choose an existing brand from the library',
|
||||
brandName: 'Enter a company name, or choose from the brand library',
|
||||
brandLibrary: 'Choose the current company',
|
||||
brandName: 'Current company from the top bar',
|
||||
website: 'Official website, optional',
|
||||
keywords: 'Type keywords and press Enter',
|
||||
primaryQuestion: 'Choose one optimization keyword',
|
||||
@@ -975,18 +1023,18 @@ const enUS = {
|
||||
},
|
||||
messages: {
|
||||
requiredField: 'Please fill in {field} first.',
|
||||
missingBrand: 'Enter or choose a company name first.',
|
||||
missingBrand: 'Select the current company in the top bar first.',
|
||||
selectBrandBeforeQuestion:
|
||||
'Choose a library brand from the company name dropdown before selecting a question.',
|
||||
'Select the current company in the top bar before continuing.',
|
||||
missingPrimaryQuestion: 'Choose one primary brand question.',
|
||||
missingTitle: 'Please choose or enter an article title.',
|
||||
missingOutline: 'Please select at least one outline section.',
|
||||
missingGeneratedOutline: 'Please generate and confirm the article outline first.',
|
||||
customOutlineTooLong: 'Custom sections cannot exceed {count} characters.',
|
||||
selectBrandBeforeCompetitors:
|
||||
'Choose a library brand from the company name dropdown before managing competitors.',
|
||||
'Select the current company in the top bar before managing competitors.',
|
||||
selectBrandBeforeFavorite:
|
||||
'Choose a library brand from the company name dropdown before saving competitors.',
|
||||
'Select the current company in the top bar before saving competitors.',
|
||||
missingCompetitorName: 'Enter a competitor name before saving it to the library.',
|
||||
savedCompetitor: 'Competitor saved to the brand library.',
|
||||
unsavedCompetitor: 'Competitor removed from the brand library.',
|
||||
|
||||
@@ -101,7 +101,7 @@ const zhCN = {
|
||||
email: "邮箱",
|
||||
loginIdentifier: "手机号 / 邮箱",
|
||||
password: "密码",
|
||||
rememberAccount: "记住账号",
|
||||
rememberAccount: "记住账号和密码",
|
||||
forgotPassword: "忘记密码",
|
||||
},
|
||||
membershipBlocked: {
|
||||
@@ -134,6 +134,9 @@ const zhCN = {
|
||||
userFallback: "管理员",
|
||||
logout: "退出",
|
||||
planFallback: "免费版",
|
||||
currentCompany: "当前公司",
|
||||
currentCompanyPlaceholder: "选择公司",
|
||||
createCompany: "创建公司",
|
||||
openNavigation: "打开导航",
|
||||
collapseNavigation: "收起导航",
|
||||
expandNavigation: "展开导航",
|
||||
@@ -165,6 +168,10 @@ const zhCN = {
|
||||
title: "欢迎回来",
|
||||
description: "登录省心推,开启品牌内容创作之旅",
|
||||
},
|
||||
brandOnboarding: {
|
||||
title: "选择进入的品牌",
|
||||
description: "首次进入前创建品牌,并初始化品牌关键词库。",
|
||||
},
|
||||
workspace: {
|
||||
title: "工作台",
|
||||
description: "模板入口、数据总览和最近生成都集中在这里。",
|
||||
@@ -238,6 +245,45 @@ const zhCN = {
|
||||
description: "你访问的链接可能已经失效或被移动。",
|
||||
},
|
||||
},
|
||||
onboardingBrand: {
|
||||
eyebrow: "Brand Onboarding",
|
||||
title: "选择进入的品牌或公司",
|
||||
subtitle: "你拥有多个品牌或公司的访问权限,请选择一个开始工作",
|
||||
createBrand: "创建新品牌或公司",
|
||||
createHint: "添加品牌或公司后会自动进入关键词初始化。",
|
||||
emptyDescription: "新用户需要先创建品牌或公司,再进入工作台开始创作。",
|
||||
noWebsite: "暂未填写官网",
|
||||
form: {
|
||||
title: "新建品牌或公司",
|
||||
name: "品牌或公司名",
|
||||
namePlaceholder: "例如:省心推 / 海翔家具",
|
||||
website: "官网(选填)",
|
||||
websitePlaceholder: "https://example.com",
|
||||
description: "简介",
|
||||
descriptionPlaceholder: "简单介绍公司的业务、产品、服务区域或核心卖点",
|
||||
},
|
||||
ai: {
|
||||
title: "正在生成品牌或公司问题",
|
||||
stages: {
|
||||
fetch: "正在获取官网信息和业务上下文…",
|
||||
generate: "正在生成适合监测的候选搜索词…",
|
||||
refine: "正在去重并筛选可保存的问题…",
|
||||
},
|
||||
},
|
||||
questions: {
|
||||
title: "选择品牌或公司问题",
|
||||
subtitle: "请选择最多 {limit} 个问题保存到关键词库,后续可继续添加或调整。",
|
||||
confirm: "保存并进入工作台",
|
||||
skip: "跳过,直接进入",
|
||||
empty: "暂时没有生成可用的问题,可以先进入工作台后手动添加。",
|
||||
selectionLimit: "最多选择 {limit} 个问题",
|
||||
},
|
||||
messages: {
|
||||
nameRequired: "请输入品牌或公司名",
|
||||
questionRequired: "请至少选择 1 个问题,或跳过后手动添加",
|
||||
aiCharged: "本次生成已消耗 {count} 个 AI 点",
|
||||
},
|
||||
},
|
||||
notFound: {
|
||||
title: "页面走丢了",
|
||||
description: "我们没有找到这个地址对应的内容,可能链接拼写有误,或者页面已经下线。",
|
||||
@@ -691,7 +737,7 @@ const zhCN = {
|
||||
sourceURL: "文章 URL",
|
||||
sourceTitle: "来源标题",
|
||||
language: "文章语言",
|
||||
brandName: "品牌/主体",
|
||||
brandName: "当前公司",
|
||||
region: "地域",
|
||||
keywords: "优化关键词",
|
||||
preservePoints: "必须保留/强调",
|
||||
@@ -704,15 +750,15 @@ const zhCN = {
|
||||
knowledgeBaseHint: "选择后,后台会检索相关知识片段并作为生成参考,未选择则只基于来源文章和当前设置生成。",
|
||||
sourceURLPlaceholder: "https://example.com/article",
|
||||
sourceTitlePlaceholder: "可选,引用来源标题会自动带入",
|
||||
brandNamePlaceholder: "必填,可输入目标达成词,或从品牌库选择",
|
||||
brandNamePlaceholder: "请先在顶部选择当前公司",
|
||||
regionPlaceholder: "例如:上海、华东、全国、北美市场",
|
||||
keywordsPlaceholder: "输入优化关键词后回车,可多选;选择品牌库主体后会显示搜索词候选",
|
||||
keywordsPlaceholder: "输入优化关键词后回车,可多选;选择当前公司后会显示搜索词候选",
|
||||
preservePointsPlaceholder: "列出必须保留的事实、数据、观点或案例",
|
||||
avoidPointsPlaceholder: "列出不能出现的说法、竞品、合规禁区或表达方式",
|
||||
extraRequirementsPlaceholder: "补充行业、渠道、结构、标题风格等自由要求",
|
||||
queued: "仿写任务已提交,正在排队生成",
|
||||
sourceURLRequired: "请先填写来源文章 URL",
|
||||
brandNameRequired: "请先填写品牌/主体",
|
||||
brandNameRequired: "请先在顶部选择当前公司",
|
||||
submitError: "仿写任务提交失败",
|
||||
backToList: "返回仿写列表",
|
||||
},
|
||||
@@ -785,7 +831,7 @@ const zhCN = {
|
||||
drawerTitle: "模版生成",
|
||||
steps: {
|
||||
basic: "基本信息",
|
||||
basicDesc: "语言、模版字段与品牌上下文",
|
||||
basicDesc: "语言、模版字段与公司上下文",
|
||||
structure: "文章结构",
|
||||
structureDesc: "标题方案与结构段落",
|
||||
generate: "生成文章",
|
||||
@@ -793,13 +839,13 @@ const zhCN = {
|
||||
},
|
||||
sections: {
|
||||
templateFields: "模版字段",
|
||||
brandContext: "品牌上下文",
|
||||
brandContext: "公司上下文",
|
||||
language: "文章语言",
|
||||
brandInfo: "品牌信息",
|
||||
brandLibrary: "品牌库",
|
||||
brandName: "公司名称",
|
||||
brandInfo: "公司信息",
|
||||
brandLibrary: "公司库",
|
||||
brandName: "当前公司",
|
||||
website: "官网地址",
|
||||
brandSummary: "AI 品牌摘要",
|
||||
brandSummary: "AI 公司摘要",
|
||||
keywords: "关键词",
|
||||
brandQuestions: "关键词库(搜索词)",
|
||||
primaryQuestion: "优化关键词",
|
||||
@@ -819,15 +865,15 @@ const zhCN = {
|
||||
inputParams: "输入参数",
|
||||
},
|
||||
hints: {
|
||||
brandContext: "可选。选择后会自动带出关键词与竞品信息。",
|
||||
brandFlow: "公司名称可直接输入,也可以从品牌库选择。选择优化关键词后,AI 会补充品牌摘要、竞品和标题建议。",
|
||||
brandSummaryPlaceholder: "AI 分析后会在这里补充品牌简介、差异点和适合切入的内容角度。",
|
||||
brandContext: "当前公司会自动带出关键词与竞品信息。",
|
||||
brandFlow: "使用顶部选择的当前公司生成文章。选择优化关键词后,AI 会补充公司摘要、竞品和标题建议。",
|
||||
brandSummaryPlaceholder: "AI 分析后会在这里补充公司简介、差异点和适合切入的内容角度。",
|
||||
keywords: "支持直接输入,也支持复用品牌词库里的关键词。AI 分析结果会自动补充到这里。",
|
||||
brandQuestions: "优化关键词决定文章主线,补充关键词只用于扩展相关搜索意图。",
|
||||
supplementalQuestions: "最多选择 3 个,用于覆盖相邻搜索问题,避免文章主题发散。",
|
||||
questionEmpty: "当前品牌还没有可选问题",
|
||||
selectBrandFirst: "请先从公司名称下拉选择品牌库对象",
|
||||
competitors: "竞品支持手动编辑、追加;只有从品牌库选择品牌后,才可以收藏到品牌词库。AI 分析会尽量补齐候选竞品。",
|
||||
questionEmpty: "当前公司还没有可选问题",
|
||||
selectBrandFirst: "请先在顶部选择当前公司",
|
||||
competitors: "竞品支持手动编辑、追加;选择当前公司后,可以收藏到公司词库。AI 分析会尽量补齐候选竞品。",
|
||||
competitorEmptyEditable: "还没有竞品,先手动添加一条或点击分析让 AI 自动补齐。",
|
||||
templateFields: "这里保留当前模板自己的补充字段,用来约束 AI 生成角度。",
|
||||
titleSelection: "下一步前会由 AI 给出 5 个更合适的标题候选,你可以在这里挑选或改写。",
|
||||
@@ -839,7 +885,7 @@ const zhCN = {
|
||||
outlinePreview: "右侧会根据当前大纲实时预览最终文章框架。",
|
||||
outlineEmpty: "生成大纲后,这里会显示可编辑的文章结构。",
|
||||
review: "确认无误后提交,文章会进入生成队列。",
|
||||
competitorEmpty: "当前品牌下暂无竞品数据",
|
||||
competitorEmpty: "当前公司下暂无竞品数据",
|
||||
customTitle: "如需手动改写,可在这里输入最终标题",
|
||||
keyPoints: "补充希望文章强调的卖点、观点或风格要求",
|
||||
async: "后端会立即创建文章和任务记录,再异步完成正文生成。提交成功后,列表会自动刷新。",
|
||||
@@ -859,7 +905,7 @@ const zhCN = {
|
||||
review: {
|
||||
templateName: "模版名称",
|
||||
articleTitle: "文章标题",
|
||||
brandContext: "品牌上下文",
|
||||
brandContext: "公司上下文",
|
||||
outline: "结构段落",
|
||||
currentTemplate: "当前模版",
|
||||
promptVisibility: "Prompt 可见性",
|
||||
@@ -877,8 +923,8 @@ const zhCN = {
|
||||
actions: "操作",
|
||||
},
|
||||
placeholders: {
|
||||
brandLibrary: "从品牌库选择已有品牌",
|
||||
brandName: "输入公司名称,或从品牌库选择",
|
||||
brandLibrary: "选择当前公司",
|
||||
brandName: "顶部选择的当前公司",
|
||||
website: "输入官网地址,选填",
|
||||
keywords: "输入关键词后回车,可多选",
|
||||
primaryQuestion: "选择一个优化关键词",
|
||||
@@ -927,16 +973,16 @@ const zhCN = {
|
||||
},
|
||||
messages: {
|
||||
requiredField: "请先填写 {field}",
|
||||
missingBrand: "请先输入或选择公司名称",
|
||||
selectBrandBeforeQuestion: "请先从公司名称下拉选择品牌库对象后再选择优化关键词",
|
||||
missingBrand: "请先在顶部选择当前公司",
|
||||
selectBrandBeforeQuestion: "请先在顶部选择当前公司后再继续",
|
||||
missingPrimaryQuestion: "请选择一个优化关键词",
|
||||
missingTitle: "请先选择或输入文章标题",
|
||||
missingReviewIntroHook: "请先选择一个评测引言钩子",
|
||||
missingOutline: "请至少选择一个文章结构段落",
|
||||
missingGeneratedOutline: "请先生成并确认文章大纲",
|
||||
customOutlineTooLong: "自定义结构不能超过 {count} 个字",
|
||||
selectBrandBeforeCompetitors: "请先从公司名称下拉选择品牌库对象后再管理竞品",
|
||||
selectBrandBeforeFavorite: "请先从公司名称下拉选择品牌库对象后再收藏竞品",
|
||||
selectBrandBeforeCompetitors: "请先在顶部选择当前公司后再管理竞品",
|
||||
selectBrandBeforeFavorite: "请先在顶部选择当前公司后再收藏竞品",
|
||||
missingCompetitorName: "至少需要填写竞品名称后才能收藏",
|
||||
savedCompetitor: "竞品已收藏到品牌词库",
|
||||
unsavedCompetitor: "已取消收藏该竞品",
|
||||
|
||||
Reference in New Issue
Block a user