添加 uipro,更新 wiki

This commit is contained in:
eafonyang
2026-07-10 11:25:45 +08:00
parent 6bb39e9172
commit f88ff46427
163 changed files with 30244 additions and 151 deletions
@@ -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上传至S3Luxsin-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校验规则修正请求体字段(长度、类型、取值范围)
- 版本冲突:
- 创建/更新时若verCodemodel组合重复,会返回该版本已存在
- **版本冲突**
- **创建/更新时若verCodemodel和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/JSONTXT 将被自动转换为 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