# vita-web **Repository Path**: edwarddamon/vita-web ## Basic Information - **Project Name**: vita-web - **Description**: 私人领域中枢管理平台 - **Primary Language**: JavaScript - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-05-29 - **Last Updated**: 2026-08-04 ## Categories & Tags **Categories**: Uncategorized **Tags**: vita ## README # 此生 · 管理台(Vita Web) **此生**(Vita,拉丁语 *vita* —「生命」)的个人私域 **Web 管理端**。面向运维与配置,提供登录鉴权、RBAC 权限体系、动态菜单与多业务模块;C 端生活场景由微信小程序 **此生录** 承载。短信与邮件通知统一使用整体品牌 **【此生】**。 ## 产品命名 | 层级 | 名称 | 说明 | |------|------|------| | 英文 / 代码 | **Vita** | 仓库、API、主题变量等技术标识 | | 中文整体品牌 | **此生** | 短信 `【此生】`、邮件主题前缀 | | Web 管理端 | **此生 · 管理台** | 本仓库 UI 与浏览器标题 | | 生活小程序 | **此生录** | C 端,见 [vita-mini](https://gitee.com/edwarddamon/vita-mini) · [功能设计](https://gitee.com/edwarddamon/vita/blob/main/MINI_PROGRAM_DESIGN.md) | Slogan:**此生所历,皆在于此** · 小程序 **此生录**:**此生之事,记于此录** 前端品牌常量统一维护于 **`service/constants/brand.js`**(页面 title、登录页、顶栏、邮件默认主题等)。 ## 技术栈 | 类别 | 技术 | |------|------| | 框架 | [Next.js 16](https://nextjs.org)(App Router) | | UI | [Ant Design 6](https://ant.design)、[Tailwind CSS 4](https://tailwindcss.com) | | 请求 | Axios | | 运行 | Node.js 18+、Yarn | ## 功能概览 - **登录**:邮箱 + 密码(MD5 传输);登录后跳转用户菜单树中首个可访问路径 - **路由守卫**:`AuthGuard` 校验登录态;`PermissionGuard` 按后端菜单树限制页面访问 - **动态菜单**:侧边栏与面包屑由后端 `sys_menu` 驱动,按角色权限过滤 - **认证管理** - 用户:列表、搜索、新增/编辑、详情、角色绑定 - 角色:列表、搜索、新增/编辑、权限绑定 - 权限:列表、搜索、新增/编辑、详情、绑定菜单 / API 资源 - API 资源:列表、搜索、新增/编辑、权限绑定 - **生活**:礼金记录(收礼、回礼等) - **消息**:邮件模板、邮件发送与记录 - **系统**:文件上传、列表与预览 - **布局**:顶栏、可折叠侧边栏、面包屑、统一列表页结构 - **主题**:`生命蓝` / `隐匿黑`,登录后在用户名下拉切换,偏好写入 `localStorage` 按钮级权限由后端 Gateway 校验(前端 `PermissionButton` 始终渲染,无权限时接口返回 405)。 ## 快速开始 ### 环境变量 在 `.env/dev`、`.env/test`、`.env/prod` 中按环境配置: ```env APP_ENV=dev HTTP_URL_PREFIX=http://localhost:8888 HTTP_TIMEOUT=30000 CRYPTO_ENABLED=true ``` | 变量 | 说明 | |------|------| | `APP_ENV` | `dev` / `test` / `prod` | | `HTTP_URL_PREFIX` | 后端 API 根地址 | | `HTTP_TIMEOUT` | 请求超时(毫秒) | | `CRYPTO_ENABLED` | 是否启用接口加解密(默认 `true`,与网关 `vita.crypto.enabled` 对齐) | ### 安装与运行 ```bash yarn install yarn dev # 开发,读取 .env/dev ``` 访问 [http://localhost:3000](http://localhost:3000)。根路径按登录态重定向至登录页或首个菜单页。 ### 构建 ```bash yarn build:dev # .env/dev yarn build:test # .env/test yarn build:prod # .env/prod yarn start # 生产模式(需先 build) ``` ## 目录结构 ``` vita-web/ ├── app/ │ ├── (auth)/login/ # 登录(GuestGuard) │ ├── (main)/ # 业务页(AuthGuard + PermissionGuard + AppShell) │ │ ├── auth/users|roles|permissions|apiResources/ │ │ ├── life/gifts/ │ │ ├── message/emailTemplates|emails/ │ │ └── system/files/ │ ├── layout.jsx │ └── page.jsx # 根路径重定向 ├── components/ │ ├── auth/ # 守卫、用户/角色/权限/API 资源等业务组件 │ ├── layout/ # AppShell、侧边栏、主题等 │ ├── life/、message/、system/ # 各业务模块 │ ├── login/ │ └── providers/ # Ant Design 注册、ThemeProvider └── service/ ├── api/ # 接口封装(见下方 API 模块) ├── crypto/ # RSA + AES-GCM 加解密 ├── auth/ # Token、用户信息、菜单 store、路由权限 ├── constants/ # 枚举与分页、品牌(brand.js)等常量 ├── theme.js # 主题色板(修改此处全站生效) ├── antd-config.js # Ant Design 主题映射 ├── menu.js # 菜单树转换、面包屑、路径解析 └── routes.js # 路由常量 ``` ## 路由说明 | 路径 | 说明 | 鉴权 | |------|------|------| | `/` | 按登录态重定向 | — | | `/login` | 登录页 | 公开 | | `/auth/users` | 用户管理 | 需登录 + 菜单权限 | | `/auth/roles` | 角色管理 | 需登录 + 菜单权限 | | `/auth/permissions` | 权限管理 | 需登录 + 菜单权限 | | `/auth/apiResources` | API 资源管理 | 需登录 + 菜单权限 | | `/auth/menus` | 重定向至权限管理 | — | | `/life/gifts` | 礼金管理 | 需登录 + 菜单权限 | | `/message/emailTemplates` | 邮件模板 | 需登录 + 菜单权限 | | `/message/emails` | 邮件记录 | 需登录 + 菜单权限 | | `/system/files` | 文件管理 | 需登录 + 菜单权限 | 路由常量见 `service/routes.js`;可见菜单由 `service/auth/menuStore.js` 缓存。 ## 主题定制 全站主题在 **`service/theme.js`** 维护,CSS 变量由根布局注入,Ant Design 通过 `service/antd-config.js` 读取同一配置。用户偏好键名:`vita-theme`。内置:**生命蓝**(`vita`)、**隐匿黑**(`noir`)。 ## API 约定 - HTTP 客户端:`service/api/commonHttp.js`(Axios) - 请求自动携带 `Authorization`(Bearer Token) - 响应 `code === 200` 为成功;`401` 清除登录态并跳转登录页 - 接口模块:`auth`、`user`、`role`、`permission`、`apiResource`、`menu`、`dict`、`gift`、`email`、`emailTemplate`、`file` ## 接口加解密(RSA + AES-GCM) 与 [vita](https://gitee.com/edwarddamon/vita) 网关协议对齐:**auth-center 提供 `/auth/crypto/publicKey` 签发 RSA 密钥对;前端缓存公钥至过期,单次请求内上下行复用同一 AES 密钥**。 ### 架构 ``` 浏览器 vita-gateway (:8888) │ GET /auth/crypto/publicKey(明文,auth-center 签发新密钥对) │ ─────────────────────────────> 返回 publicKey + keyId + expiresAt │ │ POST /auth/user/login 等 │ Header: X-Encrypt-Key = RSA(公钥, Base64(K)&Base64(IV)) │ Body: { "data": AES(K, json) } │ ─────────────────────────────> CryptoFilter 解密 → 业务 → AES(K) 加密响应 │ <───────────────────────────── │ 用同一 K 解密响应 ``` ### 涉及文件 | 文件 | 职责 | |------|------| | `service/crypto/cryptoConfig.js` | 开关、公钥路径、409 重试策略 | | `service/crypto/cryptoCache.js` | RSA 公钥缓存(内存 + sessionStorage) | | `service/crypto/cryptoUtil.js` | Web Crypto API 加解密 | | `service/api/commonHttp.js` | Axios 拦截器透明加解密 | | `service/constants/code.js` | 407 / 408 / 409 错误码 | ### 自动加密范围 | 请求 | 是否加密 | |------|----------| | `POST` + `Content-Type: application/json` | 自动 | | `GET` / `PUT` / `PATCH` / `DELETE` | 不加密 | | `FormData` 或非 JSON | 不加密 | | `config.encrypt: false` | 显式关闭 | ### 错误码与重试 | code | 含义 | 客户端行为 | |------|------|------------| | 407 | 解密失败 | 提示错误 | | 408 | 防重放失败 | 提示错误 | | **409** | **RSA 密钥不存在/过期** | **清公钥缓存 → 重拉 `/auth/crypto/publicKey` → 自动重试 1 次** | 公钥 `expiresAt` 由服务端 `vita.crypto.public-key-ttl-seconds` 控制。 ### 存储策略 | 数据 | 存储 | 重生时机 | |------|------|----------| | RSA 公钥 | 内存 + sessionStorage | 缓存缺失、`expiresAt` 将过期、收到 409 | | AES 会话密钥 | 仅当次请求 | 每个加密请求重新生成 | | Token | localStorage | 与加解密无关 | RSA 公钥采用懒加载:首次 `POST application/json` 加密请求时,若本地无有效缓存才调用 `/auth/crypto/publicKey`;业务 API 无需改动,加解密由 `commonHttp` 拦截器处理。 关闭加解密:`.env/*` 中设置 `CRYPTO_ENABLED=false`(需与网关配置一致)。 ## 开发说明 - 使用 Next.js App Router,部分 API 与常见版本有差异,可参考 `node_modules/next/dist/docs/` - 组件与页面以 JSX 为主;路径别名 `@/` 指向项目根目录 - 代码检查:`yarn lint` ## 部署 > `HTTP_URL_PREFIX`、`APP_ENV`、`HTTP_TIMEOUT` 在 **构建阶段** 由 `next.config.mjs` 写入前端包。修改 API 地址后须重新 `yarn build:*`,仅重启进程无效。 ```mermaid flowchart LR User[浏览器] --> Nginx[Nginx :443] Nginx --> Next[Next.js :3000] Next --> API[后端 Gateway] ``` | 环境 | 配置文件 | 构建命令 | |------|----------|----------| | 测试 | `.env/test` | `yarn build:test` | | 生产 | `.env/prod` | `yarn build:prod` | **手动部署:** ```bash yarn install --frozen-lockfile yarn build:prod # 或 build:test PORT=3000 NODE_ENV=production yarn start ``` **Docker:** 仓库根目录 `Dockerfile` 已启用 `output: "standalone"` 多阶段构建。 ```bash docker build -t vita-web:local . # 使用测试配置:docker build -t vita-web:local --build-arg APP_ENV=test . docker run --rm -p 3000:3000 vita-web:local ``` `APP_ENV` 写在 Dockerfile(默认 `prod`);`HTTP_URL_PREFIX` / `HTTP_TIMEOUT` / `CRYPTO_ENABLED` 读取仓库 `.env/${APP_ENV}`。改 API 地址请编辑对应 `.env` 文件后重新构建。 服务器 CI:仓库内 `ci/vita-web-ci.sh`(见 `ci/README.md`)。集群 Traefik 终止 TLS 后反代至容器 `:3000`(见 vita 仓库 `docker-compose.frontend.yml`)。 **注意:** 浏览器直连 API,后端需配置 CORS,或由 Nginx 同域转发。 **发布后验证:** 未登录跳转登录页;登录进入首个菜单页;接口指向正确 `HTTP_URL_PREFIX`;401 回登录;主题切换持久化。 ## 相关仓库 | 仓库 | 说明 | |------|------| | [vita](https://gitee.com/edwarddamon/vita) | 后端 API 与 Gateway,本地默认 `http://localhost:8888`(`.env/dev`) | | [vita-web](https://gitee.com/edwarddamon/vita-web) | Web 管理端(本仓库) | | [vita-mini](https://gitee.com/edwarddamon/vita-mini) | 微信小程序 **此生录**(Taro + React) | ## 许可证 Private — 仅供个人/内部使用。