Просмотр исходного кода

feat: 补齐 IP 操盘服务与矩阵账号能力

Yi Jiarui 2 месяцев назад
Родитель
Сommit
286d629b57

+ 20 - 0
src/app/services/ip-matrix-account.service.spec.ts

@@ -0,0 +1,20 @@
+import { TestBed } from '@angular/core/testing';
+import { IpMatrixAccountService } from './ip-matrix-account.service';
+
+describe('IpMatrixAccountService', () => {
+  it('compares multiple accounts by positioning and topic overlap', () => {
+    TestBed.configureTestingModule({
+      providers: [IpMatrixAccountService],
+    });
+    const service = TestBed.inject(IpMatrixAccountService);
+    const report = service.compareAccounts([
+      { id: 'a1', name: '老板IP', persona: '传统企业老板陪跑', topics: ['获客', '短视频', '成交'] },
+      { id: 'a2', name: '员工IP', persona: '短视频执行教练', topics: ['拍摄', '短视频', '剪辑'] },
+    ]);
+
+    expect(report.accounts.length).toBe(2);
+    expect(report.overlapWarnings.join(' ')).toContain('短视频');
+    expect(report.differentiationSuggestions.length).toBe(2);
+    expect(report.collaborationSuggestions.join(' ')).toContain('评论区问题');
+  });
+});

+ 58 - 0
src/app/services/ip-matrix-account.service.ts

@@ -0,0 +1,58 @@
+import { Injectable } from '@angular/core';
+
+export interface MatrixAccountInput {
+  id: string;
+  name: string;
+  persona: string;
+  topics: string[];
+}
+
+export interface MatrixAccountCompareReport {
+  accounts: MatrixAccountInput[];
+  overlapWarnings: string[];
+  differentiationSuggestions: string[];
+  collaborationSuggestions: string[];
+}
+
+@Injectable({ providedIn: 'root' })
+export class IpMatrixAccountService {
+  compareAccounts(accounts: MatrixAccountInput[]): MatrixAccountCompareReport {
+    const normalized = accounts.map((account) => ({
+      ...account,
+      topics: [...new Set((account.topics || []).map((item) => item.trim()).filter(Boolean))],
+    }));
+    return {
+      accounts: normalized,
+      overlapWarnings: this.overlapWarnings(normalized),
+      differentiationSuggestions: normalized.map((account) =>
+        `${account.name} 保留「${account.persona || '独立人设'}」边界,标题、案例和栏目要避免与其他账号重复。`
+      ),
+      collaborationSuggestions: this.collaborationSuggestions(normalized),
+    };
+  }
+
+  private overlapWarnings(accounts: MatrixAccountInput[]): string[] {
+    const warnings: string[] = [];
+    for (let i = 0; i < accounts.length; i += 1) {
+      for (let j = i + 1; j < accounts.length; j += 1) {
+        const overlap = accounts[i].topics.filter((topic) => accounts[j].topics.includes(topic));
+        if (overlap.length) {
+          warnings.push(`${accounts[i].name} 与 ${accounts[j].name} 在「${overlap.join('、')}」上重复,需要拆分表达角度和承接任务。`);
+        }
+      }
+    }
+    return warnings;
+  }
+
+  private collaborationSuggestions(accounts: MatrixAccountInput[]): string[] {
+    if (accounts.length < 2) {
+      return ['当前只有一个账号,先稳定定位、内容支柱和更新节奏,再扩展矩阵。'];
+    }
+    const [main, ...assistants] = accounts;
+    const assistantNames = assistants.map((item) => item.name).join('、');
+    return [
+      `${main.name} 负责主观点、信任建立和转化承接;${assistantNames} 负责教程、案例、问题收集或垂直栏目。`,
+      '评论区问题先回流到主账号选题池,再分配给不同矩阵账号生成差异化脚本。',
+    ];
+  }
+}

Разница между файлами не показана из-за своего большого размера
+ 1444 - 4
src/app/services/ip-operator.service.spec.ts


Разница между файлами не показана из-за своего большого размера
+ 2133 - 317
src/app/services/ip-operator.service.ts


Некоторые файлы не были показаны из-за большого количества измененных файлов