a
This commit is contained in:
@@ -0,0 +1,741 @@
|
||||
<!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>
|
||||
Reference in New Issue
Block a user