# BC-M-CHANNEL-001-JZ · DEV-010桔子 · 用户频道动态渲染引擎 · 环节0~1(SPA路由+模块动态加载) --- ## 一、任务定位 ### 执行环境 | 项目 | 值 | **操作系统** | macOS | | --- | --- | --- | --- | | **编辑器** | nano | **技术栈** | 纯HTML + CSS + JavaScript(无框架) | | **模块目录** | `modules/m-channel/` | **本地路径** | `/Users/chenshujun/Desktop/guanghulab/modules/m-channel/` | | **Git** | juzi0412 · push已连通 | | | --- ## 二、环节0 · SPA路由框架搭建 **Step 0-1 · 创建目录** ```bash cd /Users/chenshujun/Desktop/guanghulab mkdir -p modules/m-channel/pages mkdir -p modules/m-channel/mock-modules cd modules/m-channel ``` **Step 0-2 · 创建SPA主页 index.html** ```bash nano index.html ``` ```html 光湖频道引擎
``` **Step 0-3 · 创建路由器 channel-router.js** ```bash nano channel-router.js ``` ```jsx /* 光湖频道路由器 v1.0 */ var ChannelRouter = { routes: {}, currentRoute: null, register: function(path, handler) { this.routes[path] = handler; }, navigate: function(path) { window.location.hash = '#' + path; }, getRoute: function() { return (window.location.hash || '#/home').replace('#', ''); }, render: function() { var route = this.getRoute(); var view = document.getElementById('route-view'); var display = document.getElementById('current-route'); var handler = this.routes[route]; // 精确匹配失败 → 前缀匹配(支持 /module/m06) if (!handler) { for (var p in this.routes) { if (route.indexOf(p + '/') === 0) { handler = this.routes[p]; break; } } } if (handler) { this.currentRoute = route; handler(view); display.textContent = '路由: ' + route; // 导航高亮 var links = document.querySelectorAll('.nav-link'); for (var i = 0; i < links.length; i++) { var r = links[i].getAttribute('data-route'); links[i].classList.toggle('active', route.indexOf(r) !== -1); } } else { view.innerHTML = '

404

页面不存在

回首页
'; } }, start: function() { var self = this; window.addEventListener('hashchange', function() { self.render(); }); self.render(); } }; ``` **Step 0-4 · 创建模块加载器 module-loader.js** ```bash nano module-loader.js ``` ```jsx /* 光湖模块加载器 v1.0 · 用fetch动态加载HTML文件 */ var ModuleLoader = { registry: { 'm06': { name: '工单管理', icon: '📋', path: 'mock-modules/m06-ticket.html' }, 'm08': { name: '数据统计', icon: '📊', path: 'mock-modules/m08-analytics.html' }, 'm11': { name: '风格组件库', icon: '🎨', path: 'mock-modules/m11-theme.html' } }, cache: {}, load: function(moduleId, container) { var self = this; var m = this.registry[moduleId]; if (!m) { container.innerHTML = '

模块不存在: ' + moduleId + '

'; return; } if (this.cache[moduleId]) { container.innerHTML = this.cache[moduleId]; return; } container.innerHTML = '

加载 ' + m.name + '...

'; fetch(m.path) .then(function(r) { if (!r.ok) throw new Error(r.status); return r.text(); }) .then(function(html) { self.cache[moduleId] = html; container.innerHTML = html; }) .catch(function(e) { container.innerHTML = '

加载失败

' + e.message + '

'; }); }, getAll: function() { return this.registry; } }; ``` **Step 0-5 · 创建应用入口 app.js** ```bash nano app.js ``` ```jsx /* 光湖频道引擎 · App v1.0 */ // 首页 ChannelRouter.register('/home', function(view) { view.innerHTML = '
' + '

🌊 欢迎来到光湖

' + '

语言驱动操作系统 · 你说话,系统做事

' + '' + '
' + '
10+功能模块
' + '
12开发者
' + '
v1.0系统版本
' + '
'; }); // 频道页(从注册表动态生成卡片) ChannelRouter.register('/channel', function(view) { var mods = ModuleLoader.getAll(); var cards = ''; for (var id in mods) { var m = mods[id]; cards += '
'; cards += '' + m.icon + ''; cards += '' + m.name + ''; cards += '' + id.toUpperCase() + '
'; } cards += '
更多模块陆续上线
'; view.innerHTML = '

📺 我的频道

点击模块卡片 → 动态加载

' + cards + '
'; }); // 模块动态加载路由 ChannelRouter.register('/module', function(view) { var parts = ChannelRouter.getRoute().split('/'); var moduleId = parts[2] || ''; if (!moduleId) { ChannelRouter.navigate('/channel'); return; } ModuleLoader.load(moduleId, view); }); // 关于页 ChannelRouter.register('/about', function(view) { view.innerHTML = '
' + '

关于光湖

' + '

语言驱动的操作系统平台。用户不点菜单,只跟人格体说话。

' + '

人格体理解意图 → 系统动态渲染模块 → 你感觉整个网站只有你一个人。

' + '
'; }); // 启动 ChannelRouter.start(); console.log('🌊 光湖频道引擎启动'); ``` **Step 0-6 · 创建样式表 channel-style.css** 这个文件较长,你可以分段粘贴: ```bash nano channel-style.css ``` ```css * { margin:0; padding:0; box-sizing:border-box; } :root { --primary:#2563eb; --bg:#0f172a; --card:#1e293b; --text:#f1f5f9; --muted:#94a3b8; --border:#334155; --accent:#38bdf8; --r:12px; --t:0.3s ease; } body { font-family:-apple-system,sans-serif; background:var(--bg); color:var(--text); min-height:100vh; } #app { display:flex; flex-direction:column; min-height:100vh; } /* 导航 */ #main-nav { display:flex; align-items:center; justify-content:space-between; padding:0 24px; height:56px; background:var(--card); border-bottom:1px solid var(--border); position:sticky; top:0; z-index:100; } .nav-brand { font-size:1.2rem; font-weight:700; color:var(--accent); } .nav-links { display:flex; gap:6px; } .nav-link { color:var(--muted); text-decoration:none; padding:8px 14px; border-radius:8px; transition:var(--t); font-size:.9rem; } .nav-link:hover { color:var(--text); background:rgba(255,255,255,.05); } .nav-link.active { color:var(--accent); background:rgba(56,189,248,.1); } /* 内容区 */ #route-view { flex:1; padding:32px 24px; max-width:1100px; margin:0 auto; width:100%; } .page-box { animation:fadeIn .3s ease; } @keyframes fadeIn { from{opacity:0;transform:translateY(8px)} to{opacity:1;transform:translateY(0)} } /* 首页 */ .home { text-align:center; padding-top:80px; } .home h1 { font-size:2.4rem; margin-bottom:10px; } .sub { color:var(--muted); font-size:1.05rem; margin-bottom:28px; } .btn { padding:10px 28px; border:none; border-radius:var(--r); font-size:1rem; cursor:pointer; transition:var(--t); } .btn-primary { background:var(--primary); color:#fff; } .btn-primary:hover { background:#1d4ed8; transform:translateY(-2px); } .stats { display:flex; justify-content:center; gap:20px; margin-top:44px; } .stat { background:var(--card); border:1px solid var(--border); border-radius:var(--r); padding:20px 28px; display:flex; flex-direction:column; gap:4px; } .stat b { font-size:1.4rem; color:var(--accent); } .stat span { font-size:.8rem; color:var(--muted); } /* 频道模块网格 */ .ch-head { margin-bottom:24px; } .ch-head p { color:var(--muted); } .mod-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(170px,1fr)); gap:14px; } .mod-card { background:var(--card); border:1px solid var(--border); border-radius:var(--r); padding:22px; display:flex; flex-direction:column; align-items:center; gap:6px; cursor:pointer; transition:var(--t); } .mod-card:hover { border-color:var(--accent); transform:translateY(-4px); box-shadow:0 8px 20px rgba(0,0,0,.3); } .mod-card.dim { opacity:.45; cursor:default; } .mod-icon { font-size:1.8rem; } .mod-name { font-weight:600; font-size:.9rem; } .mod-id { font-size:.7rem; color:var(--muted); } /* 加载状态 */ .loading { display:flex; flex-direction:column; align-items:center; padding:80px 0; color:var(--muted); } .spinner { width:36px; height:36px; border:3px solid var(--border); border-top-color:var(--accent); border-radius:50%; animation:spin .8s linear infinite; margin-bottom:14px; } @keyframes spin { to{transform:rotate(360deg)} } /* 已加载模块 */ .loaded-module { animation:fadeIn .3s ease; } .module-header { display:flex; align-items:center; gap:14px; margin-bottom:20px; padding-bottom:14px; border-bottom:1px solid var(--border); } .btn-back { background:var(--card); border:1px solid var(--border); color:var(--muted); padding:8px 14px; border-radius:8px; cursor:pointer; } .btn-back:hover { color:var(--text); border-color:var(--accent); } .ticket-list { display:flex; flex-direction:column; gap:10px; } .ticket-item { display:flex; align-items:center; gap:10px; background:var(--card); border:1px solid var(--border); border-radius:8px; padding:14px; } .ticket-title { flex:1; } .ticket-date { color:var(--muted); font-size:.8rem; } .stats-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(150px,1fr)); gap:14px; } .stat-box { background:var(--card); border:1px solid var(--border); border-radius:var(--r); padding:20px; text-align:center; } .stat-val { font-size:1.4rem; font-weight:700; color:var(--accent); display:block; } .stat-lbl { font-size:.75rem; color:var(--muted); } /* 底部 */ #status-bar { display:flex; justify-content:space-between; padding:8px 24px; background:var(--card); border-top:1px solid var(--border); font-size:.78rem; color:var(--muted); } /* 响应式 */ @media(max-width:768px) { .home h1{font-size:1.7rem} .stats{flex-direction:column;align-items:center} .mod-grid{grid-template-columns:repeat(2,1fr)} } @media(max-width:480px) { .mod-grid{grid-template-columns:1fr} .nav-link{padding:6px 8px;font-size:.8rem} } ``` **Step 0-7 · 创建模拟模块文件** ```bash nano mock-modules/m06-ticket.html ``` ```html

📋 工单管理 · M06

🟢前端登录页样式修复2026-03-08
🟡统计面板响应式适配2026-03-07
🔴组件库主题切换闪烁2026-03-06
``` ```bash nano mock-modules/m08-analytics.html ``` ```html

📊 数据统计 · M08

1,247总访问
89活跃用户
23今日工单
99.7%可用率
``` ```bash nano mock-modules/m11-theme.html ``` ```html

🎨 风格组件库 · M11

这是你亲手搭建的组件库!CSS变量系统 + 双主题 + 6类组件 + 响应式。

``` --- ## 三、测试验收 ⚠️ **重要**:`fetch()` 在本地文件协议(`file://`)下不工作。需要启动本地服务器: ```bash cd /Users/chenshujun/Desktop/guanghulab/modules/m-channel python3 -m http.server 8080 ``` 浏览器打开 `http://localhost:8080` ### 环节0验收清单 - [ ] 页面打开显示首页(「欢迎来到光湖」) - [ ] 点「我的频道」→ 显示模块卡片网格 → URL变成 `#/channel` - [ ] 点「关于」→ 内容切换 → URL变成 `#/about` - [ ] **全程页面不刷新**,只有内容区在变 - [ ] 导航栏当前页有高亮效果 - [ ] 页面切换时有淡入动画 ### 环节1验收清单 - [ ] 频道页显示3个模块卡片(M06/M08/M11)+ 1个「更多模块」占位 - [ ] 点「工单管理」卡片 → 加载动画 → 显示工单列表 - [ ] 点「数据统计」卡片 → 显示数据卡片 - [ ] 点「风格组件库」卡片 → 显示组件库预览 - [ ] 模块内点「← 返回」→ 回到频道页 - [ ] 再次点同一个模块 → **瞬间加载**(缓存生效) - [ ] 浏览器控制台无报错 --- ## 四、Git提交 全部验收通过后: ```bash cd /Users/chenshujun/Desktop/guanghulab git add modules/m-channel/ git commit -m "feat(m-channel): SPA路由框架+模块动态加载 v1.0" git push ``` --- ## 五、SYSLOG回执模板 全部完成后,拷贝以下模板发给知秋: ```xml BC-M-CHANNEL-001-JZ BC-M-CHANNEL-001-JZ DEV-010 YYYY-MM-DD SPA路由框架 - 待填 模块动态加载 - 待填 待填 待填 ``` --- ## 六、PGP成长微调 --- --- **桔子,十连胜后的第一个新模块。你之前搭的组件库是皮肤,这次搭的是骨骼。皮肤+骨骼 = 网站能站起来。加油,十一连胜走起。** 🍊