migrate((db) => { const dao = new Dao(db) // 获取集合引用 const categoriesCollection = dao.findCollectionByNameOrId('categories') const tagsCollection = dao.findCollectionByNameOrId('tags') const postsCollection = dao.findCollectionByNameOrId('posts') const pagesCollection = dao.findCollectionByNameOrId('pages') const settingsCollection = dao.findCollectionByNameOrId('site_settings') const menusCollection = dao.findCollectionByNameOrId('menus') // 创建默认管理员用户 const adminCollection = dao.findCollectionByNameOrId('_pb_users_auth_') const adminRecord = new Record(adminCollection, { email: 'admin@yunsheng.digital', password: 'YunSheng@2024!Admin', passwordConfirm: 'YunSheng@2024!Admin', name: '云升数码', role: 'admin', verified: true, }) dao.saveRecord(adminRecord) // 创建默认分类 const categories = [ { name: '数码评测', slug: 'reviews', description: '专业数码产品深度评测', icon: '📱', color: '#0ea5e9', sort_order: 1, is_active: true }, { name: '技术教程', slug: 'tutorials', description: '实用技术教程与操作指南', icon: '🛠️', color: '#10b981', sort_order: 2, is_active: true }, { name: '行业资讯', slug: 'news', description: '数码科技行业最新动态', icon: '📰', color: '#f59e0b', sort_order: 3, is_active: true }, { name: '玩机技巧', slug: 'tips', description: '手机、电脑、配件使用技巧', icon: '💡', color: '#8b5cf6', sort_order: 4, is_active: true }, { name: '开箱体验', slug: 'unboxing', description: '新品开箱与第一印象', icon: '📦', color: '#ec4899', sort_order: 5, is_active: true }, { name: '对比横评', slug: 'comparison', description: '多款产品横向对比评测', icon: '⚖️', color: '#ef4444', sort_order: 6, is_active: true }, ] const categoryRecords = {} for (const cat of categories) { const record = new Record(categoriesCollection, cat) dao.saveRecord(record) categoryRecords[cat.slug] = record.id } // 创建默认标签 const tags = [ { name: '手机', slug: 'phone', color: '#0ea5e9', sort_order: 1, is_active: true }, { name: '笔记本', slug: 'laptop', color: '#10b981', sort_order: 2, is_active: true }, { name: '耳机', slug: 'headphones', color: '#f59e0b', sort_order: 3, is_active: true }, { name: '显示器', slug: 'monitor', color: '#8b5cf6', sort_order: 4, is_active: true }, { name: '键盘', slug: 'keyboard', color: '#ec4899', sort_order: 5, is_active: true }, { name: '鼠标', slug: 'mouse', color: '#ef4444', sort_order: 6, is_active: true }, { name: '配件', slug: 'accessories', color: '#6366f1', sort_order: 7, is_active: true }, { name: '智能家居', slug: 'smart-home', color: '#14b8a6', sort_order: 8, is_active: true }, { name: '摄影', slug: 'photography', color: '#f97316', sort_order: 9, is_active: true }, { name: '音频', slug: 'audio', color: '#a855f7', sort_order: 10, is_active: true }, { name: '评测', slug: 'review', color: '#06b6d4', sort_order: 11, is_active: true }, { name: '教程', slug: 'tutorial', color: '#84cc16', sort_order: 12, is_active: true }, { name: '推荐', slug: 'recommend', color: '#eab308', sort_order: 13, is_active: true }, { name: '避坑', slug: 'avoid', color: '#dc2626', sort_order: 14, is_active: true }, { name: '性价比', slug: 'value', color: '#16a34a', sort_order: 15, is_active: true }, ] const tagRecords = {} for (const tag of tags) { const record = new Record(tagsCollection, tag) dao.saveRecord(record) tagRecords[tag.slug] = record.id } // 创建站点设置 const settingsRecord = new Record(settingsCollection, { site_name: '云升数码', site_subtitle: '专业数码评测与技术分享', site_description: '云升数码致力于为用户提供专业、客观、深度的数码产品评测、技术教程和行业资讯。我们不做标题党,只做真实评测。', site_keywords: '数码评测,手机评测,笔记本评测,耳机评测,数码教程,科技资讯,开箱体验,数码推荐', site_url: 'https://yunsheng.digital', footer_text: '云升数码 - 专业数码评测与技术分享平台', footer_copyright: '© 2024 云升数码. All rights reserved.', icp_number: '京ICP备2024000000号', social_links: JSON.stringify({ github: 'https://github.com/yunsheng-digital', twitter: 'https://twitter.com/yunsheng_digital', bilibili: 'https://space.bilibili.com/yunsheng', weibo: 'https://weibo.com/yunsheng', zhihu: 'https://zhihu.com/people/yunsheng', email: 'contact@yunsheng.digital', rss: '/rss.xml', }), background_music_enabled: true, background_music_type: 'local', background_music_title: '云端漫步', background_music_artist: '云升数码', background_music_volume: 0.4, background_music_autoplay: false, background_music_loop: true, comment_enabled: false, comment_system: 'giscus', rss_enabled: true, search_enabled: true, cache_ttl: 3600, image_optimization: true, maintenance_mode: false, }) dao.saveRecord(settingsRecord) // 创建默认菜单 const headerMenuItems = [ { label: '首页', url: '/', order: 1 }, { label: '评测', url: '/category/reviews', order: 2 }, { label: '教程', url: '/category/tutorials', order: 3 }, { label: '资讯', url: '/category/news', order: 4 }, { label: '音乐', url: '/music', order: 5 }, { label: '关于', url: '/page/about', order: 6 }, ] const footerMenuItems = [ { label: '关于我们', url: '/page/about', order: 1 }, { label: '联系我们', url: '/page/contact', order: 2 }, { label: '隐私政策', url: '/page/privacy', order: 3 }, { label: '服务条款', url: '/page/terms', order: 4 }, { label: '搭建教程', url: '/page/deploy-guide', order: 5 }, { label: 'RSS 订阅', url: '/rss.xml', order: 6 }, ] const headerMenu = new Record(menusCollection, { name: '主导航', location: 'header', items: JSON.stringify(headerMenuItems), is_active: true, }) dao.saveRecord(headerMenu) const footerMenu = new Record(menusCollection, { name: '页脚导航', location: 'footer', items: JSON.stringify(footerMenuItems), is_active: true, }) dao.saveRecord(footerMenu) // 创建示例页面 const pages = [ { title: '关于我们', slug: 'about', content: JSON.stringify({ type: 'doc', content: [ { type: 'heading', attrs: { level: 1 }, content: [{ type: 'text', text: '关于云升数码' }] }, { type: 'paragraph', content: [{ type: 'text', text: '云升数码成立于 2024 年,是一个专注于数码产品深度评测、技术教程分享和行业资讯报道的专业平台。' }] }, { type: 'heading', attrs: { level: 2 }, content: [{ type: 'text', text: '我们的使命' }] }, { type: 'paragraph', content: [{ type: 'text', text: '为消费者提供最真实、最专业、最有价值的数码产品购买参考,帮助每一位数码爱好者做出明智的选择。' }] }, { type: 'heading', attrs: { level: 2 }, content: [{ type: 'text', text: '核心价值观' }] }, { type: 'bulletList', content: [ { type: 'listItem', content: [{ type: 'paragraph', content: [{ type: 'text', text: '客观公正:拒绝商业软文,坚持真实评测' }] }] }, { type: 'listItem', content: [{ type: 'paragraph', content: [{ type: 'text', text: '专业深度:深挖技术细节,不止于参数堆砌' }] }] }, { type: 'listItem', content: [{ type: 'paragraph', content: [{ type: 'text', text: '用户至上:站在消费者角度,解决真实痛点' }] }] }, { type: 'listItem', content: [{ type: 'paragraph', content: [{ type: 'text', text: '持续创新:紧跟技术潮流,探索评测新形式' }] }] }, ]}, { type: 'heading', attrs: { level: 2 }, content: [{ type: 'text', text: '联系我们' }] }, { type: 'paragraph', content: [{ type: 'text', text: '商务合作:business@yunsheng.digital' }] }, { type: 'paragraph', content: [{ type: 'text', text: '投稿建议:tips@yunsheng.digital' }] }, { type: 'paragraph', content: [{ type: 'text', text: '技术支持:tech@yunsheng.digital' }] }, ], }), template: 'default', published: true, sort_order: 1, show_in_nav: true, nav_label: '关于', }, { title: '联系我们', slug: 'contact', content: JSON.stringify({ type: 'doc', content: [ { type: 'heading', attrs: { level: 1 }, content: [{ type: 'text', text: '联系我们' }] }, { type: 'paragraph', content: [{ type: 'text', text: '欢迎通过以下方式与我们取得联系:' }] }, { type: 'heading', attrs: { level: 2 }, content: [{ type: 'text', text: '商务合作' }] }, { type: 'paragraph', content: [{ type: 'text', text: '邮箱:business@yunsheng.digital' }] }, { type: 'heading', attrs: { level: 2 }, content: [{ type: 'text', text: '投稿建议' }] }, { type: 'paragraph', content: [{ type: 'text', text: '邮箱:tips@yunsheng.digital' }] }, { type: 'heading', attrs: { level: 2 }, content: [{ type: 'text', text: '技术支持' }] }, { type: 'paragraph', content: [{ type: 'text', text: '邮箱:tech@yunsheng.digital' }] }, { type: 'heading', attrs: { level: 2 }, content: [{ type: 'text', text: '社交媒体' }] }, { type: 'bulletList', content: [ { type: 'listItem', content: [{ type: 'paragraph', content: [{ type: 'text', text: 'GitHub: github.com/yunsheng-digital' }] }] }, { type: 'listItem', content: [{ type: 'paragraph', content: [{ type: 'text', text: 'Twitter: @yunsheng_digital' }] }] }, { type: 'listItem', content: [{ type: 'paragraph', content: [{ type: 'text', text: 'Bilibili: 云升数码' }] }] }, ]}, ], }), template: 'default', published: true, sort_order: 2, show_in_nav: false, }, { title: '隐私政策', slug: 'privacy', content: JSON.stringify({ type: 'doc', content: [ { type: 'heading', attrs: { level: 1 }, content: [{ type: 'text', text: '隐私政策' }] }, { type: 'paragraph', content: [{ type: 'text', text: '云升数码(以下简称"我们")非常重视您的隐私保护。本隐私政策说明了我们如何收集、使用、存储和保护您的个人信息。' }] }, { type: 'heading', attrs: { level: 2 }, content: [{ type: 'text', text: '1. 信息收集' }] }, { type: 'paragraph', content: [{ type: 'text', text: '我们可能收集以下信息:访问日志(IP、浏览器、访问时间)、Cookie 数据、您主动提交的评论/联系表单信息。' }] }], { type: 'heading', attrs: { level: 2 }, content: [{ type: 'text', text: '2. 信息使用' }] }, { type: 'paragraph', content: [{ type: 'text', text: '收集的信息仅用于:网站统计分析、改善用户体验、回复您的咨询、发送必要通知。' }] }], { type: 'heading', attrs: { level: 2 }, content: [{ type: 'text', text: '3. 信息共享' }] }, { type: 'paragraph', content: [{ type: 'text', text: '未经您同意,我们不会向第三方披露您的个人信息,法律法规要求或保护公共利益除外。' }] }], { type: 'heading', attrs: { level: 2 }, content: [{ type: 'text', text: '4. 您的权利' }] }, { type: 'paragraph', content: [{ type: 'text', text: '您有权访问、更正、删除您的个人信息,可通过联系我们行使相关权利。' }] }], ], }), template: 'default', published: true, sort_order: 3, show_in_nav: false, }, { title: '服务条款', slug: 'terms', content: JSON.stringify({ type: 'doc', content: [ { type: 'heading', attrs: { level: 1 }, content: [{ type: 'text', text: '服务条款' }] }, { type: 'paragraph', content: [{ type: 'text', text: '欢迎使用云升数码网站服务。请仔细阅读以下条款。' }] }, { type: 'heading', attrs: { level: 2 }, content: [{ type: 'text', text: '1. 服务内容' }] }, { type: 'paragraph', content: [{ type: 'text', text: '我们提供数码评测文章、技术教程、行业资讯等内容服务。' }] }], { type: 'heading', attrs: { level: 2 }, content: [{ type: 'text', text: '2. 用户行为' }] }, { type: 'paragraph', content: [{ type: 'text', text: '禁止发布违法、侵权、垃圾、广告等有害内容。违者将删除内容并封禁账号。' }] }], { type: 'heading', attrs: { level: 2 }, content: [{ type: 'text', text: '3. 知识产权' }] }, { type: 'paragraph', content: [{ type: 'text', text: '本站原创内容版权归云升数码所有,转载请注明出处并获取授权。' }] }], { type: 'heading', attrs: { level: 2 }, content: [{ type: 'text', text: '4. 免责声明' }] }, { type: 'paragraph', content: [{ type: 'text', text: '评测内容仅供参考,购买决策请以官方信息为准。因信息滞后或错误造成的损失,本站不承担责任。' }] }], ], }), template: 'default', published: true, sort_order: 4, show_in_nav: false, }, { title: '搭建教程', slug: 'deploy-guide', content: JSON.stringify({ type: 'doc', content: [ { type: 'heading', attrs: { level: 1 }, content: [{ type: 'text', text: '云升数码站点搭建教程' }] }, { type: 'paragraph', content: [{ type: 'text', text: '本教程将指导您如何在自己的服务器上部署云升数码展示页面。' }] }, { type: 'heading', attrs: { level: 2 }, content: [{ type: 'text', text: '📋 准备工作' }] }, { type: 'bulletList', content: [ { type: 'listItem', content: [{ type: 'paragraph', content: [{ type: 'text', text: '一台 Linux 服务器(推荐 Ubuntu 22.04+ / Debian 12+)' }] }] }, { type: 'listItem', content: [{ type: 'paragraph', content: [{ type: 'text', text: '域名一个,已解析到服务器 IP' }] }] }, { type: 'listItem', content: [{ type: 'paragraph', content: [{ type: 'text', text: 'SSH 客户端(Windows 推荐 Terminal / Tabby,Mac/Linux 自带 Terminal)' }] }] }, { type: 'listItem', content: [{ type: 'paragraph', content: [{ type: 'text', text: '基本 Linux 命令行操作知识' }] }] }, ]}, { type: 'heading', attrs: { level: 2 }, content: [{ type: 'text', text: '🚀 一键部署(推荐)' }] }, { type: 'paragraph', content: [{ type: 'text', text: '我们提供了一键部署脚本,适合大多数场景:' }] }], { type: 'codeBlock', attrs: { language: 'bash' }, content: [ { type: 'text', text: '# 1. 克隆仓库\ngit clone https://git.grxiao.cn/yuns/plerr-open.git\ncd plerr-open\n\n# 2. 运行一键安装脚本\nchmod +x scripts/install.sh\nsudo ./scripts/install.sh\n\n# 3. 按提示配置域名、SSL 等\n# 4. 访问 https://your-domain.com 完成初始化' } ]}, { type: 'heading', attrs: { level: 2 }, content: [{ type: 'text', text: '🐳 Docker 部署' }] }, { type: 'paragraph', content: [{ type: 'text', text: '如果您偏好容器化部署:' }] }], { type: 'codeBlock', attrs: { language: 'bash' }, content: [ { type: 'text', text: '# 1. 进入 docker 目录\ncd docker\n\n# 2. 复制环境变量模板\ncp .env.example .env\n# 编辑 .env 配置域名、密钥等\n\n# 3. 启动服务\ndocker-compose up -d\n\n# 4. 查看日志\ndocker-compose logs -f' } ]}, { type: 'heading', attrs: { level: 2 }, content: [{ type: 'text', text: '⚙️ 手动部署步骤' }] }, { type: 'heading', attrs: { level: 3 }, content: [{ type: 'text', text: '1. 安装依赖' }] }, { type: 'codeBlock', attrs: { language: 'bash' }, content: [ { type: 'text', text: '# 更新系统\nsudo apt update && sudo apt upgrade -y\n\n# 安装 Node.js 20 (用于前端构建)\ncurl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -\nsudo apt install -y nodejs\n\n# 安装 pnpm\nnpm install -g pnpm\n\n# 安装 PocketBase (后端)\ncd /opt\nwget https://github.com/pocketbase/pocketbase/releases/download/v0.22.0/pocketbase_0.22.0_linux_amd64.zip\nunzip pocketbase_0.22.0_linux_amd64.zip\nchmod +x pocketbase\n\n# 安装 Nginx\nsudo apt install -y nginx\n\n# 安装 Certbot (SSL)\nsudo apt install -y certbot python3-certbot-nginx' } ]}, { type: 'heading', attrs: { level: 3 }, content: [{ type: 'text', text: '2. 配置 PocketBase' }] }, { type: 'codeBlock', attrs: { language: 'bash' }, content: [ { type: 'text', text: '# 创建数据目录\nmkdir -p /opt/pocketbase/pb_data\nmkdir -p /opt/pocketbase/pb_migrations\nmkdir -p /opt/pocketbase/pb_public\n\n# 复制迁移文件\ncp -r /path/to/project/apps/pb_migrations/* /opt/pocketbase/pb_migrations/\n\n# 创建 systemd 服务\nsudo tee /etc/systemd/system/pocketbase.service > /dev/null < IPS' }] }] }, { type: 'listItem', content: [{ type: 'paragraph', content: [{ type: 'text', text: '内存 16GB 起步,32GB 安心,焊死内存尽量买大内存版' }] }] }, { type: 'listItem', content: [{ type: 'paragraph', content: [{ type: 'text', text: 'SSD 1TB 起,PCIe 4.0,预留 M.2 位更佳' }] }] }, { type: 'listItem', content: [{ type: 'paragraph', content: [{ type: 'text', text: '接口要全:USB-C (支持 PD 充电/DP)、USB-A、HDMI、SD 卡槽' }] }] }, { type: 'listItem', content: [{ type: 'paragraph', content: [{ type: 'text', text: '查散热评测:同配置不同散热,性能释放相差 20%+' }] }] }, ]}, { type: 'heading', attrs: { level: 2 }, content: [{ type: 'text', text: '📅 购买时机建议' }] }, { type: 'paragraph', content: [{ type: 'text', text: '预售期(10.20-11.10)定金膨胀力度大,但需锁定款式;正式期(11.11 当天)部分款式补贴到手价更低,但热门款易断货。建议:确定目标款 → 预售期付定金 → 尾款期观望补贴 → 最后一小时决策。' }] }], ] }), cover: '', category: 'tutorials', tags: ['laptop', 'tutorial', 'recommend', 'value', 'avoid'], author: '', published: true, published_at: new Date(Date.now() - 86400000).toISOString(), featured: true, reading_time: 15, seo_title: '2024 双十一笔记本选购指南:避坑与真香推荐全清单 | 云升数码', seo_description: '2024 双十一笔记本怎么选?3000-12000 元全价位段真香/避坑清单,从参数到实测教你不花冤枉钱。', seo_keywords: '双十一,笔记本,选购指南,推荐,避坑,性价比', }, { title: 'Sony WH-1000XM5 使用半年长测:降噪之王的统治力还在吗?', slug: 'sony-wh-1000xm5-long-term-review', excerpt: JSON.stringify({ type: 'doc', content: [ { type: 'paragraph', content: [{ type: 'text', text: '作为降噪耳机领域的「长青树」,WH-1000XM5 发布已超两年。半年实战体验,聊聊它在 2024 年还能不能打,以及有哪些被忽略的缺点。' }] } ] }), content: JSON.stringify({ type: 'doc', content: [ { type: 'heading', attrs: { level: 2 }, content: [{ type: 'text', text: '前言:为什么现在还要测 XM5?' }] }, { type: 'paragraph', content: [{ type: 'text', text: '市场上 Bose QC Ultra、Apple AirPods Max、技巧 Ace 5 等强敌环伺,XM5 似乎成了「上一代旗舰」。但销量数据显示,它依然是千元以上降噪耳机的销量冠军。' }] }], { type: 'heading', attrs: { level: 2 }, content: [{ type: 'text', text: '降噪表现:依然是标杆' }] }, { type: 'paragraph', content: [{ type: 'text', text: '地铁、飞机、办公室、咖啡厅全场景测试,低频消噪深度行业顶尖,人声残留极少。自适应声控(根据气压/环境自动调节)在起飞降落时体感明显。' }] }], { type: 'heading', attrs: { level: 2 }, content: [{ type: 'text', text: '音质:V 型调音,LDAC 加持' }] }, { type: 'paragraph', content: [{ type: 'text', text: '低频下潜深、量感足但不拖泥带水;高频延伸好,LDAC 传输下解析力在蓝牙耳机中第一梯队。EQ 调节范围大,可调出监听风。' }] }], { type: 'heading', attrs: { level: 2 }, content: [{ type: 'text', text: '佩戴舒适度:褒贬不一' }] }, { type: 'paragraph', content: [{ type: 'text', text: '头梁无海绵垫、耳罩包裹感一般,大头/戴眼镜用户 2 小时后会有压迫感。夏天闷耳严重。建议换装第三方记忆棉耳罩(如 Dekoni)。' }] }], { type: 'heading', attrs: { level: 2 }, content: [{ type: 'text', text: '续航与充电:无焦虑' }] }, { type: 'paragraph', content: [{ type: 'text', text: '开启降噪 30 小时、关闭 40 小时,实测符合官方数据。3 分钟充电 3 小时听歌,Type-C 接口通用性强。' }] }], { type: 'heading', attrs: { level: 2 }, content: [{ type: 'text', text: '槽点:不折叠、无 aptX、连接切换慢' }] }, { type: 'bulletList', content: [ { type: 'listItem', content: [{ type: 'paragraph', content: [{ type: 'text', text: '收纳体积大,随身包塞不下' }] }] }, { type: 'listItem', content: [{ type: 'paragraph', content: [{ type: 'text', text: '仅支持 SBC/AAC/LDAC,安卓用户无 aptX Adaptive' }] }] }, { type: 'listItem', content: [{ type: 'paragraph', content: [{ type: 'text', text: '多点连接切换延迟 3-5 秒,不如 Apple 生态丝滑' }] }] }, { type: 'listItem', content: [{ type: 'paragraph', content: [{ type: 'text', text: '触控区误触率高,冬天戴手套不可用' }] }] }, ]}, { type: 'heading', attrs: { level: 2 }, content: [{ type: 'text', text: '结论:买不买?' }] }, { type: 'paragraph', content: [{ type: 'text', text: '追求极致降噪、音质均衡、预算 2000 元左右 → 闭眼入。\n需折叠收纳、aptX、极致舒适、Apple 生态 → 看别家。' }] }], ] }), cover: '', category: 'reviews', tags: ['headphones', 'audio', 'review', 'long-term'], author: '', published: true, published_at: new Date(Date.now() - 172800000).toISOString(), featured: false, reading_time: 10, seo_title: 'Sony WH-1000XM5 半年长测:降噪之王统治力还在吗? | 云升数码', seo_description: 'WH-1000XM5 使用半年实测:降噪/音质/舒适度/续航全维度复盘,揭露不折叠/无aptX/切换慢等真实槽点。', seo_keywords: 'WH-1000XM5,索尼,降噪耳机,长测,评测,音质', }, ] for (const post of samplePosts) { post.author = adminRecord.id post.category = categoryRecords[post.category] post.tags = post.tags.map(t => tagRecords[t]) const record = new Record(postsCollection, post) dao.saveRecord(record) } })