diff --git a/backend/wdkj-server/src/routes/knowledge.js b/backend/wdkj-server/src/routes/knowledge.js
index 3173f27..f5e70c5 100755
--- a/backend/wdkj-server/src/routes/knowledge.js
+++ b/backend/wdkj-server/src/routes/knowledge.js
@@ -5,6 +5,45 @@ const ApiResponse = require('../utils/response')
const { userAuthMiddleware } = require('../middleware/auth')
const logger = require('../utils/logger')
+/**
+ * 搜索知识
+ * GET /api/knowledge/search?q=xxx&page=1&limit=20
+ */
+router.get('/search', async (req, res) => {
+ try {
+ const { q, page = 1, limit = 20 } = req.query
+ if (!q || q.trim().length === 0) {
+ return ApiResponse.error(res, '请输入搜索关键词', 400)
+ }
+
+ const query = {
+ status: 'approved',
+ $or: [
+ { title: { $regex: q, $options: 'i' } },
+ { content: { $regex: q, $options: 'i' } },
+ { tags: { $regex: q, $options: 'i' } }
+ ]
+ }
+
+ const total = await Knowledge.countDocuments(query)
+ const result = await Knowledge.find(query)
+ .sort({ viewCount: -1, createdAt: -1 })
+ .skip((parseInt(page) - 1) * parseInt(limit))
+ .limit(parseInt(limit))
+ .lean()
+
+ return ApiResponse.paginated(res, result, {
+ page: parseInt(page),
+ limit: parseInt(limit),
+ total
+ })
+
+ } catch (error) {
+ logger.error('搜索知识失败:', error)
+ return ApiResponse.serverError(res, error.message)
+ }
+})
+
/**
* 获取知识列表
* GET /api/knowledge
diff --git a/backend/wdkj-server/src/routes/user.js b/backend/wdkj-server/src/routes/user.js
index 55081a2..249de6d 100755
--- a/backend/wdkj-server/src/routes/user.js
+++ b/backend/wdkj-server/src/routes/user.js
@@ -202,133 +202,133 @@ router.get('/achievements', async (req, res) => {
try {
const user = req.user
- // 生成成就数据
- const achievements = [
- {
- name: '探索成就',
- achievements: [
+ // 生成成就数据(AI 维度主题)
+ const achievements = [
{
- id: 'dim1_complete',
- name: '一维探索者',
- description: '完成一维空间的探索',
- icon: '⭐',
- unlocked: user.exploreData.dim1?.completed || false,
- date: user.exploreData.dim1?.completed ? user.updatedAt.toISOString().split('T')[0] : null
+ name: '知识探索',
+ achievements: [
+ {
+ id: 'dim1_read',
+ name: 'AI起源探索者',
+ description: '完成 AI 起源维度的知识阅读',
+ icon: '📜',
+ unlocked: user.exploreData.dim1?.completed || false,
+ date: user.exploreData.dim1?.completed ? user.updatedAt.toISOString().split('T')[0] : null
+ },
+ {
+ id: 'dim2_read',
+ name: 'AI发展探索者',
+ description: '完成 AI 发展维度的知识阅读',
+ icon: '🏛',
+ unlocked: user.exploreData.dim2?.completed || false,
+ date: user.exploreData.dim2?.completed ? user.updatedAt.toISOString().split('T')[0] : null
+ },
+ {
+ id: 'dim3_read',
+ name: 'AI当前探索者',
+ description: '完成 AI 当前格局维度的知识阅读',
+ icon: '♟',
+ unlocked: user.exploreData.dim3?.completed || false,
+ date: user.exploreData.dim3?.completed ? user.updatedAt.toISOString().split('T')[0] : null
+ },
+ {
+ id: 'dim4_read',
+ name: 'AI学习探索者',
+ description: '完成 AI 学习与工具维度的知识阅读',
+ icon: '🧠',
+ unlocked: user.exploreData.dim4?.completed || false,
+ date: user.exploreData.dim4?.completed ? user.updatedAt.toISOString().split('T')[0] : null
+ },
+ {
+ id: 'dim5_read',
+ name: 'AI趋势探索者',
+ description: '完成 AI 趋势追踪维度的知识阅读',
+ icon: '⚡',
+ unlocked: user.exploreData.dim5?.completed || false,
+ date: user.exploreData.dim5?.completed ? user.updatedAt.toISOString().split('T')[0] : null
+ }
+ ]
},
{
- id: 'dim2_complete',
- name: '二维探索者',
- description: '完成二维空间的探索',
- icon: '✨',
- unlocked: user.exploreData.dim2?.completed || false,
- date: user.exploreData.dim2?.completed ? user.updatedAt.toISOString().split('T')[0] : null
+ name: '收藏成就',
+ achievements: [
+ {
+ id: 'first_collection',
+ name: '初次收藏',
+ description: '收藏你的第一个 AI 知识',
+ icon: '❤️',
+ unlocked: user.collectedKnowledge?.length > 0,
+ date: user.collectedKnowledge?.length > 0 ? user.updatedAt.toISOString().split('T')[0] : null
+ },
+ {
+ id: 'five_collections',
+ name: '收藏爱好者',
+ description: '收藏5个 AI 知识',
+ icon: '🧡',
+ unlocked: user.collectedKnowledge?.length >= 5,
+ date: user.collectedKnowledge?.length >= 5 ? user.updatedAt.toISOString().split('T')[0] : null
+ },
+ {
+ id: 'ten_collections',
+ name: '收藏大师',
+ description: '收藏10个 AI 知识',
+ icon: '💛',
+ unlocked: user.collectedKnowledge?.length >= 10,
+ date: user.collectedKnowledge?.length >= 10 ? user.updatedAt.toISOString().split('T')[0] : null
+ }
+ ]
},
{
- id: 'dim3_complete',
- name: '三维探索者',
- description: '完成三维空间的探索',
- icon: '🌟',
- unlocked: user.exploreData.dim3?.completed || false,
- date: user.exploreData.dim3?.completed ? user.updatedAt.toISOString().split('T')[0] : null
+ name: 'AI 问答',
+ achievements: [
+ {
+ id: 'first_ask',
+ name: '初次提问',
+ description: '向 AI 助手提出第一个问题',
+ icon: '🤖',
+ unlocked: user.achievements?.includes('first_ask') || false,
+ date: user.achievements?.includes('first_ask') ? user.updatedAt.toISOString().split('T')[0] : null
+ },
+ {
+ id: 'ten_asks',
+ name: '勤学好问',
+ description: '向 AI 助手提出 10 个问题',
+ icon: '💡',
+ unlocked: user.achievements?.includes('ten_asks') || false,
+ date: user.achievements?.includes('ten_asks') ? user.updatedAt.toISOString().split('T')[0] : null
+ },
+ {
+ id: 'fifty_asks',
+ name: 'AI 达人',
+ description: '向 AI 助手提出 50 个问题',
+ icon: '🧠',
+ unlocked: user.achievements?.includes('fifty_asks') || false,
+ date: user.achievements?.includes('fifty_asks') ? user.updatedAt.toISOString().split('T')[0] : null
+ }
+ ]
},
{
- id: 'dim4_complete',
- name: '四维探索者',
- description: '完成四维空间的探索',
- icon: '💫',
- unlocked: user.exploreData.dim4?.completed || false,
- date: user.exploreData.dim4?.completed ? user.updatedAt.toISOString().split('T')[0] : null
- },
- {
- id: 'dim5_complete',
- name: '五维探索者',
- description: '完成五维空间的探索',
- icon: '🌌',
- unlocked: user.exploreData.dim5?.completed || false,
- date: user.exploreData.dim5?.completed ? user.updatedAt.toISOString().split('T')[0] : null
+ name: '社交成就',
+ achievements: [
+ {
+ id: 'first_share',
+ name: '初次分享',
+ description: '分享你的第一个知识给朋友',
+ icon: '📤',
+ unlocked: user.achievements?.includes('first_share') || false,
+ date: user.achievements?.includes('first_share') ? user.updatedAt.toISOString().split('T')[0] : null
+ },
+ {
+ id: 'five_shares',
+ name: '分享达人',
+ description: '分享 5 次知识给朋友',
+ icon: '📣',
+ unlocked: user.achievements?.includes('five_shares') || false,
+ date: user.achievements?.includes('five_shares') ? user.updatedAt.toISOString().split('T')[0] : null
+ }
+ ]
}
]
- },
- {
- name: '创作成就',
- achievements: [
- {
- id: 'first_work',
- name: '初次创作',
- description: '创作你的第一个作品',
- icon: '🎨',
- unlocked: user.achievements?.includes('first_work') || false,
- date: user.achievements?.includes('first_work') ? user.updatedAt.toISOString().split('T')[0] : null
- },
- {
- id: 'five_works',
- name: '创作达人',
- description: '创作5个作品',
- icon: '🏆',
- unlocked: user.achievements?.includes('five_works') || false,
- date: user.achievements?.includes('five_works') ? user.updatedAt.toISOString().split('T')[0] : null
- },
- {
- id: 'ten_works',
- name: '创作大师',
- description: '创作10个作品',
- icon: '👑',
- unlocked: user.achievements?.includes('ten_works') || false,
- date: user.achievements?.includes('ten_works') ? user.updatedAt.toISOString().split('T')[0] : null
- }
- ]
- },
- {
- name: '收藏成就',
- achievements: [
- {
- id: 'first_collection',
- name: '初次收藏',
- description: '收藏你的第一个知识',
- icon: '❤️',
- unlocked: user.collectedKnowledge?.length > 0,
- date: user.collectedKnowledge?.length > 0 ? user.updatedAt.toISOString().split('T')[0] : null
- },
- {
- id: 'five_collections',
- name: '收藏爱好者',
- description: '收藏5个知识',
- icon: '🧡',
- unlocked: user.collectedKnowledge?.length >= 5,
- date: user.collectedKnowledge?.length >= 5 ? user.updatedAt.toISOString().split('T')[0] : null
- },
- {
- id: 'ten_collections',
- name: '收藏大师',
- description: '收藏10个知识',
- icon: '💛',
- unlocked: user.collectedKnowledge?.length >= 10,
- date: user.collectedKnowledge?.length >= 10 ? user.updatedAt.toISOString().split('T')[0] : null
- }
- ]
- },
- {
- name: '社交成就',
- achievements: [
- {
- id: 'first_share',
- name: '初次分享',
- description: '分享你的第一个作品',
- icon: '📤',
- unlocked: user.achievements?.includes('first_share') || false,
- date: user.achievements?.includes('first_share') ? user.updatedAt.toISOString().split('T')[0] : null
- },
- {
- id: 'five_shares',
- name: '分享达人',
- description: '分享5个作品',
- icon: '📣',
- unlocked: user.achievements?.includes('five_shares') || false,
- date: user.achievements?.includes('five_shares') ? user.updatedAt.toISOString().split('T')[0] : null
- }
- ]
- }
- ]
return ApiResponse.success(res, achievements)
@@ -338,87 +338,87 @@ router.get('/achievements', async (req, res) => {
}
})
-/**
- * 获取用户统计数据
- * GET /api/user/stats
- */
-router.get('/stats', async (req, res) => {
- try {
- const user = req.user
- const { Gallery } = require('../models')
-
- // 获取用户作品数
- const worksCount = await Gallery.countDocuments({ userId: user._id })
-
- // 获取等级信息
- const levelInfo = user.getLevelInfo()
-
- // 计算探索时长(分钟转小时,保留1位小数)
- const playTimeHours = Math.round((user.totalPlayTime || 0) / 60 * 10) / 10
-
- return ApiResponse.success(res, {
- level: levelInfo.level,
- levelName: levelInfo.name,
- levelPoints: levelInfo.points,
- levelProgress: levelInfo.progress,
- totalProgress: levelInfo.totalProgress,
- nextLevelPoints: levelInfo.nextLevelPoints,
- totalPlayTime: playTimeHours,
- totalScore: user.totalScore || 0,
- worksCount: worksCount,
- collectionCount: user.collectedKnowledge?.length || 0,
- achievementCount: user.achievements?.length || 0,
- unlockedDims: user.unlockedDims || [1]
- })
-
- } catch (error) {
- logger.error('获取用户统计失败:', error)
- return ApiResponse.serverError(res, error.message)
- }
-})
-
-/**
- * 获取用户作品列表
- * GET /api/user/works
- */
-router.get('/works', async (req, res) => {
- try {
- const user = req.user
- const { page = 1, limit = 20 } = req.query
- const { Gallery } = require('../models')
-
- const query = { userId: user._id }
-
- const total = await Gallery.countDocuments(query)
- const works = await Gallery.find(query)
- .sort({ createdAt: -1 })
- .skip((parseInt(page) - 1) * parseInt(limit))
- .limit(parseInt(limit))
- .lean()
-
- // 格式化作品数据
- const formattedWorks = works.map(work => ({
- id: work._id,
- title: work.title,
- description: work.description,
- imageUrl: work.imageUrl,
- dimension: work.dimension,
- status: work.status,
- likes: work.likes || 0,
- views: work.views || 0,
- createdAt: work.createdAt
- }))
-
- return ApiResponse.paginated(res, formattedWorks, {
- page: parseInt(page),
- limit: parseInt(limit),
- total
- })
-
- } catch (error) {
- logger.error('获取用户作品失败:', error)
- return ApiResponse.serverError(res, error.message)
- }
-})
-
+/**
+ * 获取用户统计数据
+ * GET /api/user/stats
+ */
+router.get('/stats', async (req, res) => {
+ try {
+ const user = req.user
+ const { Gallery } = require('../models')
+
+ // 获取用户作品数
+ const worksCount = await Gallery.countDocuments({ userId: user._id })
+
+ // 获取等级信息
+ const levelInfo = user.getLevelInfo()
+
+ // 计算探索时长(分钟转小时,保留1位小数)
+ const playTimeHours = Math.round((user.totalPlayTime || 0) / 60 * 10) / 10
+
+ return ApiResponse.success(res, {
+ level: levelInfo.level,
+ levelName: levelInfo.name,
+ levelPoints: levelInfo.points,
+ levelProgress: levelInfo.progress,
+ totalProgress: levelInfo.totalProgress,
+ nextLevelPoints: levelInfo.nextLevelPoints,
+ totalPlayTime: playTimeHours,
+ totalScore: user.totalScore || 0,
+ worksCount: worksCount,
+ collectionCount: user.collectedKnowledge?.length || 0,
+ achievementCount: user.achievements?.length || 0,
+ unlockedDims: user.unlockedDims || [1]
+ })
+
+ } catch (error) {
+ logger.error('获取用户统计失败:', error)
+ return ApiResponse.serverError(res, error.message)
+ }
+})
+
+/**
+ * 获取用户作品列表
+ * GET /api/user/works
+ */
+router.get('/works', async (req, res) => {
+ try {
+ const user = req.user
+ const { page = 1, limit = 20 } = req.query
+ const { Gallery } = require('../models')
+
+ const query = { userId: user._id }
+
+ const total = await Gallery.countDocuments(query)
+ const works = await Gallery.find(query)
+ .sort({ createdAt: -1 })
+ .skip((parseInt(page) - 1) * parseInt(limit))
+ .limit(parseInt(limit))
+ .lean()
+
+ // 格式化作品数据
+ const formattedWorks = works.map(work => ({
+ id: work._id,
+ title: work.title,
+ description: work.description,
+ imageUrl: work.imageUrl,
+ dimension: work.dimension,
+ status: work.status,
+ likes: work.likes || 0,
+ views: work.views || 0,
+ createdAt: work.createdAt
+ }))
+
+ return ApiResponse.paginated(res, formattedWorks, {
+ page: parseInt(page),
+ limit: parseInt(limit),
+ total
+ })
+
+ } catch (error) {
+ logger.error('获取用户作品失败:', error)
+ return ApiResponse.serverError(res, error.message)
+ }
+})
+
module.exports = router
diff --git a/frontend/ai-dimension/src/pages.json b/frontend/ai-dimension/src/pages.json
index 00167bf..2b2c9ba 100644
--- a/frontend/ai-dimension/src/pages.json
+++ b/frontend/ai-dimension/src/pages.json
@@ -4,6 +4,14 @@
{"path": "pages/login/login", "style": {"navigationBarTitleText": "登录", "navigationStyle": "custom"}},
{"path": "pages/detail/detail", "style": {"navigationBarTitleText": "AI 知识", "navigationStyle": "custom"}},
{"path": "pages/payment/payment", "style": {"navigationBarTitleText": "订阅升级", "navigationStyle": "custom"}},
+ {"path": "pages/favorites/favorites", "style": {"navigationBarTitleText": "我的收藏", "navigationStyle": "custom"}},
+ {"path": "pages/achievements/achievements", "style": {"navigationBarTitleText": "成就", "navigationStyle": "custom"}},
+ {"path": "pages/leaderboard/leaderboard", "style": {"navigationBarTitleText": "排行榜", "navigationStyle": "custom"}},
+ {"path": "pages/search/search", "style": {"navigationBarTitleText": "搜索", "navigationStyle": "custom"}},
+ {"path": "pages/progress/progress", "style": {"navigationBarTitleText": "学习进度", "navigationStyle": "custom"}},
+ {"path": "pages/feedback/feedback", "style": {"navigationBarTitleText": "意见反馈", "navigationStyle": "custom"}},
+ {"path": "pages/settings/settings", "style": {"navigationBarTitleText": "设置", "navigationStyle": "custom"}},
+ {"path": "pages/news/news", "style": {"navigationBarTitleText": "AI 资讯", "navigationStyle": "custom"}},
{"path": "pages/dimension/dimension", "style": {"navigationBarTitleText": "", "navigationStyle": "custom"}},
{"path": "pages/chat/chat", "style": {"navigationBarTitleText": "AI 问答", "navigationStyle": "custom"}},
{"path": "pages/trend/trend", "style": {"navigationBarTitleText": "AI 趋势", "navigationStyle": "custom"}},
diff --git a/frontend/ai-dimension/src/pages/achievements/achievements.vue b/frontend/ai-dimension/src/pages/achievements/achievements.vue
new file mode 100644
index 0000000..391521c
--- /dev/null
+++ b/frontend/ai-dimension/src/pages/achievements/achievements.vue
@@ -0,0 +1,354 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 已解锁 {{ unlockedCount }} / {{ totalCount }} 个成就
+
+
+
+
+
+
+
+
+
+
+ {{ ach.icon }}
+
+
+ {{ ach.name }}
+ {{ ach.description }}
+
+ ✦ {{ formatDate(ach.date) }}
+
+
+ ⌬ 未解锁
+
+
+
+
+
+
+
+
+
+ 🏆
+ 暂无成就数据
+ 继续探索 AI 知识,解锁更多成就
+
+
+
+
+ ⏳
+ 加载中...
+
+
+
+
+
+
+
diff --git a/frontend/ai-dimension/src/pages/favorites/favorites.vue b/frontend/ai-dimension/src/pages/favorites/favorites.vue
new file mode 100644
index 0000000..0b5165e
--- /dev/null
+++ b/frontend/ai-dimension/src/pages/favorites/favorites.vue
@@ -0,0 +1,249 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ dimName(item.dimensionId) }}
+
+
+ {{ item.title }}
+
+
+ ✕
+
+
+
+
+
+
+ ⭐
+ 还没有收藏内容
+ 去探索吧,发现有趣的 AI 知识
+
+ 开始探索
+
+
+
+
+
+
+
+
diff --git a/frontend/ai-dimension/src/pages/feedback/feedback.vue b/frontend/ai-dimension/src/pages/feedback/feedback.vue
new file mode 100644
index 0000000..351204e
--- /dev/null
+++ b/frontend/ai-dimension/src/pages/feedback/feedback.vue
@@ -0,0 +1,458 @@
+
+
+
+
+ ‹
+ 意见反馈
+
+
+
+
+
+ 反馈类型
+
+
+ {{ t.icon }}
+ {{ t.name }}
+
+
+
+
+
+
+ 标题
+
+
+
+
+
+ 内容
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ fb.title || '无标题' }}
+ {{ statusLabel(fb.status) }}
+
+
+ {{ typeLabel(fb.type) }}
+ {{ formatTime(fb.createdAt || fb.time) }}
+
+
+
+
+
+ 暂无反馈记录
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/ai-dimension/src/pages/index/index.vue b/frontend/ai-dimension/src/pages/index/index.vue
index e898d66..5a9bc10 100644
--- a/frontend/ai-dimension/src/pages/index/index.vue
+++ b/frontend/ai-dimension/src/pages/index/index.vue
@@ -140,7 +140,7 @@ function goProfile() {
}
function onSearch() {
- uni.showToast({ title: '搜索功能开发中', icon: 'none' })
+ uni.navigateTo({ url: '/pages/search/search' })
}
function onNotify() {
diff --git a/frontend/ai-dimension/src/pages/leaderboard/leaderboard.vue b/frontend/ai-dimension/src/pages/leaderboard/leaderboard.vue
new file mode 100644
index 0000000..c6128d7
--- /dev/null
+++ b/frontend/ai-dimension/src/pages/leaderboard/leaderboard.vue
@@ -0,0 +1,320 @@
+
+
+
+
+
+
+
+
+
+
+ {{ tab.label }}
+
+
+
+
+
+
+
+
+ {{ idx + 1 }}
+ {{ idx + 1 }}
+
+
+
+
+
+
+ {{ (item.nickName || item.username || '用').charAt(0) }}
+
+
+
+
+
+ {{ item.nickName || item.username || '用户' }}
+ {{ item.score || 0 }} 分
+
+
+
+
+
+
+
+
+
+
+
+ 🏅
+ 暂无排行数据
+ 继续学习,看看你能排第几
+
+
+
+
+ ⏳
+ 加载中...
+
+
+
+
+
+
+
diff --git a/frontend/ai-dimension/src/pages/news/news.vue b/frontend/ai-dimension/src/pages/news/news.vue
new file mode 100644
index 0000000..d465d6f
--- /dev/null
+++ b/frontend/ai-dimension/src/pages/news/news.vue
@@ -0,0 +1,356 @@
+
+
+
+
+
+ ‹
+ AI 资讯
+
+ ↗
+
+
+
+
+
+
+ {{ heroEmoji }}
+
+
+
+
+ {{ categoryLabel }}
+
+
+
+ {{ news.title }}
+
+
+
+
+ 来源
+ {{ news.source }}
+
+
+ 时间
+ {{ formatDate(news.newsDate) }}
+
+
+ 阅读
+ {{ news.viewCount || 0 }} 次
+
+
+ 🔥
+ {{ news.hotCount || 0 }}
+
+
+
+
+
+ 摘要
+ {{ news.summary }}
+
+
+
+
+
+
+
+
+
+ 相关话题
+
+
+ {{ tag }}
+
+
+
+
+
+
+
+ {{ isCollected ? '❤️' : '🤍' }}
+ {{ isCollected ? '已收藏' : '收藏' }}
+
+
+ ↗
+ 分享
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/ai-dimension/src/pages/profile/profile.vue b/frontend/ai-dimension/src/pages/profile/profile.vue
index 0dd2a09..12762b2 100644
--- a/frontend/ai-dimension/src/pages/profile/profile.vue
+++ b/frontend/ai-dimension/src/pages/profile/profile.vue
@@ -72,6 +72,16 @@
成就
→
+
+