Files
ai-dimension/client/src/pages/dimension/dimension.vue
T
Yuzhiran Dev c1d6dd3b29 refactor: 项目架构重构 - 目录标准化 + 清理冗余
- 目录重命名: backend/wdkj-server/ → server/, frontend/ai-dimension/ → client/
- 删除 20+ 冗余文件(WDKJ 旧脚本、Windows 脚本、过时文档、设计稿)
- 更新 package.json 元数据(移除 wdkj 命名)
- 完善三级 .gitignore(根 + server + client)
- 重写 README.md 和 CHANGELOG.md
- 工具脚本移至 scripts/
2026-07-11 12:45:37 +08:00

281 lines
7.8 KiB
Vue

<template>
<view class="page-dim">
<view class="status-bar-placeholder"></view>
<view class="back-btn" @tap="goBack">
<text> 返回</text>
</view>
<!-- 维度横幅 -->
<view class="dim-banner" :style="{ borderColor: currentDim?.border }">
<text class="dim-banner-icon">{{ currentDim?.icon }}</text>
<text class="dim-banner-title">{{ currentDim?.name }}</text>
<text class="dim-banner-desc">{{ bannerDesc }}</text>
<view class="progress-track">
<view class="progress-fill" :style="{ width: progress + '%' }"></view>
</view>
<text class="progress-label">探索进度 {{ progress }}% · 已完成 {{ readCount }}/{{ totalCount }} </text>
</view>
<!-- 知识列表 -->
<view v-for="item in knowledgeList" :key="item._id" class="knowledge-item" @tap="goDetail(item)">
<view class="k-icon" :style="getItemStyle(item)">
<text>{{ item.icon || '📄' }}</text>
</view>
<view class="k-info">
<text class="k-title">{{ item.title }}</text>
<text class="k-desc">{{ item.desc }}</text>
<view class="k-meta">
<text>📖 {{ item.readTime || 5 }} 分钟</text>
<text v-if="item.collected"> 已收藏</text>
<text v-else>🔖 {{ item.collectCount || 0 }} 人收藏</text>
<text class="k-badge" :class="item.isPremium ? 'pro' : 'free'">
{{ item.isPremium ? 'Pro' : '免费' }}
</text>
</view>
</view>
</view>
<!-- 加载状态 -->
<view v-if="loading" class="loading-state">
<text>加载中...</text>
</view>
</view>
</template>
<script setup>
import { ref, computed, onMounted } from 'vue'
import { getDimension } from '@/utils/dimensions'
import { knowledgeApi } from '@/utils/api'
const dimId = ref(1)
const currentDim = computed(() => getDimension(dimId.value))
const knowledgeList = ref([])
const loading = ref(false)
const progress = ref(35)
const readCount = ref(4)
const totalCount = ref(12)
const bannerDesc = computed(() => {
const descs = {
1: '从 1950 年图灵测试到 2026 年通用人工智能,追溯 70 年演进之路',
2: '从深度学习到 Transformer,从 MoE 到多模态,理解每一次技术跃迁',
3: '大模型格局、Agent 生态、具身智能——2026 年 AI 世界全景图',
4: '提示词工程、RAG 系统、模型微调、工具链——从入门到上手',
5: '每日追踪 AI 前沿动态,不错过每一个重要时刻'
}
return descs[dimId.value] || '探索人工智能的精彩世界'
})
onMounted(() => {
const pages = getCurrentPages()
const page = pages[pages.length - 1]
if (page.options?.id) {
dimId.value = parseInt(page.options.id)
}
loadKnowledge()
})
async function loadKnowledge() {
loading.value = true
try {
const data = await knowledgeApi.list({ dim: dimId.value })
knowledgeList.value = data.map(item => ({
...item,
icon: getDimIcon(item.dim),
desc: item.content?.substring(0, 40) + '...' || '',
readTime: Math.ceil((item.content?.length || 300) / 200),
isPremium: item.isPremium,
collected: false,
collectCount: item.collectionCount
}))
} catch (e) {
// 用示例数据填充
knowledgeList.value = getSampleData(dimId.value)
} finally {
loading.value = false
}
}
function getItemStyle(item) {
const colors = [
{ bg: 'rgba(124,77,255,0.1)', color: '#b388ff' },
{ bg: 'rgba(0,188,212,0.1)', color: '#4dd0e1' },
{ bg: 'rgba(0,200,150,0.1)', color: '#4db6ac' },
{ bg: 'rgba(255,193,7,0.1)', color: '#ffd54f' },
{ bg: 'rgba(239,83,80,0.1)', color: '#ef5350' }
]
const c = colors[(item.dim || 1) - 1] || colors[0]
return {
background: c.bg,
color: c.color,
borderColor: c.bg
}
}
function getDimIcon(dim) {
const icons = ['📜', '🏛', '♟', '🧠', '⚡']
return icons[(dim || 1) - 1]
}
function getSampleData(dim) {
const samples = {
1: [
{ title: '图灵测试:人工智能的哲学起点', content: '1950 年,艾伦·图灵提出"机器能思考吗?"' },
{ title: '达特茅斯会议:AI 的诞生时刻', content: '1956 年,一群科学家正式命名了"人工智能"' },
{ title: '深蓝 vs 卡斯帕罗夫', content: '1997 年,IBM 深蓝首次击败国际象棋世界冠军' },
],
2: [
{ title: '深度学习革命', content: '从神经网络到深度学习的演进之路' },
{ title: 'Transformer 架构详解', content: '2017 年 Google 提出的革命性架构' },
],
3: [
{ title: '2026 年大模型格局', content: 'GPT、Claude、Gemini、DeepSeek 全面对比' },
{ title: 'Agent 智能体生态', content: '从 Chatbot 到自主 Agent 的进化' },
],
4: [
{ title: '提示词工程入门', content: '如何写出高质量的 prompt' },
{ title: 'RAG 系统搭建指南', content: '检索增强生成从零到一' },
],
5: [
{ title: 'DeepSeek 自研推理芯片', content: '降低对英伟达依赖的重要一步' },
{ title: 'WAIC 2026 即将开幕', content: '7 月 17 日上海,1100+ 企业参展' },
]
}
const data = samples[dim] || samples[1]
return data.map((item, i) => ({
...item,
_id: `sample-${dim}-${i}`,
dim,
icon: getDimIcon(dim),
readTime: 5 + i * 2,
isPremium: i >= 3,
collected: i === 0,
collectionCount: 10 - i * 2
}))
}
function goBack() {
uni.navigateBack()
}
function goDetail(item) {
uni.navigateTo({
url: `/pages/detail/detail?id=${item._id}`
})
}
</script>
<style lang="scss" scoped>
.page-dim {
min-height: 100vh;
padding: 0 20px 40px;
background: var(--bg-primary);
}
.status-bar-placeholder { height: 44px; }
.back-btn {
color: rgba(255,255,255,0.4);
font-size: 14px;
display: flex;
align-items: center;
gap: 6px;
padding: 10px 0 14px;
}
.dim-banner {
border-radius: 18px;
padding: 24px 20px;
margin-bottom: 20px;
background: linear-gradient(135deg, rgba(124,77,255,0.1), rgba(0,0,0,0.3));
border: 1px solid rgba(124,77,255,0.12);
position: relative;
overflow: hidden;
}
.dim-banner-icon { font-size: 28px; display: block; margin-bottom: 8px; }
.dim-banner-title { font-size: 22px; color: var(--text-primary); display: block; margin-bottom: 6px; }
.dim-banner-desc {
font-size: 12px;
color: rgba(255,255,255,0.4);
line-height: 1.6;
display: block;
}
.progress-track {
height: 3px;
background: rgba(255,255,255,0.06);
border-radius: 2px;
margin-top: 16px;
overflow: hidden;
}
.progress-fill {
height: 100%;
background: linear-gradient(90deg, #b388ff, #7c4dff);
border-radius: 2px;
}
.progress-label {
font-size: 11px;
color: rgba(255,255,255,0.2);
margin-top: 8px;
display: block;
}
.knowledge-item {
border-radius: 14px;
padding: 16px;
margin-bottom: 10px;
background: rgba(255,255,255,0.03);
border: 1px solid rgba(255,255,255,0.05);
display: flex;
gap: 14px;
align-items: flex-start;
}
.k-icon {
width: 44px; height: 44px;
border-radius: 12px;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
font-size: 18px;
border: 1px solid rgba(255,255,255,0.06);
}
.k-info { flex: 1; }
.k-title {
font-size: 14px;
color: rgba(255,255,255,0.85);
font-weight: 500;
display: block;
margin-bottom: 4px;
}
.k-desc {
font-size: 11px;
color: rgba(255,255,255,0.3);
line-height: 1.5;
margin-bottom: 8px;
display: block;
}
.k-meta {
display: flex;
gap: 12px;
align-items: center;
font-size: 10px;
color: rgba(255,255,255,0.15);
}
.k-badge {
font-size: 10px;
padding: 2px 10px;
border-radius: 6px;
font-weight: 500;
}
.k-badge.free { background: rgba(76,175,80,0.12); color: #66bb6a; }
.k-badge.pro { background: rgba(255,152,0,0.12); color: #ffa726; }
.loading-state {
text-align: center;
padding: 40px 0;
color: rgba(255,255,255,0.2);
}
</style>