143 lines
4.6 KiB
Markdown
143 lines
4.6 KiB
Markdown
# 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` 单文件实现全部功能。
|