M23环节2接入M22真实公告数据+状态API完成
This commit is contained in:
parent
0ab3c09016
commit
8f16d63ad1
|
|
@ -0,0 +1,34 @@
|
|||
[
|
||||
{
|
||||
"id": 1,
|
||||
"title": "光湖实验室v1.0全面开发中",
|
||||
"content": "12位开发者并行推进,多模块同步建设。光湖系统正在从蓝图变为现实。",
|
||||
"date": "2026-03-14",
|
||||
"type": "update",
|
||||
"priority": "high"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"title": "M22主域公告栏已上线",
|
||||
"content": "公告栏支持多语言、无障碍访问、骨架屏加载、实时数据接入。由DEV-012 Awen独立完成。",
|
||||
"date": "2026-03-13",
|
||||
"type": "update",
|
||||
"priority": "normal"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"title": "模块进度总览",
|
||||
"content": "多个模块已上线,更多模块建设中。",
|
||||
"date": "2026-03-14",
|
||||
"type": "status",
|
||||
"priority": "normal"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"title": "欢迎新开发者",
|
||||
"content": "光湖实验室持续壮大,欢迎每一位共建者。",
|
||||
"date": "2026-03-14",
|
||||
"type": "welcome",
|
||||
"priority": "normal"
|
||||
}
|
||||
]
|
||||
232
homepage/app.js
232
homepage/app.js
|
|
@ -1,99 +1,88 @@
|
|||
/**
|
||||
* app.js - 光湖首页导航中心
|
||||
* M23 环节1 · 公告轮播 + 卡片交互 + 状态动态化
|
||||
* M23 环节2 · 接入M22真实公告数据 + 状态API
|
||||
*/
|
||||
|
||||
// 公告轮播数据(Mock数据,未来对接M22真实API)
|
||||
const announcements = [
|
||||
{
|
||||
id: 1,
|
||||
title: "光湖实验室v1.0开发中",
|
||||
content: "全团队并行推进,多模块同步建设",
|
||||
date: "2026-03-13",
|
||||
type: "update"
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: "模块进度总览",
|
||||
content: "4个模块在线 · 2个建设中",
|
||||
date: "2026-03-13",
|
||||
type: "status"
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: "欢迎新开发者",
|
||||
content: "零点原核频道持续壮大",
|
||||
date: "2026-03-13",
|
||||
type: "welcome"
|
||||
}
|
||||
];
|
||||
// === M22真实公告数据接入 ===
|
||||
let announcements = [];
|
||||
let dataSource = 'loading';
|
||||
|
||||
// 模块卡片数据
|
||||
async function loadAnnouncementsFromM22() {
|
||||
const carousel = document.getElementById('announcementCarousel');
|
||||
if (carousel) {
|
||||
carousel.innerHTML = '<div style="padding: 20px; text-align: center; color: #3b82f6;">正在连接M22公告数据...</div>';
|
||||
}
|
||||
|
||||
const result = await window.ModulesAPI.getAnnouncements();
|
||||
announcements = result.data;
|
||||
dataSource = result.source;
|
||||
|
||||
if (dataSource === 'M22-live') {
|
||||
console.log('📢 首页公告:来自M22真实数据(' + announcements.length + '条)');
|
||||
} else {
|
||||
console.log('📢 首页公告:使用降级数据(M22不可用)');
|
||||
}
|
||||
|
||||
if (window.HomepageApp) {
|
||||
window.HomepageApp.currentAnnouncementIndex = 0;
|
||||
window.HomepageApp.renderCarousel();
|
||||
}
|
||||
}
|
||||
|
||||
// === 模块卡片数据 ===
|
||||
const moduleCards = [
|
||||
{
|
||||
id: "M09",
|
||||
name: "消息通知中心",
|
||||
icon: "🔔",
|
||||
status: "online",
|
||||
path: "../notification-center/"
|
||||
},
|
||||
{
|
||||
id: "M22",
|
||||
name: "主域公告栏",
|
||||
icon: "📢",
|
||||
status: "online",
|
||||
path: "../announcement/"
|
||||
},
|
||||
{
|
||||
id: "M06",
|
||||
name: "工单管理",
|
||||
icon: "🎫",
|
||||
status: "online",
|
||||
path: "../ticket-system/"
|
||||
},
|
||||
{
|
||||
id: "M16",
|
||||
name: "码字工作台",
|
||||
icon: "✍️",
|
||||
status: "building",
|
||||
path: "../writing-workspace/"
|
||||
},
|
||||
{
|
||||
id: "M11",
|
||||
name: "风格组件库",
|
||||
icon: "🎨",
|
||||
status: "online",
|
||||
path: "../ui-components/"
|
||||
},
|
||||
{
|
||||
id: "M05",
|
||||
name: "用户中心",
|
||||
icon: "👤",
|
||||
status: "building",
|
||||
path: "../user-center/"
|
||||
}
|
||||
{ id: "M09", name: "消息通知中心", icon: "🔔", status: "online", path: "../notification-center/" },
|
||||
{ id: "M22", name: "主域公告栏", icon: "📢", status: "online", path: "../announcement/" },
|
||||
{ id: "M06", name: "工单管理", icon: "🎫", status: "online", path: "../ticket-system/" },
|
||||
{ id: "M16", name: "码字工作台", icon: "✍️", status: "building", path: "../writing-workspace/" },
|
||||
{ id: "M11", name: "风格组件库", icon: "🎨", status: "online", path: "../ui-components/" },
|
||||
{ id: "M05", name: "用户中心", icon: "👤", status: "building", path: "../user-center/" }
|
||||
];
|
||||
|
||||
// 首页应用对象
|
||||
// === 工具函数 ===
|
||||
function getTypeLabel(type) {
|
||||
const labels = { update: '📢 更新', status: '📊 状态', welcome: '👋 欢迎', alert: '🚨 告警' };
|
||||
return labels[type] || '📌 公告';
|
||||
}
|
||||
|
||||
// === 模块状态更新 ===
|
||||
async function updateModuleStatusFromAPI() {
|
||||
const statusResult = await window.ModulesAPI.getAllModuleStatus();
|
||||
if (statusResult.source === 'fallback') return;
|
||||
|
||||
document.querySelectorAll('.card').forEach(card => {
|
||||
const moduleId = card.dataset.moduleId;
|
||||
if (moduleId && statusResult.data[moduleId]) {
|
||||
const status = statusResult.data[moduleId].status;
|
||||
const statusSpan = card.querySelector('.card-status');
|
||||
if (statusSpan) {
|
||||
statusSpan.className = 'card-status ' + status;
|
||||
statusSpan.textContent = status === 'online' ? '在线' : status === 'building' ? '建设中' : '离线';
|
||||
}
|
||||
}
|
||||
});
|
||||
console.log('[M23] ✅ 模块状态已从注册表更新');
|
||||
}
|
||||
|
||||
// === 首页应用对象 ===
|
||||
window.HomepageApp = {
|
||||
currentAnnouncementIndex: 0,
|
||||
carouselInterval: null,
|
||||
|
||||
init() {
|
||||
async init() {
|
||||
this.renderCards();
|
||||
this.renderCarousel();
|
||||
await loadAnnouncementsFromM22();
|
||||
await updateModuleStatusFromAPI();
|
||||
this.startCarousel();
|
||||
this.bindEvents();
|
||||
this.updateStatusBar();
|
||||
console.log('✅ 首页初始化完成 · 15连胜版');
|
||||
console.log('✅ 首页初始化完成 · 数据源:' + dataSource);
|
||||
},
|
||||
|
||||
// 渲染卡片
|
||||
renderCards() {
|
||||
const grid = document.getElementById('moduleGrid');
|
||||
if (!grid) return;
|
||||
|
||||
const cardsHTML = moduleCards.map(card => `
|
||||
grid.innerHTML = moduleCards.map(card => `
|
||||
<div class="card" data-module-id="${card.id}" data-module-path="${card.path}">
|
||||
<div class="card-header">
|
||||
<div class="card-icon">${card.icon}</div>
|
||||
|
|
@ -103,101 +92,84 @@ window.HomepageApp = {
|
|||
<span class="card-link">进入模块 →</span>
|
||||
</div>
|
||||
`).join('');
|
||||
|
||||
grid.innerHTML = cardsHTML;
|
||||
},
|
||||
|
||||
// 渲染轮播
|
||||
// 轮播渲染(带高优先级橙色边框)
|
||||
renderCarousel() {
|
||||
const carousel = document.getElementById('announcementCarousel');
|
||||
if (!carousel) return;
|
||||
|
||||
const announcement = announcements[this.currentAnnouncementIndex];
|
||||
if (!carousel || announcements.length === 0) {
|
||||
console.log('❌ 没有公告或找不到轮播容器');
|
||||
return;
|
||||
}
|
||||
|
||||
const item = announcements[this.currentAnnouncementIndex];
|
||||
const priorityStyle = item.priority === 'high' ? 'border-left: 3px solid #ff9800; padding-left: 15px;' : '';
|
||||
|
||||
carousel.innerHTML = `
|
||||
<div class="carousel-item">
|
||||
<div class="carousel-title">📢 ${announcement.title}</div>
|
||||
<div class="carousel-content">${announcement.content}</div>
|
||||
<div class="carousel-date">${announcement.date}</div>
|
||||
<div style="padding: 20px; text-align: center; ${priorityStyle}">
|
||||
<span style="display: inline-block; padding: 4px 12px; border-radius: 20px; background: rgba(59,130,246,0.2); color: #3b82f6; margin-bottom: 10px; font-size: 14px;">
|
||||
${getTypeLabel(item.type)}
|
||||
</span>
|
||||
<h3 style="font-size: 24px; margin-bottom: 10px; color: white;">${item.title}</h3>
|
||||
<p style="color: #a0a8b8; margin-bottom: 10px; line-height: 1.6;">${item.content}</p>
|
||||
<small style="color: #666; display: block; margin-bottom: 10px;">${item.date}</small>
|
||||
<div style="font-size: 12px; color: ${dataSource === 'M22-live' ? '#3b82f6' : '#888'};">
|
||||
${dataSource === 'M22-live' ? '🔗 M22 实时数据' : '📋 本地数据'}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
console.log('✅ 轮播已渲染,当前索引:', this.currentAnnouncementIndex);
|
||||
},
|
||||
|
||||
// 启动轮播(自动4秒切换)
|
||||
startCarousel() {
|
||||
if (this.carouselInterval) clearInterval(this.carouselInterval);
|
||||
this.carouselInterval = setInterval(() => {
|
||||
this.nextAnnouncement();
|
||||
}, 4000);
|
||||
this.carouselInterval = setInterval(() => this.nextAnnouncement(), 4000);
|
||||
console.log('🔄 轮播已启动,4秒自动切换');
|
||||
},
|
||||
|
||||
// 下一条公告
|
||||
nextAnnouncement() {
|
||||
if (announcements.length === 0) return;
|
||||
this.currentAnnouncementIndex = (this.currentAnnouncementIndex + 1) % announcements.length;
|
||||
this.renderCarousel();
|
||||
},
|
||||
|
||||
// 上一条公告
|
||||
prevAnnouncement() {
|
||||
if (announcements.length === 0) return;
|
||||
this.currentAnnouncementIndex = (this.currentAnnouncementIndex - 1 + announcements.length) % announcements.length;
|
||||
this.renderCarousel();
|
||||
},
|
||||
|
||||
// 模块跳转
|
||||
navigateTo(moduleId) {
|
||||
const module = moduleCards.find(m => m.id === moduleId);
|
||||
if (module) {
|
||||
console.log(`🧭 跳转到模块: ${module.name} | 路径: ${module.path}`);
|
||||
} else {
|
||||
console.log(`⚠️ 未找到模块: ${moduleId}`);
|
||||
}
|
||||
},
|
||||
|
||||
// 绑定事件
|
||||
bindEvents() {
|
||||
// 卡片点击事件
|
||||
document.querySelectorAll('.card').forEach(card => {
|
||||
card.addEventListener('click', (e) => {
|
||||
card.addEventListener('click', () => {
|
||||
const moduleId = card.dataset.moduleId;
|
||||
const modulePath = card.dataset.modulePath;
|
||||
console.log(`🖱️ 点击卡片: ${moduleId} | 路径: ${modulePath}`);
|
||||
this.navigateTo(moduleId);
|
||||
// 未来这里会实现实际跳转:window.location.href = modulePath;
|
||||
});
|
||||
});
|
||||
|
||||
// 轮播箭头点击
|
||||
document.getElementById('carouselPrev')?.addEventListener('click', () => {
|
||||
console.log('◀️ 点击左箭头');
|
||||
this.prevAnnouncement();
|
||||
});
|
||||
|
||||
document.getElementById('carouselNext')?.addEventListener('click', () => {
|
||||
console.log('▶️ 点击右箭头');
|
||||
this.nextAnnouncement();
|
||||
});
|
||||
|
||||
// 键盘事件
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'ArrowLeft') {
|
||||
console.log('⌨️ 键盘左箭头');
|
||||
this.prevAnnouncement();
|
||||
} else if (e.key === 'ArrowRight') {
|
||||
}
|
||||
if (e.key === 'ArrowRight') {
|
||||
console.log('⌨️ 键盘右箭头');
|
||||
this.nextAnnouncement();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 更新状态栏
|
||||
updateStatusBar() {
|
||||
const onlineCount = moduleCards.filter(c => c.status === 'online').length;
|
||||
const totalCount = moduleCards.length;
|
||||
console.log(`📊 系统状态: ${onlineCount}/${totalCount} 模块在线`);
|
||||
}
|
||||
};
|
||||
|
||||
// 页面加载时自动初始化
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
window.HomepageApp.init();
|
||||
});
|
||||
// 启动
|
||||
document.addEventListener('DOMContentLoaded', () => window.HomepageApp.init());
|
||||
|
||||
// 确保函数全局可用(配合 HTML onclick)
|
||||
window.prevAnnouncement = function() {
|
||||
window.HomepageApp.prevAnnouncement();
|
||||
};
|
||||
|
||||
window.nextAnnouncement = function() {
|
||||
window.HomepageApp.nextAnnouncement();
|
||||
};
|
||||
|
|
@ -18,4 +18,17 @@
|
|||
- 建设中模块:2个
|
||||
|
||||
### 备注
|
||||
✅ 环节0 验收通过,准备进入环节1
|
||||
✅ 环节0 验收通过,准备进入环节1
|
||||
## 环节1 · 公告轮播 + 卡片交互 + 状态动态化
|
||||
- 完成时间:2026-03-13
|
||||
- 开发者:DEV-012 Awen
|
||||
|
||||
### 完成内容
|
||||
- [x] 公告轮播区:自动4秒切换 + 左右箭头手动切换
|
||||
- [x] 卡片悬停:放大 + 阴影效果(很明显很好很棒)
|
||||
- [x] 状态动态化:online脉冲、building闪烁
|
||||
- [x] 键盘左右箭头支持
|
||||
- [x] 点击卡片控制台输出路径
|
||||
|
||||
### 当前状态
|
||||
✅ 环节1 验收通过,准备进入环节2
|
||||
|
|
@ -14,14 +14,16 @@
|
|||
<p class="hero-description">探索未来之域 · 零点原核频道</p>
|
||||
<a href="#" class="hero-btn">进入系统</a>
|
||||
</header>
|
||||
<!-- 公告轮播区(新增) -->
|
||||
|
||||
<!-- 公告轮播区 -->
|
||||
<div class="carousel-container">
|
||||
<div class="carousel" id="announcementCarousel">
|
||||
<!-- 轮播内容由 JS 动态生成 -->
|
||||
</div>
|
||||
<button class="carousel-arrow left" id="carouselPrev">←</button>
|
||||
<button class="carousel-arrow right" id="carouselNext">→</button>
|
||||
<button class="carousel-arrow left" id="carouselPrev" onclick="window.HomepageApp.prevAnnouncement()">←</button>
|
||||
<button class="carousel-arrow right" id="carouselNext" onclick="window.HomepageApp.nextAnnouncement()">→</button>
|
||||
</div>
|
||||
|
||||
<!-- 模块导航网格 -->
|
||||
<section class="modules">
|
||||
<h2 class="section-title">核心模块</h2>
|
||||
|
|
@ -42,7 +44,7 @@
|
|||
<p>版本 HoloLake Era · M23 首页中心</p>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<script src="modules-api.js"></script>
|
||||
<script src="app.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
{
|
||||
"M01": {
|
||||
"status": "building",
|
||||
"name": "用户登录",
|
||||
"lastUpdate": "2026-03-13"
|
||||
},
|
||||
"M05": {
|
||||
"status": "building",
|
||||
"name": "用户中心",
|
||||
"lastUpdate": "2026-03-13"
|
||||
},
|
||||
"M06": {
|
||||
"status": "online",
|
||||
"name": "工单管理",
|
||||
"lastUpdate": "2026-03-10"
|
||||
},
|
||||
"M08": {
|
||||
"status": "online",
|
||||
"name": "数据统计",
|
||||
"lastUpdate": "2026-03-10"
|
||||
},
|
||||
"M09": {
|
||||
"status": "online",
|
||||
"name": "消息通知",
|
||||
"lastUpdate": "2026-03-11"
|
||||
},
|
||||
"M11": {
|
||||
"status": "online",
|
||||
"name": "组件库",
|
||||
"lastUpdate": "2026-03-10"
|
||||
},
|
||||
"M12": {
|
||||
"status": "online",
|
||||
"name": "状态看板",
|
||||
"lastUpdate": "2026-03-06"
|
||||
},
|
||||
"M16": {
|
||||
"status": "building",
|
||||
"name": "码字工作台",
|
||||
"lastUpdate": "2026-03-13"
|
||||
},
|
||||
"M22": {
|
||||
"status": "online",
|
||||
"name": "公告栏",
|
||||
"lastUpdate": "2026-03-13"
|
||||
},
|
||||
"M23": {
|
||||
"status": "building",
|
||||
"name": "光湖首页",
|
||||
"lastUpdate": "2026-03-14"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
/**
|
||||
* modules-api.js - M23 光湖首页 · 跨模块数据桥
|
||||
* 版本:v1.0
|
||||
* 开发者:DEV-012 Awen
|
||||
* 功能:从M22读取公告数据 + 模块状态API + 错误降级
|
||||
*/
|
||||
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
// ===== Mock数据(降级兜底·当API不可用时使用) =====
|
||||
const FALLBACK_ANNOUNCEMENTS = [
|
||||
{
|
||||
"id": 1,
|
||||
"title": "光湖实验室v1.0全面开发中",
|
||||
"content": "12位开发者并行推进,多模块同步建设。光湖系统正在从蓝图变为现实。",
|
||||
"date": "2026-03-14",
|
||||
"type": "update",
|
||||
"priority": "high"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"title": "M22主域公告栏已上线",
|
||||
"content": "公告栏支持多语言、无障碍访问、骨架屏加载、实时数据接入。由DEV-012 Awen独立完成。",
|
||||
"date": "2026-03-13",
|
||||
"type": "update",
|
||||
"priority": "normal"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"title": "模块进度总览",
|
||||
"content": "多个模块已上线,更多模块建设中。",
|
||||
"date": "2026-03-14",
|
||||
"type": "status",
|
||||
"priority": "normal"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"title": "欢迎新开发者",
|
||||
"content": "光湖实验室持续壮大,欢迎每一位共建者。",
|
||||
"date": "2026-03-14",
|
||||
"type": "welcome",
|
||||
"priority": "normal"
|
||||
}
|
||||
];
|
||||
|
||||
const FALLBACK_STATUS = {
|
||||
status: "building",
|
||||
name: "未知模块",
|
||||
lastUpdate: new Date().toISOString().split('T')[0]
|
||||
};
|
||||
|
||||
// ===== 公告数据API =====
|
||||
async function getAnnouncements() {
|
||||
try {
|
||||
// 优先从M22共享数据文件读取
|
||||
const response = await fetch('/bulletin-board/shared-announcements.json');
|
||||
if (!response.ok) throw new Error('M22 data not available: ' + response.status);
|
||||
const data = await response.json();
|
||||
console.log('[ModulesAPI] M22公告数据加载成功,共' + data.length + '条');
|
||||
return { source: 'M22-live', data: data };
|
||||
} catch (err) {
|
||||
console.warn('[ModulesAPI] M22数据不可用,使用降级数据:', err.message);
|
||||
return { source: 'fallback', data: FALLBACK_ANNOUNCEMENTS };
|
||||
}
|
||||
}
|
||||
|
||||
// ===== 模块状态API =====
|
||||
async function getModuleStatus(moduleId) {
|
||||
try {
|
||||
const response = await fetch('./module-status.json');
|
||||
if (!response.ok) throw new Error('Status data not available');
|
||||
const allStatus = await response.json();
|
||||
if (allStatus[moduleId]) {
|
||||
return { source: 'local-registry', ...allStatus[moduleId] };
|
||||
}
|
||||
return { source: 'fallback', ...FALLBACK_STATUS };
|
||||
} catch (err) {
|
||||
console.warn('[ModulesAPI] 状态数据不可用:', err.message);
|
||||
return { source: 'fallback', ...FALLBACK_STATUS };
|
||||
}
|
||||
}
|
||||
|
||||
// ===== 批量获取所有模块状态 =====
|
||||
async function getAllModuleStatus() {
|
||||
try {
|
||||
const response = await fetch('./module-status.json');
|
||||
if (!response.ok) throw new Error('Status data not available');
|
||||
const data = await response.json();
|
||||
console.log('[ModulesAPI] 模块状态加载成功, 共' + Object.keys(data).length + '个模块');
|
||||
return { source: 'local-registry', data: data };
|
||||
} catch (err) {
|
||||
console.warn('[ModulesAPI] 状态数据不可用, 使用降级');
|
||||
return { source: 'fallback', data: {} };
|
||||
}
|
||||
}
|
||||
|
||||
// ===== API可用性检测 =====
|
||||
async function isAPIAvailable() {
|
||||
try {
|
||||
const response = await fetch('../bulletin-board/shared-announcements.json', { method: 'HEAD' });
|
||||
return response.ok;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// ===== 导出到全局 =====
|
||||
window.ModulesAPI = {
|
||||
getAnnouncements: getAnnouncements,
|
||||
getModuleStatus: getModuleStatus,
|
||||
getAllModuleStatus: getAllModuleStatus,
|
||||
isAPIAvailable: isAPIAvailable
|
||||
};
|
||||
|
||||
console.log('[ModulesAPI] 跨模块数据桥已初始化');
|
||||
})();
|
||||
|
|
@ -434,4 +434,11 @@ body {
|
|||
opacity: 0.5;
|
||||
text-shadow: 0 0 15px rgba(245, 158, 11, 0.8);
|
||||
}
|
||||
}
|
||||
/* ===== 强制高优先级样式 ===== */
|
||||
.high-priority {
|
||||
border-left: 3px solid #ff9800 !important;
|
||||
}
|
||||
.high-priority h3 {
|
||||
color: #ffb74d !important;
|
||||
}
|
||||
Loading…
Reference in New Issue