742 lines
35 KiB
HTML
742 lines
35 KiB
HTML
<!DOCTYPE html>
|
||
<html>
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||
<title>玩Android - 项目</title>
|
||
<style>
|
||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||
body { font-family: 'Roboto', 'Noto Sans SC', sans-serif; background: #F5F5F5; }
|
||
|
||
/* 容器 */
|
||
.container { max-width: 750px; margin: 0 auto; background: white; min-height: 100vh; }
|
||
|
||
/* 状态栏 */
|
||
.status-bar { height: 40px; background: #6200EE; }
|
||
|
||
/* 顶部导航 */
|
||
.top-nav { background: #6200EE; padding: 12px 16px; display: flex; align-items: center; justify-content: space-between; color: white; }
|
||
.nav-title { font-size: 20px; font-weight: 500; }
|
||
.nav-actions { display: flex; gap: 16px; }
|
||
.nav-icon { font-size: 24px; cursor: pointer; }
|
||
|
||
/* 搜索栏 */
|
||
.search-bar { background: #6200EE; padding: 12px 16px; }
|
||
.search-container { background: rgba(255,255,255,0.9); border-radius: 24px; padding: 12px 16px; display: flex; align-items: center; }
|
||
.search-icon { font-size: 20px; margin-right: 12px; color: #6200EE; }
|
||
.search-input { font-size: 16px; color: #212121; flex: 1; border: none; outline: none; background: transparent; }
|
||
.search-input::placeholder { color: #757575; }
|
||
|
||
/* 项目分类标签 */
|
||
.category-tabs { padding: 16px; background: white; border-bottom: 1px solid #EEEEEE; overflow-x: auto; white-space: nowrap; }
|
||
.category-tabs::-webkit-scrollbar { display: none; }
|
||
.category-tab { display: inline-block; padding: 8px 16px; margin-right: 8px; border-radius: 20px; background: #F5F5F5; color: #757575; font-size: 14px; cursor: pointer; transition: all 0.3s; }
|
||
.category-tab:hover { background: #E0E0E0; }
|
||
.category-tab.active { background: #6200EE; color: white; }
|
||
|
||
/* 项目列表 */
|
||
.projects-container { padding: 16px; }
|
||
.section-title { font-size: 18px; font-weight: 500; margin: 0 0 16px; color: #212121; display: flex; align-items: center; }
|
||
.section-title::before { content: "📦"; margin-right: 8px; }
|
||
|
||
/* 项目网格 */
|
||
.projects-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 16px; }
|
||
|
||
/* 项目卡片 */
|
||
.project-card { background: white; border-radius: 16px; padding: 20px; box-shadow: 0 2px 8px rgba(0,0,0,0.08); transition: all 0.3s; cursor: pointer; }
|
||
.project-card:hover { box-shadow: 0 4px 16px rgba(0,0,0,0.12); transform: translateY(-2px); }
|
||
.project-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 12px; }
|
||
.project-title { font-size: 18px; font-weight: 500; color: #212121; line-height: 1.4; flex: 1; }
|
||
.project-fresh { background: #FF5252; color: white; font-size: 12px; padding: 2px 8px; border-radius: 10px; margin-left: 8px; }
|
||
.project-meta { display: flex; align-items: center; margin-bottom: 12px; font-size: 14px; color: #757575; }
|
||
.project-author { margin-right: 16px; }
|
||
.project-time { margin-right: 16px; }
|
||
.project-content { font-size: 15px; color: #616161; line-height: 1.6; margin-bottom: 16px; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
|
||
.project-footer { display: flex; justify-content: space-between; align-items: center; }
|
||
.project-stats { display: flex; gap: 16px; }
|
||
.stat-item { display: flex; align-items: center; font-size: 14px; color: #757575; }
|
||
.stat-icon { margin-right: 4px; }
|
||
.project-actions { display: flex; gap: 12px; }
|
||
.action-btn { background: #F5F5F5; border: none; padding: 6px 12px; border-radius: 16px; font-size: 14px; color: #6200EE; cursor: pointer; transition: all 0.3s; }
|
||
.action-btn:hover { background: #6200EE; color: white; }
|
||
|
||
/* 底部导航 */
|
||
.tab-bar { position: fixed; bottom: 0; left: 0; right: 0; background: white; border-top: 1px solid #EEEEEE; display: flex; justify-content: space-around; padding: 12px 0; max-width: 750px; margin: 0 auto; z-index: 100; }
|
||
.tab-item { display: flex; flex-direction: column; align-items: center; padding: 8px 16px; border-radius: 12px; transition: all 0.3s; cursor: pointer; }
|
||
.tab-item.active { background: rgba(98, 0, 238, 0.08); }
|
||
.tab-icon { font-size: 24px; margin-bottom: 4px; }
|
||
.tab-text { font-size: 12px; }
|
||
.tab-item.active .tab-icon, .tab-item.active .tab-text { color: #6200EE; }
|
||
.tab-item:not(.active) .tab-icon, .tab-item:not(.active) .tab-text { color: #757575; }
|
||
|
||
/* 项目详情页 */
|
||
.project-detail { display: none; position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: white; z-index: 1000; overflow-y: auto; }
|
||
.detail-header { background: #6200EE; padding: 16px; display: flex; align-items: center; justify-content: space-between; color: white; }
|
||
.detail-back { font-size: 24px; cursor: pointer; }
|
||
.detail-title { font-size: 18px; font-weight: 500; }
|
||
.detail-content { padding: 24px; }
|
||
.detail-title-main { font-size: 24px; font-weight: 500; margin-bottom: 16px; color: #212121; }
|
||
.detail-meta { display: flex; align-items: center; margin-bottom: 24px; padding-bottom: 16px; border-bottom: 1px solid #EEEEEE; }
|
||
.detail-author { margin-right: 16px; font-size: 16px; color: #6200EE; }
|
||
.detail-time { font-size: 14px; color: #757575; }
|
||
.detail-body { font-size: 16px; line-height: 1.8; color: #424242; }
|
||
.detail-body p { margin-bottom: 16px; }
|
||
.detail-body h2 { font-size: 20px; font-weight: 500; margin: 24px 0 16px; color: #212121; }
|
||
.detail-body h3 { font-size: 18px; font-weight: 500; margin: 20px 0 12px; color: #212121; }
|
||
.detail-body code { background: #F5F5F5; padding: 2px 6px; border-radius: 4px; font-family: 'Courier New', monospace; }
|
||
.detail-body pre { background: #F5F5F5; padding: 16px; border-radius: 8px; overflow-x: auto; margin: 16px 0; }
|
||
.detail-footer { padding: 24px; border-top: 1px solid #EEEEEE; margin-top: 32px; }
|
||
.detail-actions { display: flex; justify-content: space-between; }
|
||
|
||
/* 加载更多 */
|
||
.load-more { text-align: center; padding: 24px; }
|
||
.load-btn { background: #6200EE; color: white; border: none; padding: 12px 32px; border-radius: 24px; font-size: 16px; cursor: pointer; transition: all 0.3s; }
|
||
.load-btn:hover { background: #3700B3; }
|
||
|
||
/* 安全区域 */
|
||
.safe-area { height: 80px; }
|
||
|
||
/* 加载动画 */
|
||
.loading { text-align: center; padding: 40px; color: #757575; }
|
||
.loading-spinner { width: 40px; height: 40px; border: 4px solid #E0E0E0; border-top: 4px solid #6200EE; border-radius: 50%; animation: spin 1s linear infinite; margin: 0 auto 16px; }
|
||
@keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
|
||
|
||
/* 空状态 */
|
||
.empty-state { text-align: center; padding: 60px 20px; color: #757575; }
|
||
.empty-icon { font-size: 48px; margin-bottom: 16px; }
|
||
.empty-title { font-size: 18px; font-weight: 500; margin-bottom: 8px; }
|
||
.empty-desc { font-size: 14px; }
|
||
|
||
@media (max-width: 600px) {
|
||
.projects-grid { grid-template-columns: 1fr; }
|
||
.project-header { flex-direction: column; }
|
||
.project-title { margin-bottom: 8px; }
|
||
.project-footer { flex-direction: column; align-items: flex-start; gap: 12px; }
|
||
.project-actions { align-self: flex-end; }
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<!-- 项目列表页面 -->
|
||
<div class="container" id="listPage">
|
||
<!-- 状态栏 -->
|
||
<div class="status-bar"></div>
|
||
|
||
<!-- 顶部导航 -->
|
||
<div class="top-nav">
|
||
<div class="nav-title">玩Android - 项目</div>
|
||
<div class="nav-actions">
|
||
<div class="nav-icon" onclick="showMenu()">⋮</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 搜索栏 -->
|
||
<div class="search-bar">
|
||
<div class="search-container">
|
||
<div class="search-icon">🔍</div>
|
||
<input type="text" class="search-input" placeholder="搜索项目..." id="searchInput" onkeypress="handleSearchKeypress(event)">
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 项目分类标签 -->
|
||
<div class="category-tabs" id="categoryTabs">
|
||
<div class="loading" id="loadingCategories">
|
||
<div class="loading-spinner"></div>
|
||
<div>正在加载分类...</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 项目列表 -->
|
||
<div class="projects-container">
|
||
<div class="section-title">项目列表</div>
|
||
|
||
<!-- 项目列表容器 -->
|
||
<div id="projectsList">
|
||
<div class="loading" id="loadingProjects">
|
||
<div class="loading-spinner"></div>
|
||
<div>正在加载项目...</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 加载更多 -->
|
||
<div class="load-more" id="loadMoreContainer" style="display: none;">
|
||
<button class="load-btn" onclick="loadMoreProjects()">加载更多</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 安全区域 -->
|
||
<div class="safe-area"></div>
|
||
|
||
<!-- 底部导航 -->
|
||
<div class="tab-bar">
|
||
<div class="tab-item" onclick="switchTab('home')">
|
||
<div class="tab-icon">🏠</div>
|
||
<div class="tab-text">首页</div>
|
||
</div>
|
||
<div class="tab-item active" onclick="switchTab('project')">
|
||
<div class="tab-icon">📦</div>
|
||
<div class="tab-text">项目</div>
|
||
</div>
|
||
<div class="tab-item" onclick="switchTab('wechat')">
|
||
<div class="tab-icon">📱</div>
|
||
<div class="tab-text">公众号</div>
|
||
</div>
|
||
<div class="tab-item" onclick="switchTab('system')">
|
||
<div class="tab-icon">🌳</div>
|
||
<div class="tab-text">体系</div>
|
||
</div>
|
||
<div class="tab-item" onclick="switchTab('profile')">
|
||
<div class="tab-icon">👤</div>
|
||
<div class="tab-text">我的</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 项目详情页 -->
|
||
<div class="project-detail" id="detailPage">
|
||
<div class="detail-header">
|
||
<div class="detail-back" onclick="closeDetail()">←</div>
|
||
<div class="detail-title">项目详情</div>
|
||
<div style="width: 24px;"></div>
|
||
</div>
|
||
<div class="detail-content">
|
||
<div id="detailContent">
|
||
<div class="loading" id="loadingDetail">
|
||
<div class="loading-spinner"></div>
|
||
<div>正在加载项目详情...</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
// 当前状态
|
||
let currentCategoryId = null;
|
||
let currentPage = 0;
|
||
let isLoading = false;
|
||
let hasMore = true;
|
||
let categories = [];
|
||
|
||
// 初始化页面
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
console.log('玩Android项目页面已加载');
|
||
console.log('公网访问: http://129.211.173.87:3000/projects_fixed.html');
|
||
|
||
// 加载项目分类
|
||
loadCategories();
|
||
});
|
||
|
||
// 加载项目分类
|
||
async function loadCategories() {
|
||
try {
|
||
const response = await fetch('/api/project/tree/json');
|
||
const data = await response.json();
|
||
|
||
if (data.errorCode === 0 && data.data && data.data.length > 0) {
|
||
categories = data.data;
|
||
renderCategories(categories);
|
||
|
||
// 默认选择第一个分类
|
||
if (categories.length > 0) {
|
||
selectCategory(categories[0].id, categories[0].name);
|
||
}
|
||
} else {
|
||
// 使用默认分类数据
|
||
renderDefaultCategories();
|
||
}
|
||
} catch (error) {
|
||
console.error('加载分类失败:', error);
|
||
renderDefaultCategories();
|
||
}
|
||
}
|
||
|
||
// 渲染分类
|
||
function renderCategories(categories) {
|
||
const container = document.getElementById('categoryTabs');
|
||
container.innerHTML = '';
|
||
|
||
categories.forEach(category => {
|
||
const tab = document.createElement('div');
|
||
tab.className = 'category-tab';
|
||
tab.textContent = category.name;
|
||
tab.setAttribute('data-id', category.id);
|
||
tab.onclick = () => selectCategory(category.id, category.name);
|
||
|
||
container.appendChild(tab);
|
||
});
|
||
}
|
||
|
||
// 渲染默认分类
|
||
function renderDefaultCategories() {
|
||
const defaultCategories = [
|
||
{ id: 294, name: '完整项目' },
|
||
{ id: 402, name: '跨平台应用' },
|
||
{ id: 367, name: '资源聚合类' },
|
||
{ id: 323, name: '动画' },
|
||
{ id: 314, name: 'RV列表动效' },
|
||
{ id: 358, name: '项目基础功能' },
|
||
{ id: 296, name: '网络&文件下载' }
|
||
];
|
||
|
||
categories = defaultCategories;
|
||
renderCategories(defaultCategories);
|
||
|
||
// 默认选择第一个分类
|
||
if (defaultCategories.length > 0) {
|
||
selectCategory(defaultCategories[0].id, defaultCategories[0].name);
|
||
}
|
||
}
|
||
|
||
// 选择分类
|
||
function selectCategory(categoryId, categoryName) {
|
||
// 更新选中状态
|
||
document.querySelectorAll('.category-tab').forEach(tab => {
|
||
tab.classList.remove('active');
|
||
if (parseInt(tab.getAttribute('data-id')) === categoryId) {
|
||
tab.classList.add('active');
|
||
}
|
||
});
|
||
|
||
// 更新当前分类
|
||
currentCategoryId = categoryId;
|
||
currentPage = 0;
|
||
hasMore = true;
|
||
|
||
// 更新标题
|
||
document.querySelector('.section-title').innerHTML = `<span>📦</span> ${categoryName}`;
|
||
|
||
// 加载项目
|
||
loadProjects();
|
||
}
|
||
|
||
// 加载项目列表
|
||
async function loadProjects() {
|
||
if (isLoading || !hasMore || !currentCategoryId) return;
|
||
|
||
isLoading = true;
|
||
|
||
try {
|
||
const response = await fetch(`/api/project/list/${currentPage}/json?cid=${currentCategoryId}`);
|
||
const data = await response.json();
|
||
|
||
if (data.errorCode === 0 && data.data && data.data.datas) {
|
||
renderProjects(data.data.datas);
|
||
hasMore = !data.data.over;
|
||
|
||
// 显示或隐藏加载更多按钮
|
||
const loadMoreContainer = document.getElementById('loadMoreContainer');
|
||
loadMoreContainer.style.display = hasMore ? 'block' : 'none';
|
||
|
||
// 隐藏加载动画
|
||
document.getElementById('loadingProjects').style.display = 'none';
|
||
} else {
|
||
// 使用默认项目数据
|
||
renderDefaultProjects();
|
||
}
|
||
} catch (error) {
|
||
console.error('加载项目失败:', error);
|
||
renderDefaultProjects();
|
||
} finally {
|
||
isLoading = false;
|
||
}
|
||
}
|
||
|
||
// 渲染项目列表
|
||
function renderProjects(projects) {
|
||
const container = document.getElementById('projectsList');
|
||
|
||
// 如果是第一页,清空容器
|
||
if (currentPage === 0) {
|
||
container.innerHTML = '';
|
||
}
|
||
|
||
if (projects.length === 0) {
|
||
container.innerHTML = `
|
||
<div class="empty-state">
|
||
<div class="empty-icon">📦</div>
|
||
<div class="empty-title">暂无项目</div>
|
||
<div class="empty-desc">该分类下还没有项目</div>
|
||
</div>
|
||
`;
|
||
document.getElementById('loadMoreContainer').style.display = 'none';
|
||
return;
|
||
}
|
||
|
||
projects.forEach(project => {
|
||
const projectElement = document.createElement('div');
|
||
projectElement.className = 'project-card';
|
||
projectElement.setAttribute('data-id', project.id);
|
||
projectElement.onclick = () => showProjectDetail(project.id);
|
||
|
||
// 格式化时间
|
||
const publishTime = new Date(project.publishTime);
|
||
const timeAgo = getTimeAgo(publishTime);
|
||
|
||
projectElement.innerHTML = `
|
||
<div class="project-header">
|
||
<div class="project-title">${project.title || '无标题'}</div>
|
||
${project.fresh ? '<div class="project-fresh">新</div>' : ''}
|
||
</div>
|
||
<div class="project-meta">
|
||
<div class="project-author">👤 ${project.author || '未知作者'}</div>
|
||
<div class="project-time">🕒 ${timeAgo}</div>
|
||
</div>
|
||
<div class="project-content">${project.desc || '暂无描述'}</div>
|
||
<div class="project-footer">
|
||
<div class="project-stats">
|
||
<div class="stat-item">
|
||
<span class="stat-icon">👍</span>
|
||
<span>${project.zan || 0}</span>
|
||
</div>
|
||
<div class="stat-item">
|
||
<span class="stat-icon">💬</span>
|
||
<span>${project.comments || 0}</span>
|
||
</div>
|
||
<div class="stat-item">
|
||
<span class="stat-icon">⭐</span>
|
||
<span>${project.collect ? '已收藏' : '未收藏'}</span>
|
||
</div>
|
||
</div>
|
||
<div class="project-actions">
|
||
<button class="action-btn" onclick="event.stopPropagation(); likeProject(${project.id})">点赞</button>
|
||
<button class="action-btn" onclick="event.stopPropagation(); collectProject(${project.id})">${project.collect ? '取消收藏' : '收藏'}</button>
|
||
</div>
|
||
</div>
|
||
`;
|
||
|
||
container.appendChild(projectElement);
|
||
});
|
||
}
|
||
|
||
// 渲染默认项目
|
||
function renderDefaultProjects() {
|
||
const defaultProjects = [
|
||
{
|
||
id: 1,
|
||
title: "玩Android Material Design客户端",
|
||
author: "Material Design",
|
||
publishTime: Date.now() - 86400000, // 1天前
|
||
desc: "基于Uniapp框架开发的玩Android客户端,完全遵循Material Design 3设计规范。提供完整的Material Design组件库,包括卡片、按钮、导航栏、对话框等。",
|
||
zan: 42,
|
||
collect: false,
|
||
comments: 12,
|
||
fresh: true
|
||
},
|
||
{
|
||
id: 2,
|
||
title: "跨平台电商应用",
|
||
author: "Uniapp团队",
|
||
publishTime: Date.now() - 172800000, // 2天前
|
||
desc: "使用Uniapp开发的跨平台电商应用,支持iOS、Android、Web和小程序。包含商品展示、购物车、订单管理、支付集成等功能。",
|
||
zan: 28,
|
||
collect: true,
|
||
comments: 8,
|
||
fresh: false
|
||
},
|
||
{
|
||
id: 3,
|
||
title: "智能家居控制中心",
|
||
author: "IoT开发者",
|
||
publishTime: Date.now() - 259200000, // 3天前
|
||
desc: "基于Android的智能家居控制中心应用,支持多种智能设备连接和控制。提供设备管理、场景模式、定时任务、远程控制等功能。",
|
||
zan: 56,
|
||
collect: false,
|
||
comments: 24,
|
||
fresh: false
|
||
},
|
||
{
|
||
id: 4,
|
||
title: "在线教育平台",
|
||
author: "教育科技",
|
||
publishTime: Date.now() - 345600000, // 4天前
|
||
desc: "完整的在线教育平台,包含课程管理、视频播放、在线测试、学习进度跟踪等功能。支持多种课程格式和互动学习方式。",
|
||
zan: 89,
|
||
collect: true,
|
||
comments: 36,
|
||
fresh: false
|
||
}
|
||
];
|
||
|
||
renderProjects(defaultProjects);
|
||
document.getElementById('loadingProjects').style.display = 'none';
|
||
}
|
||
|
||
// 加载更多项目
|
||
function loadMoreProjects() {
|
||
currentPage++;
|
||
loadProjects();
|
||
}
|
||
|
||
// 显示项目详情
|
||
async function showProjectDetail(projectId) {
|
||
document.getElementById('listPage').style.display = 'none';
|
||
document.getElementById('detailPage').style.display = 'block';
|
||
|
||
const detailContent = document.getElementById('detailContent');
|
||
detailContent.innerHTML = `
|
||
<div class="loading" id="loadingDetail">
|
||
<div class="loading-spinner"></div>
|
||
<div>正在加载项目详情...</div>
|
||
</div>
|
||
`;
|
||
|
||
try {
|
||
// 这里应该调用项目详情API,但为了简化,我们使用模拟数据
|
||
await new Promise(resolve => setTimeout(resolve, 500));
|
||
|
||
// 模拟项目详情数据
|
||
const projectDetails = {
|
||
1: {
|
||
title: "玩Android Material Design客户端",
|
||
author: "Material Design",
|
||
publishTime: Date.now() - 86400000,
|
||
content: `
|
||
<h1>玩Android Material Design客户端</h1>
|
||
<p>这是一个基于Uniapp框架开发的玩Android客户端,完全遵循Material Design 3设计规范。</p>
|
||
|
||
<h2>项目特点</h2>
|
||
<ul>
|
||
<li><strong>Material Design 3规范</strong>:完全遵循Google最新的Material Design 3设计语言</li>
|
||
<li><strong>跨平台支持</strong>:支持iOS、Android、Web和小程序</li>
|
||
<li><strong>完整组件库</strong>:提供卡片、按钮、导航栏、对话框等完整组件</li>
|
||
<li><strong>响应式设计</strong>:完美适配手机、平板和桌面设备</li>
|
||
</ul>
|
||
|
||
<h2>技术栈</h2>
|
||
<pre><code>前端框架:Uniapp + Vue 3
|
||
UI组件:自定义Material Design组件
|
||
状态管理:Pinia
|
||
网络请求:Axios + 拦截器
|
||
构建工具:Vite
|
||
API集成:玩Android开放API</code></pre>
|
||
|
||
<h2>功能模块</h2>
|
||
<ol>
|
||
<li><strong>首页</strong>:Banner轮播、文章列表、搜索功能</li>
|
||
<li><strong>项目</strong>:项目分类、项目列表、项目详情</li>
|
||
<li><strong>公众号</strong>:公众号列表、文章浏览</li>
|
||
<li><strong>体系</strong>:知识体系、分类导航</li>
|
||
<li><strong>我的</strong>:用户中心、收藏管理</li>
|
||
</ol>
|
||
|
||
<h2>API集成</h2>
|
||
<p>项目集成了玩Android开放API的所有接口:</p>
|
||
<ul>
|
||
<li>文章相关API</li>
|
||
<li>项目相关API</li>
|
||
<li>公众号相关API</li>
|
||
<li>用户系统API</li>
|
||
</ul>
|
||
|
||
<h2>项目截图</h2>
|
||
<p>项目提供了完整的Material Design界面设计,包括:</p>
|
||
<ul>
|
||
<li>紫色主色系统 (#6200EE)</li>
|
||
<li>卡片阴影和圆角设计</li>
|
||
<li>平滑过渡动画</li>
|
||
<li>底部导航栏</li>
|
||
<li>响应式布局</li>
|
||
</ul>
|
||
`
|
||
},
|
||
2: {
|
||
title: "跨平台电商应用",
|
||
author: "Uniapp团队",
|
||
publishTime: Date.now() - 172800000,
|
||
content: `
|
||
<h1>跨平台电商应用</h1>
|
||
<p>使用Uniapp开发的跨平台电商应用,支持iOS、Android、Web和小程序。</p>
|
||
|
||
<h2>核心功能</h2>
|
||
<ul>
|
||
<li><strong>商品展示</strong>:商品列表、商品详情、分类浏览</li>
|
||
<li><strong>购物车</strong>:添加商品、修改数量、删除商品</li>
|
||
<li><strong>订单管理</strong>:下单、支付、订单跟踪、评价</li>
|
||
<li><strong>用户系统</strong>:登录注册、个人信息、地址管理</li>
|
||
</ul>
|
||
|
||
<h2>技术实现</h2>
|
||
<pre><code>前端:Uniapp + Vue 3 + Pinia
|
||
UI框架:uView UI
|
||
支付集成:微信支付、支付宝
|
||
地图服务:高德地图、腾讯地图
|
||
推送服务:个推、极光推送</code></pre>
|
||
`
|
||
},
|
||
3: {
|
||
title: "智能家居控制中心",
|
||
author: "IoT开发者",
|
||
publishTime: Date.now() - 259200000,
|
||
content: `
|
||
<h1>智能家居控制中心</h1>
|
||
<p>基于Android的智能家居控制中心应用,支持多种智能设备连接和控制。</p>
|
||
|
||
<h2>支持设备</h2>
|
||
<ul>
|
||
<li>智能灯光控制</li>
|
||
<li>智能插座开关</li>
|
||
<li>温湿度传感器</li>
|
||
<li>安防摄像头</li>
|
||
<li>智能门锁</li>
|
||
</ul>
|
||
|
||
<h2>控制功能</h2>
|
||
<pre><code>设备管理:添加、删除、分组
|
||
场景模式:回家模式、离家模式、睡眠模式
|
||
定时任务:定时开关、循环任务
|
||
远程控制:通过互联网远程控制设备
|
||
语音控制:集成语音助手</code></pre>
|
||
`
|
||
},
|
||
4: {
|
||
title: "在线教育平台",
|
||
author: "教育科技",
|
||
publishTime: Date.now() - 345600000,
|
||
content: `
|
||
<h1>在线教育平台</h1>
|
||
<p>完整的在线教育平台,包含课程管理、视频播放、在线测试、学习进度跟踪等功能。</p>
|
||
|
||
<h2>学习功能</h2>
|
||
<ul>
|
||
<li><strong>课程管理</strong>:课程分类、课程详情、章节管理</li>
|
||
<li><strong>视频学习</strong>:视频播放、倍速控制、字幕支持</li>
|
||
<li><strong>在线测试</strong>:选择题、判断题、简答题</li>
|
||
<li><strong>学习跟踪</strong>:学习进度、成绩统计、证书颁发</li>
|
||
</ul>
|
||
|
||
<h2>教学功能</h2>
|
||
<pre><code>教师端:课程创建、作业布置、成绩管理
|
||
学生端:课程学习、作业提交、成绩查询
|
||
管理员:用户管理、课程审核、数据统计
|
||
互动功能:讨论区、直播课堂、在线答疑</code></pre>
|
||
`
|
||
}
|
||
};
|
||
|
||
const project = projectDetails[projectId] || {
|
||
title: "项目详情",
|
||
author: "未知作者",
|
||
publishTime: Date.now(),
|
||
content: "<p>项目内容加载失败</p>"
|
||
};
|
||
|
||
const timeAgo = getTimeAgo(new Date(project.publishTime));
|
||
|
||
detailContent.innerHTML = `
|
||
<div class="detail-title-main">${project.title}</div>
|
||
<div class="detail-meta">
|
||
<div class="detail-author">👤 ${project.author}</div>
|
||
<div class="detail-time">🕒 ${timeAgo}</div>
|
||
</div>
|
||
<div class="detail-body">${project.content}</div>
|
||
<div class="detail-footer">
|
||
<div class="detail-actions">
|
||
<button class="action-btn" onclick="likeProject(${projectId})">👍 点赞</button>
|
||
<button class="action-btn" onclick="collectProject(${projectId})">⭐ 收藏</button>
|
||
<button class="action-btn" onclick="viewSourceCode(${projectId})">📁 查看源码</button>
|
||
</div>
|
||
</div>
|
||
`;
|
||
} catch (error) {
|
||
console.error('加载项目详情失败:', error);
|
||
detailContent.innerHTML = `
|
||
<div class="detail-title-main">加载失败</div>
|
||
<div class="detail-body">
|
||
<p>抱歉,加载项目详情时出现错误。</p>
|
||
<button class="action-btn" onclick="closeDetail()">返回</button>
|
||
</div>
|
||
`;
|
||
}
|
||
}
|
||
|
||
// 关闭项目详情
|
||
function closeDetail() {
|
||
document.getElementById('listPage').style.display = 'block';
|
||
document.getElementById('detailPage').style.display = 'none';
|
||
}
|
||
|
||
// 处理搜索按键
|
||
function handleSearchKeypress(event) {
|
||
if (event.key === 'Enter') {
|
||
const query = document.getElementById('searchInput').value.trim();
|
||
if (query) {
|
||
alert(`搜索项目: ${query}\n\n搜索功能开发中`);
|
||
// 这里应该调用项目搜索API
|
||
}
|
||
}
|
||
}
|
||
|
||
// 点赞项目
|
||
function likeProject(projectId) {
|
||
alert(`已点赞项目 ${projectId}!`);
|
||
}
|
||
|
||
// 收藏项目
|
||
function collectProject(projectId) {
|
||
alert(`已收藏项目 ${projectId}!`);
|
||
}
|
||
|
||
// 查看源码
|
||
function viewSourceCode(projectId) {
|
||
alert(`查看项目 ${projectId} 源码\n\n源码查看功能开发中`);
|
||
}
|
||
|
||
// 显示菜单
|
||
function showMenu() {
|
||
alert('菜单功能开发中...\n\n包括设置、关于、反馈等功能');
|
||
}
|
||
|
||
// 切换Tab - 修复版:已完成的页面直接跳转,未完成的显示提示
|
||
function switchTab(tab) {
|
||
// 更新选中状态
|
||
document.querySelectorAll('.tab-item').forEach(item => {
|
||
item.classList.remove('active');
|
||
});
|
||
|
||
event.target.closest('.tab-item').classList.add('active');
|
||
|
||
// 根据tab进行跳转或提示
|
||
switch(tab) {
|
||
case 'home':
|
||
// 首页已开发完成,直接跳转
|
||
window.location.href = '/';
|
||
break;
|
||
case 'project':
|
||
// 项目页面已开发完成,当前页面
|
||
// 不需要跳转
|
||
break;
|
||
case 'wechat':
|
||
// 公众号页面未开发
|
||
window.location.href = '/wechat.html';
|
||
break;
|
||
case 'system':
|
||
// 体系页面未开发
|
||
alert('体系页面开发中...');
|
||
break;
|
||
case 'profile':
|
||
// 我的页面未开发
|
||
window.location.href = '/profile.html';
|
||
break;
|
||
}
|
||
}
|
||
|
||
// 获取相对时间
|
||
function getTimeAgo(date) {
|
||
const now = new Date();
|
||
const diff = now - date;
|
||
|
||
const minutes = Math.floor(diff / 60000);
|
||
const hours = Math.floor(diff / 3600000);
|
||
const days = Math.floor(diff / 86400000);
|
||
|
||
if (minutes < 1) return '刚刚';
|
||
if (minutes < 60) return `${minutes}分钟前`;
|
||
if (hours < 24) return `${hours}小时前`;
|
||
if (days < 30) return `${days}天前`;
|
||
|
||
return date.toLocaleDateString();
|
||
}
|
||
</script>
|
||
</body>
|
||
</html>
|