# Nanocode Portal — 设计文档 ## 项目概述 在 `/home/ubuntu/nanocode/www` 下实现一个纯前端 SPA 导航门户,作为 nginx 80 端口的首页,聚合所有个人项目的入口链接。 --- ## 技术方案 | 项 | 决策 | |---|---| | 架构 | 纯前端 SPA,单 HTML 文件 + 内嵌 CSS/JS | | 数据存储 | `localStorage`(无后端) | | 登录凭据 | 硬编码 `admin` / `abcd1234`,localStorage 标记登录态 | | 密码修改 | 老密码验证通过后,更新硬编码逻辑(localStorage 覆盖) | | 图标生成 | 根据链接名称的首字母/哈希生成固定颜色 + 大写字母 | | 布局 | CSS Grid,PC 端 4 列,响应式到移动端 1 列 | | 3D 倾斜 | CSS `transform: perspective + rotateX/Y`,基于鼠标位置计算 | --- ## 数据模型 ```json { "links": [ { "id": "uuid", "name": "个人博客", "url": "http://129.211.173.87:8888", "description": "基于 Next.js 的个人技术博客" } ], "auth": { "token": "random-string", "passwordHash": "sha256-of-current-password" } } ``` - `links` 数组存储所有导航卡片 - `auth` 对象存储登录态和密码哈希(SHA-256) --- ## 默认预设链接(根据现有项目) | 名称 | 链接 | 描述 | |---|---|---| | 个人博客 | `:8888` | Next.js 技术博客 | | 相册查看器 | `:8892` | 图片相册浏览 | | 快乐游戏 | `:8895` | Flask 小游戏集合 | | 网游引擎 | `:8900` | 网游引擎服务 | | 有声书播放器 | `:8899` | 有声书在线播放 | | WanAndroid | `:8880` | Material Design Web | | FumaMX CRM | `:10000` | CRM 管理系统 | | AI 聊天服务 | `:8890` | AI 对话服务 | | 新媒体平台 | `:18888` | CMS 内容管理系统 | | 微信小程序桥接 | `:5000` | 微信-Nanobot 桥接 | > 注:具体端口以运行时 systemd 服务实际监听为准。 --- ## 交互设计 ### 1. 未登录状态 - 页面顶部右侧:「登录」按钮 - 点击弹出模态框:账号 / 密码输入框 - 验证失败提示红色错误信息 ### 2. 登录成功状态 - 页面顶部右侧:「修改密码」+「添加链接」两个按钮 ### 3. 修改密码 - 弹窗:老密码 / 新密码 / 确认新密码 - 老密码验证通过后更新 localStorage 中的密码哈希 ### 4. 添加链接 - 弹窗:名称(文本)/ 链接(URL)/ 介绍(文本) - 提交后追加到 links 数组,重新渲染 ### 5. 卡片交互 - **常态**:白底卡片,大圆角(`border-radius: 20px`),阴影(`box-shadow`),左侧彩色圆形图标(首字母),右侧上下两行文字 - **Hover**: - 卡片 3D 倾斜(基于鼠标在卡片内的相对位置计算 `rotateX` / `rotateY`) - 右上角浮现「×」关闭按钮 - **点击关闭按钮**:确认后从数组删除,localStorage 同步更新 - **点击卡片主体**:`window.open(url, '_blank')` --- ## 3D 倾斜效果实现思路 ``` 鼠标在卡片内的相对位置 → 映射到 [-1, 1] → 乘以最大旋转角度(如 ±10deg) transform: perspective(1000px) rotateX(ry * -1) rotateY(rx) ``` - `rx` = (mouseX / cardWidth - 0.5) * 2 - `ry` = (mouseY / cardHeight - 0.5) * 2 鼠标移出时:平滑过渡(`transition: transform 0.3s ease`)复原到 `rotateX(0) rotateY(0)`。 --- ## 样式规范 - 背景:浅灰渐变或纯色 `#f5f7fa` - 顶部导航栏:白色,底部细阴影,高度 60px - 卡片:白色,圆角 20px,padding 24px,gap 24px - Grid:`grid-template-columns: repeat(4, 1fr)`,PC 端;`repeat(2, 1fr)` 平板;`1fr` 手机 - 图标:圆形 64px,背景色根据名称哈希生成(HSL 色环),文字白色大写首字母 - 关闭按钮:红色圆形,直径 24px,卡片 hover 时 `opacity: 0 → 1` --- ## 文件结构 ``` /home/ubuntu/nanocode/www/ ├── index.html # 单文件 SPA(HTML + CSS + JS) └── docs/ └── DESIGN.md # 本文档 ``` --- ## 待确认问题 1. **图标生成方式**:当前设计是根据名称首字母生成固定彩色字母图标。是否需要支持用户上传自定义图标?还是保持自动生成即可? 2. **删除确认**:点击关闭按钮删除时,是否需要二次确认弹窗("确定删除此链接?"),还是直接删除? 3. **默认链接**:上方列出的预设链接是否符合预期?是否有遗漏或不需要的项目? 4. **公网 IP**:链接中硬编码 `129.211.173.87` 是否合适,还是希望用相对路径或域名? 5. **排序**:新增链接是追加到末尾,还是可以拖拽排序? --- ## 下一步 确认上述问题后,直接编写 `/home/ubuntu/nanocode/www/index.html` 单文件实现全部功能。