const { getDb, closeDb } = require('../config/database'); const createTables = () => { const db = getDb(); // Entity表 - 知识实体表(P1-01增加entity_type,P1-02增加status/public_flag) db.exec(` CREATE TABLE IF NOT EXISTS entities ( entity_id VARCHAR(36) PRIMARY KEY, entity_type VARCHAR(64) DEFAULT 'concept', name TEXT NOT NULL, definition TEXT, description TEXT, status VARCHAR(32) DEFAULT 'active', public_flag BOOLEAN DEFAULT 1, authority_level INTEGER DEFAULT 1, metadata TEXT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ) `); // DirectedRelationship表 - 有向实体关系表 db.exec(` CREATE TABLE IF NOT EXISTS directed_relationships ( rel_id VARCHAR(36) PRIMARY KEY, source_entity_id VARCHAR(36) NOT NULL, relation_type VARCHAR(255) NOT NULL, target_entity_id VARCHAR(36) NOT NULL, rel_status VARCHAR(32) DEFAULT 'active', authority_level INTEGER DEFAULT 1, is_public BOOLEAN DEFAULT 0, effective_at DATETIME, expire_at DATETIME, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (source_entity_id) REFERENCES entities(entity_id), FOREIGN KEY (target_entity_id) REFERENCES entities(entity_id) ) `); // Content基础表 - 内容基础模型 db.exec(` CREATE TABLE IF NOT EXISTS contents ( content_id VARCHAR(36) PRIMARY KEY, title TEXT NOT NULL, body TEXT, content_type VARCHAR(32) NOT NULL, publish_status VARCHAR(32) DEFAULT 'draft', authority_level INTEGER DEFAULT 1, version_no INTEGER DEFAULT 1, version_note TEXT, metadata TEXT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP, archived_at DATETIME ) `); // Page表 - 页面扩展(P1-03增加summary) db.exec(` CREATE TABLE IF NOT EXISTS pages ( page_id VARCHAR(36) PRIMARY KEY, slug VARCHAR(255) UNIQUE, template VARCHAR(255), summary TEXT, seo_title TEXT, seo_description TEXT, seo_keywords TEXT, FOREIGN KEY (page_id) REFERENCES contents(content_id) ) `); // Article表 - 文章扩展(P1-04增加published_at) db.exec(` CREATE TABLE IF NOT EXISTS articles ( article_id VARCHAR(36) PRIMARY KEY, category VARCHAR(255), tags TEXT, cover_image VARCHAR(1024), author VARCHAR(255), published_at DATETIME, FOREIGN KEY (article_id) REFERENCES contents(content_id) ) `); // Case表 - 案例扩展(P0-01扩展完整案例字段) db.exec(` CREATE TABLE IF NOT EXISTS cases ( case_id VARCHAR(36) PRIMARY KEY, client_name TEXT, industry TEXT, challenge TEXT, solution TEXT, result TEXT, background TEXT, enterprise_stage TEXT, original_goal TEXT, current_state TEXT, surface_problem TEXT, amb_judgment TEXT, key_obstacle TEXT, root_cause TEXT, evolution_path TEXT, implementation TEXT, case_significance TEXT, FOREIGN KEY (case_id) REFERENCES contents(content_id) ) `); // FAQ表 - 常见问题扩展 db.exec(` CREATE TABLE IF NOT EXISTS faqs ( faq_id VARCHAR(36) PRIMARY KEY, question TEXT, answer TEXT, sort_order INTEGER DEFAULT 0, FOREIGN KEY (faq_id) REFERENCES contents(content_id) ) `); // Capability表 - 能力扩展 db.exec(` CREATE TABLE IF NOT EXISTS capabilities ( capability_id VARCHAR(36) PRIMARY KEY, capability_type TEXT, features TEXT, use_cases TEXT, FOREIGN KEY (capability_id) REFERENCES contents(content_id) ) `); // Service表 - 服务扩展 db.exec(` CREATE TABLE IF NOT EXISTS services ( service_id VARCHAR(36) PRIMARY KEY, service_type TEXT, pricing_model TEXT, delivery_method TEXT, FOREIGN KEY (service_id) REFERENCES contents(content_id) ) `); // EntityContentJoin表 - 实体-内容多对多关联中间表 db.exec(` CREATE TABLE IF NOT EXISTS entity_content_joins ( join_id VARCHAR(36) PRIMARY KEY, entity_id VARCHAR(36) NOT NULL, content_id VARCHAR(36) NOT NULL, join_note TEXT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (entity_id) REFERENCES entities(entity_id), FOREIGN KEY (content_id) REFERENCES contents(content_id) ) `); // 管理员账号表 db.exec(` CREATE TABLE IF NOT EXISTS admin_users ( user_id VARCHAR(36) PRIMARY KEY, username VARCHAR(64) NOT NULL UNIQUE, password_hash VARCHAR(255) NOT NULL, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ) `); // 前台可编辑站点配置 db.exec(` CREATE TABLE IF NOT EXISTS site_settings ( setting_key VARCHAR(128) PRIMARY KEY, setting_value TEXT, setting_group VARCHAR(64) DEFAULT 'general', updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ) `); // 内容判断引擎发布映射:复用既有 contents/articles,而非建立第二套文章系统。 db.exec(` CREATE TABLE IF NOT EXISTS integration_publications ( publication_id VARCHAR(36) PRIMARY KEY, content_id VARCHAR(36) NOT NULL UNIQUE, source_system VARCHAR(64) NOT NULL, source_task_id VARCHAR(128) NOT NULL, source_version_id VARCHAR(128) NOT NULL, source_version_number INTEGER NOT NULL, site_profile VARCHAR(16) NOT NULL, idempotency_key VARCHAR(255) NOT NULL UNIQUE, content_hash VARCHAR(128) NOT NULL, revision INTEGER NOT NULL DEFAULT 1, slug VARCHAR(180) UNIQUE, summary TEXT, primary_keyword VARCHAR(255), keywords_json TEXT, source_content_type VARCHAR(64), direction VARCHAR(255), target_audience VARCHAR(255), canonical_url VARCHAR(2048), human_confirmed BOOLEAN NOT NULL DEFAULT 0, confirmed_at DATETIME, knowledge_refs_json TEXT, entities_json TEXT, questions_json TEXT, facts_json TEXT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP, published_at DATETIME, UNIQUE KEY uq_integration_source_task (source_system, source_task_id, site_profile), FOREIGN KEY (content_id) REFERENCES contents(content_id) ) `); console.log('数据库表创建完成'); }; const migrate = () => { try { createTables(); seedAdminAndSettings(); console.log('数据库迁移完成'); } catch (error) { console.error('数据库迁移失败:', error); throw error; } }; const seedAdminAndSettings = () => { const db = getDb(); const crypto = require('crypto'); const user = db.prepare('SELECT user_id FROM admin_users WHERE username = ?').get('admin'); if (!user) { const initialAdminPassword = process.env.ADMIN_INITIAL_PASSWORD; if (!initialAdminPassword) { throw new Error('首次初始化管理员账号需要配置 ADMIN_INITIAL_PASSWORD'); } const salt = crypto.randomBytes(16).toString('hex'); const hash = crypto.scryptSync(initialAdminPassword, salt, 64).toString('hex'); db.prepare(` INSERT INTO admin_users (user_id, username, password_hash) VALUES (?, ?, ?) `).run(require('uuid').v4(), 'admin', `${salt}:${hash}`); console.log('默认管理员账号已创建: admin'); } const defaults = { 'site.name': ['阿美巴AI', 'general'], 'site.footerCopyright': ['© 2026 阿美巴AI. All rights reserved.', 'general'], 'site.footerEmail': ['ameiba0258@gmail.com', 'general'], 'site.footerPhone': ['4009080258', 'general'], 'site.footerAddress': ['四川省成都市双流区正兴街道湖畔路北段366号1栋3楼1号', 'general'], 'site.icp': ['蜀ICP备2025143754号-7', 'general'], 'home.heroTitle': ['阿美巴(Ameiba)', 'home'], 'home.heroSubtitle': ['AI时代企业进化平台', 'home'], 'home.heroDescription': ['我们帮助企业在AI时代实现系统化进化,从战略顶层设计到组织重塑,从经营增长到AI部署,提供完整的企业进化能力与服务。', 'home'], 'contact.title': ['联系我们', 'contact'], 'contact.contactTitle': ['联系方式', 'contact'], 'contact.email': ['contact@ameiba.com', 'contact'], 'contact.phone': ['待填充', 'contact'], 'contact.address': ['待填充', 'contact'], 'contact.serviceHoursTitle': ['服务时间', 'contact'], 'contact.serviceHours': ['周一至周五:9:00 - 18:00', 'contact'], 'contact.consultationTitle': ['咨询服务', 'contact'], 'contact.consultationIntro': ['我们提供以下咨询服务:', 'contact'], 'contact.consultationItems': ['企业进化诊断\n进化路径规划\n战略咨询\n组织变革咨询\nAI部署咨询', 'contact'], 'contact.cooperationTitle': ['合作方式', 'contact'], 'contact.cooperationItems': ['顾问服务\n咨询服务\n企业陪跑\n定制化服务', 'contact'], 'contact.faqTitle': ['常见问题', 'contact'], 'contact.faqText': ['如有其他问题,请查看', 'contact'], 'contact.relatedTitle': ['相关知识', 'contact'], }; const pageDefaults = { about: ['阿美巴是谁', '阿美巴(Ameiba)是AI时代企业进化平台,专注于帮助企业实现系统化进化。'], evolution: ['企业进化', '企业进化是企业围绕长期发展目标持续调整、重构与升级的过程。'], value: ['四大价值', '价值创造、价值传递、价值交付、价值支持共同构成企业经营的价值体系。'], amb: ['A/M/B三态模型:AI时代企业进化状态识别框架', 'A/M/B模型用于帮助企业识别自身所处的进化状态,并明确下一步行动。'], capabilities: ['企业进化能力地图', '从战略、经营、组织到AI部署,构建企业持续进化所需要的能力地图。'], cases: ['企业进化案例', '通过真实案例,展示企业在经营环境中的目标、障碍、进化路径与实施过程。'], knowledge: ['知识中心', '集中展示企业进化相关的知识、方法和实践内容。'], faq: ['常见问题', '以下是关于企业进化的常见问题解答。'], }; Object.entries(pageDefaults).forEach(([page, [title, intro]]) => { defaults[`${page}.title`] = [title, page]; defaults[`${page}.intro`] = [intro, page]; }); const extraDefaults = { 'amb.whatTitle': ['什么是A/M/B', 'amb'], 'amb.whatNote': ['A/M/B不是产品套餐,不是收费等级,不是强制线性路径,不是所有企业必须经历的三个固定阶段。', 'amb'], 'amb.whatPurpose': ['A/M/B的作用,是帮助企业识别自身所处状态,并进一步判断当前需要完成的关键进化动作。', 'amb'], 'amb.statesTitle': ['三种状态', 'amb'], 'amb.stateA': ['A态·入态|企业开始进入AI时代企业进化的一种状态', 'amb'], 'amb.stateM': ['M态·优态|企业进一步围绕现有经营与管理体系进行优化的一种状态', 'amb'], 'amb.stateB': ['B态·越态|企业突破原有运行边界、形成新的企业运行能力的一种状态', 'amb'], 'amb.recognitionTitle': ['状态识别', 'amb'], 'amb.recognitionText': ['企业可以根据自身情况处于不同状态,也不意味着所有企业必须从A到M再到B。\n企业需要根据自身发展阶段和实际情况,判断当前所处的状态,并确定需要完成的关键进化动作。', 'amb'], 'evolution.definitionTitle': ['什么是企业进化', 'evolution'], 'evolution.definitionMore': ['增长更多体现结果层变化。进化更强调底层能力、系统与企业状态的持续调整和升级。AI是时代变量和重要赋能工具,不是企业进化本身的终点。', 'evolution'], 'evolution.whyTitle': ['为什么需要企业进化', 'evolution'], 'evolution.whyIntro': ['在AI时代,企业面临着前所未有的挑战:', 'evolution'], 'evolution.whyItems': ['技术快速迭代,传统业务模式面临冲击\n客户需求变化,个性化、智能化要求提高\n竞争环境加剧,需要更高效的运营模式\n人才结构变化,需要新的组织能力', 'evolution'], 'value.overviewTitle': ['价值体系概述', 'value'], 'value.valuesTitle': ['四大价值', 'value'], 'value.relationTitle': ['价值体系的关系', 'value'], 'value.relationText': ['四大价值相互关联、相互支撑。价值创造是基础,价值传递是桥梁,价值交付是结果,价值支持是保障。企业需要在这四个维度上协调发展,才能实现持续增长。', 'value'], 'about.positionTitle': ['定位', 'about'], 'about.positionText': ['阿美巴(Ameiba)是AI时代企业进化平台,专注于帮助企业实现系统化进化,从战略顶层设计到组织重塑,从经营增长到AI部署,提供完整的企业进化能力与服务。', 'about'], 'about.existTitle': ['为什么存在', 'about'], 'about.existText': ['在AI时代,企业面临着前所未有的挑战与机遇。传统的企业管理方法已无法适应快速变化的环境,企业需要一套系统化的进化方法,实现从传统模式向AI时代模式的转型。\n阿美巴的存在,就是为了帮助企业完成这一进化过程,实现可持续增长与发展。', 'about'], 'about.audienceTitle': ['服务对象', 'about'], 'about.audienceText': ['我们服务的对象是那些希望在AI时代实现转型与增长的企业,无论企业当前处于哪个发展阶段,我们都能提供适合的进化路径与能力支持。', 'about'], 'about.historyTitle': ['发展历程', 'about'], 'about.historyText': ['待填充', 'about'], 'capabilities.overviewTitle': ['能力概述', 'capabilities'], 'capabilities.categoryTitle': ['能力分类', 'capabilities'], 'cases.overviewTitle': ['案例概述', 'cases'], 'cases.listTitle': ['案例列表', 'cases'], 'knowledge.systemTitle': ['知识体系', 'knowledge'], 'knowledge.categoryTitle': ['知识分类', 'knowledge'], 'knowledge.articleTitle': ['最新文章', 'knowledge'], 'faq.overviewTitle': ['FAQ概述', 'faq'], 'faq.listTitle': ['问题列表', 'faq'], }; Object.entries(extraDefaults).forEach(([key, [value, group]]) => { defaults[key] = [value, group]; }); Object.entries(defaults).forEach(([key, [value, group]]) => { const existing = db.prepare('SELECT setting_key FROM site_settings WHERE setting_key = ?').get(key); if (!existing) { db.prepare('INSERT INTO site_settings (setting_key, setting_value, setting_group) VALUES (?, ?, ?)').run(key, value, group); } }); // 修正早期版本中误写的 A/M-B 文案;保留管理员已编辑的其他内容。 db.prepare(` UPDATE site_settings SET setting_value = REPLACE(setting_value, 'A/M-B', 'A/M/B'), updated_at = CURRENT_TIMESTAMP WHERE setting_value LIKE '%A/M-B%' `).run(); }; if (require.main === module) { migrate(); } module.exports = { migrate, createTables, seedAdminAndSettings };