24cd9cef53
- uni-app Vue3 frontend with dark glassmorphism theme - 5 AI dimensions: Origin / Development / Current / Learning / Trend - AI Chat system prompt updated from geometry to AI - 23 AI knowledge articles initialized in DB - Trend API + cron job for daily news - Product pricing (Pro ¥19.9, VIP ¥39.9) - Pinia stores + API utilities - AGENTS.md documentation
242 lines
8.4 KiB
JavaScript
Executable File
242 lines
8.4 KiB
JavaScript
Executable File
/**
|
|
* 拼音探索模块初始化数据脚本
|
|
* 创建拼音内容、成就等基础数据
|
|
*/
|
|
|
|
require('dotenv').config({ path: './.env' });
|
|
const mongoose = require('mongoose');
|
|
const { PinyinContent, PinyinAchievement } = require('../src/models/pinyin');
|
|
const connectDB = require('../src/config/database');
|
|
|
|
// 声母数据
|
|
const initials = [
|
|
{ symbol: 'b', name: '玻', order: 1 },
|
|
{ symbol: 'p', name: '坡', order: 2 },
|
|
{ symbol: 'm', name: '摸', order: 3 },
|
|
{ symbol: 'f', name: '佛', order: 4 },
|
|
{ symbol: 'd', name: '得', order: 5 },
|
|
{ symbol: 't', name: '特', order: 6 },
|
|
{ symbol: 'n', name: '讷', order: 7 },
|
|
{ symbol: 'l', name: '勒', order: 8 },
|
|
{ symbol: 'g', name: '哥', order: 9 },
|
|
{ symbol: 'k', name: '科', order: 10 },
|
|
{ symbol: 'h', name: '喝', order: 11 },
|
|
{ symbol: 'j', name: '基', order: 12 },
|
|
{ symbol: 'q', name: '期', order: 13 },
|
|
{ symbol: 'x', name: '希', order: 14 },
|
|
{ symbol: 'zh', name: '知', order: 15 },
|
|
{ symbol: 'ch', name: '蚩', order: 16 },
|
|
{ symbol: 'sh', name: '诗', order: 17 },
|
|
{ symbol: 'r', name: '日', order: 18 },
|
|
{ symbol: 'z', name: '资', order: 19 },
|
|
{ symbol: 'c', name: '雌', order: 20 },
|
|
{ symbol: 's', name: '思', order: 21 },
|
|
{ symbol: 'y', name: '医', order: 22 },
|
|
{ symbol: 'w', name: '巫', order: 23 }
|
|
];
|
|
|
|
// 韵母数据
|
|
const finals = [
|
|
// 单韵母
|
|
{ symbol: 'a', name: '啊', order: 1 },
|
|
{ symbol: 'o', name: '喔', order: 2 },
|
|
{ symbol: 'e', name: '鹅', order: 3 },
|
|
{ symbol: 'i', name: '衣', order: 4 },
|
|
{ symbol: 'u', name: '乌', order: 5 },
|
|
{ symbol: 'ü', name: '迂', order: 6 },
|
|
// 复韵母
|
|
{ symbol: 'ai', name: '哀', order: 7 },
|
|
{ symbol: 'ei', name: '诶', order: 8 },
|
|
{ symbol: 'ui', name: '威', order: 9 },
|
|
{ symbol: 'ao', name: '熬', order: 10 },
|
|
{ symbol: 'ou', name: '欧', order: 11 },
|
|
{ symbol: 'iu', name: '优', order: 12 },
|
|
{ symbol: 'ie', name: '耶', order: 13 },
|
|
{ symbol: 'üe', name: '约', order: 14 },
|
|
{ symbol: 'er', name: '儿', order: 15 },
|
|
// 前鼻韵母
|
|
{ symbol: 'an', name: '安', order: 16 },
|
|
{ symbol: 'en', name: '恩', order: 17 },
|
|
{ symbol: 'in', name: '因', order: 18 },
|
|
{ symbol: 'un', name: '温', order: 19 },
|
|
{ symbol: 'ün', name: '晕', order: 20 },
|
|
// 后鼻韵母
|
|
{ symbol: 'ang', name: '昂', order: 21 },
|
|
{ symbol: 'eng', name: '亨', order: 22 },
|
|
{ symbol: 'ing', name: '英', order: 23 },
|
|
{ symbol: 'ong', name: '雍', order: 24 }
|
|
];
|
|
|
|
// 整体认读音节
|
|
const overalls = [
|
|
{ symbol: 'zhi', name: '织', order: 1 },
|
|
{ symbol: 'chi', name: '吃', order: 2 },
|
|
{ symbol: 'shi', name: '诗', order: 3 },
|
|
{ symbol: 'ri', name: '日', order: 4 },
|
|
{ symbol: 'zi', name: '资', order: 5 },
|
|
{ symbol: 'ci', name: '雌', order: 6 },
|
|
{ symbol: 'si', name: '思', order: 7 },
|
|
{ symbol: 'yi', name: '衣', order: 8 },
|
|
{ symbol: 'wu', name: '乌', order: 9 },
|
|
{ symbol: 'yu', name: '迂', order: 10 },
|
|
{ symbol: 'ye', name: '耶', order: 11 },
|
|
{ symbol: 'yue', name: '约', order: 12 },
|
|
{ symbol: 'yuan', name: '冤', order: 13 },
|
|
{ symbol: 'yin', name: '因', order: 14 },
|
|
{ symbol: 'yun', name: '晕', order: 15 },
|
|
{ symbol: 'ying', name: '英', order: 16 }
|
|
];
|
|
|
|
// 成就数据
|
|
const achievements = [
|
|
// 探索类成就
|
|
{ code: 'first_explore', name: '初次探索', description: '完成首次拼音探索', type: 'explore', condition: { type: 'explore_count', value: 1 } },
|
|
{ code: 'explorer_5', name: '初级探索者', description: '探索5个拼音', type: 'explore', condition: { type: 'explore_count', value: 5 } },
|
|
{ code: 'explorer_10', name: '中级探索者', description: '探索10个拼音', type: 'explore', condition: { type: 'explore_count', value: 10 } },
|
|
{ code: 'explorer_23', name: '声母专家', description: '探索所有声母', type: 'explore', condition: { type: 'explore_count', value: 23 } },
|
|
{ code: 'explorer_47', name: '拼音达人', description: '探索47个拼音', type: 'explore', condition: { type: 'explore_count', value: 47 } },
|
|
{ code: 'explorer_all', name: '拼音大师', description: '探索所有拼音', type: 'explore', condition: { type: 'explore_count', value: 63 } },
|
|
|
|
// 收集类成就
|
|
{ code: 'first_stone', name: '第一颗能量石', description: '收集第一颗能量石', type: 'collection', condition: { type: 'collect_count', value: 1 } },
|
|
{ code: 'collector_5', name: '能量收集者', description: '收集5颗能量石', type: 'collection', condition: { type: 'collect_count', value: 5 } },
|
|
{ code: 'collector_10', name: '能量守护者', description: '收集10颗能量石', type: 'collection', condition: { type: 'collect_count', value: 10 } },
|
|
{ code: 'collector_23', name: '声母守护者', description: '收集所有声母能量石', type: 'collection', condition: { type: 'collect_count', value: 23 } },
|
|
{ code: 'collector_all', name: '能量大师', description: '收集所有能量石', type: 'collection', condition: { type: 'collect_count', value: 63 } },
|
|
|
|
// 连续探索成就
|
|
{ code: 'streak_3', name: '坚持3天', description: '连续探索3天', type: 'streak', condition: { type: 'streak_days', value: 3 } },
|
|
{ code: 'streak_7', name: '坚持一周', description: '连续探索7天', type: 'streak', condition: { type: 'streak_days', value: 7 } },
|
|
{ code: 'streak_30', name: '坚持一个月', description: '连续探索30天', type: 'streak', condition: { type: 'streak_days', value: 30 } }
|
|
];
|
|
|
|
async function initPinyinContents() {
|
|
console.log('开始初始化拼音内容...');
|
|
|
|
// 初始化声母
|
|
for (const item of initials) {
|
|
await PinyinContent.findOneAndUpdate(
|
|
{ symbol: item.symbol },
|
|
{
|
|
symbol: item.symbol,
|
|
type: 'initial',
|
|
name: item.name,
|
|
order: item.order,
|
|
isFree: item.order <= 5, // 前5个免费
|
|
status: 'active',
|
|
pronunciation: `${item.name}的音`,
|
|
exploreAreas: {
|
|
audio: true,
|
|
mouth: true,
|
|
speak: true,
|
|
write: true,
|
|
game: true,
|
|
words: true
|
|
}
|
|
},
|
|
{ upsert: true, new: true }
|
|
);
|
|
}
|
|
console.log(`✅ 已初始化 ${initials.length} 个声母`);
|
|
|
|
// 初始化韵母
|
|
for (const item of finals) {
|
|
await PinyinContent.findOneAndUpdate(
|
|
{ symbol: item.symbol },
|
|
{
|
|
symbol: item.symbol,
|
|
type: 'final',
|
|
name: item.name,
|
|
order: item.order,
|
|
isFree: false, // 韵母需要解锁
|
|
status: 'active',
|
|
pronunciation: `${item.name}的音`,
|
|
exploreAreas: {
|
|
audio: true,
|
|
mouth: true,
|
|
speak: true,
|
|
write: true,
|
|
game: true,
|
|
words: true
|
|
}
|
|
},
|
|
{ upsert: true, new: true }
|
|
);
|
|
}
|
|
console.log(`✅ 已初始化 ${finals.length} 个韵母`);
|
|
|
|
// 初始化整体认读音节
|
|
for (const item of overalls) {
|
|
await PinyinContent.findOneAndUpdate(
|
|
{ symbol: item.symbol },
|
|
{
|
|
symbol: item.symbol,
|
|
type: 'overall',
|
|
name: item.name,
|
|
order: item.order,
|
|
isFree: false, // 整体认读需要解锁
|
|
status: 'active',
|
|
pronunciation: `${item.name}的音`,
|
|
exploreAreas: {
|
|
audio: true,
|
|
mouth: true,
|
|
speak: true,
|
|
write: true,
|
|
game: true,
|
|
words: true
|
|
}
|
|
},
|
|
{ upsert: true, new: true }
|
|
);
|
|
}
|
|
console.log(`✅ 已初始化 ${overalls.length} 个整体认读音节`);
|
|
}
|
|
|
|
async function initAchievements() {
|
|
console.log('开始初始化成就...');
|
|
|
|
for (let i = 0; i < achievements.length; i++) {
|
|
const item = achievements[i];
|
|
await PinyinAchievement.findOneAndUpdate(
|
|
{ code: item.code },
|
|
{
|
|
code: item.code,
|
|
name: item.name,
|
|
description: item.description,
|
|
type: item.type,
|
|
condition: item.condition,
|
|
order: i + 1,
|
|
isActive: true,
|
|
reward: {
|
|
type: 'stone',
|
|
value: 1
|
|
}
|
|
},
|
|
{ upsert: true, new: true }
|
|
);
|
|
}
|
|
console.log(`✅ 已初始化 ${achievements.length} 个成就`);
|
|
}
|
|
|
|
async function main() {
|
|
try {
|
|
// 连接数据库
|
|
await connectDB();
|
|
console.log('数据库连接成功');
|
|
|
|
// 初始化拼音内容
|
|
await initPinyinContents();
|
|
|
|
// 初始化成就
|
|
await initAchievements();
|
|
|
|
console.log('\n✨ 数据初始化完成!');
|
|
process.exit(0);
|
|
} catch (error) {
|
|
console.error('初始化失败:', error);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
main();
|