删除多余代码
This commit is contained in:
@@ -61,22 +61,6 @@
|
||||
- 编辑: `account:edit`
|
||||
- 删除: `account:delete`
|
||||
|
||||
- [x] **平台账号页面** (`/account-management/platform-account`)
|
||||
|
||||
- ✅ 引入 `useAuth` composable
|
||||
- ✅ 为"新增平台账号"按钮添加 `v-permission="'platform_account:add'"`
|
||||
- ✅ 在操作列中使用 `hasAuth()` 判断以下权限:
|
||||
- 分配角色: `platform_account:patch_role`
|
||||
- 修改密码: `platform_account:update_psd`
|
||||
- 编辑: `platform_account:edit`
|
||||
- 删除: `platform_account:delete`
|
||||
|
||||
- [x] **代理账号页面** (`/account-management/shop-account`)
|
||||
- ✅ 引入 `useAuth` composable
|
||||
- ✅ 为"新增代理账号"按钮添加 `v-permission="'shop_account:add'"`
|
||||
- ✅ 在操作列中使用 `hasAuth()` 判断以下权限:
|
||||
- 修改密码: `shop_account:update_psd`
|
||||
- 编辑: `shop_account:edit`
|
||||
|
||||
### 4. 资产管理模块 (Asset Management) ✅
|
||||
|
||||
|
||||
@@ -18,10 +18,9 @@
|
||||
|
||||
- [ ] 3.1 Update customer account types in `src/types/api/account.ts`
|
||||
- [ ] 3.2 Update AccountService in `src/api/modules/account.ts` with new endpoints
|
||||
- [ ] 3.3 Update customer account list page `/account-management/customer-account`
|
||||
- [ ] 3.4 Add create/edit customer account forms with user type selection
|
||||
- [ ] 3.5 Add password reset functionality
|
||||
- [ ] 3.6 Add status toggle functionality
|
||||
- [ ] 3.3 Add create/edit customer account forms with user type selection
|
||||
- [ ] 3.4 Add password reset functionality
|
||||
- [ ] 3.5 Add status toggle functionality
|
||||
|
||||
## 4. Enterprise Customer Enhancement
|
||||
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
# Change: 客户账户管理功能
|
||||
|
||||
## Why
|
||||
|
||||
运营平台需要统一查看和管理所有客户(包括代理商和企业客户)的账户佣金情况,包括佣金总额、可提现金额、待入账金额、已提现金额等财务数据。目前系统缺少集中的客户账户财务视图,运营人员无法高效地了解客户的佣金和提现状况。
|
||||
|
||||
## What Changes
|
||||
|
||||
- 新增客户账户管理页面(`src/views/finance/customer-account/index.vue`)
|
||||
- 提供客户账户列表查询功能,支持按客户账号、客户名称、客户类型筛选
|
||||
- 展示客户的佣金相关财务数据:
|
||||
- 佣金总额
|
||||
- 可提现金额
|
||||
- 待入账金额
|
||||
- 已提现金额
|
||||
- 提现次数
|
||||
- 最后提现时间
|
||||
- 提供查看客户账户详情功能
|
||||
- 提供查看客户流水记录功能(入口)
|
||||
- 添加国际化支持(中英文)
|
||||
- 添加路由配置(财务模块下)
|
||||
|
||||
## Impact
|
||||
|
||||
- 新增规范:`specs/customer-account-management/spec.md`
|
||||
- 新增文件:
|
||||
- `src/views/finance/customer-account/index.vue`
|
||||
- 修改文件:
|
||||
- `src/router/routes/asyncRoutes.ts`(添加路由)
|
||||
- `src/router/routesAlias.ts`(添加路由别名)
|
||||
- `src/locales/langs/zh.json`(添加中文翻译)
|
||||
- `src/locales/langs/en.json`(添加英文翻译)
|
||||
- `docs/功能.md`(文档更新)
|
||||
- 依赖模块:
|
||||
- Element Plus 组件(ElTable, ElForm, ElDialog 等)
|
||||
- 现有的 ArtTable 组件
|
||||
- 后端 API(待对接)
|
||||
@@ -1,176 +0,0 @@
|
||||
# 客户账户管理规范
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: 客户账户列表查询
|
||||
|
||||
系统 SHALL 提供客户账户列表查询功能,运营人员可以查看所有客户的账户财务信息。
|
||||
|
||||
#### Scenario: 查询所有客户账户
|
||||
|
||||
- **WHEN** 运营人员访问客户账户管理页面
|
||||
- **THEN** 系统显示所有客户账户列表,包含以下字段:
|
||||
- 客户账号
|
||||
- 客户名称
|
||||
- 客户类型(代理商/企业客户)
|
||||
- 佣金总额
|
||||
- 可提现金额
|
||||
- 待入账金额
|
||||
- 已提现金额
|
||||
- 提现次数
|
||||
- 最后提现时间
|
||||
|
||||
#### Scenario: 按客户账号搜索
|
||||
|
||||
- **WHEN** 运营人员在搜索框输入客户账号并点击查询
|
||||
- **THEN** 系统返回匹配该账号的客户记录
|
||||
|
||||
#### Scenario: 按客户名称搜索
|
||||
|
||||
- **WHEN** 运营人员在搜索框输入客户名称并点击查询
|
||||
- **THEN** 系统返回名称包含该关键词的客户记录
|
||||
|
||||
#### Scenario: 按客户类型筛选
|
||||
|
||||
- **WHEN** 运营人员选择客户类型(代理商或企业客户)并点击查询
|
||||
- **THEN** 系统返回该类型的所有客户记录
|
||||
|
||||
#### Scenario: 组合条件搜索
|
||||
|
||||
- **WHEN** 运营人员同时使用多个搜索条件(如账号 + 类型)并点击查询
|
||||
- **THEN** 系统返回同时满足所有条件的客户记录
|
||||
|
||||
#### Scenario: 重置搜索条件
|
||||
|
||||
- **WHEN** 运营人员点击重置按钮
|
||||
- **THEN** 系统清空所有搜索条件并显示完整列表
|
||||
|
||||
### Requirement: 分页功能
|
||||
|
||||
系统 SHALL 支持客户账户列表的分页展示,以提高大数据量下的性能和用户体验。
|
||||
|
||||
#### Scenario: 默认分页显示
|
||||
|
||||
- **WHEN** 运营人员首次访问页面
|
||||
- **THEN** 系统默认显示第 1 页,每页 20 条记录
|
||||
|
||||
#### Scenario: 切换页码
|
||||
|
||||
- **WHEN** 运营人员点击分页器的页码
|
||||
- **THEN** 系统跳转到对应页面并加载数据
|
||||
|
||||
#### Scenario: 调整每页显示数量
|
||||
|
||||
- **WHEN** 运营人员选择不同的每页显示数量(10/20/50/100)
|
||||
- **THEN** 系统重新加载数据并按新的数量显示
|
||||
|
||||
#### Scenario: 显示总记录数
|
||||
|
||||
- **WHEN** 数据加载完成后
|
||||
- **THEN** 分页器显示总记录数
|
||||
|
||||
### Requirement: 客户账户详情查看
|
||||
|
||||
系统 SHALL 提供客户账户详情查看功能,展示客户的完整财务信息。
|
||||
|
||||
#### Scenario: 打开详情对话框
|
||||
|
||||
- **WHEN** 运营人员点击某个客户的"查看详情"按钮
|
||||
- **THEN** 系统弹出详情对话框,展示以下信息:
|
||||
- 客户账号
|
||||
- 客户名称
|
||||
- 客户类型
|
||||
- 联系电话
|
||||
- 佣金总额
|
||||
- 可提现金额
|
||||
- 待入账金额
|
||||
- 已提现金额
|
||||
- 提现次数
|
||||
- 最后提现时间
|
||||
- 注册时间
|
||||
- 备注
|
||||
|
||||
#### Scenario: 关闭详情对话框
|
||||
|
||||
- **WHEN** 运营人员点击对话框关闭按钮或遮罩层
|
||||
- **THEN** 系统关闭详情对话框
|
||||
|
||||
### Requirement: 客户流水记录入口
|
||||
|
||||
系统 SHALL 提供客户流水记录查看入口,方便运营人员查看客户的佣金流水明细。
|
||||
|
||||
#### Scenario: 触发流水记录查看
|
||||
|
||||
- **WHEN** 运营人员点击某个客户的"流水记录"按钮
|
||||
- **THEN** 系统导航到该客户的流水记录页面或打开流水记录对话框
|
||||
|
||||
### Requirement: 数据展示样式
|
||||
|
||||
系统 SHALL 使用不同的视觉样式区分不同类型的数据,提升可读性。
|
||||
|
||||
#### Scenario: 客户类型标签样式
|
||||
|
||||
- **WHEN** 列表或详情中显示客户类型
|
||||
- **THEN** 代理商显示为绿色标签,企业客户显示为蓝色标签
|
||||
|
||||
#### Scenario: 金额颜色区分
|
||||
|
||||
- **WHEN** 列表或详情中显示金额数据
|
||||
- **THEN** 可提现金额使用绿色高亮,待入账金额使用橙色高亮
|
||||
|
||||
#### Scenario: 金额格式化
|
||||
|
||||
- **WHEN** 系统显示金额数据
|
||||
- **THEN** 金额显示为货币格式,保留两位小数,前缀人民币符号"¥"
|
||||
|
||||
### Requirement: 国际化支持
|
||||
|
||||
系统 SHALL 支持中英文双语界面,所有文案通过国际化文件管理。
|
||||
|
||||
#### Scenario: 中文界面显示
|
||||
|
||||
- **WHEN** 系统语言设置为中文
|
||||
- **THEN** 所有界面文案显示为中文
|
||||
|
||||
#### Scenario: 英文界面显示
|
||||
|
||||
- **WHEN** 系统语言设置为英文
|
||||
- **THEN** 所有界面文案显示为英文
|
||||
|
||||
### Requirement: 数据权限控制
|
||||
|
||||
系统 SHALL 根据运营人员的权限角色,控制其可见的客户账户范围。
|
||||
|
||||
#### Scenario: 管理员权限
|
||||
|
||||
- **WHEN** 管理员访问客户账户页面
|
||||
- **THEN** 系统显示所有客户账户
|
||||
|
||||
#### Scenario: 普通运营人员权限
|
||||
|
||||
- **WHEN** 普通运营人员访问客户账户页面
|
||||
- **THEN** 系统仅显示其权限范围内的客户账户
|
||||
|
||||
### Requirement: 异常处理与用户反馈
|
||||
|
||||
系统 SHALL 在操作过程中提供清晰的用户反馈和错误处理。
|
||||
|
||||
#### Scenario: 查询成功反馈
|
||||
|
||||
- **WHEN** 用户执行搜索操作且成功返回结果
|
||||
- **THEN** 系统显示成功消息提示
|
||||
|
||||
#### Scenario: 查询失败处理
|
||||
|
||||
- **WHEN** API 请求失败或超时
|
||||
- **THEN** 系统显示错误消息,并提示用户重试
|
||||
|
||||
#### Scenario: 数据加载状态
|
||||
|
||||
- **WHEN** 系统正在加载数据
|
||||
- **THEN** 显示加载动画或骨架屏,防止用户误操作
|
||||
|
||||
#### Scenario: 空数据提示
|
||||
|
||||
- **WHEN** 查询结果为空
|
||||
- **THEN** 系统显示"暂无数据"提示
|
||||
@@ -1,58 +0,0 @@
|
||||
# 实现任务清单
|
||||
|
||||
## 1. 前端页面实现
|
||||
|
||||
- [x] 1.1 创建客户账户管理页面组件 `src/views/finance/customer-account/index.vue`
|
||||
- [x] 1.1.1 实现搜索表单(客户账号、客户名称、客户类型)
|
||||
- [x] 1.1.2 实现数据表格展示(使用 ArtTable)
|
||||
- [x] 1.1.3 实现分页功能
|
||||
- [x] 1.1.4 实现详情对话框
|
||||
- [x] 1.1.5 添加操作按钮(查看详情、流水记录)
|
||||
- [x] 1.2 添加路由配置
|
||||
- [x] 1.2.1 在 `src/router/routes/asyncRoutes.ts` 中添加路由
|
||||
- [x] 1.2.2 在 `src/router/routesAlias.ts` 中添加路由别名
|
||||
- [x] 1.3 添加国际化支持
|
||||
- [x] 1.3.1 在 `src/locales/langs/zh.json` 中添加中文文案
|
||||
- [x] 1.3.2 在 `src/locales/langs/en.json` 中添加英文文案
|
||||
|
||||
## 2. API 集成(待实现)
|
||||
|
||||
- [ ] 2.1 创建 API 模块 `src/api/modules/customerAccountApi.ts`
|
||||
- [ ] 2.1.1 实现客户账户列表查询接口
|
||||
- [ ] 2.1.2 实现客户账户详情查询接口
|
||||
- [ ] 2.1.3 实现客户流水记录查询接口
|
||||
- [ ] 2.2 定义 TypeScript 类型
|
||||
- [ ] 2.2.1 定义客户账户数据类型 `CustomerAccount`
|
||||
- [ ] 2.2.2 定义搜索参数类型 `CustomerAccountSearchParams`
|
||||
- [ ] 2.2.3 定义流水记录类型 `CustomerAccountFlow`
|
||||
- [ ] 2.3 替换页面中的模拟数据为真实 API 调用
|
||||
|
||||
## 3. 流水记录功能(待实现)
|
||||
|
||||
- [ ] 3.1 创建流水记录子页面或对话框
|
||||
- [ ] 3.2 实现流水记录列表展示
|
||||
- [ ] 3.3 实现流水记录筛选和分页
|
||||
|
||||
## 4. 权限控制(待实现)
|
||||
|
||||
- [ ] 4.1 配置页面访问权限(后台权限系统)
|
||||
- [ ] 4.2 添加按钮级权限控制(如需要)
|
||||
|
||||
## 5. 测试与优化
|
||||
|
||||
- [ ] 5.1 单元测试(工具函数、业务逻辑)
|
||||
- [ ] 5.2 集成测试(API 调用)
|
||||
- [ ] 5.3 性能优化(大数据量处理)
|
||||
- [ ] 5.4 用户体验优化(加载状态、错误处理)
|
||||
|
||||
## 6. 文档更新
|
||||
|
||||
- [x] 6.1 更新 `docs/功能.md` 功能列表
|
||||
|
||||
## 当前状态
|
||||
|
||||
- ✅ 第 1 阶段(前端页面框架)已完成,使用模拟数据
|
||||
- ⏳ 第 2 阶段(API 集成)待实现
|
||||
- ⏳ 第 3 阶段(流水记录)待实现
|
||||
- ⏳ 第 4 阶段(权限控制)待实现
|
||||
- ⏳ 第 5 阶段(测试优化)待实现
|
||||
@@ -1,309 +0,0 @@
|
||||
# Device Management Design
|
||||
|
||||
## Context
|
||||
|
||||
The system currently has a basic device-import page but lacks comprehensive device management capabilities. Devices are critical assets that need to be tracked throughout their lifecycle - from import, allocation to shops, binding with SIM cards, to eventual recall. This change adds full device management to complement the existing card management features.
|
||||
|
||||
Key integration points:
|
||||
|
||||
- **Existing Card System**: Devices must bind with cards from the existing card-list module
|
||||
- **Shop System**: Devices are allocated to shops using the existing ShopService
|
||||
- **Object Storage**: Imports use the existing StorageService for large file uploads
|
||||
- **Task System**: Import tasks must integrate with the existing task-management infrastructure
|
||||
|
||||
## Goals
|
||||
|
||||
1. **Complete Lifecycle Management**: Support all device operations from import to deletion
|
||||
2. **Seamless Integration**: Reuse existing UI patterns, services, and components
|
||||
3. **Scalable Import**: Handle large CSV imports efficiently using object storage
|
||||
4. **Operation Traceability**: Track all device operations through task management
|
||||
5. **Consistent UX**: Match the look and feel of existing card-list and enterprise-customer pages
|
||||
|
||||
## Key Decisions
|
||||
|
||||
### Decision 1: Three-Step Object Storage Import
|
||||
|
||||
**Choice**: Use StorageService.getUploadUrl → uploadFile → DeviceService.importDevices
|
||||
|
||||
**Rationale**:
|
||||
|
||||
- Handles large files (thousands of devices) without timeout issues
|
||||
- Decouples upload from processing (backend can process asynchronously)
|
||||
- Consistent with modern cloud architecture patterns
|
||||
- Allows progress tracking through task management
|
||||
|
||||
**Alternatives Considered**:
|
||||
|
||||
- Direct multipart upload to backend (rejected: not scalable for large files)
|
||||
- Two-step process without pre-signed URL (rejected: less secure, more backend load)
|
||||
|
||||
**Implementation Notes**:
|
||||
|
||||
- Frontend only handles upload to object storage, not file parsing
|
||||
- Backend processes the file asynchronously and creates task records
|
||||
- Task management provides visibility into import progress
|
||||
|
||||
### Decision 2: Device-Card Binding Model
|
||||
|
||||
**Choice**: Store binding with explicit slot_position (1-4) in device_cards table
|
||||
|
||||
**Rationale**:
|
||||
|
||||
- IoT devices have physical SIM slots that need explicit identification
|
||||
- Each device can have 1-4 slots (max_sim_slots)
|
||||
- One card can only bind to one device slot (enforced by backend)
|
||||
- Slot position is critical for physical device configuration
|
||||
|
||||
**Alternatives Considered**:
|
||||
|
||||
- Auto-assign slot positions (rejected: operators need to know physical slot numbers)
|
||||
- Allow one card to bind to multiple devices (rejected: not realistic for physical SIMs)
|
||||
|
||||
**Implementation Notes**:
|
||||
|
||||
- Device detail page shows a 4-slot grid (empty slots show "Bind Card" button)
|
||||
- Binding dialog requires explicit slot selection
|
||||
- Unbinding updates bound_card_count and frees the slot
|
||||
|
||||
### Decision 3: Unified Task Management
|
||||
|
||||
**Choice**: Extend existing task-management to support device import tasks
|
||||
|
||||
**Rationale**:
|
||||
|
||||
- Reuses existing task infrastructure
|
||||
- Provides consistent UX for all import operations
|
||||
- Avoids duplicate task tracking logic
|
||||
- Allows unified search/filter across task types
|
||||
|
||||
**Alternatives Considered**:
|
||||
|
||||
- Separate device task management page (rejected: creates UX fragmentation)
|
||||
- Embed task tracking only in device-import page (rejected: limited visibility)
|
||||
|
||||
**Implementation Notes**:
|
||||
|
||||
- Add task_type field to distinguish ICCID vs Device imports
|
||||
- Task detail page renders different content based on task_type
|
||||
- Device tasks show device_no and bound ICCIDs instead of just ICCID
|
||||
|
||||
### Decision 4: Batch Operation Result Display
|
||||
|
||||
**Choice**: Show detailed results in dialog after batch allocation/recall
|
||||
|
||||
**Rationale**:
|
||||
|
||||
- Operations may partially succeed (some devices succeed, others fail)
|
||||
- Operators need to know exactly which devices failed and why
|
||||
- Allows retry of failed operations without re-selecting all devices
|
||||
|
||||
**Alternatives Considered**:
|
||||
|
||||
- Just show toast notification (rejected: insufficient detail for partial failures)
|
||||
- Navigate to separate results page (rejected: disrupts workflow)
|
||||
|
||||
**Implementation Notes**:
|
||||
|
||||
- Dialog shows summary: total, success count, failure count
|
||||
- Expandable table shows failed devices with error messages
|
||||
- Success closes dialog, partial failure keeps it open for review
|
||||
|
||||
### Decision 5: Component Reuse Strategy
|
||||
|
||||
**Choice**: Use existing Art\* components (ArtTableFullScreen, ArtSearchBar, ArtTable, ArtButtonTable)
|
||||
|
||||
**Rationale**:
|
||||
|
||||
- Maintains UI consistency across the application
|
||||
- Reduces development time
|
||||
- Leverages tested, stable components
|
||||
- Easier for users familiar with other pages
|
||||
|
||||
**Reference Implementation**:
|
||||
|
||||
- Device-list follows role/index.vue pattern
|
||||
- Device-detail follows card-list detail modal pattern
|
||||
- Search form follows enterprise-customer search pattern
|
||||
|
||||
**Implementation Notes**:
|
||||
|
||||
- Use CommonStatus for status values (ENABLED/DISABLED)
|
||||
- Use ElSwitch for status toggles
|
||||
- Use ArtButtonTable for action buttons
|
||||
- Follow ElDescriptions layout for detail pages
|
||||
|
||||
## Architecture Diagrams
|
||||
|
||||
### Device Import Flow
|
||||
|
||||
```
|
||||
┌─────────┐ 1. Select CSV ┌──────────────┐
|
||||
│ Admin │ ──────────────────> │ device-import│
|
||||
│ │ │ (Vue) │
|
||||
└─────────┘ └──────┬───────┘
|
||||
│
|
||||
│ 2. getUploadUrl()
|
||||
v
|
||||
┌──────────────┐
|
||||
│ Storage │
|
||||
│ Service │
|
||||
└──────┬───────┘
|
||||
│
|
||||
│ 3. Upload to OSS
|
||||
v
|
||||
┌──────────────┐
|
||||
│ Object │
|
||||
│ Storage │
|
||||
└──────────────┘
|
||||
│
|
||||
│ 4. importDevices(file_key)
|
||||
v
|
||||
┌──────────────┐
|
||||
│ Device │
|
||||
│ Service │
|
||||
└──────┬───────┘
|
||||
│
|
||||
│ 5. Create Task
|
||||
v
|
||||
┌──────────────┐
|
||||
│ Task │
|
||||
│ Management │
|
||||
└──────────────┘
|
||||
```
|
||||
|
||||
### Device-Card Binding
|
||||
|
||||
```
|
||||
┌─────────┐ ┌──────────────┐
|
||||
│ Device │ ───── bound to ────> │ Card │
|
||||
│ │ (1 to N) │ │
|
||||
└─────────┘ └──────────────┘
|
||||
│ │
|
||||
│ has_many bindings │ has_one binding
|
||||
v v
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ DeviceCardBinding │
|
||||
│ - device_id │
|
||||
│ - card_id │
|
||||
│ - slot_position (1-4) │
|
||||
│ - bound_at │
|
||||
└─────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Data Flow
|
||||
|
||||
### Device List Page Load
|
||||
|
||||
1. User navigates to /asset-management/device-list
|
||||
2. Vue component mounts, calls DeviceService.getDevices(params)
|
||||
3. Backend returns paginated device list with bound_card_count
|
||||
4. Table renders with status switches and action buttons
|
||||
|
||||
### Batch Allocation Flow
|
||||
|
||||
1. User selects devices, clicks "Batch Allocate"
|
||||
2. Dialog opens with shop selector
|
||||
3. User selects shop, adds remarks, confirms
|
||||
4. Call DeviceService.allocateDevices({ device_ids, shop_id, remarks })
|
||||
5. Backend processes each device, returns results array
|
||||
6. Dialog shows summary and failed device details
|
||||
|
||||
### Card Binding Flow
|
||||
|
||||
1. User opens device detail page
|
||||
2. Clicks "Bind Card" for an empty slot
|
||||
3. Dialog shows card search and slot selection
|
||||
4. User selects card and slot (e.g., slot 3)
|
||||
5. Call DeviceService.bindCard(device_id, { card_id, slot_position: 3 })
|
||||
6. Backend validates slot is empty, creates binding
|
||||
7. Refresh device detail to show new binding
|
||||
|
||||
## Migration Plan
|
||||
|
||||
### Updating Existing Device Import Page
|
||||
|
||||
**Current State** (`src/views/batch/device-import/index.vue`):
|
||||
|
||||
- Uses ElUpload with drag-and-drop
|
||||
- Mock data for import records
|
||||
- No real API integration
|
||||
|
||||
**Migration Steps**:
|
||||
|
||||
1. Replace ElUpload with three-step upload logic
|
||||
- Add getUploadUrl call
|
||||
- Add uploadFile to object storage
|
||||
- Add importDevices call with file_key
|
||||
2. Remove mock import records
|
||||
3. Link to task-management for tracking
|
||||
4. Update CSV format instructions
|
||||
|
||||
**Backward Compatibility**:
|
||||
|
||||
- This is a new feature area with no existing production data
|
||||
- No API breaking changes
|
||||
- UI changes are additive (improve existing page)
|
||||
|
||||
### Extending Task Management
|
||||
|
||||
**Current State**:
|
||||
|
||||
- Only handles ICCID import tasks
|
||||
- Single task type rendering
|
||||
|
||||
**Migration Steps**:
|
||||
|
||||
1. Add task_type filter dropdown (default: show all)
|
||||
2. Add task_type badge in task list
|
||||
3. Task detail page: switch rendering based on task_type
|
||||
4. Add device-specific fields to task detail view
|
||||
|
||||
**Backward Compatibility**:
|
||||
|
||||
- Existing ICCID tasks continue to work unchanged
|
||||
- Filter defaults to showing all types
|
||||
- No database schema changes required (task_type already exists)
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
### Unit Testing
|
||||
|
||||
- DeviceService API methods with mock responses
|
||||
- Form validation logic
|
||||
- Utility functions (formatters, validators)
|
||||
|
||||
### Integration Testing
|
||||
|
||||
- Device list search and pagination
|
||||
- Batch allocation with partial failures
|
||||
- Card binding/unbinding workflow
|
||||
- Import task creation and status tracking
|
||||
|
||||
### E2E Testing Scenarios
|
||||
|
||||
1. Import devices via CSV → verify task created → check task detail
|
||||
2. Search devices → select multiple → allocate to shop → verify shop assignment
|
||||
3. View device detail → bind card to slot 2 → unbind → verify empty slot
|
||||
4. Batch recall devices → verify shop cleared → check operation history
|
||||
|
||||
### Performance Considerations
|
||||
|
||||
- Device list pagination (default 20 per page)
|
||||
- Debounced search input (300ms delay)
|
||||
- Batch operation result pagination (if >100 results)
|
||||
- Large CSV imports handled asynchronously (no frontend timeout)
|
||||
|
||||
## Security Considerations
|
||||
|
||||
1. **Authorization**: All device operations require admin role
|
||||
2. **Input Validation**:
|
||||
- Device number format validation
|
||||
- Slot position range (1 to max_sim_slots)
|
||||
- CSV file size limits
|
||||
3. **Object Storage Security**: Pre-signed URLs expire after 15 minutes
|
||||
4. **Batch Operation Limits**: Backend enforces max 1000 devices per batch
|
||||
5. **XSS Prevention**: All user inputs sanitized before rendering
|
||||
|
||||
## Open Questions
|
||||
|
||||
None at this time. All major design decisions have been made based on existing system patterns and API specifications.
|
||||
@@ -1,67 +0,0 @@
|
||||
# Change: 添加设备管理功能
|
||||
|
||||
## Why
|
||||
|
||||
当前系统只有设备导入页面,缺少完整的设备管理能力。需要提供设备的全生命周期管理,包括:
|
||||
|
||||
- 查看和搜索设备列表
|
||||
- 查看设备详情和绑定的卡信息
|
||||
- 管理设备与卡的绑定关系
|
||||
- 批量分配和回收设备
|
||||
- 完善设备导入流程和任务追踪
|
||||
|
||||
这是物联网卡管理系统的核心资产管理功能之一。
|
||||
|
||||
## What Changes
|
||||
|
||||
### 新增功能
|
||||
|
||||
- **设备列表页面**: 支持多条件搜索、分页、列筛选、批量操作(分配、回收、删除)
|
||||
- **设备详情页面**: 展示设备基本信息、绑定的卡列表、操作历史
|
||||
- **卡绑定管理**: 在设备详情页绑定/解绑卡
|
||||
- **批量分配对话框**: 选择设备批量分配给店铺
|
||||
- **批量回收对话框**: 从店铺批量回收设备
|
||||
- **设备导入改进**: 基于对象存储的三步导入流程
|
||||
- **导入任务管理**: 任务列表和详情查看
|
||||
|
||||
### API 集成
|
||||
|
||||
- DeviceService: 11个API接口
|
||||
- 类型定义: Device, DeviceBinding, ImportTask 等
|
||||
|
||||
### UI 组件
|
||||
|
||||
- 遵循现有组件模式 (ArtTableFullScreen, ArtSearchBar等)
|
||||
- 复用 CommonStatus 统一状态变量
|
||||
- 使用 ElDescriptions、ElTag、ElSwitch 等组件
|
||||
|
||||
## Impact
|
||||
|
||||
### 影响的功能模块
|
||||
|
||||
- **新增**: 资产管理 / 设备列表(主列表页)
|
||||
- **新增**: 资产管理 / 设备详情
|
||||
- **改进**: 批量操作 / 设备导入(改为对象存储模式)
|
||||
- **新增**: 批量操作 / 导入任务列表(独立页面)
|
||||
|
||||
### 影响的代码
|
||||
|
||||
- `src/api/modules/device.ts` (新增)
|
||||
- `src/types/api/device.ts` (新增)
|
||||
- `src/views/asset-management/device-list/index.vue` (新增)
|
||||
- `src/views/asset-management/device-detail/index.vue` (新增)
|
||||
- `src/views/asset-management/task-management/index.vue` (修改:支持设备导入任务)
|
||||
- `src/views/asset-management/task-detail/index.vue` (修改:支持设备导入任务详情)
|
||||
- `src/views/batch/device-import/index.vue` (修改:使用对象存储)
|
||||
- `src/router/routes/asyncRoutes.ts` (新增路由)
|
||||
- `src/router/routesAlias.ts` (新增路由别名)
|
||||
- `src/locales/langs/zh.json` (新增翻译)
|
||||
- `src/api/modules/index.ts` (导出 DeviceService)
|
||||
- `src/types/api/index.ts` (导出 Device 类型)
|
||||
|
||||
### 依赖关系
|
||||
|
||||
- 依赖现有的 StorageService (对象存储)
|
||||
- 依赖现有的 ShopService (店铺选择)
|
||||
- 设备与卡的关联管理
|
||||
- 任务管理页面需要支持多种任务类型(ICCID导入 + 设备导入)
|
||||
@@ -1,159 +0,0 @@
|
||||
# Device Management Specification
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Device List Management
|
||||
|
||||
The system SHALL provide a searchable device list with multi-condition filtering, pagination, and batch operations.
|
||||
|
||||
#### Scenario: Search devices by multiple criteria
|
||||
|
||||
**WHEN** an administrator enters search criteria (device number, device name, status, shop, batch number, device type, manufacturer, creation time range) **THEN** the system shall display only devices matching all specified criteria with pagination support
|
||||
|
||||
#### Scenario: View device list with bound card count
|
||||
|
||||
**WHEN** the device list is displayed **THEN** each device row shall show: ID, device number, device name, device model, device type, manufacturer, max slots, bound card count, status, shop, batch number, activation time, creation time
|
||||
|
||||
#### Scenario: Toggle device status
|
||||
|
||||
**WHEN** an administrator clicks the status switch for a device **THEN** the system shall update the device status between ENABLED and DISABLED and refresh the display
|
||||
|
||||
#### Scenario: Delete a device
|
||||
|
||||
**WHEN** an administrator clicks the delete button and confirms the deletion **THEN** the system shall delete the device and refresh the list
|
||||
|
||||
#### Scenario: Select multiple devices for batch operations
|
||||
|
||||
**WHEN** an administrator checks multiple device rows **THEN** the system shall enable batch operation buttons (Allocate, Recall) and track selected device IDs
|
||||
|
||||
### Requirement: Device Detail Viewing
|
||||
|
||||
The system SHALL display comprehensive device information including basic properties and bound SIM cards.
|
||||
|
||||
#### Scenario: View device basic information
|
||||
|
||||
**WHEN** an administrator navigates to a device detail page **THEN** the system shall display all device properties in a descriptive layout: device number, name, model, type, manufacturer, max SIM slots, status, shop, batch number, activation time, creation time
|
||||
|
||||
#### Scenario: View bound SIM cards with slot positions
|
||||
|
||||
**WHEN** viewing device details **THEN** the system shall display a table of bound cards showing: slot position (1-4), ICCID, phone number, carrier, card status, and binding time
|
||||
|
||||
#### Scenario: Empty slots display
|
||||
|
||||
**WHEN** a device has fewer than max_sim_slots cards bound **THEN** empty slot positions shall be clearly indicated with "Bind Card" action buttons
|
||||
|
||||
### Requirement: Device-Card Binding Management
|
||||
|
||||
The system SHALL allow administrators to bind and unbind SIM cards to specific device slots.
|
||||
|
||||
#### Scenario: Bind a card to a device slot
|
||||
|
||||
**WHEN** an administrator selects a card and slot position (1-4) in the binding dialog **THEN** the system shall create the binding, update the bound card count, and refresh the card list
|
||||
|
||||
#### Scenario: Prevent duplicate slot binding
|
||||
|
||||
**WHEN** an administrator attempts to bind a card to an already occupied slot **THEN** the system shall show an error message and prevent the binding
|
||||
|
||||
#### Scenario: Unbind a card from device
|
||||
|
||||
**WHEN** an administrator clicks unbind for a bound card and confirms **THEN** the system shall remove the binding, decrement the bound card count, and refresh the card list
|
||||
|
||||
#### Scenario: Validate slot range
|
||||
|
||||
**WHEN** an administrator selects a slot position **THEN** the system shall only allow values from 1 to the device's max_sim_slots value
|
||||
|
||||
### Requirement: Batch Device Allocation
|
||||
|
||||
The system SHALL support batch allocation of devices to shops with result tracking.
|
||||
|
||||
#### Scenario: Allocate multiple devices to a shop
|
||||
|
||||
**WHEN** an administrator selects multiple devices, chooses a target shop, adds optional remarks, and confirms allocation **THEN** the system shall allocate all selected devices to the shop and display success/failure results for each device
|
||||
|
||||
#### Scenario: Show allocation results
|
||||
|
||||
**WHEN** the batch allocation completes **THEN** the system shall display: total count, success count, failure count, and detailed failure reasons for each failed device
|
||||
|
||||
#### Scenario: Prevent allocation of already allocated devices
|
||||
|
||||
**WHEN** the batch allocation includes devices already allocated to a shop **THEN** the system shall show warnings for those devices but proceed with allocating unallocated devices
|
||||
|
||||
### Requirement: Batch Device Recall
|
||||
|
||||
The system SHALL support batch recall of devices from shops with result tracking.
|
||||
|
||||
#### Scenario: Recall multiple devices
|
||||
|
||||
**WHEN** an administrator selects multiple devices, adds optional remarks, and confirms recall **THEN** the system shall recall all selected devices from their shops and display success/failure results
|
||||
|
||||
#### Scenario: Show recall results
|
||||
|
||||
**WHEN** the batch recall completes **THEN** the system shall display: total count, success count, failure count, and detailed failure reasons for each failed device
|
||||
|
||||
#### Scenario: Prevent recall of unallocated devices
|
||||
|
||||
**WHEN** the batch recall includes devices not allocated to any shop **THEN** the system shall show warnings for those devices but proceed with recalling allocated devices
|
||||
|
||||
### Requirement: Device Import via Object Storage
|
||||
|
||||
The system SHALL support CSV-based device import using a three-step object storage upload process.
|
||||
|
||||
#### Scenario: Import devices with three-step process
|
||||
|
||||
**WHEN** an administrator uploads a CSV file **THEN** the system shall:
|
||||
|
||||
1. Get upload URL from StorageService.getUploadUrl
|
||||
2. Upload file to object storage using StorageService.uploadFile
|
||||
3. Call DeviceService.importDevices with the file_key **AND** display the task number for tracking
|
||||
|
||||
#### Scenario: Validate CSV format
|
||||
|
||||
**WHEN** the CSV file is uploaded **THEN** the system shall validate the presence of required columns: device_no, device_name, device_model, device_type, max_sim_slots, manufacturer
|
||||
|
||||
#### Scenario: Import devices with card bindings
|
||||
|
||||
**WHEN** the CSV includes iccid_1, iccid_2, iccid_3, iccid_4 columns **THEN** the system shall attempt to bind the specified cards to slots 1-4 respectively during import
|
||||
|
||||
#### Scenario: Handle import errors
|
||||
|
||||
**WHEN** the import process encounters errors (duplicate device_no, invalid ICCID, etc.) **THEN** the system shall record failed rows in the import task with detailed error messages
|
||||
|
||||
### Requirement: Import Task Management
|
||||
|
||||
The system SHALL track device import tasks with detailed status and record information.
|
||||
|
||||
#### Scenario: List import tasks with type filter
|
||||
|
||||
**WHEN** an administrator views the task management page **THEN** the system shall display both ICCID import tasks and Device import tasks with a type filter dropdown
|
||||
|
||||
#### Scenario: View device import task details
|
||||
|
||||
**WHEN** an administrator clicks on a device import task **THEN** the system shall display: task ID, status, total count, success count, failed count, skipped count, created time, completed time
|
||||
|
||||
#### Scenario: View successful import records
|
||||
|
||||
**WHEN** viewing a device import task detail **THEN** the system shall show a table of successfully imported devices with: device_no, device_name, bound ICCIDs
|
||||
|
||||
#### Scenario: View failed import records
|
||||
|
||||
**WHEN** viewing a device import task detail with failures **THEN** the system shall show a table of failed records with: row number, device_no, failure reason
|
||||
|
||||
#### Scenario: Navigate from import page to task detail
|
||||
|
||||
**WHEN** a device import completes successfully **THEN** the system shall display the task number with a link to view task details
|
||||
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Task Type Support
|
||||
|
||||
Task management SHALL support multiple task types including ICCID import and Device import with type-specific detail views.
|
||||
|
||||
**Previous behavior**: Task management only supported ICCID import tasks.
|
||||
|
||||
#### Scenario: Filter tasks by type
|
||||
|
||||
**WHEN** an administrator selects a task type filter (ICCID Import / Device Import) **THEN** the system shall display only tasks of the selected type
|
||||
|
||||
#### Scenario: Display task type badges
|
||||
|
||||
**WHEN** viewing the task list **THEN** each task shall display a type badge indicating whether it's an ICCID import or Device import task
|
||||
@@ -1,126 +0,0 @@
|
||||
# Implementation Tasks
|
||||
|
||||
## 1. 类型定义和API服务 (Foundation)
|
||||
|
||||
- [ ] 1.1 创建 `src/types/api/device.ts` 定义所有设备相关类型
|
||||
- DeviceItem, DeviceQueryParams, DevicePageResult
|
||||
- DeviceCardBinding, DeviceCardBindingList
|
||||
- AllocateDevicesRequest/Response, RecallDevicesRequest/Response
|
||||
- BindCardRequest/Response, UnbindCardResponse
|
||||
- ImportDeviceRequest/Response, DeviceImportTask相关类型
|
||||
- [ ] 1.2 创建 `src/api/modules/device.ts` 实现 DeviceService
|
||||
- getDevices (列表)
|
||||
- getDeviceById (详情)
|
||||
- deleteDevice (删除)
|
||||
- getDeviceCards (绑定的卡列表)
|
||||
- bindCard (绑定卡)
|
||||
- unbindCard (解绑卡)
|
||||
- allocateDevices (批量分配)
|
||||
- recallDevices (批量回收)
|
||||
- importDevices (批量导入)
|
||||
- getImportTasks (导入任务列表)
|
||||
- getImportTaskDetail (导入任务详情)
|
||||
- [ ] 1.3 在 `src/api/modules/index.ts` 导出 DeviceService
|
||||
- [ ] 1.4 在 `src/types/api/index.ts` 导出 Device 相关类型
|
||||
|
||||
## 2. 设备列表页面 (Core UI)
|
||||
|
||||
- [ ] 2.1 创建 `src/views/asset-management/device-list/index.vue`
|
||||
- 搜索栏:设备号、设备名称、状态、店铺、批次号、设备类型、制造商、创建时间范围
|
||||
- 表格:展示设备信息,支持勾选、列筛选
|
||||
- 表格列:ID、设备号、设备名称、设备型号、设备类型、制造商、最大插槽数、已绑定卡数、状态、店铺、批次号、激活时间、创建时间
|
||||
- 状态使用 CommonStatus + ElSwitch 显示
|
||||
- 操作列:查看详情、删除按钮(使用 ArtButtonTable)
|
||||
- [ ] 2.2 实现批量操作按钮
|
||||
- 批量分配:弹出对话框选择目标店铺
|
||||
- 批量回收:弹出对话框确认回收
|
||||
- 导入设备:跳转到设备导入页面
|
||||
- [ ] 2.3 实现批量分配对话框
|
||||
- 选择目标店铺(下拉搜索)
|
||||
- 显示已选设备数量
|
||||
- 备注输入
|
||||
- 展示分配结果(成功/失败)
|
||||
- [ ] 2.4 实现批量回收对话框
|
||||
- 确认回收设备列表
|
||||
- 备注输入
|
||||
- 展示回收结果(成功/失败)
|
||||
|
||||
## 3. 设备详情页面 (Detail View)
|
||||
|
||||
- [ ] 3.1 创建 `src/views/asset-management/device-detail/index.vue`
|
||||
- 设备基本信息卡片(ElDescriptions)
|
||||
- 绑定的卡列表表格(展示4个插槽位置)
|
||||
- 返回按钮
|
||||
- [ ] 3.2 实现卡绑定管理
|
||||
- 绑定卡按钮:弹出对话框选择卡和插槽位置
|
||||
- 解绑按钮:每个绑定记录旁边
|
||||
- 显示插槽位置(1-4)
|
||||
- 展示卡的基本信息(ICCID、手机号、运营商、状态)
|
||||
|
||||
## 4. 任务管理改进 (Task Management)
|
||||
|
||||
- [ ] 4.1 修改 `src/views/asset-management/task-management/index.vue`
|
||||
- 添加任务类型筛选:ICCID导入 / 设备导入
|
||||
- 支持展示设备导入任务
|
||||
- 任务列表显示任务类型标签
|
||||
- [ ] 4.2 修改 `src/views/asset-management/task-detail/index.vue`
|
||||
- 根据任务类型展示不同的详情内容
|
||||
- 设备导入任务:显示设备号、绑定的ICCID、失败原因
|
||||
- 失败和跳过记录展示
|
||||
|
||||
## 5. 设备导入改进 (Import Enhancement)
|
||||
|
||||
- [ ] 5.1 修改 `src/views/batch/device-import/index.vue`
|
||||
- 改用对象存储三步上传流程
|
||||
1. 获取上传URL (StorageService.getUploadUrl)
|
||||
2. 上传文件到对象存储 (StorageService.uploadFile)
|
||||
3. 调用导入接口 (DeviceService.importDevices)
|
||||
- CSV格式说明:device_no, device_name, device_model, device_type, max_sim_slots, manufacturer, iccid_1~iccid_4, batch_no
|
||||
- 导入成功后显示任务编号,引导去任务管理查看
|
||||
- [ ] 5.2 优化导入记录展示
|
||||
- 移除mock数据,改为真实API调用
|
||||
- 点击"查看详情"跳转到任务详情页
|
||||
|
||||
## 6. 路由和导航 (Routing)
|
||||
|
||||
- [ ] 6.1 在 `src/router/routes/asyncRoutes.ts` 添加路由
|
||||
- /asset-management/device-list (设备列表)
|
||||
- /asset-management/device-detail (设备详情,带query参数id)
|
||||
- [ ] 6.2 在 `src/router/routesAlias.ts` 添加路由别名
|
||||
- DeviceList = '/asset-management/device-list'
|
||||
- DeviceDetail = '/asset-management/device-detail'
|
||||
- [ ] 6.3 在 `src/locales/langs/zh.json` 添加翻译
|
||||
- assetManagement.deviceList: "设备列表"
|
||||
- assetManagement.deviceDetail: "设备详情"
|
||||
|
||||
## 7. 测试和优化 (Testing & Polish)
|
||||
|
||||
- [ ] 7.1 功能测试
|
||||
- 设备列表的搜索、分页、排序
|
||||
- 批量分配和回收流程
|
||||
- 设备与卡的绑定/解绑
|
||||
- 设备导入完整流程
|
||||
- 任务状态查看
|
||||
- [ ] 7.2 边界情况处理
|
||||
- 空列表状态
|
||||
- 加载失败提示
|
||||
- 删除确认提示
|
||||
- 表单验证
|
||||
- [ ] 7.3 性能优化
|
||||
- 列表数据懒加载
|
||||
- 防抖搜索
|
||||
- 批量操作结果分页展示
|
||||
- [ ] 7.4 代码审查
|
||||
- TypeScript类型完整性
|
||||
- 错误处理
|
||||
- 代码复用性
|
||||
- 注释完整性
|
||||
|
||||
## Dependencies
|
||||
|
||||
- 1.x 必须先完成才能开始 2.x-6.x
|
||||
- 2.1-2.2 可以并行开发
|
||||
- 3.x 依赖 1.x,可与 2.x 并行
|
||||
- 4.x 和 5.x 依赖 1.x,可与其他任务并行
|
||||
- 6.x 可在对应页面开发完成后立即进行
|
||||
- 7.x 在所有功能开发完成后进行
|
||||
@@ -1,62 +0,0 @@
|
||||
# Change: Add IoT Card and Device Operations
|
||||
|
||||
## Why
|
||||
|
||||
运营人员和代理商需要更丰富的物联网卡和设备管理功能,包括查询流量使用情况、实名认证状态、卡片状态、启停操作,以及设备的重启、重置、限速、换卡、WiFi设置等操作。这些功能是物联网卡全生命周期管理的核心能力。
|
||||
|
||||
## What Changes
|
||||
|
||||
### IoT Card Operations (6 new APIs)
|
||||
|
||||
- 查询流量使用情况 (GET /api/admin/iot-cards/{iccid}/gateway-flow)
|
||||
- 查询实名认证状态 (GET /api/admin/iot-cards/{iccid}/gateway-realname)
|
||||
- 查询卡片状态 (GET /api/admin/iot-cards/{iccid}/gateway-status)
|
||||
- 获取实名认证链接 (GET /api/admin/iot-cards/{iccid}/realname-link)
|
||||
- 启用物联网卡 (POST /api/admin/iot-cards/{iccid}/start)
|
||||
- 停用物联网卡 (POST /api/admin/iot-cards/{iccid}/stop)
|
||||
|
||||
### Device Operations (6 new APIs)
|
||||
|
||||
- 重启设备 (POST /api/admin/devices/by-imei/{imei}/reboot)
|
||||
- 重置设备 (POST /api/admin/devices/by-imei/{imei}/reset)
|
||||
- 设置限速 (PUT /api/admin/devices/by-imei/{imei}/speed-limit)
|
||||
- 切换SIM卡 (POST /api/admin/devices/by-imei/{imei}/switch-card)
|
||||
- 设置WiFi (PUT /api/admin/devices/by-imei/{imei}/wifi)
|
||||
|
||||
### UI Changes
|
||||
|
||||
- 在 `/asset-management/iot-card-management` 页面添加操作按钮:
|
||||
- "查询流量"按钮(主要操作)
|
||||
- "更多操作"下拉菜单(包含其他5个操作)
|
||||
- 在 `/asset-management/devices` 页面添加操作按钮:
|
||||
- "重启设备"按钮(主要操作)
|
||||
- "更多操作"下拉菜单(包含其他5个操作)
|
||||
|
||||
## Impact
|
||||
|
||||
### Affected Specs
|
||||
|
||||
- **NEW**: `specs/iot-card-operations/spec.md` - IoT卡操作相关的所有需求
|
||||
- **NEW**: `specs/device-operations/spec.md` - 设备操作相关的所有需求
|
||||
|
||||
### Affected Code
|
||||
|
||||
- **API层**:
|
||||
- 新增 `src/api/modules/iotCard.ts` - IoT卡操作API方法
|
||||
- 新增 `src/api/modules/device.ts` - 设备操作API方法
|
||||
- **类型定义**:
|
||||
- 新增 `src/types/api/iotCard.ts` - IoT卡相关类型
|
||||
- 新增 `src/types/api/device.ts` - 设备相关类型
|
||||
- **页面组件**:
|
||||
- 修改 `src/views/asset-management/iot-card-management/index.vue` - 添加操作按钮和对话框
|
||||
- 修改 `src/views/asset-management/devices/index.vue` - 添加操作按钮和对话框
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
无破坏性变更。所有变更都是增量式的新功能添加。
|
||||
|
||||
## Dependencies
|
||||
|
||||
- 后端API已实现(见 `docs/2-3新增接口.md`)
|
||||
- Element Plus UI组件库(已在项目中)
|
||||
- Axios HTTP客户端(已在项目中)
|
||||
@@ -1,194 +0,0 @@
|
||||
# Device Operations Specification
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Reboot Device
|
||||
|
||||
The system SHALL provide the ability to reboot an IoT device via its IMEI.
|
||||
|
||||
#### Scenario: Successfully reboot device
|
||||
|
||||
- **WHEN** an authenticated user initiates a reboot operation on a device with valid IMEI
|
||||
- **THEN** the system sends the reboot command to the device
|
||||
- **AND** returns a success response with operation confirmation
|
||||
|
||||
#### Scenario: Reboot operation with confirmation
|
||||
|
||||
- **WHEN** a user clicks the reboot device button
|
||||
- **THEN** the system prompts for confirmation with a warning message
|
||||
- **AND** only proceeds if the user confirms the action
|
||||
|
||||
#### Scenario: Reboot with invalid IMEI
|
||||
|
||||
- **WHEN** a user attempts to reboot a device with invalid or non-existent IMEI
|
||||
- **THEN** the system returns a 400 error with appropriate error message
|
||||
|
||||
### Requirement: Reset Device to Factory Settings
|
||||
|
||||
The system SHALL provide the ability to reset an IoT device to factory settings via its IMEI.
|
||||
|
||||
#### Scenario: Successfully reset device
|
||||
|
||||
- **WHEN** an authenticated user initiates a factory reset operation on a device
|
||||
- **THEN** the system sends the reset command to the device
|
||||
- **AND** returns a success response
|
||||
|
||||
#### Scenario: Reset operation with strong confirmation
|
||||
|
||||
- **WHEN** a user clicks the factory reset button
|
||||
- **THEN** the system displays a warning dialog explaining data loss
|
||||
- **AND** requires user confirmation before proceeding
|
||||
- **AND** only executes if the user explicitly confirms
|
||||
|
||||
#### Scenario: Insufficient permissions for reset
|
||||
|
||||
- **WHEN** a user without proper permissions attempts to reset a device
|
||||
- **THEN** the system returns a 403 forbidden error
|
||||
|
||||
### Requirement: Set Device Speed Limit
|
||||
|
||||
The system SHALL provide the ability to configure upload and download speed limits for an IoT device.
|
||||
|
||||
#### Scenario: Successfully set speed limit
|
||||
|
||||
- **WHEN** an authenticated user submits valid speed limit parameters
|
||||
- **THEN** the system applies the upload and download speed limits to the device
|
||||
- **AND** returns a success response
|
||||
|
||||
#### Scenario: Configure speed limits via dialog
|
||||
|
||||
- **WHEN** a user selects the speed limit option
|
||||
- **THEN** the system displays a dialog with input fields for upload_speed and download_speed (KB/s)
|
||||
- **AND** validates that both values are integers >= 1
|
||||
|
||||
#### Scenario: Invalid speed limit parameters
|
||||
|
||||
- **WHEN** a user submits speed limits less than 1 KB/s
|
||||
- **THEN** the system returns a 400 parameter error
|
||||
- **AND** displays validation error messages
|
||||
|
||||
### Requirement: Switch Device SIM Card
|
||||
|
||||
The system SHALL provide the ability to switch the active SIM card on a multi-SIM device.
|
||||
|
||||
#### Scenario: Successfully switch to target card
|
||||
|
||||
- **WHEN** an authenticated user initiates a card switch with valid target ICCID
|
||||
- **THEN** the system switches the device to use the specified card
|
||||
- **AND** returns a success response
|
||||
|
||||
#### Scenario: Switch card via dialog
|
||||
|
||||
- **WHEN** a user selects the switch card option
|
||||
- **THEN** the system displays a dialog prompting for target_iccid
|
||||
- **AND** validates the ICCID format
|
||||
|
||||
#### Scenario: Switch to non-existent card
|
||||
|
||||
- **WHEN** a user attempts to switch to an ICCID that doesn't exist or isn't available
|
||||
- **THEN** the system returns a 400 error with descriptive message
|
||||
|
||||
### Requirement: Configure Device WiFi Settings
|
||||
|
||||
The system SHALL provide the ability to configure WiFi settings including SSID, password, and enabled status.
|
||||
|
||||
#### Scenario: Successfully configure WiFi
|
||||
|
||||
- **WHEN** an authenticated user submits valid WiFi configuration
|
||||
- **THEN** the system applies the WiFi settings to the device
|
||||
- **AND** returns a success response
|
||||
|
||||
#### Scenario: Configure WiFi via dialog
|
||||
|
||||
- **WHEN** a user selects the WiFi configuration option
|
||||
- **THEN** the system displays a dialog with fields for:
|
||||
- enabled (启用状态: 0=禁用, 1=启用)
|
||||
- ssid (WiFi名称, 1-32 characters)
|
||||
- password (WiFi密码, 8-63 characters)
|
||||
- **AND** validates all field constraints
|
||||
|
||||
#### Scenario: Invalid WiFi parameters
|
||||
|
||||
- **WHEN** a user submits WiFi configuration with invalid parameters
|
||||
- **THEN** the system returns a 400 error
|
||||
- **AND** displays specific validation errors (e.g., "SSID too long", "Password too short")
|
||||
|
||||
### Requirement: Device Management UI Integration
|
||||
|
||||
The system SHALL integrate device operations into the device management page at `/asset-management/devices`.
|
||||
|
||||
#### Scenario: Display primary operation button
|
||||
|
||||
- **WHEN** a user views the device management page
|
||||
- **THEN** the system displays a "重启设备" (Reboot Device) button as the primary operation
|
||||
|
||||
#### Scenario: Display dropdown menu for additional operations
|
||||
|
||||
- **WHEN** a user views the device management page
|
||||
- **THEN** the system displays a "更多操作" (More Operations) dropdown menu
|
||||
- **AND** the dropdown contains: 恢复出厂, 设置限速, 切换SIM卡, 设置WiFi
|
||||
|
||||
#### Scenario: Show loading indicator during operations
|
||||
|
||||
- **WHEN** a device operation is in progress
|
||||
- **THEN** the system displays a loading indicator
|
||||
- **AND** disables the operation buttons to prevent duplicate requests
|
||||
|
||||
### Requirement: Authentication and Authorization
|
||||
|
||||
The system SHALL enforce JWT-based authentication for all device operations.
|
||||
|
||||
#### Scenario: Access with valid JWT token
|
||||
|
||||
- **WHEN** a user makes a request with a valid Bearer token
|
||||
- **THEN** the system processes the request normally
|
||||
|
||||
#### Scenario: Access with expired token
|
||||
|
||||
- **WHEN** a user makes a request with an expired JWT token
|
||||
- **THEN** the system returns a 401 unauthorized error
|
||||
- **AND** redirects to the login page
|
||||
|
||||
### Requirement: Error Handling and User Feedback
|
||||
|
||||
The system SHALL provide clear error messages and success notifications for all operations.
|
||||
|
||||
#### Scenario: Display success message
|
||||
|
||||
- **WHEN** a device operation completes successfully
|
||||
- **THEN** the system displays a success message notification
|
||||
- **AND** automatically closes the operation dialog
|
||||
|
||||
#### Scenario: Handle network errors
|
||||
|
||||
- **WHEN** a network error occurs during a device operation
|
||||
- **THEN** the system displays a user-friendly error message
|
||||
- **AND** allows the user to retry the operation
|
||||
|
||||
#### Scenario: Handle server errors
|
||||
|
||||
- **WHEN** a 500 server error occurs
|
||||
- **THEN** the system displays an error message with timestamp
|
||||
- **AND** logs the error for debugging
|
||||
|
||||
### Requirement: Operation Confirmation Dialogs
|
||||
|
||||
The system SHALL require user confirmation for destructive operations.
|
||||
|
||||
#### Scenario: Confirm reboot operation
|
||||
|
||||
- **WHEN** a user initiates a reboot
|
||||
- **THEN** the system shows a confirmation dialog stating "确定要重启该设备吗?"
|
||||
- **AND** requires explicit confirmation
|
||||
|
||||
#### Scenario: Confirm factory reset operation
|
||||
|
||||
- **WHEN** a user initiates a factory reset
|
||||
- **THEN** the system shows a strong warning dialog stating "确定要恢复出厂设置吗?此操作将清除所有数据!"
|
||||
- **AND** requires explicit confirmation
|
||||
|
||||
#### Scenario: No confirmation for query operations
|
||||
|
||||
- **WHEN** a user initiates speed limit, card switch, or WiFi configuration
|
||||
- **THEN** the system displays input dialogs without confirmation prompts
|
||||
- **AND** only executes after user submits valid parameters
|
||||
@@ -1,151 +0,0 @@
|
||||
# IoT Card Operations Specification
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Query IoT Card Flow Usage
|
||||
|
||||
The system SHALL provide the ability to query real-time flow usage for an IoT card via its ICCID.
|
||||
|
||||
#### Scenario: Successfully query flow usage
|
||||
|
||||
- **WHEN** an authenticated user requests flow usage for a valid ICCID
|
||||
- **THEN** the system returns flow usage data including used flow amount and unit
|
||||
|
||||
#### Scenario: Query with invalid ICCID
|
||||
|
||||
- **WHEN** a user requests flow usage for an invalid or non-existent ICCID
|
||||
- **THEN** the system returns a 400 error with appropriate error message
|
||||
|
||||
### Requirement: Query IoT Card Realname Status
|
||||
|
||||
The system SHALL provide the ability to query the realname authentication status for an IoT card via its ICCID.
|
||||
|
||||
#### Scenario: Successfully query realname status
|
||||
|
||||
- **WHEN** an authenticated user requests realname status for a valid ICCID
|
||||
- **THEN** the system returns the current realname authentication status
|
||||
|
||||
#### Scenario: Query status for unauthenticated user
|
||||
|
||||
- **WHEN** an unauthenticated user attempts to query realname status
|
||||
- **THEN** the system returns a 401 unauthorized error
|
||||
|
||||
### Requirement: Query IoT Card Real-time Status
|
||||
|
||||
The system SHALL provide the ability to query the real-time operational status of an IoT card via its ICCID.
|
||||
|
||||
#### Scenario: Successfully query card status
|
||||
|
||||
- **WHEN** an authenticated user requests card status for a valid ICCID
|
||||
- **THEN** the system returns card status information including ICCID and current status (准备/正常/停机)
|
||||
|
||||
#### Scenario: Query with unauthorized access
|
||||
|
||||
- **WHEN** a user without proper permissions attempts to query card status
|
||||
- **THEN** the system returns a 403 forbidden error
|
||||
|
||||
### Requirement: Get IoT Card Realname Link
|
||||
|
||||
The system SHALL provide the ability to generate and retrieve a realname authentication link for an IoT card.
|
||||
|
||||
#### Scenario: Successfully retrieve realname link
|
||||
|
||||
- **WHEN** an authenticated user requests the realname link for a valid ICCID
|
||||
- **THEN** the system returns an HTTPS URL that can be used for realname authentication
|
||||
|
||||
#### Scenario: Display realname link as QR code
|
||||
|
||||
- **WHEN** the system returns a realname authentication link
|
||||
- **THEN** the UI displays the link as a QR code for easy mobile scanning
|
||||
|
||||
### Requirement: Start IoT Card (复机)
|
||||
|
||||
The system SHALL provide the ability to start (restore service) an IoT card via its ICCID.
|
||||
|
||||
#### Scenario: Successfully start a stopped card
|
||||
|
||||
- **WHEN** an authenticated user initiates a start operation on a stopped card
|
||||
- **THEN** the system processes the request and restores card service
|
||||
- **AND** displays a success message to the user
|
||||
|
||||
#### Scenario: Start operation with confirmation
|
||||
|
||||
- **WHEN** a user clicks the start card button
|
||||
- **THEN** the system prompts for confirmation before executing the operation
|
||||
- **AND** only proceeds if the user confirms the action
|
||||
|
||||
#### Scenario: Insufficient permissions for start operation
|
||||
|
||||
- **WHEN** a user without proper permissions attempts to start a card
|
||||
- **THEN** the system returns a 403 forbidden error
|
||||
|
||||
### Requirement: Stop IoT Card (停机)
|
||||
|
||||
The system SHALL provide the ability to stop (suspend service) an IoT card via its ICCID.
|
||||
|
||||
#### Scenario: Successfully stop an active card
|
||||
|
||||
- **WHEN** an authenticated user initiates a stop operation on an active card
|
||||
- **THEN** the system processes the request and suspends card service
|
||||
- **AND** displays a success message to the user
|
||||
|
||||
#### Scenario: Stop operation with confirmation
|
||||
|
||||
- **WHEN** a user clicks the stop card button
|
||||
- **THEN** the system prompts for confirmation before executing the operation
|
||||
- **AND** only proceeds if the user confirms the action
|
||||
|
||||
#### Scenario: Server error during stop operation
|
||||
|
||||
- **WHEN** a server error occurs during the stop operation
|
||||
- **THEN** the system returns a 500 error with error details
|
||||
- **AND** displays an appropriate error message to the user
|
||||
|
||||
### Requirement: IoT Card Management UI Integration
|
||||
|
||||
The system SHALL integrate IoT card operations into the card management page at `/asset-management/iot-card-management`.
|
||||
|
||||
#### Scenario: Display primary operation button
|
||||
|
||||
- **WHEN** a user views the IoT card management page
|
||||
- **THEN** the system displays a "查询流量使用" (Query Flow Usage) button as the primary operation
|
||||
|
||||
#### Scenario: Display dropdown menu for additional operations
|
||||
|
||||
- **WHEN** a user views the IoT card management page
|
||||
- **THEN** the system displays a "更多操作" (More Operations) dropdown menu
|
||||
- **AND** the dropdown contains: 查询实名状态, 查询卡状态, 获取实名链接, 启用卡片, 停用卡片
|
||||
|
||||
#### Scenario: Show operation results in dialog
|
||||
|
||||
- **WHEN** a user executes a query operation (flow, realname status, or card status)
|
||||
- **THEN** the system displays results in a modal dialog with properly formatted data
|
||||
|
||||
### Requirement: Authentication and Authorization
|
||||
|
||||
The system SHALL enforce JWT-based authentication for all IoT card operations.
|
||||
|
||||
#### Scenario: Access with valid JWT token
|
||||
|
||||
- **WHEN** a user makes a request with a valid Bearer token
|
||||
- **THEN** the system processes the request normally
|
||||
|
||||
#### Scenario: Access with expired token
|
||||
|
||||
- **WHEN** a user makes a request with an expired JWT token
|
||||
- **THEN** the system returns a 401 unauthorized error
|
||||
|
||||
### Requirement: Error Handling
|
||||
|
||||
The system SHALL provide clear error messages for all failure scenarios.
|
||||
|
||||
#### Scenario: Handle 400 parameter errors
|
||||
|
||||
- **WHEN** a request contains invalid parameters
|
||||
- **THEN** the system returns a 400 error with specific validation failure details
|
||||
|
||||
#### Scenario: Handle 500 server errors
|
||||
|
||||
- **WHEN** an internal server error occurs
|
||||
- **THEN** the system returns a 500 error with error timestamp
|
||||
- **AND** logs the error for debugging purposes
|
||||
@@ -1,86 +0,0 @@
|
||||
# Implementation Tasks
|
||||
|
||||
## 1. API Layer - IoT Card Operations
|
||||
|
||||
- [ ] 1.1 创建 `src/api/modules/iotCard.ts`
|
||||
- [ ] 1.2 实现 `getGatewayFlow(iccid)` - 查询流量使用
|
||||
- [ ] 1.3 实现 `getGatewayRealname(iccid)` - 查询实名状态
|
||||
- [ ] 1.4 实现 `getGatewayStatus(iccid)` - 查询卡片状态
|
||||
- [ ] 1.5 实现 `getRealnameLink(iccid)` - 获取实名链接
|
||||
- [ ] 1.6 实现 `startCard(iccid)` - 启用卡片
|
||||
- [ ] 1.7 实现 `stopCard(iccid)` - 停用卡片
|
||||
|
||||
## 2. API Layer - Device Operations
|
||||
|
||||
- [ ] 2.1 创建 `src/api/modules/device.ts`
|
||||
- [ ] 2.2 实现 `rebootDevice(imei)` - 重启设备
|
||||
- [ ] 2.3 实现 `resetDevice(imei)` - 重置设备
|
||||
- [ ] 2.4 实现 `setSpeedLimit(imei, params)` - 设置限速
|
||||
- [ ] 2.5 实现 `switchCard(imei, params)` - 切换SIM卡
|
||||
- [ ] 2.6 实现 `setWifi(imei, params)` - 设置WiFi
|
||||
|
||||
## 3. Type Definitions - IoT Card
|
||||
|
||||
- [ ] 3.1 创建 `src/types/api/iotCard.ts`
|
||||
- [ ] 3.2 定义流量使用响应类型 `GatewayFlowResponse`
|
||||
- [ ] 3.3 定义实名状态响应类型 `GatewayRealnameResponse`
|
||||
- [ ] 3.4 定义卡片状态响应类型 `GatewayStatusResponse`
|
||||
- [ ] 3.5 定义实名链接响应类型 `RealnameUrlResponse`
|
||||
- [ ] 3.6 定义启停操作请求类型 `StartStopCardRequest`
|
||||
|
||||
## 4. Type Definitions - Device
|
||||
|
||||
- [ ] 4.1 创建 `src/types/api/device.ts`
|
||||
- [ ] 4.2 定义限速参数类型 `SpeedLimitParams`
|
||||
- [ ] 4.3 定义换卡参数类型 `SwitchCardParams`
|
||||
- [ ] 4.4 定义WiFi参数类型 `WifiParams`
|
||||
- [ ] 4.5 定义操作响应类型 `DeviceOperationResponse`
|
||||
|
||||
## 5. UI - IoT Card Management Page
|
||||
|
||||
- [ ] 5.1 在表格操作列添加"查询流量"按钮
|
||||
- [ ] 5.2 在表格操作列添加"更多操作"下拉菜单
|
||||
- [ ] 5.3 创建"流量使用查询"对话框组件
|
||||
- [ ] 5.4 创建"实名状态查询"对话框组件
|
||||
- [ ] 5.5 创建"卡片状态查询"对话框组件
|
||||
- [ ] 5.6 创建"获取实名链接"对话框组件(显示二维码)
|
||||
- [ ] 5.7 实现"启用卡片"操作(带确认提示)
|
||||
- [ ] 5.8 实现"停用卡片"操作(带确认提示)
|
||||
|
||||
## 6. UI - Device Management Page
|
||||
|
||||
- [ ] 6.1 在表格操作列添加"重启设备"按钮
|
||||
- [ ] 6.2 在表格操作列添加"更多操作"下拉菜单
|
||||
- [ ] 6.3 实现"重启设备"操作(带确认提示)
|
||||
- [ ] 6.4 实现"重置设备"操作(带确认提示)
|
||||
- [ ] 6.5 创建"设置限速"对话框组件(包含上下行速率输入)
|
||||
- [ ] 6.6 创建"切换SIM卡"对话框组件(选择卡槽)
|
||||
- [ ] 6.7 创建"设置WiFi"对话框组件(SSID、密码、频段等)
|
||||
|
||||
## 7. Error Handling & User Feedback
|
||||
|
||||
- [ ] 7.1 为所有API调用添加错误处理
|
||||
- [ ] 7.2 添加操作成功提示消息
|
||||
- [ ] 7.3 添加操作失败错误提示
|
||||
- [ ] 7.4 添加加载状态指示器
|
||||
|
||||
## 8. Permission Control
|
||||
|
||||
- [ ] 8.1 检查IoT卡操作权限配置
|
||||
- [ ] 8.2 检查设备操作权限配置
|
||||
- [ ] 8.3 根据权限显示/隐藏操作按钮
|
||||
|
||||
## 9. Testing & Validation
|
||||
|
||||
- [ ] 9.1 测试所有IoT卡操作API调用
|
||||
- [ ] 9.2 测试所有设备操作API调用
|
||||
- [ ] 9.3 测试UI交互和对话框显示
|
||||
- [ ] 9.4 测试错误处理场景
|
||||
- [ ] 9.5 测试权限控制
|
||||
- [ ] 9.6 验证响应数据格式和显示
|
||||
|
||||
## 10. Documentation
|
||||
|
||||
- [ ] 10.1 更新API文档(如有需要)
|
||||
- [ ] 10.2 添加操作说明注释
|
||||
- [ ] 10.3 更新用户手册(如有需要)
|
||||
@@ -1,33 +0,0 @@
|
||||
# Change: 重命名 API 字段 series_allocation_id 为 series_id
|
||||
|
||||
## Why
|
||||
|
||||
后端 API 字段命名不一致。前端表单使用 `series_id`(套餐系列ID),但 API 参数仍使用 `series_allocation_id`(套餐系列分配ID)。这导致命名混淆且不符合实际业务含义(现在直接指向套餐系列 ID,而非分配记录 ID)。
|
||||
|
||||
## What Changes
|
||||
|
||||
- **BREAKING**: 重命名 4 个 API 端点的请求/响应字段
|
||||
|
||||
- `PATCH /api/admin/iot-cards/series-binding` - 请求参数 `series_allocation_id` → `series_id`
|
||||
- `PATCH /api/admin/devices/series-binding` - 请求参数 `series_allocation_id` → `series_id`
|
||||
- `GET /api/admin/iot-cards/standalone` - 查询参数和响应字段 `series_allocation_id` → `series_id`
|
||||
- `GET /api/admin/devices` - 查询参数和响应字段 `series_allocation_id` → `series_id`
|
||||
|
||||
- 前端同步修改:
|
||||
- TypeScript 类型定义
|
||||
- API 方法参数
|
||||
- 页面组件调用代码
|
||||
- 移除临时注释
|
||||
|
||||
## Impact
|
||||
|
||||
- **Affected specs**: iot-card-api, device-api
|
||||
- **Affected code**:
|
||||
- `src/types/api/device.ts` (BatchSetDeviceSeriesBindingRequest)
|
||||
- `src/types/api/card.ts` (BatchSetCardSeriesBindingRequest)
|
||||
- `src/api/modules/device.ts` (batchSetDeviceSeriesBinding)
|
||||
- `src/api/modules/card.ts` (batchSetCardSeriesBinding)
|
||||
- `src/views/asset-management/device-list/index.vue`
|
||||
- `src/views/asset-management/iot-card-management/index.vue`
|
||||
- **Breaking change**: 需要后端先部署更新,前端再部署
|
||||
- **Migration**: 更新所有使用这些字段的 API 调用
|
||||
@@ -1,104 +0,0 @@
|
||||
# Device API Specification Delta
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Device Series ID Query Parameter
|
||||
|
||||
The system SHALL support filtering devices by package series ID in query parameters.
|
||||
|
||||
**Query Parameter**: `series_id` (number, optional)
|
||||
|
||||
#### Scenario: Filter devices by series
|
||||
|
||||
- **WHEN** admin queries devices with series_id parameter
|
||||
- **THEN** system returns only devices associated with that package series
|
||||
- **AND** returns empty list if no matches found
|
||||
|
||||
#### Scenario: Query without series filter
|
||||
|
||||
- **WHEN** admin queries devices without series_id parameter
|
||||
- **THEN** system returns all devices matching other filter criteria
|
||||
- **AND** series association is not considered
|
||||
|
||||
### Requirement: Device Series ID Response Field
|
||||
|
||||
The system SHALL include package series ID in device response data.
|
||||
|
||||
**Response Field**: `series_id` (number | null)
|
||||
|
||||
- Value is package series ID if device is bound to a series
|
||||
- Value is null if device has no series binding
|
||||
|
||||
#### Scenario: Display series association
|
||||
|
||||
- **WHEN** system returns device in list response
|
||||
- **THEN** each device includes series_id field
|
||||
- **AND** field shows current series binding or null
|
||||
|
||||
#### Scenario: Null series binding
|
||||
|
||||
- **WHEN** device has no series binding
|
||||
- **THEN** series_id field is null
|
||||
- **AND** device can still be displayed in results
|
||||
|
||||
## RENAMED Requirements
|
||||
|
||||
### API Field Renaming
|
||||
|
||||
- FROM: `series_allocation_id` (in batch series binding endpoints)
|
||||
- TO: `series_id`
|
||||
|
||||
**Reason**: Field name `series_allocation_id` implied a reference to an allocation record ID, but it actually stores the package series ID directly. Renaming to `series_id` clarifies this relationship and aligns with frontend naming conventions.
|
||||
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Batch Set Device Series Binding
|
||||
|
||||
The system SHALL provide an endpoint to batch set package series binding for devices.
|
||||
|
||||
**Endpoint**: `PATCH /api/admin/devices/series-binding`
|
||||
|
||||
**Request Body**:
|
||||
|
||||
```json
|
||||
{
|
||||
"device_ids": [1, 2, 3],
|
||||
"series_id": 123 // Changed from series_allocation_id
|
||||
}
|
||||
```
|
||||
|
||||
**Field Definitions**:
|
||||
|
||||
- `device_ids`: Array of device IDs (max 500 items)
|
||||
- `series_id`: Package series ID (tb_package_series.id), 0 means clear association
|
||||
|
||||
**Response**:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"data": {
|
||||
"success_count": 3,
|
||||
"fail_count": 0,
|
||||
"failed_items": null
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Scenario: Successful batch series binding
|
||||
|
||||
- **WHEN** admin calls batch series binding API with valid device IDs and series_id
|
||||
- **THEN** system updates series association for all valid devices
|
||||
- **AND** returns success count and failure details
|
||||
|
||||
#### Scenario: Clear series association
|
||||
|
||||
- **WHEN** admin calls batch series binding API with series_id = 0
|
||||
- **THEN** system clears series association for specified devices
|
||||
- **AND** returns success confirmation
|
||||
|
||||
#### Scenario: Partial failure handling
|
||||
|
||||
- **WHEN** some devices in the batch cannot be updated
|
||||
- **THEN** system processes valid devices successfully
|
||||
- **AND** returns failed_items list with reasons for failures
|
||||
@@ -1,104 +0,0 @@
|
||||
# IoT Card API Specification Delta
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: IoT Card Series ID Query Parameter
|
||||
|
||||
The system SHALL support filtering standalone IoT cards by package series ID in query parameters.
|
||||
|
||||
**Query Parameter**: `series_id` (number, optional)
|
||||
|
||||
#### Scenario: Filter cards by series
|
||||
|
||||
- **WHEN** admin queries standalone cards with series_id parameter
|
||||
- **THEN** system returns only cards associated with that package series
|
||||
- **AND** returns empty list if no matches found
|
||||
|
||||
#### Scenario: Query without series filter
|
||||
|
||||
- **WHEN** admin queries cards without series_id parameter
|
||||
- **THEN** system returns all cards matching other filter criteria
|
||||
- **AND** series association is not considered
|
||||
|
||||
### Requirement: IoT Card Series ID Response Field
|
||||
|
||||
The system SHALL include package series ID in standalone IoT card response data.
|
||||
|
||||
**Response Field**: `series_id` (number | null)
|
||||
|
||||
- Value is package series ID if card is bound to a series
|
||||
- Value is null if card has no series binding
|
||||
|
||||
#### Scenario: Display series association
|
||||
|
||||
- **WHEN** system returns IoT card in list response
|
||||
- **THEN** each card includes series_id field
|
||||
- **AND** field shows current series binding or null
|
||||
|
||||
#### Scenario: Null series binding
|
||||
|
||||
- **WHEN** card has no series binding
|
||||
- **THEN** series_id field is null
|
||||
- **AND** card can still be displayed in results
|
||||
|
||||
## RENAMED Requirements
|
||||
|
||||
### API Field Renaming
|
||||
|
||||
- FROM: `series_allocation_id` (in batch series binding endpoints)
|
||||
- TO: `series_id`
|
||||
|
||||
**Reason**: Field name `series_allocation_id` implied a reference to an allocation record ID, but it actually stores the package series ID directly. Renaming to `series_id` clarifies this relationship and aligns with frontend naming conventions.
|
||||
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Batch Set Card Series Binding
|
||||
|
||||
The system SHALL provide an endpoint to batch set package series binding for IoT cards.
|
||||
|
||||
**Endpoint**: `PATCH /api/admin/iot-cards/series-binding`
|
||||
|
||||
**Request Body**:
|
||||
|
||||
```json
|
||||
{
|
||||
"iccids": ["898600..."],
|
||||
"series_id": 123 // Changed from series_allocation_id
|
||||
}
|
||||
```
|
||||
|
||||
**Field Definitions**:
|
||||
|
||||
- `iccids`: Array of ICCIDs (max 500 items)
|
||||
- `series_id`: Package series ID (tb_package_series.id), 0 means clear association
|
||||
|
||||
**Response**:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"data": {
|
||||
"success_count": 100,
|
||||
"fail_count": 0,
|
||||
"failed_items": null
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Scenario: Successful batch series binding
|
||||
|
||||
- **WHEN** admin calls batch series binding API with valid ICCIDs and series_id
|
||||
- **THEN** system updates series association for all valid cards
|
||||
- **AND** returns success count and failure details
|
||||
|
||||
#### Scenario: Clear series association
|
||||
|
||||
- **WHEN** admin calls batch series binding API with series_id = 0
|
||||
- **THEN** system clears series association for specified cards
|
||||
- **AND** returns success confirmation
|
||||
|
||||
#### Scenario: Partial failure handling
|
||||
|
||||
- **WHEN** some cards in the batch cannot be updated
|
||||
- **THEN** system processes valid cards successfully
|
||||
- **AND** returns failed_items list with reasons for failures
|
||||
@@ -1,37 +0,0 @@
|
||||
# Implementation Tasks
|
||||
|
||||
## 1. 类型定义更新
|
||||
|
||||
### 1.1 批量设置接口参数重命名
|
||||
|
||||
- [x] 1.1.1 更新 `src/types/api/device.ts` 中 BatchSetDeviceSeriesBindingRequest 接口,将 `series_allocation_id` 改为 `series_id`
|
||||
- [x] 1.1.2 更新 `src/types/api/card.ts` 中 BatchSetCardSeriesBindingRequest 接口,将 `series_allocation_id` 改为 `series_id`
|
||||
|
||||
### 1.2 查询参数新增字段
|
||||
|
||||
- [x] 1.2.1 在 `src/types/api/device.ts` 的 DeviceQueryParams 接口中添加 `series_id?: number` 查询参数
|
||||
- [x] 1.2.2 在 `src/types/api/card.ts` 的 StandaloneCardQueryParams 接口中添加 `series_id?: number` 查询参数
|
||||
|
||||
### 1.3 响应类型新增字段
|
||||
|
||||
- [x] 1.3.1 在 `src/types/api/device.ts` 的 Device 接口中添加 `series_id?: number | null` 响应字段(在 updated_at 后面)
|
||||
- [x] 1.3.2 在 `src/types/api/card.ts` 的 StandaloneIotCard 接口中添加 `series_id?: number | null` 响应字段(在 updated_at 后面)
|
||||
|
||||
## 2. API 方法更新
|
||||
|
||||
- [x] 2.1 更新 `src/api/modules/device.ts` 中 batchSetDeviceSeriesBinding 方法参数,将 `series_allocation_id` 改为 `series_id`
|
||||
- [x] 2.2 更新 `src/api/modules/card.ts` 中 batchSetCardSeriesBinding 方法参数,将 `series_allocation_id` 改为 `series_id`
|
||||
|
||||
## 3. 页面组件更新
|
||||
|
||||
- [x] 3.1 更新 `src/views/asset-management/device-list/index.vue` 中调用 batchSetDeviceSeriesBinding 的代码,将参数名从 `series_allocation_id` 改为 `series_id`
|
||||
- [x] 3.2 移除 device-list/index.vue 中第 1191 行的临时注释
|
||||
- [x] 3.3 更新 `src/views/asset-management/iot-card-management/index.vue` 中调用 batchSetCardSeriesBinding 的代码,将参数名从 `series_allocation_id` 改为 `series_id`
|
||||
- [x] 3.4 移除 iot-card-management/index.vue 中第 1326 行的临时注释
|
||||
|
||||
## 4. 验证
|
||||
|
||||
- [x] 4.1 运行 TypeScript 类型检查确认无类型错误
|
||||
- [ ] 4.2 本地测试批量设置 IoT 卡系列绑定功能
|
||||
- [ ] 4.3 本地测试批量设置设备系列绑定功能
|
||||
- [ ] 4.4 确认所有相关功能正常工作
|
||||
Reference in New Issue
Block a user