chore: prepare project for server deployment

This commit is contained in:
amb
2026-09-09 17:43:07 +08:00
commit d0bcff2311
83 changed files with 24163 additions and 0 deletions
+95
View File
@@ -0,0 +1,95 @@
const Content = require('../src/models/Content');
const Page = require('../src/models/Page');
const { getDb, closeDb } = require('../src/config/database');
const { migrate } = require('../src/database/migrate');
beforeAll(() => {
migrate();
});
afterAll(() => {
closeDb();
});
describe('Content Model', () => {
let contentId;
test('应该创建内容', () => {
const content = Content.create({
title: '测试内容',
body: '这是测试内容的主体',
content_type: 'page',
publish_status: 'draft'
});
expect(content).toBeDefined();
expect(content.content_id).toBeDefined();
expect(content.title).toBe('测试内容');
expect(content.body).toBe('这是测试内容的主体');
expect(content.content_type).toBe('page');
expect(content.publish_status).toBe('draft');
contentId = content.content_id;
});
test('应该根据ID查找内容', () => {
const content = Content.findById(contentId);
expect(content).toBeDefined();
expect(content.content_id).toBe(contentId);
expect(content.title).toBe('测试内容');
});
test('应该更新内容', () => {
const updatedContent = Content.update(contentId, {
title: '更新后的内容',
body: '更新后的主体'
});
expect(updatedContent.title).toBe('更新后的内容');
expect(updatedContent.body).toBe('更新后的主体');
});
test('应该进行状态流转', () => {
// draft -> review
const reviewContent = Content.transitionStatus(contentId, 'review');
expect(reviewContent.publish_status).toBe('review');
// review -> published
const publishedContent = Content.transitionStatus(contentId, 'published');
expect(publishedContent.publish_status).toBe('published');
expect(publishedContent.version_no).toBe(2);
// published -> unpublished
const unpublishedContent = Content.transitionStatus(contentId, 'unpublished');
expect(unpublishedContent.publish_status).toBe('unpublished');
// unpublished -> historical
const historicalContent = Content.transitionStatus(contentId, 'historical');
expect(historicalContent.publish_status).toBe('historical');
expect(historicalContent.archived_at).toBeDefined();
});
test('应该创建历史版本', () => {
// 先创建一个新的内容
const newContent = Content.create({
title: '历史版本测试',
body: '这是历史版本测试的主体',
content_type: 'article',
publish_status: 'draft'
});
// 创建历史版本
const historicalVersion = Content.createHistoricalVersion(newContent.content_id);
expect(historicalVersion).toBeDefined();
expect(historicalVersion.version_no).toBe(newContent.version_no + 1);
expect(historicalVersion.publish_status).toBe('historical');
});
test('应该删除内容', () => {
const result = Content.delete(contentId);
expect(result.changes).toBe(1);
const content = Content.findById(contentId);
expect(content).toBeUndefined();
});
});
+104
View File
@@ -0,0 +1,104 @@
const Entity = require('../src/models/Entity');
const DirectedRelationship = require('../src/models/DirectedRelationship');
const { getDb, closeDb } = require('../src/config/database');
const { migrate } = require('../src/database/migrate');
beforeAll(() => {
migrate();
});
afterAll(() => {
closeDb();
});
describe('DirectedRelationship Model', () => {
let entity1Id, entity2Id, relId;
beforeAll(() => {
// 创建测试实体
const entity1 = Entity.create({
name: '实体1',
definition: '第一个测试实体'
});
entity1Id = entity1.entity_id;
const entity2 = Entity.create({
name: '实体2',
definition: '第二个测试实体'
});
entity2Id = entity2.entity_id;
});
test('应该创建关系', () => {
const relationship = DirectedRelationship.create({
source_entity_id: entity1Id,
relation_type: '包含',
target_entity_id: entity2Id,
rel_status: 'active',
authority_level: 3,
is_public: 1
});
expect(relationship).toBeDefined();
expect(relationship.rel_id).toBeDefined();
expect(relationship.source_entity_id).toBe(entity1Id);
expect(relationship.relation_type).toBe('包含');
expect(relationship.target_entity_id).toBe(entity2Id);
expect(relationship.rel_status).toBe('active');
expect(relationship.authority_level).toBe(3);
expect(relationship.is_public).toBe(1);
relId = relationship.rel_id;
});
test('应该根据ID查找关系', () => {
const relationship = DirectedRelationship.findById(relId);
expect(relationship).toBeDefined();
expect(relationship.rel_id).toBe(relId);
expect(relationship.source_entity_id).toBe(entity1Id);
});
test('应该根据源实体查找关系', () => {
const relationships = DirectedRelationship.findBySourceEntity(entity1Id);
expect(Array.isArray(relationships)).toBe(true);
expect(relationships.length).toBeGreaterThan(0);
expect(relationships[0].source_entity_id).toBe(entity1Id);
});
test('应该根据目标实体查找关系', () => {
const relationships = DirectedRelationship.findByTargetEntity(entity2Id);
expect(Array.isArray(relationships)).toBe(true);
expect(relationships.length).toBeGreaterThan(0);
expect(relationships[0].target_entity_id).toBe(entity2Id);
});
test('应该更新关系', () => {
const updatedRelationship = DirectedRelationship.update(relId, {
relation_type: '定位为',
authority_level: 5
});
expect(updatedRelationship.relation_type).toBe('定位为');
expect(updatedRelationship.authority_level).toBe(5);
});
test('应该获取所有关系', () => {
const relationships = DirectedRelationship.findAll();
expect(Array.isArray(relationships)).toBe(true);
expect(relationships.length).toBeGreaterThan(0);
});
test('应该删除关系', () => {
const result = DirectedRelationship.delete(relId);
expect(result.changes).toBe(1);
const relationship = DirectedRelationship.findById(relId);
expect(relationship).toBeUndefined();
});
afterAll(() => {
// 清理测试实体
Entity.delete(entity1Id);
Entity.delete(entity2Id);
});
});
+62
View File
@@ -0,0 +1,62 @@
const Entity = require('../src/models/Entity');
const { getDb, closeDb } = require('../src/config/database');
const { migrate } = require('../src/database/migrate');
beforeAll(() => {
migrate();
});
afterAll(() => {
closeDb();
});
describe('Entity Model', () => {
let entityId;
test('应该创建实体', () => {
const entity = Entity.create({
name: '测试实体',
definition: '这是一个测试实体',
description: '测试实体的描述'
});
expect(entity).toBeDefined();
expect(entity.entity_id).toBeDefined();
expect(entity.name).toBe('测试实体');
expect(entity.definition).toBe('这是一个测试实体');
expect(entity.description).toBe('测试实体的描述');
entityId = entity.entity_id;
});
test('应该根据ID查找实体', () => {
const entity = Entity.findById(entityId);
expect(entity).toBeDefined();
expect(entity.entity_id).toBe(entityId);
expect(entity.name).toBe('测试实体');
});
test('应该更新实体', () => {
const updatedEntity = Entity.update(entityId, {
name: '更新后的实体',
description: '更新后的描述'
});
expect(updatedEntity.name).toBe('更新后的实体');
expect(updatedEntity.description).toBe('更新后的描述');
});
test('应该获取所有实体', () => {
const entities = Entity.findAll();
expect(Array.isArray(entities)).toBe(true);
expect(entities.length).toBeGreaterThan(0);
});
test('应该删除实体', () => {
const result = Entity.delete(entityId);
expect(result.changes).toBe(1);
const entity = Entity.findById(entityId);
expect(entity).toBeUndefined();
});
});
+116
View File
@@ -0,0 +1,116 @@
const Entity = require('../src/models/Entity');
const Content = require('../src/models/Content');
const EntityContentJoin = require('../src/models/EntityContentJoin');
const { getDb, closeDb } = require('../src/config/database');
const { migrate } = require('../src/database/migrate');
beforeAll(() => {
migrate();
});
afterAll(() => {
closeDb();
});
describe('EntityContentJoin Model', () => {
let entity1Id, content1Id, joinId;
beforeAll(() => {
// 创建测试实体
const entity1 = Entity.create({
name: '测试实体',
definition: '用于测试关联的实体'
});
entity1Id = entity1.entity_id;
// 创建测试内容
const content1 = Content.create({
title: '测试内容',
body: '用于测试关联的内容',
content_type: 'article',
publish_status: 'draft'
});
content1Id = content1.content_id;
});
test('应该创建关联', () => {
const join = EntityContentJoin.create({
entity_id: entity1Id,
content_id: content1Id,
join_note: '测试关联备注'
});
expect(join).toBeDefined();
expect(join.join_id).toBeDefined();
expect(join.entity_id).toBe(entity1Id);
expect(join.content_id).toBe(content1Id);
expect(join.join_note).toBe('测试关联备注');
joinId = join.join_id;
});
test('应该根据ID查找关联', () => {
const join = EntityContentJoin.findById(joinId);
expect(join).toBeDefined();
expect(join.join_id).toBe(joinId);
expect(join.entity_id).toBe(entity1Id);
});
test('应该根据实体ID查找关联', () => {
const joins = EntityContentJoin.findByEntityId(entity1Id);
expect(Array.isArray(joins)).toBe(true);
expect(joins.length).toBeGreaterThan(0);
expect(joins[0].entity_id).toBe(entity1Id);
});
test('应该根据内容ID查找关联', () => {
const joins = EntityContentJoin.findByContentId(content1Id);
expect(Array.isArray(joins)).toBe(true);
expect(joins.length).toBeGreaterThan(0);
expect(joins[0].content_id).toBe(content1Id);
});
test('应该更新关联', () => {
const updatedJoin = EntityContentJoin.update(joinId, {
join_note: '更新后的关联备注'
});
expect(updatedJoin.join_note).toBe('更新后的关联备注');
});
test('应该获取所有关联', () => {
const joins = EntityContentJoin.findAll();
expect(Array.isArray(joins)).toBe(true);
expect(joins.length).toBeGreaterThan(0);
});
test('应该删除关联', () => {
const result = EntityContentJoin.delete(joinId);
expect(result.changes).toBe(1);
const join = EntityContentJoin.findById(joinId);
expect(join).toBeUndefined();
});
test('应该根据实体和内容删除关联', () => {
// 重新创建关联
const newJoin = EntityContentJoin.create({
entity_id: entity1Id,
content_id: content1Id
});
// 删除关联
const result = EntityContentJoin.deleteByEntityAndContent(entity1Id, content1Id);
expect(result.changes).toBe(1);
// 验证删除
const join = EntityContentJoin.findById(newJoin.join_id);
expect(join).toBeUndefined();
});
afterAll(() => {
// 清理测试数据
Entity.delete(entity1Id);
Content.delete(content1Id);
});
});
+211
View File
@@ -0,0 +1,211 @@
# 阿美巴AI官网 第三期 测试脚本运行说明
## 概述
本目录包含第三期AI认知验证闭环的所有测试脚本,用于验证整套站点是否满足产品核心目标:AI可以发现、理解、验证阿美巴知识网络。
## 目录结构
```
tests/
├── ai_cognitive_testset.md # AI认知测试集文档
├── crawler/ # 爬虫校验脚本
│ └── crawler.js
├── content_filter/ # 内容边界校验脚本
│ ├── content_filter.js
│ └── ten_questions.js
├── project_audit.js # V1.0全项目盘点脚本
├── reports/ # 测试报告输出目录
└── README.md # 本说明文档
```
## 前置条件
### 1. 环境要求
- Node.js >= 14.x
- npm >= 6.x
### 2. 服务要求
- 后端服务运行中(默认端口3000)
- 前端服务运行中(默认端口3000)
### 3. 启动服务
```bash
# 启动后端服务
cd /Users/mac/Documents/GrowthMini/测试/AI官网升级版
npm run dev
# 启动前端服务(新终端)
cd /Users/mac/Documents/GrowthMini/测试/AI官网升级版/frontend
npm run dev
```
## 测试脚本运行
### 1. 模拟抓取校验脚本
**功能**: 自动遍历全站sitemap.xml,抓取全部公开页面,校验页面质量
**运行命令**:
```bash
cd /Users/mac/Documents/GrowthMini/测试/AI官网升级版
node tests/crawler/crawler.js
```
**校验内容**:
- HTTP状态码(404/500异常页面告警)
- H1标签唯一性
- H2/H3标题层级规范
- JSON-LD结构化数据语法合法性
- 内部语义链接可访问性
**输出报告**:
- `tests/reports/crawler_report.json` - JSON格式报告
- `tests/reports/crawler_report.md` - 可读格式报告
### 2. 内容边界隔离校验脚本
**功能**: 自动校验draft/review/unpublished/historical状态内容是否在公开页面不可见
**运行命令**:
```bash
cd /Users/mac/Documents/GrowthMini/测试/AI官网升级版
node tests/content_filter/content_filter.js
```
**校验内容**:
- draft状态内容在公开页面不可见
- review状态内容在公开页面不可见
- unpublished状态内容在公开页面不可见
- historical状态内容在公开页面不可见
- 仅published状态内容对外暴露
- 历史版本数据仅存在后台CMS
**输出报告**:
- `tests/reports/content_filter_report.json` - JSON格式报告
- `tests/reports/content_filter_report.md` - 可读格式报告
### 3. 十问认知基线校验模块
**功能**: 读取站点公开页面内容,提取核心文本、实体定义、实体关系,和产品文档《十问》标准答案做文本比对校验
**运行命令**:
```bash
cd /Users/mac/Documents/GrowthMini/测试/AI官网升级版
node tests/content_filter/ten_questions.js
```
**校验内容**:
- 阿美巴是谁?
- 什么是企业进化?
- 为什么目标先于问题?
- 四大价值是什么?
- A/M-B是什么?
- 企业进化需要哪些能力?
- 如何判断企业处于哪个阶段?
- 阿美巴提供什么服务?
- 如何开始企业进化?
- 企业进化的价值是什么?
**输出报告**:
- `tests/reports/ten_questions_report.json` - JSON格式报告
- `tests/reports/ten_questions_report.md` - 可读格式报告
### 4. V1.0全项目盘点脚本
**功能**: 自动扫描全项目代码库,生成盘点报告
**运行命令**:
```bash
cd /Users/mac/Documents/GrowthMini/测试/AI官网升级版
node tests/project_audit.js
```
**校验内容**:
- V1.0必须实现清单(50项)
- V1.0明确不做清单(10项)
- 代码预埋排查
**输出报告**:
- `tests/reports/project_audit_report.json` - JSON格式报告
- `tests/reports/project_audit_report.md` - 可读格式报告
## 环境变量配置
可以通过环境变量自定义配置:
```bash
# 设置后端服务地址
export BASE_URL=http://localhost:3000
# 运行脚本
node tests/crawler/crawler.js
```
## 测试报告说明
### 报告格式
所有脚本都会生成两种格式的报告:
1. **JSON报告**: 机器可读格式,便于自动化处理
2. **MD报告**: 人类可读格式,便于查看和分享
### 报告内容
- **摘要**: 总数、通过数、失败数、通过率
- **失败详情**: 失败项的具体信息
- **建议修复方案**: 针对失败项的修复建议
## 常见问题
### Q1: 脚本运行报错 "Cannot find module"
**解决方案**: 安装依赖
```bash
cd /Users/mac/Documents/GrowthMini/测试/AI官网升级版
npm install
```
### Q2: 脚本运行报错 "请求超时"
**解决方案**: 确保后端服务已启动
```bash
cd /Users/mac/Documents/GrowthMini/测试/AI官网升级版
npm run dev
```
### Q3: 报告中显示大量失败项
**可能原因**:
1. 服务未启动
2. 端口配置错误
3. 网络连接问题
**解决方案**:
1. 确保服务已启动
2. 检查端口配置
3. 检查网络连接
### Q4: 如何自定义测试页面列表
**解决方案**: 修改脚本中的页面列表
```javascript
// 在crawler.js中修改
const pages = [
'/',
'/about',
// 添加更多页面
];
```
## 注意事项
1. **测试环境**: 建议在测试环境运行,避免影响生产环境
2. **数据准备**: 确保CMS中已录入测试数据
3. **服务状态**: 确保后端和前端服务正常运行
4. **报告归档**: 定期归档测试报告,便于追溯
## 联系方式
如有问题,请联系开发团队。
+575
View File
@@ -0,0 +1,575 @@
# AI认知测试集
项目编号:阿美巴AI官网-20260908-03
产品真相源:《阿美巴AI官网|项目总指令 V1.2 FINAL(产品冻结版)》
用途:验证AI是否能正确发现、理解、验证阿美巴知识网络
## 一、测试集概述
### 1.1 测试目标
- 验证AI是否能正确识别阿美巴核心实体
- 验证AI是否能正确读取实体定义和实体关系
- 验证AI输出是否对齐产品文档《十问》标准答案
- 验证内容边界隔离是否有效
### 1.2 测试范围
- 实体认知用例:检验AI对核心实体的理解
- 十问认知用例:检验AI对标准问答的掌握
- 内容边界用例:检验非published内容的隔离性
### 1.3 测试方法
- 静态文本比对
- 结构化数据验证
- 内容可访问性检查
---
## 二、实体认知用例
### 2.1 阿美巴实体
#### 测试用例:TC-ENTITY-001
- **测试目标**:AI是否能正确识别"阿美巴"实体
- **测试方法**:搜索"阿美巴"关键词,验证是否返回正确定义
- **预期标准答案**:阿美巴(Ameiba)是AI时代企业进化平台
- **校验要点**:
1. 搜索结果包含"阿美巴"实体
2. 实体定义包含"AI时代企业进化平台"
3. 实体描述包含定位、使命等信息
- **失败判定**:
- 搜索无结果
- 定义错误或不完整
- 与产品文档定义不符
#### 测试用例:TC-ENTITY-002
- **测试目标**:AI是否能正确识别阿美巴的服务对象
- **测试方法**:访问/about页面,验证服务对象描述
- **预期标准答案**:服务对象是希望在AI时代实现转型与增长的企业
- **校验要点**:
1. 页面包含服务对象描述
2. 描述与产品文档一致
- **失败判定**:
- 页面无服务对象描述
- 描述与产品文档不符
---
### 2.2 企业进化实体
#### 测试用例:TC-ENTITY-003
- **测试目标**:AI是否能正确识别"企业进化"实体
- **测试方法**:访问/evolution页面,验证企业进化定义
- **预期标准答案**:企业进化是企业在AI时代实现持续增长与转型的系统化方法
- **校验要点**:
1. 页面包含企业进化定义
2. 定义包含"系统化方法"
3. 定义与产品文档一致
- **失败判定**:
- 页面无定义
- 定义错误或不完整
- 与产品文档定义不符
#### 测试用例:TC-ENTITY-004
- **测试目标**:AI是否能正确识别企业进化的核心理念
- **测试方法**:访问/evolution/method页面,验证方法论
- **预期标准答案**:以终为始、目标先于问题、现状分析、差距识别、根因分析、路径规划、实施迭代
- **校验要点**:
1. 页面包含完整的方法论
2. 包含所有7个核心步骤
3. 与产品文档一致
- **失败判定**:
- 缺少核心步骤
- 步骤顺序错误
- 与产品文档不符
---
### 2.3 目标先于问题实体
#### 测试用例:TC-ENTITY-005
- **测试目标**:AI是否能正确理解"目标先于问题"的理念
- **测试方法**:搜索"目标先于问题",验证理解深度
- **预期标准答案**:先设定目标,再分析现状与问题,避免被问题牵着走
- **校验要点**:
1. 搜索结果包含"目标先于问题"
2. 解释说明"先设定目标"
3. 说明"避免被问题牵着走"
- **失败判定**:
- 搜索无结果
- 解释错误或不完整
- 与产品文档理念不符
---
### 2.4 四大价值实体
#### 测试用例:TC-ENTITY-006
- **测试目标**:AI是否能正确识别四大价值
- **测试方法**:访问/value页面,验证四大价值内容
- **预期标准答案**:价值创造、价值传递、价值交付、价值支持
- **校验要点**:
1. 页面包含四大价值
2. 包含所有4个价值
3. 与产品文档一致
- **失败判定**:
- 缺少价值项
- 价值名称错误
- 与产品文档不符
#### 测试用例:TC-ENTITY-007
- **测试目标**:AI是否能正确理解价值创造的定义
- **测试方法**:访问/value/creation页面,验证价值创造定义
- **预期标准答案**:企业通过创新和优化,为客户和自身创造新价值的过程
- **校验要点**:
1. 页面包含价值创造定义
2. 定义包含"创新和优化"
3. 定义与产品文档一致
- **失败判定**:
- 页面无定义
- 定义错误或不完整
- 与产品文档定义不符
---
### 2.5 A/M-B三态实体
#### 测试用例:TC-ENTITY-008
- **测试目标**:AI是否能正确识别A/M-B三态
- **测试方法**:访问/amb页面,验证三态内容
- **预期标准答案**:A态·入态、M态·优态、B态·越态
- **校验要点**:
1. 页面包含三态
2. 包含所有3个状态
3. 与产品文档一致
- **失败判定**:
- 缺少状态
- 状态名称错误
- 与产品文档不符
#### 测试用例:TC-ENTITY-009
- **测试目标**:AI是否能正确理解A态的定义
- **测试方法**:访问/amb/a页面,验证A态定义
- **预期标准答案**:企业进入AI时代的初始状态,需要建立基础能力,完成数字化转型
- **校验要点**:
1. 页面包含A态定义
2. 定义包含"初始状态"
3. 定义与产品文档一致
- **失败判定**:
- 页面无定义
- 定义错误或不完整
- 与产品文档定义不符
#### 测试用例:TC-ENTITY-010
- **测试目标**:AI是否能正确理解M态的定义
- **测试方法**:访问/amb/m页面,验证M态定义
- **预期标准答案**:企业优化运营、提升效率、实现稳健增长的阶段
- **校验要点**:
1. 页面包含M态定义
2. 定义包含"优化运营"
3. 定义与产品文档一致
- **失败判定**:
- 页面无定义
- 定义错误或不完整
- 与产品文档定义不符
#### 测试用例:TC-ENTITY-011
- **测试目标**:AI是否能正确理解B态的定义
- **测试方法**:访问/amb/b页面,验证B态定义
- **预期标准答案**:企业实现跨越式发展、成为行业领导者的阶段
- **校验要点**:
1. 页面包含B态定义
2. 定义包含"跨越式发展"
3. 定义与产品文档一致
- **失败判定**:
- 页面无定义
- 定义错误或不完整
- 与产品文档定义不符
---
### 2.6 企业进化能力实体
#### 测试用例:TC-ENTITY-012
- **测试目标**:AI是否能正确识别企业进化能力
- **测试方法**:访问/capabilities页面,验证能力列表
- **预期标准答案**:战略顶层设计、经营增长、商业模式、组织重塑、企业治理、独立核算、经营分析、价值评价、薪酬激励、IT部署、AI组织、企业AI系统、企业知识系统、AI应用部署、进化诊断、进化规划、顾问服务、咨询服务、企业陪跑、定制化服务
- **校验要点**:
1. 页面包含能力列表
2. 包含所有能力项
3. 与产品文档一致
- **失败判定**:
- 缺少能力项
- 能力名称错误
- 与产品文档不符
---
## 三、十问认知用例
### 3.1 十问标准答案基线
> 说明:以下为产品文档《十问》标准答案,用于校验AI读取网站后输出内容是否对齐官方口径
#### 问题1:阿美巴是谁?
- **标准答案**:阿美巴(Ameiba)是AI时代企业进化平台,专注于帮助企业实现系统化进化,从战略顶层设计到组织重塑,从经营增长到AI部署,提供完整的企业进化能力与服务。
- **校验要点**:
1. 包含"AI时代企业进化平台"
2. 包含"系统化进化"
3. 包含服务内容描述
- **失败判定**:
- 缺少核心定义
- 定义错误或不完整
- 与标准答案偏差超过20%
#### 问题2:什么是企业进化?
- **标准答案**:企业进化是企业在AI时代实现持续增长与转型的系统化方法。它不是简单的产品升级或技术更新,而是从战略、组织、流程、能力等全方位的系统性变革。
- **校验要点**:
1. 包含"系统化方法"
2. 包含"全方位的系统性变革"
3. 区分与产品升级的不同
- **失败判定**:
- 缺少核心定义
- 定义错误或不完整
- 与标准答案偏差超过20%
#### 问题3:为什么目标先于问题?
- **标准答案**:传统的问题导向方法容易让企业陷入"救火"模式,被动应对各种问题。而目标导向的方法让企业主动设定方向,有计划地推进进化。只有先明确目标,才能判断哪些问题是真正需要解决的,哪些问题是次要的,从而集中资源解决关键问题。
- **校验要点**:
1. 包含"目标导向"
2. 包含"主动设定方向"
3. 说明与问题导向的区别
- **失败判定**:
- 缺少核心理念
- 理念错误或不完整
- 与标准答案偏差超过20%
#### 问题4:四大价值是什么?
- **标准答案**:四大价值包括价值创造、价值传递、价值交付、价值支持。价值创造是基础,价值传递是桥梁,价值交付是结果,价值支持是保障。企业需要在这四个维度上协调发展,才能实现持续增长。
- **校验要点**:
1. 包含四大价值名称
2. 包含各价值的角色定位
3. 说明四者关系
- **失败判定**:
- 缺少价值项
- 价值名称错误
- 与标准答案偏差超过20%
#### 问题5:A/M-B是什么?
- **标准答案**:A/M-B是企业进化阶段模型,描述了企业在AI时代进化的三个阶段。A态·入态是企业进入AI时代的初始状态,需要建立基础能力;M态·优态是企业优化运营、提升效率的阶段;B态·越态是企业实现跨越式发展、成为行业领导者的阶段。这是企业进化的阶段模型,不是产品套餐。
- **校验要点**:
1. 包含"阶段模型"
2. 包含三态定义
3. 明确"不是产品套餐"
- **失败判定**:
- 缺少阶段模型定义
- 三态定义错误
- 与标准答案偏差超过20%
#### 问题6:企业进化需要哪些能力?
- **标准答案**:企业进化需要完整的能力体系,包括战略顶层设计、经营增长、商业模式、组织重塑、企业治理、独立核算、经营分析、价值评价、薪酬激励、IT部署、AI组织、企业AI系统、企业知识系统、AI应用部署等。这些能力是底层实体,不是产品套餐。
- **校验要点**:
1. 包含核心能力列表
2. 明确"底层实体"
3. 明确"不是产品套餐"
- **失败判定**:
- 缺少能力列表
- 能力名称错误
- 与标准答案偏差超过20%
#### 问题7:如何判断企业处于哪个阶段?
- **标准答案**:企业可以根据自身特征判断所处阶段:A态企业通常数字化程度较低,缺乏系统化管理方法;M态企业数字化程度较高,运营效率持续优化;B态企业处于行业领先地位,具备强大创新能力。判断依据包括数字化程度、运营效率、组织能力、创新能力等维度。
- **校验要点**:
1. 包含各阶段特征
2. 包含判断维度
3. 与产品文档一致
- **失败判定**:
- 缺少阶段特征
- 特征描述错误
- 与标准答案偏差超过20%
#### 问题8:阿美巴提供什么服务?
- **标准答案**:阿美巴提供顾问服务、咨询服务、企业陪跑、定制化服务等。服务内容包括企业进化诊断、进化路径规划、战略咨询、组织变革咨询、AI部署咨询等。具体服务根据企业需求和阶段匹配。
- **校验要点**:
1. 包含服务类型
2. 包含服务内容
3. 说明匹配逻辑
- **失败判定**:
- 缺少服务类型
- 服务内容错误
- 与标准答案偏差超过20%
#### 问题9:如何开始企业进化?
- **标准答案**:企业进化从明确目标开始。首先确定企业进化的终极目标,然后分析现状与目标的差距,识别关键障碍,制定进化路径,分阶段实施,持续迭代优化。阿美巴可以提供专业诊断和规划服务,帮助企业制定适合的进化方案。
- **校验要点**:
1. 包含"明确目标"
2. 包含实施步骤
3. 说明阿美巴的作用
- **失败判定**:
- 缺少核心步骤
- 步骤描述错误
- 与标准答案偏差超过20%
#### 问题10:企业进化的价值是什么?
- **标准答案**:企业进化的价值在于帮助企业在AI时代实现可持续增长与发展。通过系统化的进化方法,企业可以提升运营效率、增强创新能力、优化组织结构、提高市场竞争力,最终实现从传统模式向AI时代模式的转型。
- **校验要点**:
1. 包含"可持续增长与发展"
2. 包含具体价值点
3. 说明转型目标
- **失败判定**:
- 缺少核心价值
- 价值描述错误
- 与标准答案偏差超过20%
---
### 3.2 十问测试用例
#### 测试用例:TC-TEN-001
- **测试目标**:AI是否能正确回答"阿美巴是谁?"
- **测试方法**:访问/about页面,提取核心定义
- **预期标准答案**:见问题1标准答案
- **校验要点**:
1. 页面包含标准答案核心内容
2. 内容与标准答案偏差不超过20%
- **失败判定**:
- 页面无相关内容
- 内容与标准答案偏差超过20%
#### 测试用例:TC-TEN-002
- **测试目标**:AI是否能正确回答"什么是企业进化?"
- **测试方法**:访问/evolution页面,提取核心定义
- **预期标准答案**:见问题2标准答案
- **校验要点**:
1. 页面包含标准答案核心内容
2. 内容与标准答案偏差不超过20%
- **失败判定**:
- 页面无相关内容
- 内容与标准答案偏差超过20%
#### 测试用例:TC-TEN-003
- **测试目标**:AI是否能正确回答"为什么目标先于问题?"
- **测试方法**:访问/evolution/method页面,提取核心理念
- **预期标准答案**:见问题3标准答案
- **校验要点**:
1. 页面包含标准答案核心内容
2. 内容与标准答案偏差不超过20%
- **失败判定**:
- 页面无相关内容
- 内容与标准答案偏差超过20%
#### 测试用例:TC-TEN-004
- **测试目标**:AI是否能正确回答"四大价值是什么?"
- **测试方法**:访问/value页面,提取核心内容
- **预期标准答案**:见问题4标准答案
- **校验要点**:
1. 页面包含标准答案核心内容
2. 内容与标准答案偏差不超过20%
- **失败判定**:
- 页面无相关内容
- 内容与标准答案偏差超过20%
#### 测试用例:TC-TEN-005
- **测试目标**:AI是否能正确回答"A/M-B是什么?"
- **测试方法**:访问/amb页面,提取核心定义
- **预期标准答案**:见问题5标准答案
- **校验要点**:
1. 页面包含标准答案核心内容
2. 内容与标准答案偏差不超过20%
- **失败判定**:
- 页面无相关内容
- 内容与标准答案偏差超过20%
#### 测试用例:TC-TEN-006
- **测试目标**:AI是否能正确回答"企业进化需要哪些能力?"
- **测试方法**:访问/capabilities页面,提取能力列表
- **预期标准答案**:见问题6标准答案
- **校验要点**:
1. 页面包含标准答案核心内容
2. 内容与标准答案偏差不超过20%
- **失败判定**:
- 页面无相关内容
- 内容与标准答案偏差超过20%
#### 测试用例:TC-TEN-007
- **测试目标**:AI是否能正确回答"如何判断企业处于哪个阶段?"
- **测试方法**:访问/amb页面,提取阶段特征
- **预期标准答案**:见问题7标准答案
- **校验要点**:
1. 页面包含标准答案核心内容
2. 内容与标准答案偏差不超过20%
- **失败判定**:
- 页面无相关内容
- 内容与标准答案偏差超过20%
#### 测试用例:TC-TEN-008
- **测试目标**:AI是否能正确回答"阿美巴提供什么服务?"
- **测试方法**:访问/capabilities和/contact页面,提取服务内容
- **预期标准答案**:见问题8标准答案
- **校验要点**:
1. 页面包含标准答案核心内容
2. 内容与标准答案偏差不超过20%
- **失败判定**:
- 页面无相关内容
- 内容与标准答案偏差超过20%
#### 测试用例:TC-TEN-009
- **测试目标**:AI是否能正确回答"如何开始企业进化?"
- **测试方法**:访问/evolution/method页面,提取实施步骤
- **预期标准答案**:见问题9标准答案
- **校验要点**:
1. 页面包含标准答案核心内容
2. 内容与标准答案偏差不超过20%
- **失败判定**:
- 页面无相关内容
- 内容与标准答案偏差超过20%
#### 测试用例:TC-TEN-010
- **测试目标**:AI是否能正确回答"企业进化的价值是什么?"
- **测试方法**:访问首页和/value页面,提取核心价值
- **预期标准答案**:见问题10标准答案
- **校验要点**:
1. 页面包含标准答案核心内容
2. 内容与标准答案偏差不超过20%
- **失败判定**:
- 页面无相关内容
- 内容与标准答案偏差超过20%
---
## 四、内容边界隔离用例
### 4.1 状态隔离测试
#### 测试用例:TC-BOUNDARY-001
- **测试目标**:draft状态内容是否在公开页面不可见
- **测试方法**:检查所有公开页面,验证不包含draft状态内容
- **预期结果**:所有公开页面不包含draft状态内容
- **校验要点**:
1. 页面不显示draft内容
2. 接口不返回draft内容
3. sitemap不包含draft内容
- **失败判定**:
- 任何公开页面显示draft内容
- 接口返回draft内容
- sitemap包含draft内容
#### 测试用例:TC-BOUNDARY-002
- **测试目标**:review状态内容是否在公开页面不可见
- **测试方法**:检查所有公开页面,验证不包含review状态内容
- **预期结果**:所有公开页面不包含review状态内容
- **校验要点**:
1. 页面不显示review内容
2. 接口不返回review内容
3. sitemap不包含review内容
- **失败判定**:
- 任何公开页面显示review内容
- 接口返回review内容
- sitemap包含review内容
#### 测试用例:TC-BOUNDARY-003
- **测试目标**:unpublished状态内容是否在公开页面不可见
- **测试方法**:检查所有公开页面,验证不包含unpublished状态内容
- **预期结果**:所有公开页面不包含unpublished状态内容
- **校验要点**:
1. 页面不显示unpublished内容
2. 接口不返回unpublished内容
3. sitemap不包含unpublished内容
- **失败判定**:
- 任何公开页面显示unpublished内容
- 接口返回unpublished内容
- sitemap包含unpublished内容
#### 测试用例:TC-BOUNDARY-004
- **测试目标**:historical状态内容是否在公开页面不可见
- **测试方法**:检查所有公开页面,验证不包含historical状态内容
- **预期结果**:所有公开页面不包含historical状态内容
- **校验要点**:
1. 页面不显示historical内容
2. 接口不返回historical内容
3. sitemap不包含historical内容
- **失败判定**:
- 任何公开页面显示historical内容
- 接口返回historical内容
- sitemap包含historical内容
### 4.2 可见性测试
#### 测试用例:TC-BOUNDARY-005
- **测试目标**:仅published状态内容是否对外暴露
- **测试方法**:检查所有公开页面,验证仅包含published状态内容
- **预期结果**:所有公开页面仅包含published状态内容
- **校验要点**:
1. 页面仅显示published内容
2. 接口仅返回published内容
3. sitemap仅包含published内容
- **失败判定**:
- 任何公开页面显示非published内容
- 接口返回非published内容
- sitemap包含非published内容
### 4.3 历史版本隔离测试
#### 测试用例:TC-BOUNDARY-006
- **测试目标**:历史版本数据是否仅存在后台CMS
- **测试方法**:检查前端和公开接口,验证不包含历史版本数据
- **预期结果**:前端和公开接口不包含历史版本数据
- **校验要点**:
1. 前端页面不显示历史版本
2. 公开接口不返回历史版本
3. 历史版本仅在后台CMS可见
- **失败判定**:
- 前端页面显示历史版本
- 公开接口返回历史版本
- 历史版本在前端或公开接口可见
---
## 五、测试执行说明
### 5.1 执行环境
- Node.js >= 14.x
- npm >= 6.x
- 后端服务运行中(端口3000)
- 前端服务运行中(端口3000)
### 5.2 执行步骤
1. 启动后端服务:`npm run dev`
2. 启动前端服务:`cd frontend && npm run dev`
3. 执行测试脚本:
- 模拟抓取校验:`node tests/crawler/crawler.js`
- 内容边界校验:`node tests/content_filter/content_filter.js`
- 十问基线校验:`node tests/content_filter/ten_questions.js`
4. 查看测试报告
### 5.3 结果判定
- **通过**:所有测试用例通过
- **警告**:部分测试用例失败,但不影响核心功能
- **失败**:核心测试用例失败,需要修复
### 5.4 报告格式
测试报告包含:
- 测试用例总数
- 通过用例数
- 失败用例数
- 警告用例数
- 失败用例详情
- 建议修复方案
---
## 六、测试集维护
### 6.1 版本管理
- 测试集版本:V1.0
- 创建日期:2026-09-08
- 维护人员:开发团队
### 6.2 更新规则
- 当产品文档更新时,同步更新测试集
- 当新增功能时,补充相应测试用例
- 当发现缺陷时,添加回归测试用例
### 6.3 归档规则
- 每次测试完成后,归档测试报告
- 保留历史测试报告,便于追溯
- 定期清理过期测试数据
+515
View File
@@ -0,0 +1,515 @@
/**
* 内容边界隔离校验脚本
* 自动校验draft/review/unpublished/historical状态内容是否在公开页面不可见
*/
const https = require('https');
const http = require('http');
const { JSDOM } = require('jsdom');
const fs = require('fs');
const path = require('path');
// 配置
const CONFIG = {
baseUrl: process.env.BASE_URL || 'http://localhost:3000',
timeout: 10000,
outputDir: path.join(__dirname, '../reports'),
};
// 测试结果
const results = {
totalChecks: 0,
passedChecks: 0,
failedChecks: 0,
errors: [],
details: [],
};
/**
* 获取页面内容
*/
function fetchPage(url) {
return new Promise((resolve, reject) => {
const protocol = url.startsWith('https') ? https : http;
const timeout = CONFIG.timeout;
const req = protocol.get(url, { timeout }, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
resolve({
status: res.statusCode,
headers: res.headers,
body: data,
url: url,
});
});
});
req.on('error', (err) => {
reject(err);
});
req.on('timeout', () => {
req.destroy();
reject(new Error('请求超时'));
});
});
}
/**
* 获取API响应
*/
function fetchApi(url) {
return new Promise((resolve, reject) => {
const protocol = url.startsWith('https') ? https : http;
const timeout = CONFIG.timeout;
const req = protocol.get(url, { timeout }, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
try {
const jsonData = JSON.parse(data);
resolve({
status: res.statusCode,
headers: res.headers,
data: jsonData,
url: url,
});
} catch (error) {
resolve({
status: res.statusCode,
headers: res.headers,
data: null,
raw: data,
url: url,
});
}
});
});
req.on('error', (err) => {
reject(err);
});
req.on('timeout', () => {
req.destroy();
reject(new Error('请求超时'));
});
});
}
/**
* 检查页面是否包含非published状态内容
*/
function checkPageContent(html, url) {
const dom = new JSDOM(html);
const body = dom.window.document.body.textContent.toLowerCase();
// 非published状态的关键词
const nonPublishedKeywords = [
'draft',
'review',
'unpublished',
'historical',
'草稿',
'审核中',
'已下线',
'历史版本',
];
const foundKeywords = [];
nonPublishedKeywords.forEach((keyword) => {
if (body.includes(keyword)) {
foundKeywords.push(keyword);
}
});
return {
valid: foundKeywords.length === 0,
message: foundKeywords.length === 0
? '页面不包含非published状态内容'
: `页面包含非published状态关键词: ${foundKeywords.join(', ')}`,
foundKeywords: foundKeywords,
};
}
/**
* 检查API是否返回非published状态内容
*/
function checkApiContent(data, url) {
const issues = [];
// 检查返回的数据
function checkItem(item) {
if (item && item.publish_status && item.publish_status !== 'published') {
issues.push({
id: item.content_id || item.entity_id,
title: item.title || item.name,
status: item.publish_status,
});
}
}
// 递归检查数据
if (Array.isArray(data)) {
data.forEach(checkItem);
} else if (data && typeof data === 'object') {
if (data.list && Array.isArray(data.list)) {
data.list.forEach(checkItem);
} else {
checkItem(data);
}
}
return {
valid: issues.length === 0,
message: issues.length === 0
? 'API不返回非published状态内容'
: `API返回${issues.length}条非published状态内容`,
issues: issues,
};
}
/**
* 检查sitemap是否包含非published状态内容
*/
function checkSitemap(html) {
const dom = new JSDOM(html);
const urls = dom.window.document.querySelectorAll('url');
const issues = [];
urls.forEach((url) => {
const loc = url.querySelector('loc');
if (loc) {
const urlStr = loc.textContent.toLowerCase();
// 检查URL是否包含非published状态标识
if (urlStr.includes('draft') || urlStr.includes('review') ||
urlStr.includes('unpublished') || urlStr.includes('historical')) {
issues.push(urlStr);
}
}
});
return {
valid: issues.length === 0,
message: issues.length === 0
? 'sitemap不包含非published状态内容'
: `sitemap包含${issues.length}条非published状态URL`,
issues: issues,
};
}
/**
* 校验公开页面
*/
async function validatePublicPages() {
const pages = [
'/',
'/about',
'/evolution',
'/evolution/method',
'/value',
'/value/creation',
'/value/transfer',
'/value/delivery',
'/value/support',
'/amb',
'/amb/a',
'/amb/m',
'/amb/b',
'/capabilities',
'/cases',
'/knowledge',
'/concepts',
'/faq',
'/match',
'/contact',
];
const pageResults = [];
for (const pagePath of pages) {
const url = `${CONFIG.baseUrl}${pagePath}`;
console.log(`校验页面: ${url}`);
try {
const response = await fetchPage(url);
const checkResult = checkPageContent(response.body, url);
pageResults.push({
url: url,
status: response.status,
check: checkResult,
});
results.totalChecks++;
if (checkResult.valid) {
results.passedChecks++;
console.log(` ✓ ${checkResult.message}`);
} else {
results.failedChecks++;
results.errors.push({
url: url,
error: checkResult.message,
keywords: checkResult.foundKeywords,
});
console.log(` ✗ ${checkResult.message}`);
}
} catch (error) {
results.totalChecks++;
results.failedChecks++;
results.errors.push({
url: url,
error: `页面访问失败: ${error.message}`,
});
console.log(` ✗ 页面访问失败: ${error.message}`);
}
}
return pageResults;
}
/**
* 校验公开API
*/
async function validatePublicApis() {
const apis = [
'/api/public/entities',
'/api/public/contents',
'/api/public/contents?type=page',
'/api/public/contents?type=article',
'/api/public/contents?type=case',
'/api/public/contents?type=faq',
'/api/public/contents?type=capability',
'/api/public/contents?type=service',
];
const apiResults = [];
for (const apiPath of apis) {
const url = `${CONFIG.baseUrl}${apiPath}`;
console.log(`校验API: ${url}`);
try {
const response = await fetchApi(url);
const checkResult = checkApiContent(response.data, url);
apiResults.push({
url: url,
status: response.status,
check: checkResult,
});
results.totalChecks++;
if (checkResult.valid) {
results.passedChecks++;
console.log(` ✓ ${checkResult.message}`);
} else {
results.failedChecks++;
results.errors.push({
url: url,
error: checkResult.message,
issues: checkResult.issues,
});
console.log(` ✗ ${checkResult.message}`);
}
} catch (error) {
results.totalChecks++;
results.failedChecks++;
results.errors.push({
url: url,
error: `API访问失败: ${error.message}`,
});
console.log(` ✗ API访问失败: ${error.message}`);
}
}
return apiResults;
}
/**
* 校验sitemap
*/
async function validateSitemap() {
const url = `${CONFIG.baseUrl}/sitemap.xml`;
console.log(`校验sitemap: ${url}`);
try {
const response = await fetchPage(url);
const checkResult = checkSitemap(response.body);
results.totalChecks++;
if (checkResult.valid) {
results.passedChecks++;
console.log(` ✓ ${checkResult.message}`);
} else {
results.failedChecks++;
results.errors.push({
url: url,
error: checkResult.message,
issues: checkResult.issues,
});
console.log(` ✗ ${checkResult.message}`);
}
return {
url: url,
status: response.status,
check: checkResult,
};
} catch (error) {
results.totalChecks++;
results.failedChecks++;
results.errors.push({
url: url,
error: `sitemap访问失败: ${error.message}`,
});
console.log(` ✗ sitemap访问失败: ${error.message}`);
return {
url: url,
status: 'error',
check: {
valid: false,
message: `sitemap访问失败: ${error.message}`,
},
};
}
}
/**
* 生成测试报告
*/
function generateReport() {
// 创建报告目录
if (!fs.existsSync(CONFIG.outputDir)) {
fs.mkdirSync(CONFIG.outputDir, { recursive: true });
}
const reportPath = path.join(CONFIG.outputDir, 'content_filter_report.json');
const reportContent = {
summary: {
totalTime: new Date().toISOString(),
baseUrl: CONFIG.baseUrl,
totalChecks: results.totalChecks,
passedChecks: results.passedChecks,
failedChecks: results.failedChecks,
passRate: ((results.passedChecks / results.totalChecks) * 100).toFixed(2) + '%',
},
errors: results.errors,
details: results.details,
};
fs.writeFileSync(reportPath, JSON.stringify(reportContent, null, 2));
// 生成可读报告
const readableReportPath = path.join(CONFIG.outputDir, 'content_filter_report.md');
let readableReport = `# 内容边界隔离校验报告
生成时间: ${new Date().toISOString()}
## 摘要
- 总检查项: ${results.totalChecks}
- 通过检查: ${results.passedChecks}
- 失败检查: ${results.failedChecks}
- 通过率: ${((results.passedChecks / results.totalChecks) * 100).toFixed(2)}%
## 失败详情
`;
if (results.errors.length === 0) {
readableReport += '无失败项\n\n';
} else {
results.errors.forEach((error, index) => {
readableReport += `${index + 1}. ${error.url}\n - ${error.error}\n\n`;
if (error.keywords) {
readableReport += ` - 发现关键词: ${error.keywords.join(', ')}\n\n`;
}
if (error.issues) {
readableReport += ` - 问题项: ${JSON.stringify(error.issues)}\n\n`;
}
});
}
readableReport += `## 校验规则
1. draft/review/unpublished/historical状态内容绝对不会出现在公开页面、接口、sitemap内
2. 仅published状态实体、内容对外暴露
3. 历史版本数据仅存在后台CMS,前端/公开接口不可访问
## 结论
`;
if (results.failedChecks === 0) {
readableReport += '✅ 所有内容边界隔离检查通过\n';
} else {
readableReport += `❌ 存在${results.failedChecks}项内容边界隔离问题,需要修复\n`;
}
fs.writeFileSync(readableReportPath, readableReport);
console.log(`报告已生成:`);
console.log(` - JSON报告: ${reportPath}`);
console.log(` - 可读报告: ${readableReportPath}`);
}
/**
* 主函数
*/
async function main() {
console.log('开始内容边界隔离校验...');
console.log(`目标URL: ${CONFIG.baseUrl}`);
// 校验公开页面
console.log('\n=== 校验公开页面 ===');
const pageResults = await validatePublicPages();
results.details.push(...pageResults);
// 校验公开API
console.log('\n=== 校验公开API ===');
const apiResults = await validatePublicApis();
results.details.push(...apiResults);
// 校验sitemap
console.log('\n=== 校验sitemap ===');
const sitemapResult = await validateSitemap();
results.details.push(sitemapResult);
// 生成报告
console.log('\n正在生成报告...');
generateReport();
console.log('\n校验完成!');
console.log(`通过率: ${((results.passedChecks / results.totalChecks) * 100).toFixed(2)}%`);
// 返回结果
return results;
}
// 如果直接运行此脚本
if (require.main === module) {
main().catch(console.error);
}
module.exports = {
main,
validatePublicPages,
validatePublicApis,
validateSitemap,
CONFIG,
};
+507
View File
@@ -0,0 +1,507 @@
/**
* 十问认知基线静态校验模块
* 读取站点公开页面内容,提取核心文本、实体定义、实体关系
* 和产品文档《十问》标准答案做文本比对校验,输出差异报告
*/
const https = require('https');
const http = require('http');
const { JSDOM } = require('jsdom');
const fs = require('fs');
const path = require('path');
// 配置
const CONFIG = {
baseUrl: process.env.BASE_URL || 'http://localhost:3000',
timeout: 10000,
outputDir: path.join(__dirname, '../reports'),
similarityThreshold: 0.8, // 相似度阈值(80%)
};
// 十问标准答案基线
const TEN_QUESTIONS = [
{
id: 'Q1',
question: '阿美巴是谁?',
standardAnswer: '阿美巴(Ameiba)是AI时代企业进化平台,专注于帮助企业实现系统化进化,从战略顶层设计到组织重塑,从经营增长到AI部署,提供完整的企业进化能力与服务。',
keywords: ['阿美巴', 'AI时代', '企业进化平台', '系统化进化'],
relatedPages: ['/about'],
},
{
id: 'Q2',
question: '什么是企业进化?',
standardAnswer: '企业进化是企业在AI时代实现持续增长与转型的系统化方法。它不是简单的产品升级或技术更新,而是从战略、组织、流程、能力等全方位的系统性变革。',
keywords: ['企业进化', '系统化方法', '全方位', '系统性变革'],
relatedPages: ['/evolution'],
},
{
id: 'Q3',
question: '为什么目标先于问题?',
standardAnswer: '传统的问题导向方法容易让企业陷入"救火"模式,被动应对各种问题。而目标导向的方法让企业主动设定方向,有计划地推进进化。只有先明确目标,才能判断哪些问题是真正需要解决的,哪些问题是次要的,从而集中资源解决关键问题。',
keywords: ['目标先于问题', '目标导向', '主动设定方向', '避免被动'],
relatedPages: ['/evolution/method'],
},
{
id: 'Q4',
question: '四大价值是什么?',
standardAnswer: '四大价值包括价值创造、价值传递、价值交付、价值支持。价值创造是基础,价值传递是桥梁,价值交付是结果,价值支持是保障。企业需要在这四个维度上协调发展,才能实现持续增长。',
keywords: ['四大价值', '价值创造', '价值传递', '价值交付', '价值支持'],
relatedPages: ['/value'],
},
{
id: 'Q5',
question: 'A/M-B是什么?',
standardAnswer: 'A/M-B是企业进化阶段模型,描述了企业在AI时代进化的三个阶段。A态·入态是企业进入AI时代的初始状态,需要建立基础能力;M态·优态是企业优化运营、提升效率的阶段;B态·越态是企业实现跨越式发展、成为行业领导者的阶段。这是企业进化的阶段模型,不是产品套餐。',
keywords: ['A/M-B', '阶段模型', 'A态', 'M态', 'B态', '不是产品套餐'],
relatedPages: ['/amb'],
},
{
id: 'Q6',
question: '企业进化需要哪些能力?',
standardAnswer: '企业进化需要完整的能力体系,包括战略顶层设计、经营增长、商业模式、组织重塑、企业治理、独立核算、经营分析、价值评价、薪酬激励、IT部署、AI组织、企业AI系统、企业知识系统、AI应用部署等。这些能力是底层实体,不是产品套餐。',
keywords: ['能力体系', '战略顶层设计', '底层实体', '不是产品套餐'],
relatedPages: ['/capabilities'],
},
{
id: 'Q7',
question: '如何判断企业处于哪个阶段?',
standardAnswer: '企业可以根据自身特征判断所处阶段:A态企业通常数字化程度较低,缺乏系统化管理方法;M态企业数字化程度较高,运营效率持续优化;B态企业处于行业领先地位,具备强大创新能力。判断依据包括数字化程度、运营效率、组织能力、创新能力等维度。',
keywords: ['判断阶段', '数字化程度', '运营效率', '组织能力', '创新能力'],
relatedPages: ['/amb'],
},
{
id: 'Q8',
question: '阿美巴提供什么服务?',
standardAnswer: '阿美巴提供顾问服务、咨询服务、企业陪跑、定制化服务等。服务内容包括企业进化诊断、进化路径规划、战略咨询、组织变革咨询、AI部署咨询等。具体服务根据企业需求和阶段匹配。',
keywords: ['顾问服务', '咨询服务', '企业陪跑', '定制化服务'],
relatedPages: ['/capabilities', '/contact'],
},
{
id: 'Q9',
question: '如何开始企业进化?',
standardAnswer: '企业进化从明确目标开始。首先确定企业进化的终极目标,然后分析现状与目标的差距,识别关键障碍,制定进化路径,分阶段实施,持续迭代优化。阿美巴可以提供专业诊断和规划服务,帮助企业制定适合的进化方案。',
keywords: ['明确目标', '分析差距', '识别障碍', '制定路径', '分阶段实施'],
relatedPages: ['/evolution/method'],
},
{
id: 'Q10',
question: '企业进化的价值是什么?',
standardAnswer: '企业进化的价值在于帮助企业在AI时代实现可持续增长与发展。通过系统化的进化方法,企业可以提升运营效率、增强创新能力、优化组织结构、提高市场竞争力,最终实现从传统模式向AI时代模式的转型。',
keywords: ['可持续增长', '提升效率', '增强创新', '优化结构', '提高竞争力'],
relatedPages: ['/', '/value'],
},
];
/**
* 获取页面内容
*/
function fetchPage(url) {
return new Promise((resolve, reject) => {
const protocol = url.startsWith('https') ? https : http;
const timeout = CONFIG.timeout;
const req = protocol.get(url, { timeout }, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
resolve({
status: res.statusCode,
headers: res.headers,
body: data,
url: url,
});
});
});
req.on('error', (err) => {
reject(err);
});
req.on('timeout', () => {
req.destroy();
reject(new Error('请求超时'));
});
});
}
/**
* 提取页面文本内容
*/
function extractTextContent(html) {
const dom = new JSDOM(html);
const body = dom.window.document.body;
// 移除脚本和样式
const scripts = body.querySelectorAll('script, style');
scripts.forEach((script) => script.remove());
// 获取文本内容
let text = body.textContent || '';
// 清理文本
text = text
.replace(/\s+/g, ' ') // 合并空白字符
.replace(/\n+/g, '\n') // 合并换行符
.trim();
return text;
}
/**
* 提取页面结构化内容
*/
function extractStructuredContent(html) {
const dom = new JSDOM(html);
const document = dom.window.document;
// 提取标题
const h1 = document.querySelector('h1');
const h2s = document.querySelectorAll('h2');
const h3s = document.querySelectorAll('h3');
// 提取段落
const paragraphs = document.querySelectorAll('p');
// 提取列表
const lists = document.querySelectorAll('ul, ol');
// 提取JSON-LD
const jsonLdScripts = document.querySelectorAll('script[type="application/ld+json"]');
const jsonLdData = [];
jsonLdScripts.forEach((script) => {
try {
const data = JSON.parse(script.textContent);
jsonLdData.push(data);
} catch (error) {
// 忽略解析错误
}
});
return {
title: h1 ? h1.textContent.trim() : '',
h2s: Array.from(h2s).map((h2) => h2.textContent.trim()),
h3s: Array.from(h3s).map((h3) => h3.textContent.trim()),
paragraphs: Array.from(paragraphs).map((p) => p.textContent.trim()),
lists: Array.from(lists).map((list) => {
const items = list.querySelectorAll('li');
return Array.from(items).map((item) => item.textContent.trim());
}),
jsonLd: jsonLdData,
};
}
/**
* 计算文本相似度(简单的关键词匹配)
*/
function calculateSimilarity(text1, text2, keywords) {
const text1Lower = text1.toLowerCase();
const text2Lower = text2.toLowerCase();
let matchedKeywords = 0;
let totalKeywords = keywords.length;
keywords.forEach((keyword) => {
const keywordLower = keyword.toLowerCase();
if (text1Lower.includes(keywordLower) && text2Lower.includes(keywordLower)) {
matchedKeywords++;
}
});
return totalKeywords > 0 ? matchedKeywords / totalKeywords : 0;
}
/**
* 检查关键词是否存在
*/
function checkKeywords(text, keywords) {
const textLower = text.toLowerCase();
const foundKeywords = [];
const missingKeywords = [];
keywords.forEach((keyword) => {
const keywordLower = keyword.toLowerCase();
if (textLower.includes(keywordLower)) {
foundKeywords.push(keyword);
} else {
missingKeywords.push(keyword);
}
});
return {
found: foundKeywords,
missing: missingKeywords,
coverage: keywords.length > 0 ? foundKeywords.length / keywords.length : 0,
};
}
/**
* 校验单个问题
*/
async function validateQuestion(question) {
console.log(`\n校验问题: ${question.question}`);
const results = {
question: question,
pageResults: [],
overallStatus: 'passed',
missingKeywords: [],
similarityScore: 0,
};
for (const pagePath of question.relatedPages) {
const url = `${CONFIG.baseUrl}${pagePath}`;
console.log(` 访问页面: ${url}`);
try {
const response = await fetchPage(url);
if (response.status !== 200) {
results.pageResults.push({
url: url,
status: 'failed',
error: `HTTP状态码: ${response.status}`,
});
results.overallStatus = 'failed';
continue;
}
// 提取内容
const textContent = extractTextContent(response.body);
const structuredContent = extractStructuredContent(response.body);
// 检查关键词
const keywordCheck = checkKeywords(textContent, question.keywords);
// 计算相似度
const similarity = calculateSimilarity(
textContent,
question.standardAnswer,
question.keywords
);
// 判断是否通过
const passed = keywordCheck.coverage >= CONFIG.similarityThreshold;
results.pageResults.push({
url: url,
status: passed ? 'passed' : 'warning',
keywordCoverage: keywordCheck.coverage,
foundKeywords: keywordCheck.found,
missingKeywords: keywordCheck.missing,
similarity: similarity,
contentPreview: textContent.substring(0, 200) + '...',
});
if (!passed) {
results.overallStatus = 'warning';
results.missingKeywords.push(...keywordCheck.missing);
}
results.similarityScore = Math.max(results.similarityScore, similarity);
console.log(` 关键词覆盖: ${(keywordCheck.coverage * 100).toFixed(2)}%`);
console.log(` 相似度: ${(similarity * 100).toFixed(2)}%`);
console.log(` 状态: ${passed ? '✓ 通过' : '⚠ 警告'}`);
} catch (error) {
results.pageResults.push({
url: url,
status: 'failed',
error: `页面访问失败: ${error.message}`,
});
results.overallStatus = 'failed';
console.log(` ✗ 页面访问失败: ${error.message}`);
}
}
// 去重missingKeywords
results.missingKeywords = [...new Set(results.missingKeywords)];
return results;
}
/**
* 生成测试报告
*/
function generateReport(allResults) {
// 创建报告目录
if (!fs.existsSync(CONFIG.outputDir)) {
fs.mkdirSync(CONFIG.outputDir, { recursive: true });
}
const reportPath = path.join(CONFIG.outputDir, 'ten_questions_report.json');
// 统计
const summary = {
totalTime: new Date().toISOString(),
totalQuestions: allResults.length,
passedQuestions: allResults.filter((r) => r.overallStatus === 'passed').length,
warningQuestions: allResults.filter((r) => r.overallStatus === 'warning').length,
failedQuestions: allResults.filter((r) => r.overallStatus === 'failed').length,
averageSimilarity: 0,
};
// 计算平均相似度
const totalSimilarity = allResults.reduce((sum, r) => sum + r.similarityScore, 0);
summary.averageSimilarity = allResults.length > 0
? (totalSimilarity / allResults.length * 100).toFixed(2) + '%'
: '0%';
const reportContent = {
summary: summary,
questions: allResults.map((r) => ({
id: r.question.id,
question: r.question.question,
status: r.overallStatus,
similarity: r.similarityScore,
missingKeywords: r.missingKeywords,
pageResults: r.pageResults,
})),
};
fs.writeFileSync(reportPath, JSON.stringify(reportContent, null, 2));
// 生成可读报告
const readableReportPath = path.join(CONFIG.outputDir, 'ten_questions_report.md');
let readableReport = `# 十问认知基线校验报告
生成时间: ${new Date().toISOString()}
## 摘要
- 总问题数: ${summary.totalQuestions}
- 通过问题: ${summary.passedQuestions}
- 警告问题: ${summary.warningQuestions}
- 失败问题: ${summary.failedQuestions}
- 平均相似度: ${summary.averageSimilarity}
## 详细结果
`;
allResults.forEach((result) => {
const statusIcon = result.overallStatus === 'passed' ? '✅' :
result.overallStatus === 'warning' ? '⚠️' : '❌';
readableReport += `### ${statusIcon} ${result.question.id}: ${result.question.question}
**标准答案**: ${result.question.standardAnswer}
**校验结果**:
- 状态: ${result.overallStatus}
- 相似度: ${(result.similarityScore * 100).toFixed(2)}%
`;
if (result.missingKeywords.length > 0) {
readableReport += `- 缺失关键词: ${result.missingKeywords.join(', ')}
`;
}
readableReport += `
**页面详情**:
`;
result.pageResults.forEach((pageResult) => {
readableReport += `- ${pageResult.url}
- 状态: ${pageResult.status}
`;
if (pageResult.error) {
readableReport += ` - 错误: ${pageResult.error}
`;
}
if (pageResult.keywordCoverage !== undefined) {
readableReport += ` - 关键词覆盖: ${(pageResult.keywordCoverage * 100).toFixed(2)}%
`;
}
if (pageResult.foundKeywords) {
readableReport += ` - 找到关键词: ${pageResult.foundKeywords.join(', ')}
`;
}
if (pageResult.missingKeywords && pageResult.missingKeywords.length > 0) {
readableReport += ` - 缺失关键词: ${pageResult.missingKeywords.join(', ')}
`;
}
});
readableReport += '\n';
});
readableReport += `## 结论
`;
if (summary.failedQuestions === 0 && summary.warningQuestions === 0) {
readableReport += '✅ 所有问题都通过校验,网站内容与产品文档《十问》标准答案高度一致\n';
} else if (summary.failedQuestions === 0) {
readableReport += `⚠️ ${summary.warningQuestions}个问题有警告,需要人工复核\n`;
} else {
readableReport += `❌ ${summary.failedQuestions}个问题失败,需要修复\n`;
}
readableReport += `
## 建议
1. 对于警告项,建议人工复核页面内容,确保与标准答案一致
2. 对于缺失关键词,建议在CMS后台编辑相关页面,补充关键词内容
3. 定期执行此校验,确保内容一致性
## 注意事项
- 本报告仅输出差异清单,不自动修正页面内容
- 内容修改需要人工进入CMS后台编辑
- 相似度计算基于关键词匹配,仅供参考
`;
fs.writeFileSync(readableReportPath, readableReport);
console.log(`报告已生成:`);
console.log(` - JSON报告: ${reportPath}`);
console.log(` - 可读报告: ${readableReportPath}`);
}
/**
* 主函数
*/
async function main() {
console.log('开始十问认知基线校验...');
console.log(`目标URL: ${CONFIG.baseUrl}`);
const allResults = [];
// 逐个校验问题
for (const question of TEN_QUESTIONS) {
const result = await validateQuestion(question);
allResults.push(result);
}
// 生成报告
console.log('\n正在生成报告...');
generateReport(allResults);
// 统计结果
const passed = allResults.filter((r) => r.overallStatus === 'passed').length;
const warning = allResults.filter((r) => r.overallStatus === 'warning').length;
const failed = allResults.filter((r) => r.overallStatus === 'failed').length;
console.log('\n校验完成!');
console.log(`通过: ${passed}, 警告: ${warning}, 失败: ${failed}`);
// 返回结果
return allResults;
}
// 如果直接运行此脚本
if (require.main === module) {
main().catch(console.error);
}
module.exports = {
main,
validateQuestion,
TEN_QUESTIONS,
CONFIG,
};
+507
View File
@@ -0,0 +1,507 @@
/**
* 模拟抓取校验脚本
* 自动遍历全站sitemap.xml,抓取全部公开页面,校验页面质量
*/
const https = require('https');
const http = require('http');
const { JSDOM } = require('jsdom');
const fs = require('fs');
const path = require('path');
// 配置
const CONFIG = {
baseUrl: process.env.BASE_URL || 'http://localhost:3000',
timeout: 10000,
outputDir: path.join(__dirname, '../reports'),
};
// 测试结果
const results = {
totalPages: 0,
passedPages: 0,
failedPages: 0,
warnings: 0,
errors: [],
warningsList: [],
details: [],
};
/**
* 获取页面内容
*/
function fetchPage(url) {
return new Promise((resolve, reject) => {
const protocol = url.startsWith('https') ? https : http;
const timeout = CONFIG.timeout;
const req = protocol.get(url, { timeout }, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
resolve({
status: res.statusCode,
headers: res.headers,
body: data,
url: url,
});
});
});
req.on('error', (err) => {
reject(err);
});
req.on('timeout', () => {
req.destroy();
reject(new Error('请求超时'));
});
});
}
/**
* 解析sitemap.xml
*/
async function parseSitemap() {
try {
const response = await fetchPage(`${CONFIG.baseUrl}/sitemap.xml`);
const dom = new JSDOM(response.body);
const urls = dom.window.document.querySelectorAll('url');
const sitemapUrls = [];
urls.forEach((url) => {
const loc = url.querySelector('loc');
if (loc) {
sitemapUrls.push(loc.textContent);
}
});
return sitemapUrls;
} catch (error) {
console.error('解析sitemap失败:', error.message);
return [];
}
}
/**
* 校验H1唯一性
*/
function validateH1(html, url) {
const dom = new JSDOM(html);
const h1Elements = dom.window.document.querySelectorAll('h1');
if (h1Elements.length === 0) {
return {
valid: false,
message: '缺少H1标签',
};
}
if (h1Elements.length > 1) {
return {
valid: false,
message: `存在${h1Elements.length}个H1标签,应唯一`,
};
}
return {
valid: true,
message: 'H1标签唯一',
content: h1Elements[0].textContent.trim(),
};
}
/**
* 校验标题层级
*/
function validateHeadings(html, url) {
const dom = new JSDOM(html);
const headings = dom.window.document.querySelectorAll('h1, h2, h3, h4, h5, h6');
const headingLevels = [];
headings.forEach((h) => {
const level = parseInt(h.tagName.substring(1));
headingLevels.push(level);
});
// 检查层级是否连续
let previousLevel = 0;
let isValid = true;
let errorMessage = '';
for (let i = 0; i < headingLevels.length; i++) {
const currentLevel = headingLevels[i];
// H1应该在最前面
if (i === 0 && currentLevel !== 1) {
isValid = false;
errorMessage = '第一个标题应该是H1';
break;
}
// 检查层级跳跃
if (currentLevel > previousLevel + 1 && previousLevel !== 0) {
isValid = false;
errorMessage = `标题层级跳跃:从H${previousLevel}到H${currentLevel}`;
break;
}
previousLevel = currentLevel;
}
return {
valid: isValid,
message: errorMessage || '标题层级规范',
headings: headingLevels,
};
}
/**
* 校验JSON-LD结构化数据
*/
function validateJsonLd(html, url) {
const dom = new JSDOM(html);
const scripts = dom.window.document.querySelectorAll('script[type="application/ld+json"]');
const jsonLdData = [];
let isValid = true;
let errorMessage = '';
scripts.forEach((script) => {
try {
const data = JSON.parse(script.textContent);
jsonLdData.push(data);
// 基本结构校验
if (!data['@context']) {
isValid = false;
errorMessage = 'JSON-LD缺少@context';
}
if (!data['@type']) {
isValid = false;
errorMessage = 'JSON-LD缺少@type';
}
} catch (error) {
isValid = false;
errorMessage = `JSON-LD语法错误: ${error.message}`;
}
});
return {
valid: isValid,
message: errorMessage || 'JSON-LD结构化数据合法',
count: jsonLdData.length,
data: jsonLdData,
};
}
/**
* 校验内部链接
*/
function validateInternalLinks(html, baseUrl) {
const dom = new JSDOM(html);
const links = dom.window.document.querySelectorAll('a[href]');
const internalLinks = [];
const brokenLinks = [];
links.forEach((link) => {
const href = link.getAttribute('href');
// 跳过外部链接和锚点
if (href.startsWith('http') || href.startsWith('#') || href.startsWith('mailto:')) {
return;
}
// 构建完整URL
let fullUrl;
if (href.startsWith('/')) {
fullUrl = `${CONFIG.baseUrl}${href}`;
} else {
fullUrl = `${CONFIG.baseUrl}/${href}`;
}
internalLinks.push({
text: link.textContent.trim(),
href: href,
fullUrl: fullUrl,
});
});
return {
valid: true,
message: `发现${internalLinks.length}个内部链接`,
links: internalLinks,
brokenLinks: brokenLinks,
};
}
/**
* 校验单个页面
*/
async function validatePage(url) {
const pageResult = {
url: url,
status: 'passed',
checks: [],
errors: [],
warnings: [],
};
try {
// 获取页面
const response = await fetchPage(url);
// 校验HTTP状态码
if (response.status !== 200) {
pageResult.status = 'failed';
pageResult.errors.push(`HTTP状态码异常: ${response.status}`);
results.errors.push({
url: url,
error: `HTTP状态码异常: ${response.status}`,
});
}
pageResult.checks.push({
name: 'HTTP状态码',
status: response.status === 200 ? 'passed' : 'failed',
message: `状态码: ${response.status}`,
});
// 校验H1唯一性
const h1Result = validateH1(response.body, url);
pageResult.checks.push({
name: 'H1唯一性',
status: h1Result.valid ? 'passed' : 'failed',
message: h1Result.message,
content: h1Result.content,
});
if (!h1Result.valid) {
pageResult.status = 'failed';
pageResult.errors.push(h1Result.message);
results.errors.push({
url: url,
error: h1Result.message,
});
}
// 校验标题层级
const headingsResult = validateHeadings(response.body, url);
pageResult.checks.push({
name: '标题层级',
status: headingsResult.valid ? 'passed' : 'failed',
message: headingsResult.message,
});
if (!headingsResult.valid) {
pageResult.status = 'failed';
pageResult.errors.push(headingsResult.message);
results.errors.push({
url: url,
error: headingsResult.message,
});
}
// 校验JSON-LD
const jsonLdResult = validateJsonLd(response.body, url);
pageResult.checks.push({
name: 'JSON-LD结构化数据',
status: jsonLdResult.valid ? 'passed' : 'failed',
message: jsonLdResult.message,
count: jsonLdResult.count,
});
if (!jsonLdResult.valid) {
pageResult.status = 'failed';
pageResult.errors.push(jsonLdResult.message);
results.errors.push({
url: url,
error: jsonLdResult.message,
});
}
// 校验内部链接
const linksResult = validateInternalLinks(response.body, url);
pageResult.checks.push({
name: '内部链接',
status: linksResult.valid ? 'passed' : 'failed',
message: linksResult.message,
linkCount: linksResult.links.length,
});
} catch (error) {
pageResult.status = 'failed';
pageResult.errors.push(`页面抓取失败: ${error.message}`);
results.errors.push({
url: url,
error: `页面抓取失败: ${error.message}`,
});
}
return pageResult;
}
/**
* 生成测试报告
*/
function generateReport() {
// 创建报告目录
if (!fs.existsSync(CONFIG.outputDir)) {
fs.mkdirSync(CONFIG.outputDir, { recursive: true });
}
const reportPath = path.join(CONFIG.outputDir, 'crawler_report.json');
const reportContent = {
summary: {
totalTime: new Date().toISOString(),
baseUrl: CONFIG.baseUrl,
totalPages: results.totalPages,
passedPages: results.passedPages,
failedPages: results.failedPages,
warnings: results.warnings,
passRate: ((results.passedPages / results.totalPages) * 100).toFixed(2) + '%',
},
errors: results.errors,
warnings: results.warningsList,
details: results.details,
};
fs.writeFileSync(reportPath, JSON.stringify(reportContent, null, 2));
// 生成可读报告
const readableReportPath = path.join(CONFIG.outputDir, 'crawler_report.md');
let readableReport = `# 爬虫校验报告
生成时间: ${new Date().toISOString()}
## 摘要
- 总页面数: ${results.totalPages}
- 通过页面: ${results.passedPages}
- 失败页面: ${results.failedPages}
- 警告: ${results.warnings}
- 通过率: ${((results.passedPages / results.totalPages) * 100).toFixed(2)}%
## 失败详情
`;
if (results.errors.length === 0) {
readableReport += '无失败项\n\n';
} else {
results.errors.forEach((error, index) => {
readableReport += `${index + 1}. ${error.url}\n - ${error.error}\n\n`;
});
}
readableReport += `## 页面详情
`;
results.details.forEach((detail) => {
readableReport += `### ${detail.url}
状态: ${detail.status}
`;
detail.checks.forEach((check) => {
readableReport += `- ${check.name}: ${check.status} - ${check.message}\n`;
});
readableReport += '\n';
});
fs.writeFileSync(readableReportPath, readableReport);
console.log(`报告已生成:`);
console.log(` - JSON报告: ${reportPath}`);
console.log(` - 可读报告: ${readableReportPath}`);
}
/**
* 主函数
*/
async function main() {
console.log('开始爬虫校验...');
console.log(`目标URL: ${CONFIG.baseUrl}`);
// 获取sitemap
console.log('正在解析sitemap...');
const sitemapUrls = await parseSitemap();
if (sitemapUrls.length === 0) {
console.log('未找到sitemap,使用默认页面列表');
// 默认页面列表
sitemapUrls.push(
`${CONFIG.baseUrl}/`,
`${CONFIG.baseUrl}/about`,
`${CONFIG.baseUrl}/evolution`,
`${CONFIG.baseUrl}/evolution/method`,
`${CONFIG.baseUrl}/value`,
`${CONFIG.baseUrl}/value/creation`,
`${CONFIG.baseUrl}/value/transfer`,
`${CONFIG.baseUrl}/value/delivery`,
`${CONFIG.baseUrl}/value/support`,
`${CONFIG.baseUrl}/amb`,
`${CONFIG.baseUrl}/amb/a`,
`${CONFIG.baseUrl}/amb/m`,
`${CONFIG.baseUrl}/amb/b`,
`${CONFIG.baseUrl}/capabilities`,
`${CONFIG.baseUrl}/cases`,
`${CONFIG.baseUrl}/knowledge`,
`${CONFIG.baseUrl}/concepts`,
`${CONFIG.baseUrl}/faq`,
`${CONFIG.baseUrl}/match`,
`${CONFIG.baseUrl}/contact`
);
}
console.log(`共发现${sitemapUrls.length}个页面`);
// 逐个校验页面
for (let i = 0; i < sitemapUrls.length; i++) {
const url = sitemapUrls[i];
console.log(`[${i + 1}/${sitemapUrls.length}] 正在校验: ${url}`);
const pageResult = await validatePage(url);
results.details.push(pageResult);
results.totalPages++;
if (pageResult.status === 'passed') {
results.passedPages++;
console.log(` ✓ 通过`);
} else {
results.failedPages++;
console.log(` ✗ 失败`);
pageResult.errors.forEach((error) => {
console.log(` - ${error}`);
});
}
}
// 生成报告
console.log('\n正在生成报告...');
generateReport();
console.log('\n校验完成!');
console.log(`通过率: ${((results.passedPages / results.totalPages) * 100).toFixed(2)}%`);
// 返回结果
return results;
}
// 如果直接运行此脚本
if (require.main === module) {
main().catch(console.error);
}
module.exports = {
main,
validatePage,
parseSitemap,
CONFIG,
};
+548
View File
@@ -0,0 +1,548 @@
/**
* 数据模型验证脚本
* 验证P0系统微调后的数据模型一致性
*/
const { getDb, closeDb } = require('../src/config/database');
const { migrate } = require('../src/database/migrate');
const Entity = require('../src/models/Entity');
const Content = require('../src/models/Content');
const Page = require('../src/models/Page');
const Article = require('../src/models/Article');
const Case = require('../src/models/Case');
const FAQ = require('../src/models/FAQ');
const Capability = require('../src/models/Capability');
const Service = require('../src/models/Service');
const DirectedRelationship = require('../src/models/DirectedRelationship');
const EntityContentJoin = require('../src/models/EntityContentJoin');
// 测试结果
const results = {
entity: { passed: 0, failed: 0, details: [] },
page: { passed: 0, failed: 0, details: [] },
article: { passed: 0, failed: 0, details: [] },
case: { passed: 0, failed: 0, details: [] },
faq: { passed: 0, failed: 0, details: [] },
capability: { passed: 0, failed: 0, details: [] },
service: { passed: 0, failed: 0, details: [] },
relation: { passed: 0, failed: 0, details: [] },
join: { passed: 0, failed: 0, details: [] },
lifecycle: { passed: 0, failed: 0, details: [] },
authority: { passed: 0, failed: 0, details: [] },
};
/**
* 验证Entity模型
*/
function verifyEntity() {
console.log('\n=== 验证Entity模型 ===');
// 测试创建Entity
try {
const entity = Entity.create({
entity_type: 'concept',
name: '测试实体',
definition: '测试定义',
description: '测试描述',
status: 'active',
public_flag: 1,
authority_level: 2,
});
if (entity.entity_id && entity.entity_type === 'concept' && entity.status === 'active' && entity.public_flag === 1) {
results.entity.passed++;
results.entity.details.push('Entity创建成功,新字段正确');
} else {
results.entity.failed++;
results.entity.details.push('Entity创建失败:新字段不正确');
}
// 测试读取Entity
const foundEntity = Entity.findById(entity.entity_id);
if (foundEntity && foundEntity.entity_type === 'concept' && foundEntity.status === 'active') {
results.entity.passed++;
results.entity.details.push('Entity读取成功,新字段正确');
} else {
results.entity.failed++;
results.entity.details.push('Entity读取失败:新字段不正确');
}
// 测试更新Entity
const updatedEntity = Entity.update(entity.entity_id, {
entity_type: 'method',
status: 'inactive',
public_flag: 0,
});
if (updatedEntity.entity_type === 'method' && updatedEntity.status === 'inactive' && updatedEntity.public_flag === 0) {
results.entity.passed++;
results.entity.details.push('Entity更新成功,新字段正确');
} else {
results.entity.failed++;
results.entity.details.push('Entity更新失败:新字段不正确');
}
// 清理测试数据
Entity.delete(entity.entity_id);
} catch (error) {
results.entity.failed++;
results.entity.details.push(`Entity测试失败: ${error.message}`);
}
console.log(`Entity: ${results.entity.passed} passed, ${results.entity.failed} failed`);
}
/**
* 验证Page模型
*/
function verifyPage() {
console.log('\n=== 验证Page模型 ===');
try {
// 测试创建Page
const page = Page.create({
title: '测试页面',
body: '测试内容',
slug: 'test-page',
summary: '测试摘要',
seo_title: '测试SEO标题',
seo_description: '测试SEO描述',
});
if (page.page_id && page.summary === '测试摘要') {
results.page.passed++;
results.page.details.push('Page创建成功,summary字段正确');
} else {
results.page.failed++;
results.page.details.push('Page创建失败:summary字段不正确');
}
// 测试读取Page
const foundPage = Page.findById(page.page_id);
if (foundPage && foundPage.summary === '测试摘要') {
results.page.passed++;
results.page.details.push('Page读取成功,summary字段正确');
} else {
results.page.failed++;
results.page.details.push('Page读取失败:summary字段不正确');
}
// 清理测试数据
Content.delete(page.page_id);
} catch (error) {
results.page.failed++;
results.page.details.push(`Page测试失败: ${error.message}`);
}
console.log(`Page: ${results.page.passed} passed, ${results.page.failed} failed`);
}
/**
* 验证Article模型
*/
function verifyArticle() {
console.log('\n=== 验证Article模型 ===');
try {
// 测试创建Article
const article = Article.create({
title: '测试文章',
body: '测试内容',
category: '测试分类',
author: '测试作者',
published_at: '2026-09-08T00:00:00.000Z',
});
if (article.article_id && article.published_at === '2026-09-08T00:00:00.000Z') {
results.article.passed++;
results.article.details.push('Article创建成功,published_at字段正确');
} else {
results.article.failed++;
results.article.details.push('Article创建失败:published_at字段不正确');
}
// 测试读取Article
const foundArticle = Article.findById(article.article_id);
if (foundArticle && foundArticle.published_at === '2026-09-08T00:00:00.000Z') {
results.article.passed++;
results.article.details.push('Article读取成功,published_at字段正确');
} else {
results.article.failed++;
results.article.details.push('Article读取失败:published_at字段不正确');
}
// 清理测试数据
Content.delete(article.article_id);
} catch (error) {
results.article.failed++;
results.article.details.push(`Article测试失败: ${error.message}`);
}
console.log(`Article: ${results.article.passed} passed, ${results.article.failed} failed`);
}
/**
* 验证Case模型(P0-01扩展字段)
*/
function verifyCase() {
console.log('\n=== 验证Case模型(P0-01扩展字段)===');
try {
// 测试创建Case
const caseData = Case.create({
title: '测试案例',
body: '测试内容',
client_name: '测试客户',
industry: '测试行业',
background: '测试企业背景',
enterprise_stage: 'A态',
original_goal: '测试原始目标',
current_state: '测试当前状态',
surface_problem: '测试表面问题',
amb_judgment: '测试阿美巴判断',
key_obstacle: '测试关键障碍',
root_cause: '测试根因',
evolution_path: '测试进化路径',
implementation: '测试实施过程',
result: '测试结果',
case_significance: '测试案例意义',
});
// 验证所有新字段
const expectedValues = {
background: '测试企业背景',
enterprise_stage: 'A态',
original_goal: '测试原始目标',
current_state: '测试当前状态',
surface_problem: '测试表面问题',
amb_judgment: '测试阿美巴判断',
key_obstacle: '测试关键障碍',
root_cause: '测试根因',
evolution_path: '测试进化路径',
implementation: '测试实施过程',
case_significance: '测试案例意义',
};
let allFieldsCorrect = true;
for (const [field, expected] of Object.entries(expectedValues)) {
if (caseData[field] !== expected) {
allFieldsCorrect = false;
console.log(`字段 ${field} 不正确: 期望 "${expected}", 实际 "${caseData[field]}"`);
break;
}
}
if (caseData.case_id && allFieldsCorrect) {
results.case.passed++;
results.case.details.push('Case创建成功,所有P0-01扩展字段正确');
} else {
results.case.failed++;
results.case.details.push('Case创建失败:P0-01扩展字段不正确');
}
// 测试读取Case
const foundCase = Case.findById(caseData.case_id);
if (foundCase && foundCase.background === '测试企业背景' && foundCase.case_significance === '测试案例意义') {
results.case.passed++;
results.case.details.push('Case读取成功,所有P0-01扩展字段正确');
} else {
results.case.failed++;
results.case.details.push('Case读取失败:P0-01扩展字段不正确');
}
// 清理测试数据
Content.delete(caseData.case_id);
} catch (error) {
results.case.failed++;
results.case.details.push(`Case测试失败: ${error.message}`);
}
console.log(`Case: ${results.case.passed} passed, ${results.case.failed} failed`);
}
/**
* 验证Entity-Content多对多关系
*/
function verifyEntityContentJoin() {
console.log('\n=== 验证Entity-Content多对多关系 ===');
try {
// 创建测试Entity
const entity1 = Entity.create({
entity_type: 'concept',
name: '测试实体1',
});
const entity2 = Entity.create({
entity_type: 'concept',
name: '测试实体2',
});
// 创建测试Content
const content = Content.create({
title: '测试内容',
body: '测试内容',
content_type: 'article',
});
// 创建关联:一个Content关联多个Entity
const join1 = EntityContentJoin.create({
entity_id: entity1.entity_id,
content_id: content.content_id,
});
const join2 = EntityContentJoin.create({
entity_id: entity2.entity_id,
content_id: content.content_id,
});
// 验证一个Content关联多个Entity
const contentJoins = EntityContentJoin.findByContentId(content.content_id);
if (contentJoins.length === 2) {
results.join.passed++;
results.join.details.push('一个Content关联多个Entity成功');
} else {
results.join.failed++;
results.join.details.push('一个Content关联多个Entity失败');
}
// 创建另一个Content
const content2 = Content.create({
title: '测试内容2',
body: '测试内容2',
content_type: 'article',
});
// 创建关联:一个Entity关联多个Content
const join3 = EntityContentJoin.create({
entity_id: entity1.entity_id,
content_id: content2.content_id,
});
// 验证一个Entity关联多个Content
const entityJoins = EntityContentJoin.findByEntityId(entity1.entity_id);
if (entityJoins.length === 2) {
results.join.passed++;
results.join.details.push('一个Entity关联多个Content成功');
} else {
results.join.failed++;
results.join.details.push('一个Entity关联多个Content失败');
}
// 清理测试数据
EntityContentJoin.delete(join1.join_id);
EntityContentJoin.delete(join2.join_id);
EntityContentJoin.delete(join3.join_id);
Entity.delete(entity1.entity_id);
Entity.delete(entity2.entity_id);
Content.delete(content.content_id);
Content.delete(content2.content_id);
} catch (error) {
results.join.failed++;
results.join.details.push(`Entity-Content多对多测试失败: ${error.message}`);
}
console.log(`Entity-Content多对多: ${results.join.passed} passed, ${results.join.failed} failed`);
}
/**
* 验证内容生命周期
*/
function verifyContentLifecycle() {
console.log('\n=== 验证内容生命周期 ===');
try {
// 创建测试Content
const content = Content.create({
title: '测试内容',
body: '测试内容',
content_type: 'article',
publish_status: 'draft',
});
// 测试draft -> review
const reviewContent = Content.transitionStatus(content.content_id, 'review');
if (reviewContent.publish_status === 'review') {
results.lifecycle.passed++;
results.lifecycle.details.push('draft -> review 转换成功');
} else {
results.lifecycle.failed++;
results.lifecycle.details.push('draft -> review 转换失败');
}
// 测试review -> published
const publishedContent = Content.transitionStatus(content.content_id, 'published');
if (publishedContent.publish_status === 'published' && publishedContent.version_no === 2) {
results.lifecycle.passed++;
results.lifecycle.details.push('review -> published 转换成功,版本号递增');
} else {
results.lifecycle.failed++;
results.lifecycle.details.push('review -> published 转换失败');
}
// 测试published -> unpublished
const unpublishedContent = Content.transitionStatus(content.content_id, 'unpublished');
if (unpublishedContent.publish_status === 'unpublished') {
results.lifecycle.passed++;
results.lifecycle.details.push('published -> unpublished 转换成功');
} else {
results.lifecycle.failed++;
results.lifecycle.details.push('published -> unpublished 转换失败');
}
// 测试unpublished -> historical
const historicalContent = Content.transitionStatus(content.content_id, 'historical');
if (historicalContent.publish_status === 'historical' && historicalContent.archived_at) {
results.lifecycle.passed++;
results.lifecycle.details.push('unpublished -> historical 转换成功,记录归档时间');
} else {
results.lifecycle.failed++;
results.lifecycle.details.push('unpublished -> historical 转换失败');
}
// 清理测试数据
Content.delete(content.content_id);
} catch (error) {
results.lifecycle.failed++;
results.lifecycle.details.push(`内容生命周期测试失败: ${error.message}`);
}
console.log(`内容生命周期: ${results.lifecycle.passed} passed, ${results.lifecycle.failed} failed`);
}
/**
* 验证Authority权威等级
*/
function verifyAuthority() {
console.log('\n=== 验证Authority权威等级 ===');
try {
// 测试Entity的authority_level
const entity = Entity.create({
entity_type: 'concept',
name: '测试实体',
authority_level: 3,
});
if (entity.authority_level === 3) {
results.authority.passed++;
results.authority.details.push('Entity authority_level设置成功');
} else {
results.authority.failed++;
results.authority.details.push('Entity authority_level设置失败');
}
// 测试Relation的authority_level
const entity2 = Entity.create({
entity_type: 'concept',
name: '测试实体2',
});
const relation = DirectedRelationship.create({
source_entity_id: entity.entity_id,
relation_type: '测试关系',
target_entity_id: entity2.entity_id,
authority_level: 4,
});
if (relation.authority_level === 4) {
results.authority.passed++;
results.authority.details.push('Relation authority_level设置成功');
} else {
results.authority.failed++;
results.authority.details.push('Relation authority_level设置失败');
}
// 测试Content的authority_level
const content = Content.create({
title: '测试内容',
body: '测试内容',
content_type: 'article',
authority_level: 5,
});
if (content.authority_level === 5) {
results.authority.passed++;
results.authority.details.push('Content authority_level设置成功');
} else {
results.authority.failed++;
results.authority.details.push('Content authority_level设置失败');
}
// 清理测试数据
Entity.delete(entity.entity_id);
Entity.delete(entity2.entity_id);
DirectedRelationship.delete(relation.rel_id);
Content.delete(content.content_id);
} catch (error) {
results.authority.failed++;
results.authority.details.push(`Authority测试失败: ${error.message}`);
}
console.log(`Authority: ${results.authority.passed} passed, ${results.authority.failed} failed`);
}
/**
* 主函数
*/
function main() {
console.log('开始数据模型验证...');
// 初始化数据库
migrate();
// 执行验证
verifyEntity();
verifyPage();
verifyArticle();
verifyCase();
verifyEntityContentJoin();
verifyContentLifecycle();
verifyAuthority();
// 统计结果
let totalPassed = 0;
let totalFailed = 0;
for (const key in results) {
totalPassed += results[key].passed;
totalFailed += results[key].failed;
}
console.log('\n=== 验证结果汇总 ===');
console.log(`总测试: ${totalPassed + totalFailed}`);
console.log(`通过: ${totalPassed}`);
console.log(`失败: ${totalFailed}`);
console.log(`通过率: ${((totalPassed / (totalPassed + totalFailed)) * 100).toFixed(2)}%`);
// 输出详细结果
console.log('\n=== 详细结果 ===');
for (const key in results) {
console.log(`\n${key}:`);
results[key].details.forEach(detail => {
console.log(` - ${detail}`);
});
}
// 关闭数据库
closeDb();
return results;
}
// 如果直接运行此脚本
if (require.main === module) {
main();
}
module.exports = {
main,
results,
};
+605
View File
@@ -0,0 +1,605 @@
/**
* P0正式内容工程写入脚本
* 将冻结内容准确写入系统
*/
const { getDb, closeDb } = require('../src/config/database');
const { migrate } = require('../src/database/migrate');
const Entity = require('../src/models/Entity');
const Content = require('../src/models/Content');
const Page = require('../src/models/Page');
const Article = require('../src/models/Article');
const Case = require('../src/models/Case');
const FAQ = require('../src/models/FAQ');
const Capability = require('../src/models/Capability');
const Service = require('../src/models/Service');
const DirectedRelationship = require('../src/models/DirectedRelationship');
const EntityContentJoin = require('../src/models/EntityContentJoin');
// P0核心Entity定义
const P0_ENTITIES = [
{
entity_id: 'E-AMEBA-MAIN',
entity_type: 'organization',
name: '阿美巴',
definition: '阿美巴以企业进化为核心、AI为时代背景和赋能工具的企业咨询与进化服务机构,聚焦长期系统性升级。',
description: '阿美巴|AI时代企业进化平台。各项能力升级最终应服务于企业整体进化目标。服务对象主要为国内中小企业,重点关注实体企业、制造型企业。',
status: 'active',
public_flag: 1,
authority_level: 1,
},
{
entity_id: 'E-EVOLUTION',
entity_type: 'concept',
name: '企业进化',
definition: '企业围绕长期发展目标,在战略、经营、商业模式、组织、价值、AI适应以及底层管理能力等方面持续调整、重构与升级,从而形成长期发展能力的过程。',
description: '增长更多体现结果层变化。进化更强调底层能力、系统与企业状态的持续调整和升级。AI是时代变量和重要赋能工具,不是企业进化本身的终点。',
status: 'active',
public_flag: 1,
authority_level: 2,
},
{
entity_id: 'E-GOAL',
entity_type: 'concept',
name: '企业进化目标',
definition: '企业进化目标是企业开展进化工作的一个重要起点和核心参照。',
description: '企业进化目标主要关注:中长期发展方向、企业价值定位、希望形成的企业状态、企业未来需要具备的能力。目标可以根据企业发展阶段和外部环境动态调整。',
status: 'active',
public_flag: 1,
authority_level: 2,
},
{
entity_id: 'E-ENDSTART',
entity_type: 'method',
name: '以终为始',
definition: '以目标状态为参照,再反向分析企业当前状态及差距。',
description: '先明确希望到哪里,再分析现在在哪里,最后确定中间需要完成什么。"以终为始"是阿美巴企业进化工作的基本指导原则之一。',
status: 'active',
public_flag: 1,
authority_level: 3,
},
{
entity_id: 'E-PRIORITY',
entity_type: 'method',
name: '目标先于问题',
definition: '问题的重要性与优先级,需要结合企业整体进化目标判断。',
description: '不是所有问题都需要立即解决。如果某个问题与企业当前核心进化目标关联较弱,可以暂缓、简化或降低优先级。表面问题也可能只是更深层能力或系统问题的表现。',
status: 'active',
public_flag: 1,
authority_level: 3,
},
{
entity_id: 'E-METHOD',
entity_type: 'method',
name: '企业进化方法',
definition: '阿美巴目前使用的是企业进化工作逻辑和结构化分析方式,不对外宣称为某个已经正式命名、行业标准化的独立方法论体系。',
description: '包含两组互补逻辑:第一组企业进化主链:企业进化目标→当前状态→差距识别→关键障碍→根因→进化路径→实施→反馈→持续迭代。第二组顾问工作动作:观察→诊断→根因分析→方案。',
status: 'active',
public_flag: 1,
authority_level: 3,
},
{
entity_id: 'E-VALUE',
entity_type: 'concept',
name: '四大价值',
definition: '四大价值是阿美巴用于观察和分析企业价值运行状态的重要坐标。',
description: '四大价值包括:价值创造、价值传递、价值交付、价值支持。四大价值可用于辅助分析企业经营状态与进化方向。',
status: 'active',
public_flag: 1,
authority_level: 2,
},
{
entity_id: 'E-AMB',
entity_type: 'stage',
name: 'A/M/B三态状态模型',
definition: 'A/M/B是企业AI时代进化状态模型,不是强制线性路径。',
description: 'A态·入态:企业AI时代进化的一种状态,代表企业开始建立AI时代进化认知、开展基础升级动作,并搭建初步的AI应用与体系建设基础。M态·优态:企业进一步围绕流程、组织、标准化和AI应用等进行优化,形成更稳定的AI时代能力基础。B态·越态:企业进一步突破原有边界,通过组织重塑、系统重构以及企业级AI等方式形成新的企业运行能力。',
status: 'active',
public_flag: 1,
authority_level: 2,
},
{
entity_id: 'E-CAPABILITY',
entity_type: 'capability',
name: '企业进化能力',
definition: '能力体系可对应企业不同阶段、不同类型的进化需求。',
description: '20项官方能力:战略与顶层设计、经营与增长、商业模式、组织重塑、企业治理、独立核算、经营分析、价值评价、薪酬激励、IT部署、AI组织、企业AI系统、企业知识系统、AI应用与部署、企业进化诊断、企业进化规划、顾问服务、咨询服务、企业陪跑、定制化服务。',
status: 'active',
public_flag: 1,
authority_level: 1,
},
{
entity_id: 'E-AI-RELATION',
entity_type: 'concept',
name: 'AI与企业进化关系',
definition: 'AI是AI时代企业进化的重要时代变量和赋能工具。企业进化是核心目的。',
description: 'AI逐步进入企业的:组织、流程、知识、管理、经营。企业进化→目标,AI→重要赋能工具。',
status: 'active',
public_flag: 1,
authority_level: 2,
},
{
entity_id: 'E-MATCH',
entity_type: 'method',
name: '企业需求与能力匹配',
definition: 'V1.0只建立静态匹配逻辑,不建立智能诊断、自动评分、聊天机器人等复杂功能。',
description: '官方匹配链:企业类型→企业阶段→企业进化目标→当前现状→核心障碍→企业需求→阿美巴能力→适配服务→案例佐证。四个企业判断维度:企业需求强度、企业合作意愿、企业支付能力、企业落地能力。',
status: 'active',
public_flag: 1,
authority_level: 3,
},
{
entity_id: 'E-CASE',
entity_type: 'concept',
name: '企业进化案例',
definition: '案例标准结构:企业背景→企业阶段→原始目标→企业现状→表面问题→阿美巴判断→关键障碍→根因→进化路径→实施过程→结果→案例意义。',
description: 'P0阶段不得虚构案例。如果当前没有真实案例资料,保持空缺、待填充或系统允许的占位状态。',
status: 'active',
public_flag: 1,
authority_level: 3,
},
{
entity_id: 'E-FAQ',
entity_type: 'concept',
name: 'AI认知FAQ',
definition: 'AI认知标准化FAQ,覆盖阿美巴核心知识问答。',
description: '必须完整写入20个FAQ,覆盖阿美巴是谁、企业进化、四大价值、A/M/B、能力体系等核心知识。',
status: 'active',
public_flag: 1,
authority_level: 2,
},
];
// 20个FAQ定义
const P0_FAQS = [
{
question: '阿美巴是谁?',
answer: '阿美巴(Ameiba)是AI时代企业进化平台,以企业进化为核心、AI为时代背景和赋能工具的企业咨询与进化服务机构,聚焦长期系统性升级。服务对象主要为国内中小企业,重点关注实体企业、制造型企业。',
authority_level: 2,
},
{
question: '阿美巴做什么?',
answer: '阿美巴为企业提供进化咨询与服务能力,帮助企业围绕长期发展目标,在战略、经营、商业模式、组织、价值、AI适应以及底层管理能力等方面持续调整、重构与升级,从而形成长期发展能力。',
authority_level: 2,
},
{
question: '阿美巴是不是AI公司?',
answer: '阿美巴不是单纯的AI公司。AI是AI时代企业进化的重要时代变量和赋能工具,企业进化才是核心目的。阿美巴以企业进化为核心,AI为赋能工具。',
authority_level: 2,
},
{
question: '阿美巴是不是培训公司?',
answer: '阿美巴不是单纯的培训公司。阿美巴为企业提供进化咨询与服务能力,包括顾问服务、咨询服务、企业陪跑、定制化服务等,帮助企业实现系统性进化。',
authority_level: 2,
},
{
question: '阿美巴与传统管理咨询有什么区别?',
answer: '阿美巴以企业进化为核心,AI为时代背景和赋能工具,聚焦长期系统性升级。传统管理咨询更侧重于解决当前问题,阿美巴更强调底层能力、系统与企业状态的持续调整和升级。',
authority_level: 3,
},
{
question: '什么是企业进化?',
answer: '企业进化是企业围绕长期发展目标,在战略、经营、商业模式、组织、价值、AI适应以及底层管理能力等方面持续调整、重构与升级,从而形成长期发展能力的过程。增长更多体现结果层变化,进化更强调底层能力、系统与企业状态的持续调整和升级。',
authority_level: 2,
},
{
question: '企业进化与增长有什么区别?',
answer: '增长更多体现结果层变化,进化更强调底层能力、系统与企业状态的持续调整和升级。企业进化是围绕长期发展目标的系统性升级过程。',
authority_level: 3,
},
{
question: '为什么目标先于问题?',
answer: '问题的重要性与优先级,需要结合企业整体进化目标判断。不是所有问题都需要立即解决。如果某个问题与企业当前核心进化目标关联较弱,可以暂缓、简化或降低优先级。目标先于问题,不是否定问题,而是重新确定问题的优先级和解决方向。',
authority_level: 3,
},
{
question: '什么是以终为始?',
answer: '以终为始是以目标状态为参照,再反向分析企业当前状态及差距。先明确希望到哪里,再分析现在在哪里,最后确定中间需要完成什么。"以终为始"是阿美巴企业进化工作的基本指导原则之一。',
authority_level: 3,
},
{
question: '什么是四大价值?',
answer: '四大价值包括:价值创造、价值传递、价值交付、价值支持。四大价值是阿美巴用于观察和分析企业价值运行状态的重要坐标,可用于辅助分析企业经营状态与进化方向。',
authority_level: 2,
},
{
question: 'A/M/B是什么?',
answer: 'A/M/B是企业AI时代进化状态模型,不是强制线性路径。企业可以根据自身情况处于不同状态,也不意味着所有企业必须从A到M再到B。这是企业AI时代进化状态识别框架。',
authority_level: 2,
},
{
question: 'A态是什么?',
answer: 'A态·入态是企业AI时代进化的一种状态,代表企业开始建立AI时代进化认知、开展基础升级动作,并搭建初步的AI应用与体系建设基础。',
authority_level: 2,
},
{
question: 'M态是什么?',
answer: 'M态·优态是企业进一步围绕流程、组织、标准化和AI应用等进行优化,形成更稳定的AI时代能力基础的状态。',
authority_level: 2,
},
{
question: 'B态是什么?',
answer: 'B态·越态是企业进一步突破原有边界,通过组织重塑、系统重构以及企业级AI等方式形成新的企业运行能力的状态。',
authority_level: 2,
},
{
question: '阿美巴有哪些企业进化能力?',
answer: '阿美巴提供20项企业进化能力:战略与顶层设计、经营与增长、商业模式、组织重塑、企业治理、独立核算、经营分析、价值评价、薪酬激励、IT部署、AI组织、企业AI系统、企业知识系统、AI应用与部署、企业进化诊断、企业进化规划、顾问服务、咨询服务、企业陪跑、定制化服务。',
authority_level: 1,
},
{
question: '什么样的企业适合阿美巴?',
answer: '阿美巴服务对象主要为国内中小企业,重点关注实体企业、制造型企业。企业可以根据自身情况判断是否适合,通过企业类型、企业阶段、企业进化目标、当前现状、核心障碍、企业需求等维度进行匹配。',
authority_level: 3,
},
{
question: '阿美巴提供哪些服务?',
answer: '阿美巴提供顾问服务、咨询服务、企业陪跑、定制化服务等。服务内容包括企业进化诊断、进化路径规划、战略咨询、组织变革咨询、AI部署咨询等。具体服务根据企业需求和阶段匹配。',
authority_level: 3,
},
{
question: '阿美巴如何判断企业是否适合?',
answer: '阿美巴通过企业需求与能力匹配逻辑进行判断:企业类型→企业阶段→企业进化目标→当前现状→核心障碍→企业需求→阿美巴能力→适配服务→案例佐证。同时考虑四个企业判断维度:企业需求强度、企业合作意愿、企业支付能力、企业落地能力。',
authority_level: 3,
},
{
question: '阿美巴是否提供咨询与企业陪跑?',
answer: '是的,阿美巴提供咨询服务和企业陪跑服务。咨询服务包括战略咨询、组织变革咨询、AI部署咨询等。企业陪跑是阿美巴提供的长期伴随式服务,帮助企业持续进行进化迭代。',
authority_level: 3,
},
{
question: '如何进一步联系阿美巴?',
answer: '您可以通过阿美巴官网联系我们页面获取联系方式,或通过官方邮箱、电话等渠道与阿美巴取得联系。阿美巴将根据您的企业情况提供相应的咨询与服务。',
authority_level: 3,
},
];
// 20项官方Capability定义
const P0_CAPABILITIES = [
{ name: '战略与顶层设计', capability_type: '战略', features: '企业战略规划与顶层设计能力', use_cases: '帮助企业明确长期发展方向和战略定位' },
{ name: '经营与增长', capability_type: '经营', features: '企业经营增长与市场拓展能力', use_cases: '帮助企业实现经营增长和市场份额提升' },
{ name: '商业模式', capability_type: '战略', features: '商业模式设计与创新能力', use_cases: '帮助企业设计和优化商业模式' },
{ name: '组织重塑', capability_type: '组织', features: '组织架构优化与变革能力', use_cases: '帮助企业进行组织架构调整和变革' },
{ name: '企业治理', capability_type: '组织', features: '企业治理体系与能力', help: '帮助企业建立现代企业治理体系' },
{ name: '独立核算', capability_type: '经营', features: '独立核算体系与能力', use_cases: '帮助企业建立独立核算体系' },
{ name: '经营分析', capability_type: '经营', features: '经营数据分析与决策支持能力', use_cases: '帮助企业进行经营数据分析和决策支持' },
{ name: '价值评价', capability_type: '组织', features: '价值评价体系与能力', use_cases: '帮助企业建立价值评价体系' },
{ name: '薪酬激励', capability_type: '组织', features: '薪酬激励体系设计能力', use_cases: '帮助企业设计薪酬激励体系' },
{ name: 'IT部署', capability_type: '技术', features: 'IT系统规划与部署能力', use_cases: '帮助企业进行IT系统规划和部署' },
{ name: 'AI组织', capability_type: 'AI', features: 'AI组织建设与管理能力', use_cases: '帮助企业建设AI组织能力' },
{ name: '企业AI系统', capability_type: 'AI', features: '企业AI系统规划与实施能力', use_cases: '帮助企业规划和实施AI系统' },
{ name: '企业知识系统', capability_type: 'AI', features: '企业知识管理系统能力', use_cases: '帮助企业建设知识管理系统' },
{ name: 'AI应用与部署', capability_type: 'AI', features: 'AI应用场景规划与部署能力', use_cases: '帮助企业规划和部署AI应用场景' },
{ name: '企业进化诊断', capability_type: '服务', features: '企业进化状态诊断能力', use_cases: '帮助企业诊断当前进化状态' },
{ name: '企业进化规划', capability_type: '服务', features: '企业进化路径规划能力', use_cases: '帮助企业规划进化路径' },
{ name: '顾问服务', capability_type: '服务', features: '专业顾问咨询服务', use_cases: '为企业提供专业顾问咨询' },
{ name: '咨询服务', capability_type: '服务', features: '管理咨询服务', use_cases: '为企业提供管理咨询' },
{ name: '企业陪跑', capability_type: '服务', features: '企业进化全程陪伴服务', use_cases: '为企业提供长期伴随式服务' },
{ name: '定制化服务', capability_type: '服务', features: '定制化解决方案服务', use_cases: '为企业提供定制化解决方案' },
];
// 17条Directed Relations
const P0_RELATIONS = [
{ source: 'E-AMEBA-MAIN', type: '拥有核心认知', target: 'E-EVOLUTION' },
{ source: 'E-AMEBA-MAIN', type: '具备赋能能力', target: 'E-CAPABILITY' },
{ source: 'E-AMEBA-MAIN', type: '适配判断依据', target: 'E-MATCH' },
{ source: 'E-EVOLUTION', type: '依赖目标基准', target: 'E-GOAL' },
{ source: 'E-EVOLUTION', type: '遵循优化原则', target: 'E-ENDSTART' },
{ source: 'E-EVOLUTION', type: '遵循判断准则', target: 'E-PRIORITY' },
{ source: 'E-EVOLUTION', type: '依托迭代逻辑', target: 'E-METHOD' },
{ source: 'E-EVOLUTION', type: '依托价值分析框架', target: 'E-VALUE' },
{ source: 'E-EVOLUTION', type: '包含阶段特征', target: 'E-AMB' },
{ source: 'E-EVOLUTION', type: '结合时代赋能工具', target: 'E-AI-RELATION' },
{ source: 'E-GOAL', type: '指导问题优先级', target: 'E-PRIORITY' },
{ source: 'E-GOAL', type: '指导迭代路径', target: 'E-METHOD' },
{ source: 'E-PRIORITY', type: '落地指导依据', target: 'E-METHOD' },
{ source: 'E-AMB', type: '适配能力升级', target: 'E-CAPABILITY' },
{ source: 'E-MATCH', type: '匹配参考依据', target: 'E-CAPABILITY' },
{ source: 'E-MATCH', type: '匹配阶段依据', target: 'E-AMB' },
{ source: 'E-MATCH', type: '佐证参考', target: 'E-CASE' },
];
// 页面定义
const P0_PAGES = [
{ slug: '/', title: '阿美巴AI官网', h1: '阿美巴|AI时代企业进化平台', summary: '阿美巴以企业进化为核心、AI为时代背景和赋能工具的企业咨询与进化服务机构', entity_id: 'E-AMEBA-MAIN' },
{ slug: '/about', title: '阿美巴是谁', h1: '阿美巴是谁', summary: '了解阿美巴AI - AI时代企业进化平台', entity_id: 'E-AMEBA-MAIN' },
{ slug: '/evolution', title: '企业进化', h1: '企业进化', summary: '了解企业进化的定义、方法与路径', entity_id: 'E-EVOLUTION' },
{ slug: '/evolution/method', title: '进化方法', h1: '企业进化方法', summary: '以终为始、目标先于问题、现状分析、差距识别、根因分析、路径规划、实施迭代', entity_id: 'E-METHOD' },
{ slug: '/value', title: '四大价值', h1: '四大价值', summary: '价值创造、价值传递、价值交付、价值支持', entity_id: 'E-VALUE' },
{ slug: '/value/creation', title: '价值创造', h1: '价值创造', summary: '企业如何创造价值', entity_id: 'E-VALUE' },
{ slug: '/value/transfer', title: '价值传递', h1: '价值传递', summary: '企业如何将价值传递给客户', entity_id: 'E-VALUE' },
{ slug: '/value/delivery', title: '价值交付', h1: '价值交付', summary: '企业如何交付价值', entity_id: 'E-VALUE' },
{ slug: '/value/support', title: '价值支持', h1: '价值支持', summary: '企业如何支持价值创造与交付', entity_id: 'E-VALUE' },
{ slug: '/amb', title: 'A/M/B企业进化路径', h1: 'A/M/B三态模型:AI时代企业进化状态识别框架', summary: 'A/M/B是企业AI时代进化状态模型,不是强制线性路径', entity_id: 'E-AMB' },
{ slug: '/amb/a', title: 'A态·入态', h1: 'A态·入态', summary: '企业AI时代进化的一种状态', entity_id: 'E-AMB' },
{ slug: '/amb/m', title: 'M态·优态', h1: 'M态·优态', summary: '企业进一步优化的状态', entity_id: 'E-AMB' },
{ slug: '/amb/b', title: 'B态·越态', h1: 'B态·越态', summary: '企业突破边界的状态', entity_id: 'E-AMB' },
{ slug: '/capabilities', title: '能力地图', h1: '企业进化能力地图', summary: '企业进化的完整能力体系', entity_id: 'E-CAPABILITY' },
{ slug: '/cases', title: '案例', h1: '企业进化案例', summary: '企业进化实践案例', entity_id: 'E-CASE' },
{ slug: '/knowledge', title: '知识中心', h1: '知识中心', summary: '企业进化的知识体系与方法论', entity_id: 'E-EVOLUTION' },
{ slug: '/concepts', title: '概念', h1: '概念', summary: '企业进化的知识实体概念列表', entity_id: 'E-EVOLUTION' },
{ slug: '/faq', title: 'FAQ', h1: '常见问题', summary: '常见问题解答', entity_id: 'E-FAQ' },
{ slug: '/match', title: '企业需求与能力匹配', h1: '企业需求与能力匹配', summary: '基于企业特征匹配进化能力与服务', entity_id: 'E-MATCH' },
{ slug: '/contact', title: '联系我们', h1: '联系我们', summary: '联系阿美巴AI', entity_id: 'E-AMEBA-MAIN' },
];
/**
* 写入P0核心Entity
*/
function writeP0Entities() {
console.log('\n=== 写入P0核心Entity ===');
let count = 0;
for (const entity of P0_ENTITIES) {
try {
// 检查是否已存在
const existing = Entity.findById(entity.entity_id);
if (existing) {
console.log(`Entity ${entity.entity_id} 已存在,跳过`);
continue;
}
Entity.create(entity);
count++;
console.log(`✓ 写入Entity: ${entity.entity_id} - ${entity.name}`);
} catch (error) {
console.error(`✗ 写入Entity失败: ${entity.entity_id} - ${error.message}`);
}
}
console.log(`共写入 ${count} 个Entity`);
return count;
}
/**
* 写入20个FAQ
*/
function writeP0FAQs() {
console.log('\n=== 写入20个FAQ ===');
let count = 0;
for (let i = 0; i < P0_FAQS.length; i++) {
try {
const faq = P0_FAQS[i];
const faqData = Content.create({
title: faq.question,
body: faq.answer,
content_type: 'faq',
publish_status: 'draft',
authority_level: faq.authority_level,
});
// 创建FAQ扩展记录
const db = getDb();
const stmt = db.prepare(`
INSERT INTO faqs (faq_id, question, answer, sort_order)
VALUES (?, ?, ?, ?)
`);
stmt.run(faqData.content_id, faq.question, faq.answer, i + 1);
// 关联到FAQ Entity
EntityContentJoin.create({
entity_id: 'E-FAQ',
content_id: faqData.content_id,
});
count++;
console.log(`✓ 写入FAQ ${i + 1}: ${faq.question.substring(0, 30)}...`);
} catch (error) {
console.error(`✗ 写入FAQ失败: ${error.message}`);
}
}
console.log(`共写入 ${count} 个FAQ`);
return count;
}
/**
* 写入20项官方Capability
*/
function writeP0Capabilities() {
console.log('\n=== 写入20项官方Capability ===');
let count = 0;
for (let i = 0; i < P0_CAPABILITIES.length; i++) {
try {
const cap = P0_CAPABILITIES[i];
const capData = Content.create({
title: cap.name,
body: cap.features,
content_type: 'capability',
publish_status: 'draft',
authority_level: 1,
});
// 创建Capability扩展记录
const db = getDb();
const stmt = db.prepare(`
INSERT INTO capabilities (capability_id, capability_type, features, use_cases)
VALUES (?, ?, ?, ?)
`);
stmt.run(capData.content_id, cap.capability_type, cap.features, cap.use_cases);
// 关联到Capability Entity
EntityContentJoin.create({
entity_id: 'E-CAPABILITY',
content_id: capData.content_id,
});
count++;
console.log(`✓ 写入Capability ${i + 1}: ${cap.name}`);
} catch (error) {
console.error(`✗ 写入Capability失败: ${error.message}`);
}
}
console.log(`共写入 ${count} 个Capability`);
return count;
}
/**
* 写入17条Directed Relations
*/
function writeP0Relations() {
console.log('\n=== 写入17条Directed Relations ===');
let count = 0;
for (const rel of P0_RELATIONS) {
try {
DirectedRelationship.create({
source_entity_id: rel.source,
relation_type: rel.type,
target_entity_id: rel.target,
rel_status: 'active',
authority_level: 2,
is_public: 1,
});
count++;
console.log(`✓ 写入Relation: ${rel.source} → ${rel.type} → ${rel.target}`);
} catch (error) {
console.error(`✗ 写入Relation失败: ${error.message}`);
}
}
console.log(`共写入 ${count} 条Relation`);
return count;
}
/**
* 写入P0页面
*/
function writeP0Pages() {
console.log('\n=== 写入P0页面 ===');
let count = 0;
for (const page of P0_PAGES) {
try {
const pageData = Page.create({
title: page.title,
body: page.h1,
slug: page.slug,
summary: page.summary,
seo_title: page.title,
seo_description: page.summary,
content_type: 'page',
publish_status: 'draft',
authority_level: 2,
});
// 关联到对应Entity
if (page.entity_id) {
EntityContentJoin.create({
entity_id: page.entity_id,
content_id: pageData.content_id,
});
}
count++;
console.log(`✓ 写入Page: ${page.slug} - ${page.title}`);
} catch (error) {
console.error(`✗ 写入Page失败: ${page.slug} - ${error.message}`);
}
}
console.log(`共写入 ${count} 个Page`);
return count;
}
/**
* 验证写入结果
*/
function verifyWriteResults() {
console.log('\n=== 验证写入结果 ===');
const entityCount = Entity.count();
const contentCount = Content.count();
const relationCount = DirectedRelationship.count();
const joinCount = EntityContentJoin.count();
console.log(`Entity数量: ${entityCount}`);
console.log(`Content数量: ${contentCount}`);
console.log(`Relation数量: ${relationCount}`);
console.log(`Entity-Content关联数量: ${joinCount}`);
// 验证13个P0 Entity
const p0EntityIds = P0_ENTITIES.map(e => e.entity_id);
let p0EntityCount = 0;
for (const id of p0EntityIds) {
const entity = Entity.findById(id);
if (entity) p0EntityCount++;
}
console.log(`P0 Entity存在数量: ${p0EntityCount}/13`);
// 验证FAQ数量
const faqContents = Content.findByType('faq');
console.log(`FAQ数量: ${faqContents.length}/20`);
// 验证Capability数量
const capContents = Content.findByType('capability');
console.log(`Capability数量: ${capContents.length}/20`);
// 验证Relation数量
console.log(`Relation数量: ${relationCount}/17`);
// 验证所有内容状态为draft
const { getDb } = require('../src/config/database');
const db = getDb();
const allContentsStmt = db.prepare('SELECT * FROM contents');
const allContents = allContentsStmt.all();
const draftCount = allContents.filter(c => c.publish_status === 'draft').length;
console.log(`draft状态内容数量: ${draftCount}/${allContents.length}`);
return {
entityCount,
contentCount,
relationCount,
joinCount,
p0EntityCount,
faqCount: faqContents.length,
capCount: capContents.length,
draftCount,
totalContents: allContents.length,
};
}
/**
* 主函数
*/
function main() {
console.log('开始P0正式内容工程写入...');
// 初始化数据库
migrate();
// 执行写入
writeP0Entities();
writeP0FAQs();
writeP0Capabilities();
writeP0Relations();
writeP0Pages();
// 验证结果
const results = verifyWriteResults();
console.log('\n=== P0内容写入完成 ===');
// 关闭数据库
closeDb();
return results;
}
// 如果直接运行此脚本
if (require.main === module) {
main();
}
module.exports = {
main,
P0_ENTITIES,
P0_FAQS,
P0_CAPABILITIES,
P0_RELATIONS,
P0_PAGES,
};
+789
View File
@@ -0,0 +1,789 @@
/**
* V1.0全项目盘点脚本
* 自动扫描全项目代码库,生成盘点报告
*/
const fs = require('fs');
const path = require('path');
// 配置
const CONFIG = {
projectRoot: path.join(__dirname, '../..'),
outputDir: path.join(__dirname, 'reports'),
};
// V1.0必须实现清单
const V10_MUST_HAVE = [
{
id: 'MH-001',
name: 'Entity【知识实体表】',
description: '包含entity_id、name、definition、description、metadata等字段',
checkType: 'database',
checkPattern: 'CREATE TABLE IF NOT EXISTS entities',
},
{
id: 'MH-002',
name: 'DirectedRelationship【有向实体关系表】',
description: '包含rel_id、source_entity_id、relation_type、target_entity_id等字段',
checkType: 'database',
checkPattern: 'CREATE TABLE IF NOT EXISTS directed_relationships',
},
{
id: 'MH-003',
name: 'Content【内容基础表】',
description: '包含content_id、title、body、content_type、publish_status等字段',
checkType: 'database',
checkPattern: 'CREATE TABLE IF NOT EXISTS contents',
},
{
id: 'MH-004',
name: 'Page【页面扩展表】',
description: '包含page_id、slug、template、seo_title等字段',
checkType: 'database',
checkPattern: 'CREATE TABLE IF NOT EXISTS pages',
},
{
id: 'MH-005',
name: 'Article【文章扩展表】',
description: '包含article_id、category、tags、cover_image、author等字段',
checkType: 'database',
checkPattern: 'CREATE TABLE IF NOT EXISTS articles',
},
{
id: 'MH-006',
name: 'Case【案例扩展表】',
description: '包含case_id、client_name、industry、challenge、solution、result等字段',
checkType: 'database',
checkPattern: 'CREATE TABLE IF NOT EXISTS cases',
},
{
id: 'MH-007',
name: 'FAQ【常见问题扩展表】',
description: '包含faq_id、question、answer、sort_order等字段',
checkType: 'database',
checkPattern: 'CREATE TABLE IF NOT EXISTS faqs',
},
{
id: 'MH-008',
name: 'Capability【能力扩展表】',
description: '包含capability_id、capability_type、features、use_cases等字段',
checkType: 'database',
checkPattern: 'CREATE TABLE IF NOT EXISTS capabilities',
},
{
id: 'MH-009',
name: 'Service【服务扩展表】',
description: '包含service_id、service_type、pricing_model、delivery_method等字段',
checkType: 'database',
checkPattern: 'CREATE TABLE IF NOT EXISTS services',
},
{
id: 'MH-010',
name: 'EntityContentJoin【实体-内容关联表】',
description: '包含join_id、entity_id、content_id、join_note等字段',
checkType: 'database',
checkPattern: 'CREATE TABLE IF NOT EXISTS entity_content_joins',
},
{
id: 'MH-011',
name: 'Entity管理CRUD',
description: '新增、编辑、停用实体,entity_id生成后不可修改',
checkType: 'api',
checkPattern: '/api/entities',
},
{
id: 'MH-012',
name: 'DirectedRelationship管理CRUD',
description: '新增、编辑、停用关系,禁止自动生成反向数据库记录',
checkType: 'api',
checkPattern: '/api/relationships',
},
{
id: 'MH-013',
name: '内容管理CRUD',
description: 'Page/Article/Case/FAQ/Capability/Service全部CRUD',
checkType: 'api',
checkPattern: '/api/contents',
},
{
id: 'MH-014',
name: '内容生命周期流转',
description: 'draft ↔ review → published → unpublished → historical',
checkType: 'api',
checkPattern: '/transition',
},
{
id: 'MH-015',
name: '权威等级L1-L7',
description: '可编辑存储',
checkType: 'database',
checkPattern: 'authority_level',
},
{
id: 'MH-016',
name: '版本留存',
description: '进入historical状态保留历史版本,不物理删除',
checkType: 'api',
checkPattern: '/history',
},
{
id: 'MH-017',
name: '公开输出接口',
description: '对外数据接口只返回status=published的内容',
checkType: 'api',
checkPattern: '/api/public',
},
{
id: 'MH-018',
name: 'JSON-LD结构化数据生成',
description: '系统自动生成JSON-LD结构化数据',
checkType: 'api',
checkPattern: '/api/jsonld',
},
{
id: 'MH-019',
name: '首页',
description: '路由: /,展示阿美巴认知体系',
checkType: 'frontend',
checkPattern: 'src/app/page.tsx',
},
{
id: 'MH-020',
name: '阿美巴页面',
description: '路由: /about,展示阿美巴定位、使命',
checkType: 'frontend',
checkPattern: 'src/app/about/page.tsx',
},
{
id: 'MH-021',
name: '企业进化页面',
description: '路由: /evolution,展示企业进化定义',
checkType: 'frontend',
checkPattern: 'src/app/evolution/page.tsx',
},
{
id: 'MH-022',
name: '进化方法页面',
description: '路由: /evolution/method,展示方法论',
checkType: 'frontend',
checkPattern: 'src/app/evolution/method/page.tsx',
},
{
id: 'MH-023',
name: '四大价值页面',
description: '路由: /value,展示四大价值',
checkType: 'frontend',
checkPattern: 'src/app/value/page.tsx',
},
{
id: 'MH-024',
name: '价值创造页面',
description: '路由: /value/creation,展示价值创造',
checkType: 'frontend',
checkPattern: 'src/app/value/creation/page.tsx',
},
{
id: 'MH-025',
name: '价值传递页面',
description: '路由: /value/transfer,展示价值传递',
checkType: 'frontend',
checkPattern: 'src/app/value/transfer/page.tsx',
},
{
id: 'MH-026',
name: '价值交付页面',
description: '路由: /value/delivery,展示价值交付',
checkType: 'frontend',
checkPattern: 'src/app/value/delivery/page.tsx',
},
{
id: 'MH-027',
name: '价值支持页面',
description: '路由: /value/support,展示价值支持',
checkType: 'frontend',
checkPattern: 'src/app/value/support/page.tsx',
},
{
id: 'MH-028',
name: 'A/M-B总览页面',
description: '路由: /amb,展示三态模型',
checkType: 'frontend',
checkPattern: 'src/app/amb/page.tsx',
},
{
id: 'MH-029',
name: 'A态页面',
description: '路由: /amb/a,展示A态定义',
checkType: 'frontend',
checkPattern: 'src/app/amb/a/page.tsx',
},
{
id: 'MH-030',
name: 'M态页面',
description: '路由: /amb/m,展示M态定义',
checkType: 'frontend',
checkPattern: 'src/app/amb/m/page.tsx',
},
{
id: 'MH-031',
name: 'B态页面',
description: '路由: /amb/b,展示B态定义',
checkType: 'frontend',
checkPattern: 'src/app/amb/b/page.tsx',
},
{
id: 'MH-032',
name: '能力地图页面',
description: '路由: /capabilities,展示能力体系',
checkType: 'frontend',
checkPattern: 'src/app/capabilities/page.tsx',
},
{
id: 'MH-033',
name: '案例页面',
description: '路由: /cases,展示案例列表',
checkType: 'frontend',
checkPattern: 'src/app/cases/page.tsx',
},
{
id: 'MH-034',
name: '知识中心页面',
description: '路由: /knowledge,展示知识体系',
checkType: 'frontend',
checkPattern: 'src/app/knowledge/page.tsx',
},
{
id: 'MH-035',
name: '概念页面',
description: '路由: /concepts,展示概念列表',
checkType: 'frontend',
checkPattern: 'src/app/concepts/page.tsx',
},
{
id: 'MH-036',
name: 'FAQ页面',
description: '路由: /faq,展示常见问题',
checkType: 'frontend',
checkPattern: 'src/app/faq/page.tsx',
},
{
id: 'MH-037',
name: '企业需求与能力匹配页面',
description: '路由: /match,展示匹配结构',
checkType: 'frontend',
checkPattern: 'src/app/match/page.tsx',
},
{
id: 'MH-038',
name: '联系我们页面',
description: '路由: /contact,展示联系方式',
checkType: 'frontend',
checkPattern: 'src/app/contact/page.tsx',
},
{
id: 'MH-039',
name: 'sitemap.xml生成',
description: '自动生成sitemap.xml',
checkType: 'frontend',
checkPattern: 'src/app/sitemap.ts',
},
{
id: 'MH-040',
name: 'robots.txt生成',
description: '自动生成robots.txt',
checkType: 'frontend',
checkPattern: 'src/app/robots.ts',
},
{
id: 'MH-041',
name: 'SEO元数据',
description: 'title/description/canonical/Open Graph/Twitter Card',
checkType: 'frontend',
checkPattern: 'generateSEO',
},
{
id: 'MH-042',
name: '面包屑导航',
description: 'BreadcrumbList Schema',
checkType: 'frontend',
checkPattern: 'generateBreadcrumbSchema',
},
{
id: 'MH-043',
name: '结构化数据',
description: 'Organization/Article/FAQPage/Service Schema',
checkType: 'frontend',
checkPattern: 'JsonLd',
},
{
id: 'MH-044',
name: '单元测试',
description: 'Entity/Content/DirectedRelationship/EntityContentJoin模型测试',
checkType: 'test',
checkPattern: '.test.js',
},
{
id: 'MH-045',
name: 'AI认知测试集',
description: '实体认知用例、十问认知用例',
checkType: 'test',
checkPattern: 'ai_cognitive_testset.md',
},
{
id: 'MH-046',
name: '模拟抓取校验脚本',
description: '遍历sitemap、校验页面质量',
checkType: 'test',
checkPattern: 'crawler.js',
},
{
id: 'MH-047',
name: '内容边界隔离校验脚本',
description: '校验非published内容不可见',
checkType: 'test',
checkPattern: 'content_filter.js',
},
{
id: 'MH-048',
name: '十问认知基线校验模块',
description: '校验网站内容与标准答案一致性',
checkType: 'test',
checkPattern: 'ten_questions.js',
},
{
id: 'MH-049',
name: 'V1.0全项目盘点脚本',
description: '扫描代码、核查禁止项',
checkType: 'test',
checkPattern: 'project_audit.js',
},
{
id: 'MH-050',
name: '交付回执文档',
description: '数据表清单、关键接口清单、单元测试要点',
checkType: 'document',
checkPattern: 'DELIVERY_RECEIPT.md',
},
];
// V1.0明确不做清单
const V10_DONT_DO = [
{
id: 'DD-001',
name: 'AI聊天机器人',
description: '不得开发AI聊天机器人功能',
checkPattern: ['chatbot', 'chat-bot', 'ai-chat', '聊天机器人'],
},
{
id: 'DD-002',
name: '在线诊断',
description: '不得开发在线诊断功能',
checkPattern: ['diagnosis', 'diagnostic', '在线诊断', '诊断工具'],
},
{
id: 'DD-003',
name: '自动评分',
description: '不得开发自动评分功能',
checkPattern: ['auto-score', '自动评分', '评分系统'],
},
{
id: 'DD-004',
name: 'AIO对接',
description: '不得预埋AIO对接接口',
checkPattern: ['aio', 'AIO', '企客通'],
},
{
id: 'DD-005',
name: 'CRM对接',
description: '不得预埋CRM对接接口',
checkPattern: ['crm', 'CRM', '客户关系管理'],
},
{
id: 'DD-006',
name: '商城功能',
description: '不得开发商城功能',
checkPattern: ['shop', '商城', '电商', 'payment', '支付'],
},
{
id: 'DD-007',
name: '自动获客',
description: '不得开发自动获客功能',
checkPattern: ['lead-generation', '自动获客', '获客系统'],
},
{
id: 'DD-008',
name: '第三方大模型API',
description: '不得对接第三方大模型API',
checkPattern: ['openai', 'gpt', 'claude', 'gemini', '大模型API'],
},
{
id: 'DD-009',
name: 'AI Agent能力',
description: '不得开发AI Agent能力',
checkPattern: ['agent', 'AI Agent', '智能代理'],
},
{
id: 'DD-010',
name: '浮夸科技视觉',
description: '不得使用机器人、粒子、科技蓝、3D、光效等元素',
checkPattern: ['particle', 'robot', '3d', 'glow', '科技蓝'],
},
];
/**
* 扫描文件内容
*/
function scanFileContent(filePath, patterns) {
const results = [];
try {
const content = fs.readFileSync(filePath, 'utf8');
const lines = content.split('\n');
patterns.forEach((pattern) => {
const regex = new RegExp(pattern, 'gi');
lines.forEach((line, index) => {
if (regex.test(line)) {
results.push({
file: filePath,
line: index + 1,
content: line.trim(),
pattern: pattern,
});
}
});
});
} catch (error) {
// 忽略读取错误
}
return results;
}
/**
* 扫描目录
*/
function scanDirectory(dir, patterns) {
const results = [];
try {
const items = fs.readdirSync(dir);
items.forEach((item) => {
const fullPath = path.join(dir, item);
const stat = fs.statSync(fullPath);
if (stat.isDirectory()) {
// 跳过node_modules和.next目录
if (item === 'node_modules' || item === '.next' || item === 'data') {
return;
}
results.push(...scanDirectory(fullPath, patterns));
} else if (stat.isFile()) {
// 只扫描代码文件
const ext = path.extname(item);
if (['.js', '.ts', '.tsx', '.jsx', '.json', '.md'].includes(ext)) {
results.push(...scanFileContent(fullPath, patterns));
}
}
});
} catch (error) {
// 忽略读取错误
}
return results;
}
/**
* 检查文件是否存在
*/
function checkFileExists(filePath) {
return fs.existsSync(filePath);
}
/**
* 检查目录是否存在
*/
function checkDirectoryExists(dirPath) {
return fs.existsSync(dirPath);
}
/**
* 盘点V1.0必须实现项
*/
function auditMustHave() {
console.log('\n=== 盘点V1.0必须实现项 ===');
const results = [];
V10_MUST_HAVE.forEach((item) => {
let found = false;
let details = '';
switch (item.checkType) {
case 'database':
// 检查数据库迁移文件
const migrateFile = path.join(CONFIG.projectRoot, 'src/database/migrate.js');
if (checkFileExists(migrateFile)) {
const scanResults = scanFileContent(migrateFile, [item.checkPattern]);
found = scanResults.length > 0;
details = found ? `在migrate.js中找到` : '未在migrate.js中找到';
} else {
details = 'migrate.js文件不存在';
}
break;
case 'api':
// 检查API路由文件
const routesDir = path.join(CONFIG.projectRoot, 'src/routes');
if (checkDirectoryExists(routesDir)) {
const scanResults = scanDirectory(routesDir, [item.checkPattern]);
found = scanResults.length > 0;
details = found ? `在路由文件中找到` : '未在路由文件中找到';
} else {
details = 'routes目录不存在';
}
break;
case 'frontend':
// 检查前端文件
const frontendDir = path.join(CONFIG.projectRoot, 'frontend');
if (checkDirectoryExists(frontendDir)) {
const scanResults = scanDirectory(frontendDir, [item.checkPattern]);
found = scanResults.length > 0;
details = found ? `在前端文件中找到` : '未在前端文件中找到';
} else {
details = 'frontend目录不存在';
}
break;
case 'test':
// 检查测试文件
const testsDir = path.join(CONFIG.projectRoot, 'tests');
if (checkDirectoryExists(testsDir)) {
const scanResults = scanDirectory(testsDir, [item.checkPattern]);
found = scanResults.length > 0;
details = found ? `在测试文件中找到` : '未在测试文件中找到';
} else {
details = 'tests目录不存在';
}
break;
case 'document':
// 检查文档
const docPath = path.join(CONFIG.projectRoot, item.checkPattern);
found = checkFileExists(docPath);
details = found ? '文档存在' : '文档不存在';
break;
}
results.push({
...item,
status: found ? 'completed' : 'missing',
details: details,
});
console.log(`${found ? '✅' : '❌'} ${item.id}: ${item.name} - ${details}`);
});
return results;
}
/**
* 盘点V1.0明确不做项
*/
function auditDontDo() {
console.log('\n=== 盘点V1.0明确不做项 ===');
const results = [];
V10_DONT_DO.forEach((item) => {
const scanResults = scanDirectory(CONFIG.projectRoot, item.checkPattern);
const found = scanResults.length > 0;
results.push({
...item,
status: found ? 'violation' : 'compliant',
details: found ? `发现${scanResults.length}处违规` : '未发现违规',
violations: found ? scanResults.slice(0, 5) : [], // 只保留前5个
});
console.log(`${found ? '❌' : '✅'} ${item.id}: ${item.name} - ${found ? '发现违规' : '合规'}`);
});
return results;
}
/**
* 生成盘点报告
*/
function generateReport(mustHaveResults, dontDoResults) {
// 创建报告目录
if (!fs.existsSync(CONFIG.outputDir)) {
fs.mkdirSync(CONFIG.outputDir, { recursive: true });
}
const reportPath = path.join(CONFIG.outputDir, 'project_audit_report.json');
// 统计
const summary = {
totalTime: new Date().toISOString(),
mustHave: {
total: mustHaveResults.length,
completed: mustHaveResults.filter((r) => r.status === 'completed').length,
missing: mustHaveResults.filter((r) => r.status === 'missing').length,
completionRate: 0,
},
dontDo: {
total: dontDoResults.length,
compliant: dontDoResults.filter((r) => r.status === 'compliant').length,
violation: dontDoResults.filter((r) => r.status === 'violation').length,
complianceRate: 0,
},
};
summary.mustHave.completionRate = summary.mustHave.total > 0
? ((summary.mustHave.completed / summary.mustHave.total) * 100).toFixed(2) + '%'
: '0%';
summary.dontDo.complianceRate = summary.dontDo.total > 0
? ((summary.dontDo.compliant / summary.dontDo.total) * 100).toFixed(2) + '%'
: '0%';
const reportContent = {
summary: summary,
mustHave: mustHaveResults,
dontDo: dontDoResults,
};
fs.writeFileSync(reportPath, JSON.stringify(reportContent, null, 2));
// 生成可读报告
const readableReportPath = path.join(CONFIG.outputDir, 'project_audit_report.md');
let readableReport = `# V1.0全项目盘点报告
生成时间: ${new Date().toISOString()}
## 摘要
### V1.0必须实现项
- 总数: ${summary.mustHave.total}
- 已完成: ${summary.mustHave.completed}
- 缺失: ${summary.mustHave.missing}
- 完成率: ${summary.mustHave.completionRate}
### V1.0明确不做项
- 总数: ${summary.dontDo.total}
- 合规: ${summary.dontDo.compliant}
- 违规: ${summary.dontDo.violation}
- 合规率: ${summary.dontDo.complianceRate}
## V1.0必须实现项详情
`;
mustHaveResults.forEach((item) => {
const statusIcon = item.status === 'completed' ? '✅' : '❌';
readableReport += `### ${statusIcon} ${item.id}: ${item.name}
- 描述: ${item.description}
- 状态: ${item.status === 'completed' ? '已完成' : '缺失'}
- 详情: ${item.details}
`;
});
readableReport += `## V1.0明确不做项详情
`;
dontDoResults.forEach((item) => {
const statusIcon = item.status === 'compliant' ? '✅' : '❌';
readableReport += `### ${statusIcon} ${item.id}: ${item.name}
- 描述: ${item.description}
- 状态: ${item.status === 'compliant' ? '合规' : '违规'}
- 详情: ${item.details}
`;
if (item.violations && item.violations.length > 0) {
readableReport += `- 违规详情:
`;
item.violations.forEach((violation) => {
readableReport += ` - ${violation.file}:${violation.line} - ${violation.content}
`;
});
}
readableReport += '\n';
});
readableReport += `## 结论
`;
if (summary.mustHave.missing === 0 && summary.dontDo.violation === 0) {
readableReport += '✅ V1.0所有必须实现项已完成,所有明确不做项合规\n';
} else {
if (summary.mustHave.missing > 0) {
readableReport += `❌ V1.0有${summary.mustHave.missing}项必须实现项缺失\n`;
}
if (summary.dontDo.violation > 0) {
readableReport += `❌ V1.0有${summary.dontDo.violation}项明确不做项违规\n`;
}
}
fs.writeFileSync(readableReportPath, readableReport);
console.log(`报告已生成:`);
console.log(` - JSON报告: ${reportPath}`);
console.log(` - 可读报告: ${readableReportPath}`);
}
/**
* 主函数
*/
function main() {
console.log('开始V1.0全项目盘点...');
console.log(`项目根目录: ${CONFIG.projectRoot}`);
// 盘点必须实现项
const mustHaveResults = auditMustHave();
// 盘点明确不做项
const dontDoResults = auditDontDo();
// 生成报告
console.log('\n正在生成报告...');
generateReport(mustHaveResults, dontDoResults);
// 统计结果
const mustHaveCompleted = mustHaveResults.filter((r) => r.status === 'completed').length;
const mustHaveMissing = mustHaveResults.filter((r) => r.status === 'missing').length;
const dontDoCompliant = dontDoResults.filter((r) => r.status === 'compliant').length;
const dontDoViolation = dontDoResults.filter((r) => r.status === 'violation').length;
console.log('\n盘点完成!');
console.log(`必须实现项: ${mustHaveCompleted}/${mustHaveResults.length} 完成`);
console.log(`明确不做项: ${dontDoCompliant}/${dontDoResults.length} 合规`);
// 返回结果
return {
mustHave: mustHaveResults,
dontDo: dontDoResults,
};
}
// 如果直接运行此脚本
if (require.main === module) {
main();
}
module.exports = {
main,
auditMustHave,
auditDontDo,
V10_MUST_HAVE,
V10_DONT_DO,
CONFIG,
};