添加 uipro,更新 wiki
This commit is contained in:
@@ -3,23 +3,14 @@ schema_version: 1
|
||||
locale: zh-CN
|
||||
branch: main
|
||||
nodes_managed: true
|
||||
exported_at: "2026-07-09T02:41:34Z"
|
||||
exported_at: "2026-07-10T03:11:01Z"
|
||||
modules:
|
||||
"":
|
||||
dir_name: 耳机品牌与 OTA 升级管理平台(前后端编排)
|
||||
title: 耳机品牌与 OTA 升级管理平台(前后端编排)
|
||||
scope:
|
||||
- .gitignore
|
||||
- README.md
|
||||
- DEPLOY.md
|
||||
- docker-compose.yml
|
||||
- scripts/
|
||||
- .env
|
||||
- .env.example
|
||||
dir_name: 音频设备管理仪表盘(前后端单体仓库)
|
||||
title: 音频设备管理仪表盘(前后端单体仓库)
|
||||
scope: []
|
||||
source_files: []
|
||||
children:
|
||||
- backend
|
||||
- frontend
|
||||
children: []
|
||||
depends_on: []
|
||||
related_to: []
|
||||
backend:
|
||||
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
---
|
||||
kind: dependency_management
|
||||
name: pnpm 多包依赖管理(前后端双 package.json)
|
||||
category: dependency_management
|
||||
scope:
|
||||
- '**'
|
||||
source_files:
|
||||
- backend/package.json
|
||||
- backend/pnpm-lock.yaml
|
||||
- frontend/package.json
|
||||
- frontend/pnpm-workspace.yaml
|
||||
- frontend/pnpm-lock.yaml
|
||||
- frontend/package-lock.json
|
||||
---
|
||||
|
||||
本仓库采用 pnpm 作为统一的 Node.js 包管理器,前后端各自维护独立的 package.json,通过 lockfile 锁定依赖版本,未启用 monorepo workspace 模式。
|
||||
|
||||
1. 使用的系统/工具
|
||||
- 包管理器:pnpm v11.5.2,在 backend/package.json 与 frontend/package.json 中均通过 packageManager 字段声明,确保团队成员使用一致版本。
|
||||
- Lockfile:后端使用 pnpm-lock.yaml(lockfileVersion 9.0),前端同时存在 pnpm-lock.yaml 与 package-lock.json(后者为历史遗留)。
|
||||
- 构建工具:前端基于 Vite(vite.config.js),后端无构建步骤,直接运行 src/app.js。
|
||||
|
||||
2. 关键文件
|
||||
- backend/package.json — 后端依赖声明(Express、Sequelize、MySQL2、AWS S3 SDK、Redis、Zod 等)
|
||||
- backend/pnpm-lock.yaml — 后端精确锁定的依赖树
|
||||
- frontend/package.json — 前端依赖声明(Vue3、Element Plus、Axios、Vite 等)
|
||||
- frontend/pnpm-workspace.yaml — 仅开启 allowBuilds.esbuild: true,未定义任何 workspace 包
|
||||
- frontend/pnpm-lock.yaml / frontend/package-lock.json — 前端锁文件(二者并存)
|
||||
|
||||
3. 架构与约定
|
||||
- 双包结构:前后端各自独立,不存在共享的 packages/ 或 workspace: 引用;pnpm-workspace.yaml 为空配置,说明当前不是 monorepo。
|
||||
- 版本策略:所有依赖均采用 ^ 语义化版本范围(如 express: ^4.21、vue: ^3.3.4),实际安装版本由 lockfile 固定。
|
||||
- 私有源/代理:未发现 .npmrc、.pnpmrc 或 registry 相关配置,默认使用 npm 官方源;也未见 @scope 私有包引用。
|
||||
- 缓存:根目录存在 .pnpm-store/v11/,表明 pnpm 全局存储已启用。
|
||||
|
||||
4. 开发者应遵循的规则
|
||||
- 统一使用 pnpm 安装/更新依赖,避免混用 npm/yarn,以免生成冲突的 lockfile。
|
||||
- 新增依赖时只修改对应子目录的 package.json,提交后让 CI 重新生成 lockfile。
|
||||
- 不要手动编辑 lockfile;如需升级,使用 pnpm up <pkg> 或 pnpm update。
|
||||
- 清理前端的 package-lock.json,统一以 pnpm-lock.yaml 为准,消除双锁文件带来的歧义。
|
||||
- 若未来引入共享包,应在 pnpm-workspace.yaml 中显式声明 workspace,并迁移到 monorepo 模式。
|
||||
@@ -0,0 +1,32 @@
|
||||
---
|
||||
kind: error_handling
|
||||
name: 前后端统一错误响应与拦截机制
|
||||
category: error_handling
|
||||
scope:
|
||||
- '**'
|
||||
source_files:
|
||||
- backend/src/utils/response.js
|
||||
- backend/src/middleware/auth.js
|
||||
- backend/src/app.js
|
||||
- frontend/src/utils/request.js
|
||||
---
|
||||
|
||||
本仓库采用「后端统一响应体 + 前端 Axios 拦截器」的轻量级错误处理方案,未引入专门的错误类型库或全局异常中间件。
|
||||
|
||||
**后端(Express)**
|
||||
- 统一响应封装:`backend/src/utils/response.js` 提供 `ApiResponse.success / error / noData` 三个工厂方法,约定 `code=1` 成功、`code=0` 业务错误、`code=2` 无数据;`PageData` 用于分页结构。
|
||||
- 路由层自行 try/catch:各 `routes/*.js` 在控制器内捕获异常,记录 `logger.error(e.message)` 后返回 `ApiResponse.error(...)`,错误消息多为硬编码中文提示,未使用 HTTP 状态码区分语义。
|
||||
- 认证中间件 `middleware/auth.js` 单独处理鉴权错误:401 返回 `{ detail: '...' }`,403 返回权限不足信息,与业务错误体结构不同。
|
||||
- 服务层 `services/*.js` 直接 `throw new Error(...)` 向上抛出具体错误(如 Redis/S3/曲线接口失败),由调用方路由捕获。
|
||||
- 应用入口 `app.js` 仅在启动阶段同步数据库时 try/catch,未注册全局 Express 错误处理中间件(`app.use((err, req, res, next) => ...)`)。
|
||||
|
||||
**前端(Vue3 + Axios)**
|
||||
- `frontend/src/utils/request.js` 通过 Axios 拦截器集中处理:
|
||||
- 请求拦截:自动注入 `Authorization: Bearer <token>`,跳过 `/auth/login`。
|
||||
- 响应拦截:当 `res.code === 0` 时,若 `config.skipErrorToast` 未设置则弹出 `ElMessage.error`,并将 `responseData` 挂载到抛出的 Error 对象上供上层消费。
|
||||
- HTTP 错误:401 清除本地 token、跳转登录页并携带 redirect;403 显示警告;其他网络错误统一 `ElMessage.error`。
|
||||
- 业务 API 模块(`frontend/src/api/*.js`)基于此 request 实例发起请求,依赖 Promise reject 分支处理业务错误。
|
||||
|
||||
**设计决策与不足**
|
||||
- 优点:前后端对 `code/msg/data` 协议一致,前端拦截器屏蔽了重复的错误提示逻辑。
|
||||
- 不足:缺少统一的错误码枚举、HTTP 状态码未与业务错误解耦、未定义全局错误中间件导致未捕获异常可能返回默认 HTML 500 页面。
|
||||
@@ -0,0 +1,47 @@
|
||||
---
|
||||
kind: logging_system
|
||||
name: 基于 Winston 的日志系统
|
||||
category: logging_system
|
||||
scope:
|
||||
- '**'
|
||||
source_files:
|
||||
- backend/src/config/logger.js
|
||||
- backend/src/app.js
|
||||
- backend/src/config/database.js
|
||||
- backend/package.json
|
||||
---
|
||||
|
||||
## 1. 使用的系统与框架
|
||||
- 后端采用 **Winston v3** 作为统一日志框架,通过 `backend/src/config/logger.js` 集中创建并导出单例 logger。
|
||||
- 前端(Vue3)未发现专用日志库,未在前端代码中引入结构化日志输出。
|
||||
- Sequelize 在开发环境将 SQL 查询直接 `console.log` 到控制台,生产环境关闭 SQL 日志。
|
||||
|
||||
## 2. 核心文件与包
|
||||
- `backend/src/config/logger.js` — Winston 实例定义、格式与传输配置
|
||||
- `backend/src/app.js` — 应用启动时记录数据库同步、服务监听等关键事件
|
||||
- `backend/package.json` — 依赖声明 `winston: ^3.14`
|
||||
- `backend/logs/app.log` — 默认文件日志输出路径
|
||||
- `backend/src/config/database.js` — Sequelize 的 `logging` 开关逻辑
|
||||
|
||||
## 3. 架构与约定
|
||||
- **单例导出**:`logger.js` 使用 `winston.createLogger()` 创建全局 logger,并通过 `module.exports = logger` 供各模块 `require('../config/logger')` 复用。
|
||||
- **日志级别**:全局默认 level 为 `info`;业务代码中使用 `logger.info / warn / error` 三个级别,未见 `debug` 调用。
|
||||
- **输出格式**:时间戳 + 级别 + 消息 + 可选 JSON meta 字段,形如:
|
||||
```
|
||||
2026-06-09 12:34:56 - info - User admin logged in {}
|
||||
```
|
||||
- **双通道输出**:同时写入 Console 和文件 `backend/logs/app.log`,编码 UTF-8。
|
||||
- **无按级别/日期分片**:当前仅一个 `app.log` 文件,未启用 `FileTransport` 的 `maxsize`、`maxFiles`、`filename` 模板等滚动策略。
|
||||
- **Sequelize SQL 日志**:仅在 `isDevelopment` 时开启,输出到 `console.log`,不经过 Winston。
|
||||
- **中间件层**:未集成 Express 请求日志中间件(如 `morgan`),HTTP 访问日志未统一采集。
|
||||
|
||||
## 4. 开发者应遵循的规则
|
||||
- **统一入口**:所有日志必须通过 `const logger = require('../config/logger')` 获取,禁止直接使用 `console.log` 输出业务日志。
|
||||
- **级别选择**:
|
||||
- `info`:正常业务流程事件(登录成功、密码修改、数据操作完成等)
|
||||
- `warn`:可恢复异常或潜在问题(登录失败、参数校验警告等)
|
||||
- `error`:不可恢复错误(数据库异常、外部服务调用失败等)
|
||||
- **结构化字段**:通过第三个参数传入对象以附加上下文,例如 `logger.warn({ username, ip }, 'Login failed')`,该对象会被序列化为 JSON 追加到消息末尾。
|
||||
- **敏感信息**:避免在日志中记录明文密码、完整 token 等敏感内容。
|
||||
- **SQL 调试**:如需查看底层 SQL,确保环境变量处于开发模式以使 Sequelize logging 生效;生产环境应保持关闭以避免性能损耗。
|
||||
- **日志轮转**:当前未配置自动轮转,部署时应配合外部工具(如 `logrotate`、Docker log driver)管理 `backend/logs/app.log` 大小。
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
---
|
||||
kind: build_system
|
||||
name: 构建与部署体系(Docker Compose + pnpm + Vite)
|
||||
category: build_system
|
||||
scope:
|
||||
- '**'
|
||||
source_files:
|
||||
- docker-compose.yml
|
||||
- backend/Dockerfile
|
||||
- frontend/Dockerfile
|
||||
- frontend/vite.config.js
|
||||
- scripts/upload.sh
|
||||
- DEPLOY.md
|
||||
- backend/package.json
|
||||
- frontend/package.json
|
||||
---
|
||||
|
||||
## 1. 使用的系统与方法
|
||||
|
||||
- **包管理器**:pnpm@11.5.2,前后端均通过 `packageManager` 字段锁定版本。
|
||||
- **前端构建**:Vite 6 + Vue 3,开发端口 3000,生产构建产物输出到 `frontend/dist/`,并通过 Rollup `manualChunks` 将 vue、element-plus 等拆分为独立 chunk。
|
||||
- **后端运行**:Express + Sequelize,入口 `backend/src/app.js`,默认监听 8000(容器内),本地开发可通过 `.env` 的 `PORT=8083` 覆盖。
|
||||
- **容器编排**:Docker Compose 定义两个服务——`backend`(node:22-alpine)和 `frontend`(nginx:alpine),共享自定义 bridge 网络 `audio-network`。
|
||||
- **发布脚本**:`scripts/upload.sh` 基于 rsync+ssh 将前端 dist、后端源码、compose 文件同步至远程服务器 `/data/project/dashboard/`。
|
||||
|
||||
## 2. 关键文件与位置
|
||||
|
||||
| 类别 | 文件 | 作用 |
|
||||
|------|------|------|
|
||||
| 编排 | `docker-compose.yml` | 定义 backend/frontend 服务、端口映射、日志轮转、数据卷挂载 |
|
||||
| 后端镜像 | `backend/Dockerfile` | node:22-alpine,仅安装 prod 依赖,CMD 启动 `src/app.js` |
|
||||
| 前端镜像 | `frontend/Dockerfile` | 多阶段构建:node:18-alpine 构建 → nginx:alpine 托管静态资源 |
|
||||
| 前端构建配置 | `frontend/vite.config.js` | 开发代理 `/api→localhost:8083`、chunk 拆分、别名 `@` |
|
||||
| 上传脚本 | `scripts/upload.sh` | rsync 推送 frontend/backend/compose 三套预设目标 |
|
||||
| 部署文档 | `DEPLOY.md` | 完整的首次部署、增量更新、环境变量说明、目录结构约定 |
|
||||
| 后端脚本 | `backend/start.sh / stop.sh / restart.sh` | 非 Docker 场景下的进程启停辅助 |
|
||||
|
||||
## 3. 架构与约定
|
||||
|
||||
### 3.1 构建流水线
|
||||
|
||||
```
|
||||
本地开发
|
||||
├─ frontend/pnpm dev (vite, :3000) → 代理 /api → localhost:8083
|
||||
└─ backend/pnpm start (node src/app.js, :8000 或 .env PORT)
|
||||
|
||||
本地构建
|
||||
├─ pnpm --dir frontend build → frontend/dist/
|
||||
└─ scripts/upload.sh [frontend|backend|compose|all]
|
||||
|
||||
服务器部署
|
||||
├─ docker compose build --no-cache backend # 首次或依赖变更
|
||||
├─ docker compose up -d # 启动全部服务
|
||||
└─ docker compose restart frontend # 仅前端热更
|
||||
```
|
||||
|
||||
- 前端采用**多阶段 Docker 构建**,最终镜像仅包含 nginx + 静态文件,体积最小化。
|
||||
- 后端镜像使用 `--frozen-lockfile --prod` 安装,确保构建可重复且不携带 devDependencies。
|
||||
- 宿主机通过 volume 挂载 `/data/projects/source` 给后端容器,用于 X9 OTA 升级包本地存储;前端 `dist/` 与 `nginx.conf` 也通过 volume 挂载,避免重建镜像。
|
||||
|
||||
### 3.2 端口与环境变量约定
|
||||
|
||||
| 组件 | 容器内端口 | 宿主机映射 | 备注 |
|
||||
|------|-----------|-----------|------|
|
||||
| frontend (nginx) | 80 | 8082 | 反向代理 `/api` 到 `http://backend:8000` |
|
||||
| backend (Node) | 8000 | 8083 | 由 Compose 强制覆盖 `PORT=8000` |
|
||||
| 本地开发 (vite) | 3000 | — | 通过 proxy 转发 `/api` 到 8083 |
|
||||
|
||||
- 所有环境变量统一放在根目录 `.env`,Compose 通过 `env_file` 注入,不再各自维护 `.env`。
|
||||
- 敏感信息(JWT_SECRET、数据库密码等)不随 `upload.sh` 上传,需在服务器单独维护。
|
||||
|
||||
### 3.3 上传策略
|
||||
|
||||
`scripts/upload.sh` 定义了三个预设集合:
|
||||
- `frontend`:仅 `frontend/dist/`
|
||||
- `backend`:`backend/src/` + `package.json` + `pnpm-lock.yaml`(不含 Dockerfile)
|
||||
- `compose`:`docker-compose.yml`
|
||||
|
||||
支持 `-n` dry-run 预览、任意路径透传、自动创建远端目录。
|
||||
|
||||
## 4. 开发者应遵循的规则
|
||||
|
||||
1. **新增依赖**:在对应子模块执行 `pnpm add ...`,确保 `pnpm-lock.yaml` 提交到 Git,以便 `--frozen-lockfile` 构建成功。
|
||||
2. **修改前端路由/样式**:直接 `pnpm dev` 本地调试,无需重新构建镜像;生产发布前执行 `pnpm build` 并 `./scripts/upload.sh frontend`。
|
||||
3. **修改后端接口**:`./scripts/upload.sh backend` 后在服务器执行 `docker compose build --no-cache backend && docker compose up -d backend`。
|
||||
4. **修改 Compose 配置**:`./scripts/upload.sh compose` 后 `docker compose up -d` 即可生效。
|
||||
5. **不要**在代码中硬编码端口或路径,一律通过 `.env` 或 Compose `environment` 注入。
|
||||
6. **OTA 包存放**:仅通过 volume 挂载的 `/data/projects/source` 写入,不要改动 Dockerfile 中的 COPY 范围。
|
||||
7. **本地非 Docker 开发**:先 `cd backend && pnpm start`,再 `cd frontend && pnpm dev`,确保根目录 `.env` 中 `PORT=8083`。
|
||||
@@ -0,0 +1,47 @@
|
||||
---
|
||||
kind: configuration_system
|
||||
name: 环境变量与配置加载体系
|
||||
category: configuration_system
|
||||
scope:
|
||||
- '**'
|
||||
source_files:
|
||||
- backend/src/app.js
|
||||
- backend/src/config/loadEnv.js
|
||||
- backend/src/config/env.js
|
||||
- backend/src/config/database.js
|
||||
- backend/src/config/redis.js
|
||||
- .env.example
|
||||
- docker-compose.yml
|
||||
---
|
||||
|
||||
## 系统概览
|
||||
本仓库采用「进程级 .env 文件 + 环境变量」的轻量配置方案,由后端在启动时统一加载,未引入第三方配置中心或 YAML/JSON 配置文件。所有运行时参数通过 `process.env` 注入,开发环境与生产环境通过 `APP_ENV` 区分。
|
||||
|
||||
## 核心机制
|
||||
- **统一入口加载**:`backend/src/app.js` 首行 `require('./config/loadEnv')`,确保应用启动前完成 `.env` 解析。
|
||||
- **dotenv 加载策略**:`loadEnv.js` 固定从仓库根目录读取 `.env`(`path.resolve(__dirname, '../../../.env')`),仅在文件存在时调用 `dotenv.config()`;Docker 部署时通过 `docker-compose.yml` 的 `env_file` 注入,容器内无 `.env` 也不会覆盖已存在的环境变量。
|
||||
- **环境判断工具**:`config/env.js` 暴露 `APP_ENV`、`isDevelopment`、`isProduction`,供各模块按环境切换行为(如数据库日志开关)。
|
||||
|
||||
## 配置项分类与约定
|
||||
| 类别 | 关键变量 | 默认值 / 说明 |
|
||||
|---|---|---|
|
||||
| 数据库 | `DATABASE_HOST`, `DATABASE_PORT`, `DATABASE_NAME`, `DATABASE_USER`, `DATABASE_PASSWORD` | MySQL,Sequelize 直连,`dialectOptions.charset='utf8mb4'`,开发模式打印 SQL |
|
||||
| 应用 | `APP_NAME`, `APP_ENV`, `PORT` | `APP_ENV=development|production`;本地默认 8083,Docker 内 8000 |
|
||||
| 认证 | `JWT_SECRET`, `DASHBOARD_ADMIN_USERNAME`, `DASHBOARD_ADMIN_PASSWORD` | 首次启动自动创建超级管理员 |
|
||||
| S3 存储 | `AWS_REGION`, `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `AWS_S3_OTA_BUCKET`, `AWS_S3_MEASUREMENT_BUCKET` | 正式环境可通过 IAM 角色免 AK/SK 访问 |
|
||||
| OTA 地址 | `OTA_X8_PUBLIC_BASE`, `OTA_X9_URL_BASE`, `OTA_UPLOAD_DIR` | X8/X9 升级包基 URL;上传目录仅生产环境需显式配置 |
|
||||
| Redis 缓存 | `REDIS_HOST`, `REDIS_PORT`, `REDIS_PASSWORD`, `REDIS_EQ_DB` | ioredis 单例,连接失败记录错误日志 |
|
||||
| 外部服务 | `MEILISEARCH_*`, `CURVE_API_BASE_URL` | 搜索与曲线 API 基础地址 |
|
||||
|
||||
## 架构与约定
|
||||
- **单一来源**:`.env.example` 是配置清单,实际 `.env` 不应提交到版本库(已在 `.gitignore` 中忽略)。
|
||||
- **分层组织**:`backend/src/config/` 下每个子模块只负责自身依赖的配置读取(database、redis、logger),不互相耦合。
|
||||
- **环境变量优先**:所有配置均从 `process.env` 读取,并带合理默认值,保证本地可零配置运行。
|
||||
- **Docker 集成**:`docker-compose.yml` 通过 `env_file: [.env]` 和 `environment:` 覆盖端口与环境变量,实现同一份 `.env` 同时驱动本地与容器。
|
||||
|
||||
## 开发者规则
|
||||
1. 新增配置项先在 `.env.example` 中添加注释与默认值,再在对应 `config/*.js` 中读取。
|
||||
2. 敏感信息(密码、密钥)一律走环境变量,禁止硬编码或写入代码。
|
||||
3. 使用 `APP_ENV` 做环境分支逻辑,不要直接检查主机名或路径。
|
||||
4. Docker 部署时通过 compose 的 `environment` 覆盖必要变量,保持 `.env` 最小化。
|
||||
5. 若某配置有默认值且允许空值,务必在读取处提供 fallback,避免启动期崩溃。
|
||||
@@ -0,0 +1,7 @@
|
||||
schema_version: 1
|
||||
module_path: ""
|
||||
title: 音频设备管理仪表盘(前后端单体仓库)
|
||||
scope: []
|
||||
source_files: []
|
||||
depends_on: []
|
||||
related_to: []
|
||||
@@ -0,0 +1 @@
|
||||
后端:Express 4 + Sequelize 6 + mysql2 + jsonwebtoken + multer + @aws-sdk/client-s3 + winston + ioredis + zod;前端:Vue 3 + vue-router 4 + Element Plus(含 dark css-vars)+ vite 6 + axios;部署:Docker Compose(backend 镜像自 build,frontend 使用 nginx:alpine 静态托管)。
|
||||
@@ -0,0 +1,5 @@
|
||||
仓库采用前后端分离的单体结构:
|
||||
- `backend/src` 为 Express API 服务,入口 `app.js` 统一挂载 CORS、JSON 解析、`bodyLimit` 中间件,并通过 `routes/index.js` 聚合 auth/brands/models/ota/blacklist/otaTargetDevice/shareCodeLogs/users/dashboard 等路由;数据层使用 Sequelize + mysql2,模型集中在 `models/` 并导出到 `models/index.js`;外部依赖通过 `services/` 抽象(curveClient 调用第三方曲线服务、eqCacheStorage/squiglink 处理 EQ 缓存、measurementStorage/otaStorage 对接 S3、userBootstrap 负责超级管理员初始化);鉴权由 `middleware/auth.js` + `utils/jwt.js` 实现。
|
||||
- `frontend/src` 为 Vite + Vue3 + Element Plus SPA,`router/index.js` 集中声明所有页面路由并在 `beforeEach` 中做 token 校验与超级管理员权限拦截;`api/` 下每个文件对应一个后端模块的 axios 封装;`views/` 按功能域分目录组织页面,`components/` 存放全局复用组件(ChangePasswordDialog、SidebarLogo、TabsView),`layout/index.vue` 提供侧边栏+标签页布局。
|
||||
- 顶层 `docker-compose.yml` 编排 backend(Node)与 frontend(nginx:alpine 静态托管 dist),共享 `audio-network` 网络;`.env.example` 提供环境变量模板。
|
||||
- 依赖方向单向:前端 → 后端 REST API,后端 → MySQL/S3/Redis/第三方 curve 服务,无跨包反向引用。
|
||||
@@ -0,0 +1 @@
|
||||
基于 Vue3 + Express/Sequelize 的耳机品牌、型号、OTA 与用户管理后台,提供曲线上传、S3 存储与 Element Plus 驱动的 Web 界面。
|
||||
@@ -0,0 +1 @@
|
||||
开发:`pnpm install` 后分别进入 `backend` 和 `frontend` 执行 `pnpm dev`;生产:`cd frontend && pnpm build` 生成 `dist/`,再 `docker compose up -d --build` 启动双容器,需提前准备 `.env`(参考 `.env.example`)并挂载 `/data/projects/source` 供 S3 本地模拟访问。
|
||||
@@ -0,0 +1,5 @@
|
||||
- 后端路由以独立文件暴露 express router,再由 `routes/index.js` 统一收集注册,避免在 app.js 内散写 use()。
|
||||
- Sequelize 模型按领域单文件定义(Brand/Model/Ota/BlackList 等),并通过 `models/index.js` 集中 re-export 给 routes/services 使用。
|
||||
- 前端路由采用懒加载 `() => import('@/views/...')` 形式,meta 字段声明 title/icon/requiresAuth/requiresSuperAdmin 控制导航与守卫。
|
||||
- 前端 API 调用按业务域拆分到 `src/api/*.js`,每个文件对应一个后端路由模块,统一通过 `axios` 实例发起请求。
|
||||
- 前端页面按功能域在 `views/<domain>/index.vue` 下组织,复杂页面内部再拆 `components/` 与 `composables/` 子目录。
|
||||
@@ -14,6 +14,14 @@
|
||||
- [frontend/src/views/login/index.vue](file://frontend/src/views/login/index.vue)
|
||||
</cite>
|
||||
|
||||
## 更新摘要
|
||||
**所做更改**
|
||||
- 更新了侧边栏导航系统架构,从六个独立菜单项简化为三个主要分类
|
||||
- 新增了侧边栏轨道导航(Rail Navigation)功能,提供快速展开侧边栏的交互体验
|
||||
- 改进了导航链接实现方式,采用普通锚元素配合点击处理器替代Vue Router链接
|
||||
- 增强了用户体验,实现了自动展开侧边栏的智能交互逻辑
|
||||
- 更新了导航分类结构,重新组织了耳机管理、升级管理和分享码三大功能模块
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
@@ -29,9 +37,14 @@
|
||||
|
||||
本项目采用现代化的Vue 3 + Element Plus前端技术栈构建,布局组件是整个系统的骨架结构,负责组织页面的整体架构。该布局组件实现了响应式设计,支持桌面端和移动端的自适应布局,提供了完整的导航体系和主题适配功能。
|
||||
|
||||
**最新更新** 导航系统进行了重大改进,采用了创新的三层导航架构:
|
||||
- **侧边栏轨道导航**:轻量化的图标导航条,提供快速访问入口
|
||||
- **主菜单导航**:分类化的三级菜单结构,包含耳机管理、升级管理和分享码三大模块
|
||||
- **顶部面包屑导航**:动态生成的路径导航,增强用户定位能力
|
||||
|
||||
布局组件的核心特色包括:
|
||||
- **双层导航系统**:侧边栏主导航 + 顶部面包屑导航
|
||||
- **动态侧边栏**:支持展开/收起的玻璃拟态设计
|
||||
- **三层导航系统**:轨道导航 + 分类菜单 + 面包屑导航
|
||||
- **智能侧边栏**:支持展开/收起的玻璃拟态设计,具备自动展开功能
|
||||
- **标签页管理**:多标签页浏览和持久化存储
|
||||
- **深色主题**:基于CSS变量的主题系统
|
||||
- **响应式适配**:针对不同屏幕尺寸的优化布局
|
||||
@@ -67,18 +80,18 @@ end
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [frontend/src/layout/index.vue:1-338](file://frontend/src/layout/index.vue#L1-L338)
|
||||
- [frontend/src/router/index.js:1-91](file://frontend/src/router/index.js#L1-L91)
|
||||
- [frontend/src/layout/index.vue:1-349](file://frontend/src/layout/index.vue#L1-L349)
|
||||
- [frontend/src/router/index.js:1-103](file://frontend/src/router/index.js#L1-L103)
|
||||
|
||||
**章节来源**
|
||||
- [frontend/src/layout/index.vue:1-338](file://frontend/src/layout/index.vue#L1-L338)
|
||||
- [frontend/src/router/index.js:1-91](file://frontend/src/router/index.js#L1-L91)
|
||||
- [frontend/src/layout/index.vue:1-349](file://frontend/src/layout/index.vue#L1-L349)
|
||||
- [frontend/src/router/index.js:1-103](file://frontend/src/router/index.js#L1-L103)
|
||||
|
||||
## 核心组件
|
||||
|
||||
### 主布局组件架构
|
||||
|
||||
主布局组件采用Element Plus的容器布局系统,实现了经典的三段式布局:
|
||||
主布局组件采用Element Plus的容器布局系统,实现了经典的三段式布局,并集成了全新的三层导航架构:
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
@@ -91,12 +104,18 @@ B --> G[ElAside<br/>侧边栏容器]
|
||||
G --> H[SidebarInner<br/>侧边栏内部容器]
|
||||
H --> I[SidebarLogo<br/>Logo组件]
|
||||
H --> J[SidebarNavWrap<br/>导航包装器]
|
||||
J --> K[SidebarRail<br/>侧边栏导航条]
|
||||
J --> L[LuxMenu<br/>主菜单]
|
||||
J --> K[SidebarRail<br/>轨道导航]
|
||||
J --> L[LuxMenu<br/>分类菜单]
|
||||
K --> M[耳机管理图标]
|
||||
K --> N[升级管理图标]
|
||||
K --> O[分享码图标]
|
||||
L --> P[耳机管理子菜单]
|
||||
L --> Q[升级管理子菜单]
|
||||
L --> R[分享码子菜单]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [frontend/src/layout/index.vue:9-138](file://frontend/src/layout/index.vue#L9-L138)
|
||||
- [frontend/src/layout/index.vue:9-146](file://frontend/src/layout/index.vue#L9-L146)
|
||||
|
||||
### 组件层次结构
|
||||
|
||||
@@ -109,6 +128,8 @@ class LuxLayout {
|
||||
+railNavItems : Array
|
||||
+breadcrumbTitle : ComputedRef
|
||||
+breadcrumbSection : ComputedRef
|
||||
+handleRailClick()
|
||||
+resolveOpenedMenus()
|
||||
+handleLogout()
|
||||
+handleUserMenuCommand()
|
||||
}
|
||||
@@ -134,12 +155,12 @@ LuxLayout --> ChangePasswordDialog : "使用"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [frontend/src/layout/index.vue:144-222](file://frontend/src/layout/index.vue#L144-L222)
|
||||
- [frontend/src/layout/index.vue:152-233](file://frontend/src/layout/index.vue#L152-L233)
|
||||
- [frontend/src/components/SidebarLogo.vue:52-58](file://frontend/src/components/SidebarLogo.vue#L52-L58)
|
||||
- [frontend/src/components/TabsView.vue:55-63](file://frontend/src/components/TabsView.vue#L55-L63)
|
||||
|
||||
**章节来源**
|
||||
- [frontend/src/layout/index.vue:144-222](file://frontend/src/layout/index.vue#L144-L222)
|
||||
- [frontend/src/layout/index.vue:152-233](file://frontend/src/layout/index.vue#L152-L233)
|
||||
|
||||
## 架构概览
|
||||
|
||||
@@ -148,89 +169,108 @@ LuxLayout --> ChangePasswordDialog : "使用"
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant User as 用户
|
||||
participant Rail as 轨道导航
|
||||
participant Menu as 主菜单
|
||||
participant Router as Vue Router
|
||||
participant Layout as 布局组件
|
||||
participant Tabs as 标签页组件
|
||||
participant View as 页面视图
|
||||
User->>Router : 访问页面
|
||||
User->>Rail : 点击轨道图标
|
||||
Rail->>Layout : handleRailClick()
|
||||
Layout->>Layout : isSidebarCollapsed = false
|
||||
Note over Layout : 自动展开侧边栏
|
||||
User->>Menu : 选择菜单项
|
||||
Menu->>Router : 路由跳转
|
||||
Router->>Layout : 加载布局
|
||||
Layout->>Layout : 初始化状态
|
||||
Layout->>Tabs : 渲染标签页
|
||||
Tabs->>View : 加载页面内容
|
||||
View-->>User : 显示页面
|
||||
Note over Layout,Tabs : 动态标签页管理
|
||||
Note over Layout,View : 路由变化触发更新
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [frontend/src/router/index.js:64-88](file://frontend/src/router/index.js#L64-L88)
|
||||
- [frontend/src/layout/index.vue:173-179](file://frontend/src/layout/index.vue#L173-L179)
|
||||
- [frontend/src/layout/index.vue:195-197](file://frontend/src/layout/index.vue#L195-L197)
|
||||
- [frontend/src/router/index.js:76-100](file://frontend/src/router/index.js#L76-L100)
|
||||
|
||||
### 数据流架构
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[用户交互] --> B[路由变化监听]
|
||||
B --> C[激活菜单项计算]
|
||||
C --> D[面包屑标题计算]
|
||||
D --> E[侧边栏展开状态]
|
||||
F[页面内容] --> G[标签页管理]
|
||||
G --> H[会话存储持久化]
|
||||
H --> I[页面缓存控制]
|
||||
J[用户菜单] --> K[权限检查]
|
||||
K --> L[功能访问控制]
|
||||
L --> M[页面跳转]
|
||||
A[用户交互] --> B{轨道导航点击}
|
||||
B --> |是| C[handleRailClick()]
|
||||
C --> D[展开侧边栏]
|
||||
B --> |否| E[路由变化监听]
|
||||
E --> F[激活菜单项计算]
|
||||
F --> G[面包屑标题计算]
|
||||
G --> H[侧边栏展开状态]
|
||||
I[页面内容] --> J[标签页管理]
|
||||
J --> K[会话存储持久化]
|
||||
K --> L[页面缓存控制]
|
||||
M[用户菜单] --> N[权限检查]
|
||||
N --> O[功能访问控制]
|
||||
O --> P[页面跳转]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [frontend/src/layout/index.vue:154-221](file://frontend/src/layout/index.vue#L154-L221)
|
||||
- [frontend/src/layout/index.vue:174-212](file://frontend/src/layout/index.vue#L174-L212)
|
||||
|
||||
**章节来源**
|
||||
- [frontend/src/layout/index.vue:154-221](file://frontend/src/layout/index.vue#L154-L221)
|
||||
- [frontend/src/layout/index.vue:174-212](file://frontend/src/layout/index.vue#L174-L212)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### 主布局组件详解
|
||||
|
||||
#### 布局结构设计
|
||||
#### 三层导航结构设计
|
||||
|
||||
主布局组件采用了响应式设计原则,通过CSS Grid和Flexbox实现灵活的布局:
|
||||
主布局组件采用了创新的三层导航架构,通过CSS Grid和Flexbox实现灵活的布局:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "桌面端布局"
|
||||
A[侧边栏 64px] --> B[展开时 220px]
|
||||
C[右侧内容区] --> D[弹性增长]
|
||||
E[顶部导航] --> F[44px高度]
|
||||
G[底部版权] --> H[自动高度]
|
||||
subgraph "轨道导航层"
|
||||
A[SidebarRail<br/>64px宽度] --> B[三个分类图标]
|
||||
B --> C[耳机管理图标]
|
||||
B --> D[升级管理图标]
|
||||
B --> E[分享码图标]
|
||||
end
|
||||
subgraph "移动端适配"
|
||||
I[触摸手势] --> J[侧边栏滑动]
|
||||
K[小屏优化] --> L[图标导航优先]
|
||||
M[响应式断点] --> N[768px以下]
|
||||
subgraph "主菜单层"
|
||||
F[LuxMenu<br/>220px宽度] --> G[耳机管理子菜单]
|
||||
F --> H[升级管理子菜单]
|
||||
F --> I[分享码子菜单]
|
||||
G --> J[品牌管理]
|
||||
G --> K[型号管理]
|
||||
H --> L[OTA管理]
|
||||
H --> M[黑名单管理]
|
||||
H --> N[定向升级]
|
||||
I --> O[分享日志]
|
||||
end
|
||||
subgraph "面包屑层"
|
||||
P[顶部导航] --> Q[动态路径生成]
|
||||
Q --> R[当前页面标识]
|
||||
end
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [frontend/src/layout/index.vue:10-15](file://frontend/src/layout/index.vue#L10-L15)
|
||||
- [frontend/src/styles/lux-theme.css:101-130](file://frontend/src/styles/lux-theme.css#L101-L130)
|
||||
- [frontend/src/layout/index.vue:22-91](file://frontend/src/layout/index.vue#L22-L91)
|
||||
- [frontend/src/layout/index.vue:189-193](file://frontend/src/layout/index.vue#L189-L193)
|
||||
|
||||
#### 导航系统实现
|
||||
#### 智能导航系统实现
|
||||
|
||||
布局组件实现了双层导航系统:
|
||||
布局组件实现了智能化的三层导航系统:
|
||||
|
||||
1. **侧边栏主导航**:使用`SidebarRail`和`LuxMenu`实现
|
||||
2. **顶部面包屑导航**:动态生成面包屑路径
|
||||
3. **用户下拉菜单**:权限相关的用户操作
|
||||
1. **轨道导航层**:轻量化的图标导航,点击后自动展开侧边栏
|
||||
2. **主菜单层**:分类化的三级菜单结构,支持展开/收起
|
||||
3. **面包屑导航层**:动态生成面包屑路径,提供清晰的页面定位
|
||||
|
||||
**更新** 轨道导航采用普通锚元素配合点击处理器,提供了更灵活的导航行为和更好的用户体验。
|
||||
|
||||
**章节来源**
|
||||
- [frontend/src/layout/index.vue:18-137](file://frontend/src/layout/index.vue#L18-L137)
|
||||
- [frontend/src/layout/index.vue:22-91](file://frontend/src/layout/index.vue#L22-L91)
|
||||
|
||||
### 侧边栏组件分析
|
||||
|
||||
#### 设计特点
|
||||
#### 创新的双层设计
|
||||
|
||||
侧边栏采用了创新的玻璃拟态设计:
|
||||
侧边栏采用了创新的玻璃拟态双层设计:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
@@ -241,25 +281,28 @@ class SidebarGlass {
|
||||
+borderRight : 1px solid rgba(255,255,255,0.08)
|
||||
+transition : width 0.30s ease
|
||||
}
|
||||
class SidebarRail {
|
||||
+position : absolute
|
||||
+visibility : hidden/visible
|
||||
+opacity : 0/1
|
||||
+pointerEvents : none/auto
|
||||
+railNavItems : Array
|
||||
}
|
||||
class SidebarLogo {
|
||||
+collapsed : Boolean
|
||||
+animation : slide/fade
|
||||
+responsive : true
|
||||
}
|
||||
class SidebarNavWrap {
|
||||
+position : absolute
|
||||
+position : relative
|
||||
+overflow : hidden
|
||||
+flex : 1
|
||||
}
|
||||
class SidebarRail {
|
||||
+visibility : hidden/visible
|
||||
+opacity : 0/1
|
||||
+pointerEvents : none/auto
|
||||
}
|
||||
class LuxMenu {
|
||||
+expanded : true/false
|
||||
+activeItem : highlight
|
||||
+hoverEffect : gradient
|
||||
+elSubMenus : Array
|
||||
}
|
||||
SidebarGlass --> SidebarLogo
|
||||
SidebarGlass --> SidebarNavWrap
|
||||
@@ -268,12 +311,12 @@ SidebarNavWrap --> LuxMenu
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [frontend/src/layout/index.vue:10-86](file://frontend/src/layout/index.vue#L10-L86)
|
||||
- [frontend/src/layout/index.vue:10-93](file://frontend/src/layout/index.vue#L10-L93)
|
||||
- [frontend/src/styles/lux-theme.css:101-195](file://frontend/src/styles/lux-theme.css#L101-L195)
|
||||
|
||||
#### 交互逻辑
|
||||
#### 智能交互逻辑
|
||||
|
||||
侧边栏的交互逻辑通过Vue的响应式系统实现:
|
||||
侧边栏的交互逻辑通过Vue的响应式系统实现,新增了智能展开功能:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
@@ -283,17 +326,62 @@ B --> |false| D[保持状态]
|
||||
E[鼠标离开] --> F{isSidebarCollapsed}
|
||||
F --> |false| G[设置为true]
|
||||
F --> |true| H[保持状态]
|
||||
I[菜单点击] --> J[更新activeMenu]
|
||||
J --> K[同步面包屑]
|
||||
K --> L[更新openedMenus]
|
||||
I[轨道导航点击] --> J[handleRailClick()]
|
||||
J --> K[强制展开侧边栏]
|
||||
K --> L[设置isSidebarCollapsed = false]
|
||||
M[菜单点击] --> N[更新activeMenu]
|
||||
N --> O[同步面包屑]
|
||||
O --> P[更新openedMenus]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [frontend/src/layout/index.vue:13-14](file://frontend/src/layout/index.vue#L13-L14)
|
||||
- [frontend/src/layout/index.vue:166-179](file://frontend/src/layout/index.vue#L166-L179)
|
||||
- [frontend/src/layout/index.vue:195-197](file://frontend/src/layout/index.vue#L195-L197)
|
||||
- [frontend/src/layout/index.vue:181-187](file://frontend/src/layout/index.vue#L181-L187)
|
||||
|
||||
**更新** 新增了`handleRailClick()`函数,当用户点击轨道导航图标时,会自动展开侧边栏,提供更好的用户体验。
|
||||
|
||||
**章节来源**
|
||||
- [frontend/src/layout/index.vue:10-86](file://frontend/src/layout/index.vue#L10-L86)
|
||||
- [frontend/src/layout/index.vue:10-93](file://frontend/src/layout/index.vue#L10-L93)
|
||||
|
||||
### 导航分类重构
|
||||
|
||||
#### 三大功能模块
|
||||
|
||||
导航系统重构为三个主要功能模块:
|
||||
|
||||
1. **耳机管理模块** (`index="1"`)
|
||||
- 品牌管理 (`/brand`)
|
||||
- 型号管理 (`/model`)
|
||||
|
||||
2. **升级管理模块** (`index="upgrade"`)
|
||||
- OTA 管理 (`/ota`)
|
||||
- 黑名单管理 (`/blacklist`)
|
||||
- 定向升级 (`/ota-target-device`)
|
||||
|
||||
3. **分享码模块** (`index="share-code"`)
|
||||
- 分享日志 (`/share-code/log`)
|
||||
|
||||
#### 智能菜单展开逻辑
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[路由路径] --> B{路径匹配}
|
||||
B --> |/brand 或 /model| C[展开耳机管理]
|
||||
B --> |/ota 或 /blacklist 或 /ota-target-device| D[展开升级管理]
|
||||
B --> |/share-code/*| E[展开分享码]
|
||||
B --> |其他路径| F[不展开任何菜单]
|
||||
C --> G[openedMenus = ['1']]
|
||||
D --> H[openedMenus = ['upgrade']]
|
||||
E --> I[openedMenus = ['share-code']]
|
||||
F --> J[openedMenus = []]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [frontend/src/layout/index.vue:174-179](file://frontend/src/layout/index.vue#L174-L179)
|
||||
|
||||
**章节来源**
|
||||
- [frontend/src/layout/index.vue:49-90](file://frontend/src/layout/index.vue#L49-L90)
|
||||
|
||||
### 标签页组件分析
|
||||
|
||||
@@ -408,10 +496,13 @@ M[Vue Router] --> N[路由导航]
|
||||
N --> O[权限控制]
|
||||
P[Auth Utils] --> Q[用户认证]
|
||||
Q --> R[权限验证]
|
||||
S[Icons] --> T[Headset, Upload, Share等图标]
|
||||
T --> U[轨道导航图标]
|
||||
T --> V[菜单项图标]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [frontend/src/layout/index.vue:149-152](file://frontend/src/layout/index.vue#L149-L152)
|
||||
- [frontend/src/layout/index.vue:156-160](file://frontend/src/layout/index.vue#L156-L160)
|
||||
- [frontend/src/router/index.js:1-5](file://frontend/src/router/index.js#L1-L5)
|
||||
|
||||
### 外部依赖分析
|
||||
@@ -425,8 +516,10 @@ Q --> R[权限验证]
|
||||
| 路由管理 | vue-router | 最新版 | 页面导航 |
|
||||
| 图标系统 | @element-plus/icons-vue | 最新版 | 图标组件 |
|
||||
|
||||
**更新** 新增了多个图标组件的使用,包括Headset、Upload、Share等用于新的导航系统。
|
||||
|
||||
**章节来源**
|
||||
- [frontend/src/layout/index.vue:144-152](file://frontend/src/layout/index.vue#L144-L152)
|
||||
- [frontend/src/layout/index.vue:156-160](file://frontend/src/layout/index.vue#L156-L160)
|
||||
- [frontend/src/router/index.js:1-5](file://frontend/src/router/index.js#L1-L5)
|
||||
|
||||
## 性能考虑
|
||||
@@ -439,6 +532,7 @@ Q --> R[权限验证]
|
||||
2. **懒加载**:路由级别的组件懒加载
|
||||
3. **缓存机制**:标签页内容的KeepAlive缓存
|
||||
4. **事件节流**:侧边栏交互事件的处理
|
||||
5. **计算属性优化**:使用computed缓存导航状态计算结果
|
||||
|
||||
### 内存管理
|
||||
|
||||
@@ -452,6 +546,8 @@ F --> G[释放内存]
|
||||
G --> H[垃圾回收]
|
||||
I[标签页切换] --> J[KeepAlive缓存]
|
||||
J --> K[避免重复渲染]
|
||||
L[导航状态变化] --> M[响应式更新]
|
||||
M --> N[最小化重渲染]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
@@ -461,6 +557,20 @@ J --> K[避免重复渲染]
|
||||
|
||||
### 常见问题及解决方案
|
||||
|
||||
#### 导航系统问题
|
||||
|
||||
**问题**:轨道导航点击无反应
|
||||
**原因**:`handleRailClick`函数未正确绑定
|
||||
**解决**:检查模板中的`@click.prevent="handleRailClick"`绑定
|
||||
|
||||
**问题**:侧边栏无法展开
|
||||
**原因**:`isSidebarCollapsed`状态异常
|
||||
**解决**:检查watch监听器和状态更新逻辑
|
||||
|
||||
**问题**:菜单分类不正确
|
||||
**原因**:`resolveOpenedMenus`函数路径匹配错误
|
||||
**解决**:验证路由路径前缀匹配逻辑
|
||||
|
||||
#### 布局显示异常
|
||||
|
||||
**问题**:侧边栏宽度不正确
|
||||
@@ -482,16 +592,25 @@ J --> K[避免重复渲染]
|
||||
**解决**:确保在组件卸载时清理所有监听器
|
||||
|
||||
**章节来源**
|
||||
- [frontend/src/layout/index.vue:173-179](file://frontend/src/layout/index.vue#L173-L179)
|
||||
- [frontend/src/layout/index.vue:195-197](file://frontend/src/layout/index.vue#L195-L197)
|
||||
- [frontend/src/layout/index.vue:174-187](file://frontend/src/layout/index.vue#L174-L187)
|
||||
- [frontend/src/components/TabsView.vue:276-286](file://frontend/src/components/TabsView.vue#L276-L286)
|
||||
|
||||
## 结论
|
||||
|
||||
本布局组件展现了现代前端开发的最佳实践,通过精心设计的架构实现了:
|
||||
|
||||
1. **优秀的用户体验**:响应式设计和流畅的交互效果
|
||||
2. **可维护性**:清晰的组件分离和模块化设计
|
||||
3. **可扩展性**:灵活的主题系统和配置选项
|
||||
4. **性能优化**:合理的渲染策略和资源管理
|
||||
1. **创新的三层导航系统**:轨道导航 + 分类菜单 + 面包屑导航,提供丰富的导航体验
|
||||
2. **智能交互设计**:自动展开侧边栏、智能菜单展开、流畅的过渡动画
|
||||
3. **优秀的用户体验**:响应式设计和流畅的交互效果
|
||||
4. **可维护性**:清晰的组件分离和模块化设计
|
||||
5. **可扩展性**:灵活的主题系统和配置选项
|
||||
6. **性能优化**:合理的渲染策略和资源管理
|
||||
|
||||
该布局组件为整个Dashboard系统提供了坚实的基础,支持未来功能的扩展和定制化需求。通过合理的架构设计和实现细节,确保了系统的稳定性和可维护性。
|
||||
**最新更新亮点**:
|
||||
- **简化的导航结构**:从六个独立菜单项重构为三个主要分类,提升了导航效率
|
||||
- **创新的轨道导航**:轻量化的图标导航条,提供快速访问入口
|
||||
- **智能的用户体验**:点击轨道图标自动展开侧边栏,减少操作步骤
|
||||
- **灵活的导航实现**:采用普通锚元素配合点击处理器,提供更灵活的导航行为
|
||||
|
||||
该布局组件为整个Dashboard系统提供了坚实的基础,支持未来功能的扩展和定制化需求。通过合理的架构设计和实现细节,确保了系统的稳定性和可维护性。新的导航系统不仅提升了用户体验,也为后续的功能扩展提供了良好的架构基础。
|
||||
@@ -15,6 +15,13 @@
|
||||
- [frontend/package.json](file://frontend/package.json)
|
||||
</cite>
|
||||
|
||||
## 更新摘要
|
||||
**变更内容**
|
||||
- 版本唯一性约束从'verCode + model'升级为'verCode + model + beta',支持同一设备型号下存在多个不同beta状态的版本
|
||||
- 在创建/更新接口中新增对beta字段的支持,允许设置灰度发布状态
|
||||
- 前端新增beta筛选功能,支持按灰度状态过滤版本列表
|
||||
- 实现基于(model, beta)组合的最新版本标识显示逻辑
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
@@ -30,11 +37,12 @@
|
||||
## 简介
|
||||
本文件为OTA固件管理API的完整RESTful接口文档,涵盖固件版本管理的HTTP方法、URL模式、请求/响应格式以及文件上传处理流程。内容包括:
|
||||
- 固件版本列表查询、详情获取、创建、更新、删除接口
|
||||
- 设备端“最新版本检查”接口
|
||||
- 设备端"最新版本检查"接口
|
||||
- 文件上传(Luxsin-X8上传至S3,Luxsin-X9保存到本地目录)
|
||||
- 存储服务配置与使用示例
|
||||
- 固件版本比较、强制更新策略与兼容性检查机制
|
||||
- 下载链接生成、版本升级通知与错误处理实现指南
|
||||
- **新增**:Beta版本支持与灰度发布管理功能
|
||||
|
||||
## 项目结构
|
||||
后端采用Express + Sequelize + MySQL架构,前端基于Vue3 + Element Plus。OTA相关逻辑集中在路由、模型、服务层与验证器中,并通过统一响应封装返回。
|
||||
@@ -65,20 +73,20 @@ STORE --> ENV
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [backend/src/routes/ota.js:1-292](file://backend/src/routes/ota.js#L1-L292)
|
||||
- [backend/src/routes/ota.js:1-295](file://backend/src/routes/ota.js#L1-L295)
|
||||
- [frontend/src/api/ota.js:1-68](file://frontend/src/api/ota.js#L1-L68)
|
||||
- [frontend/src/views/ota/index.vue:1-628](file://frontend/src/views/ota/index.vue#L1-L628)
|
||||
- [frontend/src/views/ota/index.vue:1-1068](file://frontend/src/views/ota/index.vue#L1-L1068)
|
||||
|
||||
章节来源
|
||||
- [backend/src/routes/ota.js:1-292](file://backend/src/routes/ota.js#L1-L292)
|
||||
- [backend/src/routes/ota.js:1-295](file://backend/src/routes/ota.js#L1-L295)
|
||||
- [frontend/src/api/ota.js:1-68](file://frontend/src/api/ota.js#L1-L68)
|
||||
- [frontend/src/views/ota/index.vue:1-628](file://frontend/src/views/ota/index.vue#L1-L628)
|
||||
- [frontend/src/views/ota/index.vue:1-1068](file://frontend/src/views/ota/index.vue#L1-L1068)
|
||||
|
||||
## 核心组件
|
||||
- 路由层:定义所有OTA相关HTTP接口,包含设备端“最新版本检查”和后台管理接口。
|
||||
- 路由层:定义所有OTA相关HTTP接口,包含设备端"最新版本检查"和后台管理接口。
|
||||
- 认证中间件:保护后台接口,要求Bearer Token。
|
||||
- 参数校验:使用Zod对创建/更新请求体进行严格校验。
|
||||
- 数据模型:Sequelize定义的OTA表结构,包含版本号、MD5、强制更新、定向灰度、时间窗口等字段。
|
||||
- 参数校验:使用Zod对创建/更新请求体进行严格校验,支持beta字段验证。
|
||||
- 数据模型:Sequelize定义的OTA表结构,包含版本号、MD5、强制更新、定向灰度、时间窗口等字段,**新增beta字段支持**。
|
||||
- 存储服务:根据设备型号选择不同存储路径(S3或本地),并生成公开下载链接。
|
||||
- 响应封装:统一封装成功/错误/无数据三类响应格式。
|
||||
|
||||
@@ -117,7 +125,7 @@ Router->>Logger : 记录查询结果
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### 设备端“最新版本检查”
|
||||
### 设备端"最新版本检查"
|
||||
- 方法与路径:GET /api/ota/latest/check
|
||||
- 请求参数:
|
||||
- currentVerCode: 当前设备版本号(整数)
|
||||
@@ -145,10 +153,13 @@ Router->>Logger : 记录查询结果
|
||||
- verName: 模糊匹配版本名称
|
||||
- model: 模糊匹配设备型号
|
||||
- status: 状态(0/1)
|
||||
- **beta: 灰度状态筛选(0/1)**
|
||||
- 响应:分页数据(items、total、skip、limit)
|
||||
|
||||
**更新** 新增beta参数支持,可按灰度状态筛选版本列表
|
||||
|
||||
章节来源
|
||||
- [backend/src/routes/ota.js:107-143](file://backend/src/routes/ota.js#L107-L143)
|
||||
- [backend/src/routes/ota.js:107-145](file://backend/src/routes/ota.js#L107-L145)
|
||||
|
||||
#### 获取指定OTA详情
|
||||
- 方法与路径:GET /api/ota/:ota_id
|
||||
@@ -156,12 +167,12 @@ Router->>Logger : 记录查询结果
|
||||
- 响应:单条记录或无数据
|
||||
|
||||
章节来源
|
||||
- [backend/src/routes/ota.js:145-160](file://backend/src/routes/ota.js#L145-L160)
|
||||
- [backend/src/routes/ota.js:147-162](file://backend/src/routes/ota.js#L147-L162)
|
||||
|
||||
#### 创建OTA版本
|
||||
- 方法与路径:POST /api/ota/
|
||||
- 请求体字段(必填/可选见校验规则):
|
||||
- verCode: 整数(唯一性约束:同model下不可重复)
|
||||
- verCode: 整数(**唯一性约束:同model+beta下不可重复**)
|
||||
- verName: 字符串(1~20)
|
||||
- url: 字符串(下载地址或上传后生成的URL)
|
||||
- md5: 32位十六进制字符串
|
||||
@@ -170,13 +181,15 @@ Router->>Logger : 记录查询结果
|
||||
- model: 设备型号(可空)
|
||||
- hw: 硬件版本号(默认0)
|
||||
- target: 是否定向(0/1,默认0)
|
||||
- beta: 是否灰度(0/1,默认0)
|
||||
- **beta: 是否灰度(0/1,默认0)**
|
||||
- startTime/endTime: 时间字符串(可空)
|
||||
- status: 状态(0/1,默认1)
|
||||
- 响应:创建成功的记录
|
||||
|
||||
**更新** 版本唯一性约束已更新为'verCode + model + beta'组合,允许同一设备型号下存在多个不同beta状态的版本
|
||||
|
||||
章节来源
|
||||
- [backend/src/routes/ota.js:162-194](file://backend/src/routes/ota.js#L162-L194)
|
||||
- [backend/src/routes/ota.js:164-196](file://backend/src/routes/ota.js#L164-L196)
|
||||
- [backend/src/validators/ota.js:1-36](file://backend/src/validators/ota.js#L1-L36)
|
||||
- [backend/src/models/Ota.js:1-97](file://backend/src/models/Ota.js#L1-L97)
|
||||
|
||||
@@ -185,11 +198,13 @@ Router->>Logger : 记录查询结果
|
||||
- 请求体字段:同创建接口(部分字段可为空表示不更新)
|
||||
- 响应:更新后的记录
|
||||
- 注意:
|
||||
- 若更新版本号或设备型号,需保证新的组合在同model下唯一
|
||||
- **若更新版本号、设备型号或灰度状态,需保证新的组合在同model+beta下唯一**
|
||||
- 日期字段会自动转换为Date类型
|
||||
|
||||
**更新** 版本冲突检查逻辑已更新,现在考虑beta字段参与唯一性验证
|
||||
|
||||
章节来源
|
||||
- [backend/src/routes/ota.js:196-247](file://backend/src/routes/ota.js#L196-L247)
|
||||
- [backend/src/routes/ota.js:198-250](file://backend/src/routes/ota.js#L198-L250)
|
||||
- [backend/src/validators/ota.js:19-33](file://backend/src/validators/ota.js#L19-L33)
|
||||
|
||||
#### 删除OTA版本
|
||||
@@ -197,7 +212,7 @@ Router->>Logger : 记录查询结果
|
||||
- 响应:删除成功消息
|
||||
|
||||
章节来源
|
||||
- [backend/src/routes/ota.js:249-268](file://backend/src/routes/ota.js#L249-L268)
|
||||
- [backend/src/routes/ota.js:252-271](file://backend/src/routes/ota.js#L252-L271)
|
||||
|
||||
### 文件上传与存储
|
||||
|
||||
@@ -255,14 +270,18 @@ Router-->>Client : 成功响应
|
||||
- 前端API模块提供:
|
||||
- 列表、详情、创建、更新、删除、上传包等方法
|
||||
- OTA页面视图:
|
||||
- 支持搜索(版本名、设备型号、状态、版本号)
|
||||
- 支持搜索(版本名、设备型号、状态、版本号、**灰度状态**)
|
||||
- 分页与表格展示
|
||||
- **新增beta筛选下拉框,支持按灰度状态过滤**
|
||||
- **实现基于(model, beta)组合的最新版本标识显示**
|
||||
- 上传升级包(X8/X9)并回填URL与MD5
|
||||
- 表单校验与提交
|
||||
|
||||
**更新** 前端新增beta筛选功能和智能最新版本标识显示逻辑
|
||||
|
||||
章节来源
|
||||
- [frontend/src/api/ota.js:1-68](file://frontend/src/api/ota.js#L1-L68)
|
||||
- [frontend/src/views/ota/index.vue:1-628](file://frontend/src/views/ota/index.vue#L1-L628)
|
||||
- [frontend/src/views/ota/index.vue:1-1068](file://frontend/src/views/ota/index.vue#L1-L1068)
|
||||
|
||||
## 依赖关系分析
|
||||
|
||||
@@ -317,7 +336,7 @@ OtaRoute --> ApiResponse : "统一响应"
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [backend/src/routes/ota.js:1-292](file://backend/src/routes/ota.js#L1-L292)
|
||||
- [backend/src/routes/ota.js:1-295](file://backend/src/routes/ota.js#L1-L295)
|
||||
- [backend/src/middleware/auth.js:1-36](file://backend/src/middleware/auth.js#L1-L36)
|
||||
- [backend/src/utils/response.js:1-25](file://backend/src/utils/response.js#L1-L25)
|
||||
- [backend/src/validators/ota.js:1-36](file://backend/src/validators/ota.js#L1-L36)
|
||||
@@ -326,13 +345,14 @@ OtaRoute --> ApiResponse : "统一响应"
|
||||
|
||||
## 性能考量
|
||||
- 列表查询限制每页最大1000条,避免一次性返回过多数据。
|
||||
- “最新版本检查”接口按verCode降序查询第一条,索引建议:
|
||||
- "最新版本检查"接口按verCode降序查询第一条,索引建议:
|
||||
- 在verCode、model、status上建立复合索引以提升查询效率。
|
||||
- **建议增加beta字段的索引以优化灰度版本筛选查询**。
|
||||
- 文件上传使用内存存储(multer.memoryStorage),大文件可能影响内存占用,建议:
|
||||
- 控制上传文件大小与超时时间(前端已设置较长超时)。
|
||||
- 对于X8大文件,优先考虑流式上传或分片上传策略(当前实现为一次性上传)。
|
||||
|
||||
[本节为通用性能建议,不直接分析具体文件]
|
||||
**更新** 建议为beta字段添加数据库索引以优化灰度版本筛选性能
|
||||
|
||||
## 故障排查指南
|
||||
- 认证失败(401):
|
||||
@@ -340,24 +360,28 @@ OtaRoute --> ApiResponse : "统一响应"
|
||||
- 确认Token未过期
|
||||
- 参数校验失败:
|
||||
- 按照Zod校验规则修正请求体字段(长度、类型、取值范围)
|
||||
- 版本冲突:
|
||||
- 创建/更新时若verCode与model组合重复,会返回“该版本已存在”
|
||||
- **版本冲突**:
|
||||
- **创建/更新时若verCode、model和beta组合重复,会返回"该版本已存在(相同版本+灰度状态)"**
|
||||
- **确保在同一设备型号和灰度状态下版本号的唯一性**
|
||||
- S3上传失败:
|
||||
- 检查AWS_REGION、AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY与AWS_S3_OTA_BUCKET配置
|
||||
- 确认S3权限与存储桶存在
|
||||
- 无可用版本:
|
||||
- 设备端查询不到更高版本时返回“无数据”,确认目标设备型号、硬件版本与状态
|
||||
- 设备端查询不到更高版本时返回"无数据",确认目标设备型号、硬件版本与状态
|
||||
|
||||
**更新** 版本冲突错误信息已更新,明确说明需要检查verCode + model + beta组合的唯一性
|
||||
|
||||
章节来源
|
||||
- [backend/src/middleware/auth.js:1-36](file://backend/src/middleware/auth.js#L1-L36)
|
||||
- [backend/src/validators/ota.js:1-36](file://backend/src/validators/ota.js#L1-L36)
|
||||
- [backend/src/routes/ota.js:174-181](file://backend/src/routes/ota.js#L174-L181)
|
||||
- [backend/src/routes/ota.js:176-183](file://backend/src/routes/ota.js#L176-L183)
|
||||
- [backend/src/routes/ota.js:223-231](file://backend/src/routes/ota.js#L223-L231)
|
||||
- [backend/src/services/otaStorage.js:72-103](file://backend/src/services/otaStorage.js#L72-L103)
|
||||
|
||||
## 结论
|
||||
本OTA固件API提供了完善的版本管理能力,支持设备端“最新版本检查”与后台管理功能,结合S3与本地存储策略满足不同设备型号的升级包分发需求。通过严格的参数校验与统一响应封装,提升了接口的稳定性与易用性。建议在生产环境中完善索引、优化大文件上传策略,并加强S3权限与监控告警。
|
||||
本OTA固件API提供了完善的版本管理能力,支持设备端"最新版本检查"与后台管理功能,结合S3与本地存储策略满足不同设备型号的升级包分发需求。**新增的beta版本支持功能使得系统能够管理同一设备型号下的多个灰度版本,提升了版本发布的灵活性和可控性**。通过严格的参数校验与统一响应封装,提升了接口的稳定性与易用性。建议在生产环境中完善索引、优化大文件上传策略,并加强S3权限与监控告警。
|
||||
|
||||
[本节为总结性内容,不直接分析具体文件]
|
||||
**更新** 系统现已支持完整的灰度发布管理,允许在同一设备型号下并行管理稳定版和测试版固件。
|
||||
|
||||
## 附录
|
||||
|
||||
@@ -373,16 +397,38 @@ OtaRoute --> ApiResponse : "统一响应"
|
||||
- 版本比较:仅返回verCode大于当前版本且状态为可用的最高版本
|
||||
- 强制更新:由force字段控制,客户端据此决定是否强制升级
|
||||
- 定向/灰度:target/beta字段可用于控制发布范围
|
||||
- **新版本管理**:系统支持同一设备型号下存在多个不同beta状态的版本,每个(beta, model)组合都有独立的最新版本标识
|
||||
|
||||
**更新** 最新版本标识逻辑已更新,现在基于(model, beta)组合来计算和显示latest标签
|
||||
|
||||
章节来源
|
||||
- [backend/src/routes/ota.js:77-89](file://backend/src/routes/ota.js#L77-L89)
|
||||
- [backend/src/models/Ota.js:33-66](file://backend/src/models/Ota.js#L33-L66)
|
||||
- [frontend/src/views/ota/index.vue:428-443](file://frontend/src/views/ota/index.vue#L428-L443)
|
||||
|
||||
### 前端调用示例(参考)
|
||||
- 列表查询:传入skip、limit、verName、model、status、verCode
|
||||
- 列表查询:传入skip、limit、verName、model、status、verCode、**beta**
|
||||
- 上传包:构造FormData,包含package_file与model,设置Content-Type为multipart/form-data
|
||||
- 提交表单:根据设备型号决定是否需要先上传包再填写URL/MD5
|
||||
- **beta筛选**:在searchForm中添加beta字段,值为0或1进行灰度状态筛选
|
||||
|
||||
**更新** 前端API调用示例已更新,包含beta参数的使用方法
|
||||
|
||||
章节来源
|
||||
- [frontend/src/api/ota.js:13-67](file://frontend/src/api/ota.js#L13-L67)
|
||||
- [frontend/src/views/ota/index.vue:420-449](file://frontend/src/views/ota/index.vue#L420-L449)
|
||||
- [frontend/src/views/ota/index.vue:412-418](file://frontend/src/views/ota/index.vue#L412-L418)
|
||||
- [frontend/src/views/ota/index.vue:597-599](file://frontend/src/views/ota/index.vue#L597-L599)
|
||||
|
||||
### Beta版本管理特性
|
||||
- **版本唯一性**:同一设备型号下,相同版本号但不同beta状态的版本可以共存
|
||||
- **灰度发布**:通过beta字段控制版本是否为灰度版本(0=否,1=是)
|
||||
- **智能标识**:前端自动计算并显示每个(model, beta)组合下的最新版本标签
|
||||
- **筛选功能**:支持按beta状态筛选版本列表,便于管理不同发布阶段的版本
|
||||
|
||||
**新增** Beta版本管理功能的详细说明
|
||||
|
||||
章节来源
|
||||
- [backend/src/routes/ota.js:176-183](file://backend/src/routes/ota.js#L176-L183)
|
||||
- [backend/src/routes/ota.js:218-231](file://backend/src/routes/ota.js#L218-L231)
|
||||
- [frontend/src/views/ota/index.vue:428-443](file://frontend/src/views/ota/index.vue#L428-L443)
|
||||
- [frontend/src/views/ota/index.vue:35-45](file://frontend/src/views/ota/index.vue#L35-L45)
|
||||
@@ -12,15 +12,15 @@
|
||||
- [backend/src/routes/ota.js](file://backend/src/routes/ota.js)
|
||||
- [backend/src/services/squiglink.js](file://backend/src/services/squiglink.js)
|
||||
- [frontend/src/views/model/components/ModelFormDialog.vue](file://frontend/src/views/model/components/ModelFormDialog.vue)
|
||||
- [backend/src/services/measurementStorage.js](file://backend/src/services/measurementStorage.js)
|
||||
</cite>
|
||||
|
||||
## 更新摘要
|
||||
**变更内容**
|
||||
- 新增squig.link外部URL数据源抓取功能
|
||||
- 增强模型创建/更新流程支持外部频响数据源
|
||||
- 添加squiglink_csv字段支持直接上传CSV内容
|
||||
- 新增squiglink-fetch接口用于从外部URL获取频响数据
|
||||
- 前端ModelFormDialog组件集成squig.link导入功能
|
||||
- 新增测量文件S3自动迁移功能,当更新型号的路径相关字段时自动迁移现有CSV文件
|
||||
- 增强型号更新接口的智能文件处理逻辑
|
||||
- 实现S3服务端文件复制与删除操作,确保数据一致性
|
||||
- 优化型号管理流程,减少手动文件干预需求
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
@@ -34,16 +34,16 @@
|
||||
9. [结论](#结论)
|
||||
|
||||
## 简介
|
||||
本文件为型号管理API的详细RESTful API文档,覆盖型号的CRUD操作、查询筛选与排序、数据验证规则,以及与OTA固件的一对多关联关系与级联操作。文档同时提供前端调用示例与后端实现细节,帮助开发者快速集成与维护。**最新更新**:新增squig.link外部数据源支持,增强模型创建/更新流程以支持外部URL数据源。
|
||||
本文件为型号管理API的详细RESTful API文档,覆盖型号的CRUD操作、查询筛选与排序、数据验证规则,以及与OTA固件的一对多关联关系与级联操作。文档同时提供前端调用示例与后端实现细节,帮助开发者快速集成与维护。**最新更新**:新增squig.link外部数据源支持及测量文件S3自动迁移功能,显著提升型号数据管理的自动化程度和数据一致性保障。
|
||||
|
||||
## 项目结构
|
||||
型号管理API位于后端Express应用中,采用模块化设计:
|
||||
- 路由层:集中于 models.js,提供型号的增删改查、搜索推送、频响文件处理、**squig.link数据抓取**等接口
|
||||
- 路由层:集中于 models.js,提供型号的增删改查、搜索推送、频响文件处理、**squig.link数据抓取**、**S3文件自动迁移**等接口
|
||||
- 模型层:Model.js 定义数据库表结构
|
||||
- 验证层:model.js 使用Zod进行请求体验证
|
||||
- 工具层:response.js 统一响应格式
|
||||
- 中间件:auth.js 提供鉴权保护
|
||||
- **服务层**:squiglink.js 提供squig.link外部数据源抓取服务
|
||||
- **服务层**:squiglink.js 提供squig.link外部数据源抓取服务,measurementStorage.js 提供S3存储与文件迁移服务
|
||||
- 前端封装:frontend/src/api/model.js 提供HTTP调用封装
|
||||
- **前端组件**:ModelFormDialog.vue 集成squig.link导入功能
|
||||
|
||||
@@ -55,11 +55,13 @@ R --> V["验证层<br/>backend/src/validators/model.js"]
|
||||
R --> U["工具层<br/>backend/src/utils/response.js"]
|
||||
R --> A["中间件<br/>backend/src/middleware/auth.js"]
|
||||
R --> S["服务层<br/>backend/src/services/squiglink.js"]
|
||||
R --> MS["存储服务<br/>backend/src/services/measurementStorage.js"]
|
||||
R -. 关联 .-> OTA["OTA模型<br/>backend/src/models/Ota.js"]
|
||||
MS -. 存储 .-> S3["S3对象存储"]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [backend/src/routes/models.js:1-659](file://backend/src/routes/models.js#L1-L659)
|
||||
- [backend/src/routes/models.js:1-668](file://backend/src/routes/models.js#L1-L668)
|
||||
- [backend/src/models/Model.js:1-53](file://backend/src/models/Model.js#L1-L53)
|
||||
- [backend/src/validators/model.js:1-22](file://backend/src/validators/model.js#L1-L22)
|
||||
- [backend/src/utils/response.js:1-25](file://backend/src/utils/response.js#L1-L25)
|
||||
@@ -67,10 +69,11 @@ R -. 关联 .-> OTA["OTA模型<br/>backend/src/models/Ota.js"]
|
||||
- [frontend/src/api/model.js:1-165](file://frontend/src/api/model.js#L1-L165)
|
||||
- [backend/src/models/Ota.js:1-97](file://backend/src/models/Ota.js#L1-L97)
|
||||
- [backend/src/services/squiglink.js:1-322](file://backend/src/services/squiglink.js#L1-L322)
|
||||
- [backend/src/services/measurementStorage.js:1-165](file://backend/src/services/measurementStorage.js#L1-L165)
|
||||
- [frontend/src/views/model/components/ModelFormDialog.vue:1-555](file://frontend/src/views/model/components/ModelFormDialog.vue#L1-L555)
|
||||
|
||||
**章节来源**
|
||||
- [backend/src/routes/models.js:1-659](file://backend/src/routes/models.js#L1-L659)
|
||||
- [backend/src/routes/models.js:1-668](file://backend/src/routes/models.js#L1-L668)
|
||||
- [backend/src/models/Model.js:1-53](file://backend/src/models/Model.js#L1-L53)
|
||||
- [backend/src/validators/model.js:1-22](file://backend/src/validators/model.js#L1-L22)
|
||||
- [backend/src/utils/response.js:1-25](file://backend/src/utils/response.js#L1-L25)
|
||||
@@ -78,15 +81,17 @@ R -. 关联 .-> OTA["OTA模型<br/>backend/src/models/Ota.js"]
|
||||
- [frontend/src/api/model.js:1-165](file://frontend/src/api/model.js#L1-L165)
|
||||
- [backend/src/models/Ota.js:1-97](file://backend/src/models/Ota.js#L1-L97)
|
||||
- [backend/src/services/squiglink.js:1-322](file://backend/src/services/squiglink.js#L1-L322)
|
||||
- [backend/src/services/measurementStorage.js:1-165](file://backend/src/services/measurementStorage.js#L1-L165)
|
||||
- [frontend/src/views/model/components/ModelFormDialog.vue:1-555](file://frontend/src/views/model/components/ModelFormDialog.vue#L1-L555)
|
||||
|
||||
## 核心组件
|
||||
- 路由控制器:models.js 提供型号的列表查询、详情获取、创建、更新、删除、搜索推送、频响文件上传与查询、**squig.link数据抓取**等接口
|
||||
- 路由控制器:models.js 提供型号的列表查询、详情获取、创建、更新、删除、搜索推送、频响文件处理、**squig.link数据抓取**、**S3文件自动迁移**等接口
|
||||
- 数据模型:Model.js 定义型号字段及约束
|
||||
- 请求验证:model.js 使用Zod Schema进行创建/更新的输入校验
|
||||
- 统一响应:response.js 提供统一的响应结构
|
||||
- 鉴权中间件:auth.js 实现Bearer Token鉴权
|
||||
- **squig.link服务**:squiglink.js 提供外部数据源抓取功能
|
||||
- **S3存储服务**:measurementStorage.js 提供文件上传、下载、迁移等存储服务
|
||||
- 前端封装:frontend/src/api/model.js 提供HTTP调用封装
|
||||
- **前端组件**:ModelFormDialog.vue 集成squig.link导入功能
|
||||
|
||||
@@ -97,11 +102,12 @@ R -. 关联 .-> OTA["OTA模型<br/>backend/src/models/Ota.js"]
|
||||
- [backend/src/utils/response.js:1-25](file://backend/src/utils/response.js#L1-L25)
|
||||
- [backend/src/middleware/auth.js:3-26](file://backend/src/middleware/auth.js#L3-L26)
|
||||
- [backend/src/services/squiglink.js:1-322](file://backend/src/services/squiglink.js#L1-L322)
|
||||
- [backend/src/services/measurementStorage.js:1-165](file://backend/src/services/measurementStorage.js#L1-L165)
|
||||
- [frontend/src/api/model.js:13-165](file://frontend/src/api/model.js#L13-L165)
|
||||
- [frontend/src/views/model/components/ModelFormDialog.vue:158-464](file://frontend/src/views/model/components/ModelFormDialog.vue#L158-L464)
|
||||
|
||||
## 架构概览
|
||||
型号管理API采用分层架构,路由层负责HTTP协议与参数解析,模型层负责数据持久化,验证层确保输入合法性,工具层统一输出格式,中间件提供安全控制,**服务层提供外部数据源集成**。
|
||||
型号管理API采用分层架构,路由层负责HTTP协议与参数解析,模型层负责数据持久化,验证层确保输入合法性,工具层统一输出格式,中间件提供安全控制,**服务层提供外部数据源集成与S3存储管理**。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
@@ -110,6 +116,7 @@ participant R as "路由(models.js)"
|
||||
participant V as "验证(model.js)"
|
||||
participant M as "模型(Model.js)"
|
||||
participant S as "服务(squiglink.js)"
|
||||
participant MS as "存储服务(measurementStorage.js)"
|
||||
participant U as "响应(response.js)"
|
||||
participant A as "鉴权(auth.js)"
|
||||
C->>R : "HTTP请求"
|
||||
@@ -119,6 +126,8 @@ R->>V : "请求体验证"
|
||||
V-->>R : "验证结果"
|
||||
R->>S : "外部数据源抓取可选"
|
||||
S-->>R : "抓取结果"
|
||||
R->>MS : "S3文件操作(上传/迁移)"
|
||||
MS-->>R : "操作结果"
|
||||
R->>M : "数据库操作"
|
||||
M-->>R : "结果"
|
||||
R->>U : "封装响应"
|
||||
@@ -130,6 +139,7 @@ U-->>C : "统一响应"
|
||||
- [backend/src/validators/model.js:3-19](file://backend/src/validators/model.js#L3-L19)
|
||||
- [backend/src/models/Model.js:4-50](file://backend/src/models/Model.js#L4-L50)
|
||||
- [backend/src/services/squiglink.js:261-310](file://backend/src/services/squiglink.js#L261-L310)
|
||||
- [backend/src/services/measurementStorage.js:116-157](file://backend/src/services/measurementStorage.js#L116-L157)
|
||||
- [backend/src/utils/response.js:1-25](file://backend/src/utils/response.js#L1-L25)
|
||||
- [backend/src/middleware/auth.js:3-26](file://backend/src/middleware/auth.js#L3-L26)
|
||||
|
||||
@@ -240,11 +250,14 @@ datetime create_at
|
||||
- 路径参数:model_id(整数)
|
||||
- 表单字段:同创建,支持部分字段更新(传入'null'表示保持原值)
|
||||
- 文件处理:同创建,若上传需提供source与form
|
||||
- **智能文件迁移**:当未上传新文件且路径相关字段(source、form、brand_name、name)发生变更时,系统自动将现有CSV文件从旧路径迁移到新路径
|
||||
- 成功响应:更新后的型号信息
|
||||
- 异常响应:未找到、重复、格式不支持、通用错误
|
||||
|
||||
**新增** 智能S3文件自动迁移功能,确保数据一致性与完整性
|
||||
|
||||
**章节来源**
|
||||
- [backend/src/routes/models.js:439-526](file://backend/src/routes/models.js#L439-L526)
|
||||
- [backend/src/routes/models.js:439-535](file://backend/src/routes/models.js#L439-L535)
|
||||
- [backend/src/validators/model.js:12-19](file://backend/src/validators/model.js#L12-L19)
|
||||
- [backend/src/utils/response.js:1-25](file://backend/src/utils/response.js#L1-L25)
|
||||
- [backend/src/middleware/auth.js:3-26](file://backend/src/middleware/auth.js#L3-L26)
|
||||
@@ -260,7 +273,7 @@ datetime create_at
|
||||
- 异常响应:未找到、Meilisearch删除失败、通用错误
|
||||
|
||||
**章节来源**
|
||||
- [backend/src/routes/models.js:528-554](file://backend/src/routes/models.js#L528-L554)
|
||||
- [backend/src/routes/models.js:537-563](file://backend/src/routes/models.js#L537-L563)
|
||||
- [backend/src/utils/response.js:1-25](file://backend/src/utils/response.js#L1-L25)
|
||||
- [backend/src/middleware/auth.js:3-26](file://backend/src/middleware/auth.js#L3-L26)
|
||||
|
||||
@@ -309,7 +322,7 @@ string model
|
||||
- 输出:推送成功数量、任务ID与推送数据
|
||||
|
||||
**章节来源**
|
||||
- [backend/src/routes/models.js:556-656](file://backend/src/routes/models.js#L556-L656)
|
||||
- [backend/src/routes/models.js:565-665](file://backend/src/routes/models.js#L565-L665)
|
||||
|
||||
### 频响文件上传与查询
|
||||
- 上传:POST /api/models/(multipart/form-data),支持TXT自动转换为CSV,**新增squiglink_csv字段**
|
||||
@@ -362,15 +375,65 @@ string model
|
||||
**新增** 完整的squig.link外部数据源支持
|
||||
|
||||
**章节来源**
|
||||
- [backend/src/routes/models.js:307-369](file://backend/src/routes/models.js#L307-L369)
|
||||
- [backend/src/routes/models.js:307-369](file://backend/src/routes/models.js#L307-369)
|
||||
- [backend/src/services/squiglink.js:1-322](file://backend/src/services/squiglink.js#L1-L322)
|
||||
- [frontend/src/views/model/components/ModelFormDialog.vue:158-464](file://frontend/src/views/model/components/ModelFormDialog.vue#L158-L464)
|
||||
|
||||
### S3文件自动迁移功能
|
||||
|
||||
#### 智能文件迁移机制
|
||||
- **触发条件**:更新型号时未上传新文件且路径相关字段发生变更
|
||||
- **路径字段**:source(来源)、form(佩戴方式)、brand_name(品牌名)、name(型号名)
|
||||
- **迁移策略**:服务端直接复制后删除,无需下载再上传
|
||||
- **原子操作**:复制成功后才删除旧文件,确保数据完整性
|
||||
|
||||
#### S3存储服务功能
|
||||
- **文件路径构建**:autoeq/measurements/{source}/data/{form}/{brandFirstChar}/{brand model}.csv
|
||||
- **上传服务**:uploadMeasurementToS3 - 支持CSV文件上传到S3
|
||||
- **读取服务**:getMeasurementFromS3 - 从S3读取CSV文件内容
|
||||
- **迁移服务**:moveMeasurementOnS3 - 实现S3文件的智能迁移
|
||||
- **路径生成**:buildMeasurementKey - 根据参数生成标准S3 Key
|
||||
|
||||
#### 迁移流程详解
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[更新型号请求] --> B{是否上传新文件?}
|
||||
B --> |是| C[上传新文件到S3]
|
||||
B --> |否| D{路径字段是否变更?}
|
||||
D --> |否| E[直接更新数据库]
|
||||
D --> |是| F[计算新旧S3路径]
|
||||
F --> G{路径是否相同?}
|
||||
G --> |是| H[跳过迁移]
|
||||
G --> |否| I[执行S3复制操作]
|
||||
I --> J[复制成功后删除旧文件]
|
||||
J --> K[更新数据库]
|
||||
C --> L[返回成功响应]
|
||||
E --> L
|
||||
H --> L
|
||||
K --> L
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [backend/src/routes/models.js:502-509](file://backend/src/routes/models.js#L502-L509)
|
||||
- [backend/src/services/measurementStorage.js:116-157](file://backend/src/services/measurementStorage.js#L116-L157)
|
||||
|
||||
#### 错误处理与日志记录
|
||||
- **文件不存在**:跳过迁移并记录日志,不影响更新操作
|
||||
- **网络异常**:抛出明确错误信息,便于问题排查
|
||||
- **权限问题**:详细的错误描述,指导权限配置
|
||||
- **路径冲突**:自动检测路径变化,避免不必要的操作
|
||||
|
||||
**新增** 完整的S3文件自动迁移功能,提升数据管理自动化水平
|
||||
|
||||
**章节来源**
|
||||
- [backend/src/routes/models.js:502-509](file://backend/src/routes/models.js#L502-L509)
|
||||
- [backend/src/services/measurementStorage.js:110-165](file://backend/src/services/measurementStorage.js#L110-L165)
|
||||
|
||||
## 依赖分析
|
||||
- 路由依赖:models.js 依赖Model模型、Zod验证器、响应工具、鉴权中间件,并与Meilisearch、S3服务交互,**新增squiglink服务依赖**
|
||||
- 路由依赖:models.js 依赖Model模型、Zod验证器、响应工具、鉴权中间件,并与Meilisearch、S3服务交互,**新增squiglink服务依赖与measurementStorage服务依赖**
|
||||
- 模型依赖:Model.js 依赖Sequelize ORM
|
||||
- 前端依赖:frontend/src/api/model.js 依赖通用请求封装
|
||||
- **服务依赖**:squiglink.js 依赖axios、logger,提供外部数据源抓取功能
|
||||
- **服务依赖**:squiglink.js 依赖axios、logger,提供外部数据源抓取功能;measurementStorage.js 依赖AWS SDK、logger,提供S3存储服务
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
@@ -379,21 +442,24 @@ R --> V["model.js(Zod)"]
|
||||
R --> U["response.js"]
|
||||
R --> A["auth.js"]
|
||||
R --> S["squiglink.js"]
|
||||
R --> MS["measurementStorage.js"]
|
||||
R -. 外部 .-> MS["Meilisearch"]
|
||||
R -. 外部 .-> S3["S3存储"]
|
||||
S -. 外部 .-> SL["squig.link"]
|
||||
MS -. 外部 .-> AWS["AWS SDK"]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [backend/src/routes/models.js:1-659](file://backend/src/routes/models.js#L1-L659)
|
||||
- [backend/src/routes/models.js:1-668](file://backend/src/routes/models.js#L1-L668)
|
||||
- [backend/src/models/Model.js:1-53](file://backend/src/models/Model.js#L1-L53)
|
||||
- [backend/src/validators/model.js:1-22](file://backend/src/validators/model.js#L1-L22)
|
||||
- [backend/src/utils/response.js:1-25](file://backend/src/utils/response.js#L1-L25)
|
||||
- [backend/src/middleware/auth.js:1-36](file://backend/src/middleware/auth.js#L1-L36)
|
||||
- [backend/src/services/squiglink.js:1-322](file://backend/src/services/squiglink.js#L1-L322)
|
||||
- [backend/src/services/measurementStorage.js:1-165](file://backend/src/services/measurementStorage.js#L1-L165)
|
||||
|
||||
**章节来源**
|
||||
- [backend/src/routes/models.js:1-659](file://backend/src/routes/models.js#L1-L659)
|
||||
- [backend/src/routes/models.js:1-668](file://backend/src/routes/models.js#L1-L668)
|
||||
|
||||
## 性能考虑
|
||||
- 分页限制:列表查询limit上限为1000,避免一次性返回过多数据
|
||||
@@ -402,6 +468,8 @@ S -. 外部 .-> SL["squig.link"]
|
||||
- 验证前置:使用Zod在进入数据库操作前完成字段校验,减少无效请求
|
||||
- **squig.link抓取超时**:设置15秒超时,避免外部服务影响系统性能
|
||||
- **squigsites.json缓存**:1小时TTL减少对外部服务的频繁请求
|
||||
- **S3迁移优化**:服务端直接复制,避免网络传输开销,提高迁移效率
|
||||
- **路径变更检测**:智能判断是否需要迁移,避免不必要的S3操作
|
||||
|
||||
## 故障排除指南
|
||||
- 401 未登录/无效凭证:检查Authorization头是否为Bearer Token且有效
|
||||
@@ -412,6 +480,8 @@ S -. 外部 .-> SL["squig.link"]
|
||||
- Meilisearch异常:检查服务连通性与API密钥
|
||||
- **squig.link抓取失败**:检查share_url格式、网络连通性、目标站点可用性
|
||||
- **squig.link文件下载失败**:确认文件存在、权限正确、支持的文件后缀
|
||||
- **S3迁移失败**:检查AWS凭证配置、S3 Bucket权限、网络连接状态
|
||||
- **文件路径错误**:确认source、form、brand_name、name字段值符合规范
|
||||
|
||||
**章节来源**
|
||||
- [backend/src/middleware/auth.js:3-26](file://backend/src/middleware/auth.js#L3-L26)
|
||||
@@ -419,6 +489,7 @@ S -. 外部 .-> SL["squig.link"]
|
||||
- [backend/src/routes/models.js:322-325](file://backend/src/routes/models.js#L322-L325)
|
||||
- [backend/src/routes/models.js:450-455](file://backend/src/routes/models.js#L450-L455)
|
||||
- [backend/src/services/squiglink.js:33-47](file://backend/src/services/squiglink.js#L33-L47)
|
||||
- [backend/src/services/measurementStorage.js:149-156](file://backend/src/services/measurementStorage.js#L149-L156)
|
||||
|
||||
## 结论
|
||||
型号管理API提供了完善的CRUD能力、灵活的查询过滤与排序、严格的输入验证、以及与搜索与存储系统的集成。**最新更新**:新增squig.link外部数据源支持,显著提升了型号数据的获取效率和准确性。结合OTA模型的关联关系,可支撑从型号到固件升级的完整业务闭环。建议在生产环境中关注分页与超时配置、文件上传性能与安全策略、**squig.link抓取的超时与缓存策略**,并在删除型号前做好OTA关联清理。
|
||||
型号管理API提供了完善的CRUD能力、灵活的查询过滤与排序、严格的输入验证、以及与搜索与存储系统的集成。**最新更新**:新增squig.link外部数据源支持及测量文件S3自动迁移功能,显著提升了型号数据的获取效率和数据一致性保障。智能文件迁移机制确保了在更新型号路径相关字段时,现有CSV文件能够自动迁移到新路径,无需人工干预。结合OTA模型的关联关系,可支撑从型号到固件升级的完整业务闭环。建议在生产环境中关注分页与超时配置、文件上传性能与安全策略、**squig.link抓取的超时与缓存策略**、**S3迁移的性能监控与错误处理**,并在删除型号前做好OTA关联清理。
|
||||
@@ -33,6 +33,13 @@
|
||||
- [frontend/src/views/system/users/index.vue](file://frontend/src/views/system/users/index.vue)
|
||||
</cite>
|
||||
|
||||
## 更新摘要
|
||||
**变更内容**
|
||||
- OTA固件管理功能已更新以支持beta版本特性
|
||||
- 版本唯一性规则从'verCode + model'变更为'verCode + model + beta'组合
|
||||
- 允许同一设备型号下存在多个不同beta状态的固件版本
|
||||
- 前端界面新增beta状态筛选和显示功能
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
@@ -99,7 +106,8 @@ ROUTER --> UTILS_AUTH
|
||||
- 型号管理
|
||||
- 支持型号增删改查、频响文件上传(CSV/TXT/JSON)、S3 存储、Meilisearch 推送与校验、Redis EQ 缓存读取。
|
||||
- OTA 固件管理
|
||||
- 支持 X8/X9 设备固件包上传(S3 或本地),设备端“最新版本检查”接口,后台管理列表与编辑。
|
||||
- 支持 X8/X9 设备固件包上传(S3 或本地),设备端"最新版本检查"接口,后台管理列表与编辑。
|
||||
- **新增**:支持beta版本管理,允许同一设备型号下存在多个不同beta状态的固件版本。
|
||||
- 分享码日志管理
|
||||
- 提供分享码导出/导入日志的查询接口,支持多维过滤与排序。
|
||||
- 权限模型
|
||||
@@ -111,7 +119,7 @@ ROUTER --> UTILS_AUTH
|
||||
- [backend/src/models/DashboardUser.js:1-58](file://backend/src/models/DashboardUser.js#L1-L58)
|
||||
- [backend/src/routes/brands.js:1-147](file://backend/src/routes/brands.js#L1-L147)
|
||||
- [backend/src/routes/models.js:1-569](file://backend/src/routes/models.js#L1-L569)
|
||||
- [backend/src/routes/ota.js:1-292](file://backend/src/routes/ota.js#L1-L292)
|
||||
- [backend/src/routes/ota.js:1-295](file://backend/src/routes/ota.js#L1-L295)
|
||||
- [backend/src/routes/shareCodeLogs.js:1-88](file://backend/src/routes/shareCodeLogs.js#L1-L88)
|
||||
- [frontend/src/router/index.js:1-91](file://frontend/src/router/index.js#L1-L91)
|
||||
|
||||
@@ -153,7 +161,7 @@ end
|
||||
- 登录流程
|
||||
- 前端提交用户名与密码,后端校验账号是否存在且启用,验证密码哈希,更新最近登录时间,签发 Access Token 并返回用户信息。
|
||||
- 当前用户
|
||||
- 需携带有效 Token 调用“获取当前用户”,后端返回用户基础信息。
|
||||
- 需携带有效 Token 调用"获取当前用户",后端返回用户基础信息。
|
||||
- 修改密码
|
||||
- 需携带有效 Token,校验旧密码,长度不少于 6 位,成功后更新密码哈希。
|
||||
- 鉴权中间件
|
||||
@@ -290,17 +298,20 @@ ModelR-->>FE : 返回字段值
|
||||
|
||||
### OTA 固件管理
|
||||
- 功能点
|
||||
- 设备端“最新版本检查”:无需登录,按当前版本号、设备型号与硬件版本筛选可用升级包。
|
||||
- 设备端"最新版本检查":无需登录,按当前版本号、设备型号与硬件版本筛选可用升级包。
|
||||
- 后台上传固件包:支持 X8(S3)、X9(本地);自动计算 MD5,返回下载地址与存储键。
|
||||
- 后台管理:列表查询、详情、创建、更新(版本号+型号唯一性校验)、删除。
|
||||
- 后台管理:列表查询、详情、创建、更新(版本号+型号+灰度状态唯一性校验)、删除。
|
||||
- **新增**:Beta版本支持,允许同一设备型号下存在多个不同beta状态的固件版本。
|
||||
- 关键参数
|
||||
- 最新版本检查:currentVerCode、model、hw。
|
||||
- 上传:model、package_file。
|
||||
- 列表:verCode、verName、model、status、skip、limit。
|
||||
- 列表:verCode、verName、model、status、beta、skip、limit。
|
||||
- 创建/更新:verCode、verName、url、md5、force、desc、model、hw、target、beta、startTime、endTime、status。
|
||||
- 返回值
|
||||
- 统一 ApiResponse 包裹,成功时返回列表、单条记录或上传结果。
|
||||
|
||||
**更新** 版本唯一性规则已从'verCode + model'组合变更为'verCode + model + beta'组合,允许同一设备型号下存在多个不同beta状态的固件版本。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Device as "设备端"
|
||||
@@ -315,19 +326,23 @@ Admin->>OTAR : POST /api/ota/upload-package
|
||||
OTAR->>OtaSvc : 校验并保存升级包
|
||||
OtaSvc-->>OTAR : 返回 md5/filename/url/s3_key
|
||||
OTAR-->>Admin : 返回上传结果
|
||||
Admin->>OTAR : POST /api/ota/ (含beta字段)
|
||||
OTAR->>DB : 检查verCode+model+beta唯一性
|
||||
DB-->>OTAR : 唯一性检查结果
|
||||
OTAR-->>Admin : 创建结果
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [backend/src/routes/ota.js:68-102](file://backend/src/routes/ota.js#L68-L102)
|
||||
- [backend/src/routes/ota.js:24-66](file://backend/src/routes/ota.js#L24-L66)
|
||||
- [backend/src/routes/ota.js:107-143](file://backend/src/routes/ota.js#L107-L143)
|
||||
- [backend/src/routes/ota.js:162-194](file://backend/src/routes/ota.js#L162-L194)
|
||||
- [backend/src/routes/ota.js:196-247](file://backend/src/routes/ota.js#L196-L247)
|
||||
- [backend/src/routes/ota.js:249-268](file://backend/src/routes/ota.js#L249-L268)
|
||||
- [backend/src/routes/ota.js:107-145](file://backend/src/routes/ota.js#L107-L145)
|
||||
- [backend/src/routes/ota.js:165-196](file://backend/src/routes/ota.js#L165-L196)
|
||||
- [backend/src/routes/ota.js:198-250](file://backend/src/routes/ota.js#L198-L250)
|
||||
- [backend/src/routes/ota.js:252-271](file://backend/src/routes/ota.js#L252-L271)
|
||||
- [backend/src/services/otaStorage.js](file://backend/src/services/otaStorage.js)
|
||||
|
||||
章节来源
|
||||
- [backend/src/routes/ota.js:1-292](file://backend/src/routes/ota.js#L1-L292)
|
||||
- [backend/src/routes/ota.js:1-295](file://backend/src/routes/ota.js#L1-L295)
|
||||
|
||||
### 用户权限管理
|
||||
- 角色模型
|
||||
@@ -447,6 +462,7 @@ Services --> Cache["Redis"]
|
||||
- 文件格式不支持:仅允许 CSV/TXT/JSON,TXT 将被自动转换为 CSV。
|
||||
- OTA 上传
|
||||
- 仅支持指定设备型号;S3 未配置或上传失败会返回明确错误。
|
||||
- **新增**:版本唯一性冲突检查包含beta状态,确保verCode+model+beta组合唯一。
|
||||
- Meilisearch 集成
|
||||
- 推送/删除失败:检查服务可达性与 API Key;关注返回的任务 UID。
|
||||
- 分享码日志
|
||||
@@ -458,11 +474,12 @@ Services --> Cache["Redis"]
|
||||
- [backend/src/routes/brands.js:62-80](file://backend/src/routes/brands.js#L62-L80)
|
||||
- [backend/src/routes/models.js:319-335](file://backend/src/routes/models.js#L319-L335)
|
||||
- [backend/src/routes/ota.js:27-58](file://backend/src/routes/ota.js#L27-L58)
|
||||
- [backend/src/routes/ota.js:176-183](file://backend/src/routes/ota.js#L176-L183)
|
||||
- [backend/src/routes/models.js:543-561](file://backend/src/routes/models.js#L543-L561)
|
||||
- [backend/src/routes/shareCodeLogs.js:37-48](file://backend/src/routes/shareCodeLogs.js#L37-L48)
|
||||
|
||||
## 结论
|
||||
本系统围绕“认证—权限—数据模型—业务路由—服务集成”的清晰分层组织,通过统一的响应封装与中间件机制保障了接口一致性与安全性。品牌、型号、OTA、分享码日志等核心功能均具备完善的 CRUD、校验与外部集成能力,适合在生产环境中稳定运行。建议持续完善监控与告警、日志分级与外部服务降级策略,以进一步提升稳定性与可观测性。
|
||||
本系统围绕"认证—权限—数据模型—业务路由—服务集成"的清晰分层组织,通过统一的响应封装与中间件机制保障了接口一致性与安全性。品牌、型号、OTA、分享码日志等核心功能均具备完善的 CRUD、校验与外部集成能力,适合在生产环境中稳定运行。**新增的beta版本支持功能进一步增强了OTA固件管理的灵活性,允许在同一设备型号下管理多个不同灰度状态的版本**。建议持续完善监控与告警、日志分级与外部服务降级策略,以进一步提升稳定性与可观测性。
|
||||
|
||||
## 附录
|
||||
- 前端页面与路由对应关系
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user