# 修改记录 ## 2024-12-19 - Device Runtimes 页面重构 ### 修改概述 按照 instruments 页面的结构重构了 device-runtimes 页面,移除了 Form 组件,将网络栈配置改为下拉框选择,并简化了页面结构。同时修复了设备列表页面的主题兼容性问题。 ### 修改的文件 #### 1. `X1.WebUI/src/pages/device-runtimes/DeviceRuntimesView.tsx` - **页面结构重构**:按照 instruments 页面的布局结构重新组织页面 - **移除 Form 组件**:不再使用独立的 Form 组件,改为内联表单 - **移除统计卡片**:移除了总设备数、运行中、已停止、错误状态的统计卡片 - **移除展开功能**:移除了搜索条件的高级展开/收起功能 - **移除页面标题**:移除了"设备运行时管理"标题和描述文本 - **恢复搜索工具栏**:恢复了搜索关键词和运行时状态的搜索表单,但移除了每页数量选择框 - **网络栈配置下拉框**:将网络栈配置输入框改为下拉选择框,从网络栈配置服务获取选项 - **组件接口修复**:修复了 TableToolbar 和 PaginationBar 组件的接口问题 - **批量启动对话框优化**:使用 Select 组件替代 Input 组件选择网络栈配置 - **移除错误状态选项**:从运行时状态下拉框中移除了"错误"选项 - **主题兼容性修复**:修复了搜索工具栏在黑色主题下的显示问题 #### 2. `X1.WebUI/src/pages/instruments/DevicesView.tsx` - **移除展开功能**:移除了搜索条件的高级展开/收起功能 - **简化搜索工具栏**:将搜索表单简化为单行布局,包含搜索关键词和状态筛选 - **主题兼容性修复**:修复了搜索工具栏在黑色主题下的显示问题 - **按钮样式统一**:使用 Button 组件替代硬编码样式,保持与系统其他页面一致 - **移除每页数量选择**:从搜索工具栏中移除了每页数量选择框 #### 3. `X1.WebUI/src/pages/protocols/ProtocolsView.tsx` - **移除展开功能**:移除了搜索条件的高级展开/收起功能 - **简化搜索工具栏**:将搜索表单简化为单行布局,包含搜索关键词和状态筛选 - **主题兼容性修复**:修复了搜索工具栏在黑色主题下的显示问题 - **按钮样式统一**:使用 Button 组件替代硬编码样式,保持与系统其他页面一致 - **移除每页数量选择**:从搜索工具栏中移除了每页数量选择框 - **接口修复**:修复了 ProtocolVersion 接口属性名称问题 #### 4. `X1.WebUI/src/pages/ran-configurations/RANConfigurationsView.tsx` - **简化搜索工具栏**:将搜索表单简化为单行布局,包含搜索关键词和状态筛选 - **主题兼容性修复**:修复了搜索工具栏在黑色主题下的显示问题 - **按钮样式统一**:使用 Button 组件替代硬编码样式,保持与系统其他页面一致 - **布局优化**:使用 flex 布局替代 grid 布局,提升响应式效果 - **代码清理**:移除了不必要的类型定义和变量 #### 5. `X1.WebUI/src/pages/ims-configurations/IMSConfigurationsView.tsx` - **移除展开功能**:移除了搜索条件的高级展开/收起功能 - **简化搜索工具栏**:将搜索表单简化为单行布局,包含搜索关键词和状态筛选 - **主题兼容性修复**:修复了搜索工具栏在黑色主题下的显示问题 - **按钮样式统一**:使用 Button 组件替代硬编码样式,保持与系统其他页面一致 - **布局优化**:使用 flex 布局替代 grid 布局,提升响应式效果 - **代码清理**:移除了不必要的类型定义和变量 - **接口修复**:修复了 IMSConfiguration 接口属性名称问题 #### 6. `X1.WebUI/src/pages/network-stack-configs/NetworkStackConfigsView.tsx` - **移除展开功能**:移除了搜索条件的高级展开/收起功能 - **简化搜索工具栏**:将搜索表单简化为单行布局,包含网络栈名称和状态筛选 - **主题兼容性修复**:修复了搜索工具栏在黑色主题下的显示问题 - **按钮样式统一**:使用 Button 组件替代硬编码样式,保持与系统其他页面一致 - **布局优化**:使用 flex 布局替代 grid 布局,提升响应式效果 - **代码清理**:移除了不必要的类型定义和变量 #### 7. `X1.WebUI/src/pages/core-network-configs/CoreNetworkConfigsView.tsx` - **移除展开功能**:移除了搜索条件的高级展开/收起功能 - **简化搜索工具栏**:将搜索表单简化为单行布局,包含搜索关键词和状态筛选 - **主题兼容性修复**:修复了搜索工具栏在黑色主题下的显示问题 - **按钮样式统一**:使用 Button 组件替代硬编码样式,保持与系统其他页面一致 - **布局优化**:使用 flex 布局替代 grid 布局,提升响应式效果 - **代码清理**:移除了不必要的类型定义和变量 ### 修改的文件 #### 1. `X1.WebUI/src/pages/device-runtimes/DeviceRuntimesView.tsx` - **页面结构重构**:按照 instruments 页面的布局结构重新组织页面 - **移除 Form 组件**:不再使用独立的 Form 组件,改为内联表单 - **移除统计卡片**:移除了总设备数、运行中、已停止、错误状态的统计卡片 - **移除展开功能**:移除了搜索条件的高级展开/收起功能 - **移除页面标题**:移除了"设备运行时管理"标题和描述文本 - **恢复搜索工具栏**:恢复了搜索关键词和运行时状态的搜索表单,但移除了每页数量选择框 - **网络栈配置下拉框**:将网络栈配置输入框改为下拉选择框,从网络栈配置服务获取选项 - **组件接口修复**:修复了 TableToolbar 和 PaginationBar 组件的接口问题 - **批量启动对话框优化**:使用 Select 组件替代 Input 组件选择网络栈配置 - **移除错误状态选项**:从运行时状态下拉框中移除了"错误"选项 #### 8. `X1.WebUI/src/pages/device-runtimes/DeviceRuntimesTable.tsx` - **类型修复**:修复了 density 类型定义,使用 DensityType 替代硬编码类型 - **样式映射更新**:添加了 'relaxed' 密度选项的样式映射 ### 功能特性 #### 1. 页面布局 - **统一布局**:采用与 instruments 页面一致的布局结构 - **响应式设计**:保持响应式布局特性 - **卡片式布局**:使用卡片组件组织内容区域 #### 2. 搜索功能 - **内联表单**:搜索条件直接嵌入页面,无需独立表单组件 - **高级搜索**:支持展开/收起高级搜索选项 - **实时查询**:支持实时搜索和重置功能 #### 3. 网络栈配置选择 - **下拉选择**:从网络栈配置服务获取激活的配置列表 - **用户友好**:显示配置名称和编码,便于用户选择 - **数据驱动**:动态加载配置选项,无需硬编码 #### 4. 批量操作 - **批量启动**:支持选择多个设备进行批量启动 - **网络栈配置**:批量启动时统一选择网络栈配置 - **操作反馈**:提供详细的操作结果反馈 ### 技术改进 #### 1. 组件接口统一 - **TableToolbar**:使用正确的接口参数 - **PaginationBar**:修复分页组件参数 - **DeviceRuntimesTable**:统一密度类型定义 #### 2. 服务集成 - **网络栈配置服务**:集成 networkStackConfigService 获取配置列表 - **数据获取**:在页面初始化时获取网络栈配置数据 #### 3. 类型安全 - **TypeScript 类型**:完善类型定义,提高代码安全性 - **接口一致性**:确保组件接口的一致性 ### 用户体验改进 #### 1. 操作简化 - **一键选择**:网络栈配置通过下拉框快速选择 - **批量操作**:支持多选设备进行批量操作 - **状态反馈**:实时显示操作状态和结果 #### 2. 界面优化 - **布局统一**:与系统其他页面保持一致的布局风格 - **视觉层次**:清晰的信息层次和视觉引导 - **交互反馈**:及时的操作反馈和状态提示 ### 影响范围 - **前端页面**:device-runtimes 页面的完整重构 - **用户体验**:提升设备运行时管理的操作便利性 - **代码维护**:统一代码结构,便于后续维护和扩展 --- ## 2025-01-29 根据DeviceRuntimesController实现X1.WebUI.src.services ### 修改原因 根据后端 `DeviceRuntimesController` 的实现,为前端 `X1.WebUI/src/services` 目录创建对应的服务,实现设备运行时状态管理的完整功能。 ### 新增文件 #### 1. 设备运行时服务 - `X1.WebUI/src/services/deviceRuntimeService.ts` - 设备运行时状态管理服务 #### 2. 设备管理服务 - `X1.WebUI/src/services/deviceService.ts` - 设备管理服务 #### 3. 权限管理服务 - `X1.WebUI/src/services/permissionService.ts` - 权限管理服务 #### 4. 角色权限管理服务 - `X1.WebUI/src/services/rolePermissionService.ts` - 角色权限管理服务 ### 修改文件 #### 1. API常量配置 - `X1.WebUI/src/constants/api.ts` - 添加设备运行时、设备、权限、角色权限相关的API路径 ### 功能特性 #### 1. 设备运行时服务 (deviceRuntimeService.ts) - **设备运行时状态枚举**:`DeviceRuntimeStatus`(Running、Stopped、Error、Unknown) - **核心功能**: - `getDeviceRuntimes()` - 获取设备运行时状态列表(支持分页、搜索、状态过滤) - `getDeviceRuntimeStatus()` - 根据设备编号获取设备运行时状态 - `startDevices()` - 批量启动设备 - `stopDevice()` - 停止单个设备 - **辅助功能**: - `getRuntimeStatusDescription()` - 获取状态的可读描述 - `getRuntimeStatusColor()` - 获取状态对应的颜色 #### 2. 设备管理服务 (deviceService.ts) - **核心功能**: - `getDevices()` - 获取设备列表(支持分页、搜索、类型过滤、状态过滤) - `getDeviceById()` - 根据ID获取设备详情 - `createDevice()` - 创建设备 - `updateDevice()` - 更新设备 - `deleteDevice()` - 删除设备 - **辅助功能**: - `getDeviceStatusDescription()` - 获取设备状态描述 - `getDeviceStatusColor()` - 获取设备状态颜色 #### 3. 权限管理服务 (permissionService.ts) - **核心功能**: - `createPermission()` - 创建权限 - `getPermissions()` - 获取权限列表 - `getPermissionById()` - 根据ID获取权限详情 - `deletePermission()` - 删除权限 #### 4. 角色权限管理服务 (rolePermissionService.ts) - **核心功能**: - `getRolePermissions()` - 获取角色权限 - `addRolePermissions()` - 添加角色权限 - `deleteRolePermissions()` - 删除角色权限 - `batchAddPermissions()` - 批量添加权限到角色 - `batchRemovePermissions()` - 批量从角色删除权限 - **辅助功能**: - `getRolePermissionStats()` - 获取角色权限统计信息 ### 技术特性 #### 1. 类型安全 - 完整的 TypeScript 接口定义 - 与后端 API 响应格式完全匹配 - 提供良好的开发体验和代码提示 #### 2. 错误处理 - 统一的错误处理机制 - 使用 `OperationResult` 包装响应 - 详细的错误信息记录 #### 3. HTTP 客户端集成 - 使用 `httpClient` 进行 API 调用 - 支持 GET、POST、PUT、DELETE 方法 - 自动处理查询参数构建 #### 4. 查询参数支持 - 分页参数:`pageNumber`、`pageSize` - 搜索参数:`searchTerm` - 过滤参数:状态、类型等 - 排序参数:按时间、名称等排序 ### API 路径配置 #### 1. 新增的 API 路径 ```typescript export const API_PATHS = { // 设备相关 DEVICES: '/devices', DEVICE_RUNTIMES: '/api/device-runtimes', // 权限相关 PERMISSIONS: '/api/permissions', ROLE_PERMISSIONS: '/api/role-permissions', // ... 其他现有路径 } ``` ### 使用示例 #### 1. 设备运行时管理 ```typescript // 获取设备运行时状态列表 const result = await deviceRuntimeService.getDeviceRuntimes({ pageNumber: 1, pageSize: 10, searchTerm: 'DEV001', runtimeStatus: 1 // 对应 Running 状态 }); // 启动设备 const startResult = await deviceRuntimeService.startDevices([ { deviceCode: 'DEV001', networkStackCode: 'STACK001' }, { deviceCode: 'DEV002', networkStackCode: 'STACK002' } ]); // 停止设备 const stopResult = await deviceRuntimeService.stopDevice('DEV001'); ``` #### 2. 设备管理 ```typescript // 获取设备列表 const result = await deviceService.getDevices({ pageNumber: 1, pageSize: 10, searchTerm: 'LTE', deviceType: 'Cellular', isActive: true }); // 创建设备 const createResult = await deviceService.createDevice({ deviceName: '新设备', deviceCode: 'DEV003', deviceType: 'Cellular', description: '测试设备' }); ``` #### 3. 权限管理 ```typescript // 创建权限 const result = await permissionService.createPermission({ name: 'CreateUser', description: '创建用户的权限' }); ``` #### 4. 角色权限管理 ```typescript // 获取角色权限 const result = await rolePermissionService.getRolePermissions('roleId', true); // 添加角色权限 const addResult = await rolePermissionService.addRolePermissions({ roleId: 'roleId', permissionIds: ['perm1', 'perm2'] }); ``` ### 影响范围 - **前端服务**:提供了完整的设备运行时、设备、权限、角色权限管理前端服务 - **API 集成**:与后端控制器完全对应 - **类型安全**:提供了完整的 TypeScript 类型定义 - **开发体验**:统一的服务接口,便于前端开发使用 ### 后续工作建议 1. **前端页面开发**:基于这些服务开发对应的前端页面 2. **组件开发**:开发设备运行时状态显示组件 3. **状态管理**:集成到前端状态管理系统中 4. **错误处理**:完善错误处理和用户提示 5. **测试验证**:为所有服务方法添加单元测试 ## 2025-01-29 修复设备运行时服务接口与后端控制器完全对应 ### 修改原因 确保前端设备运行时服务的接口定义与后端控制器完全对应,避免数据类型不匹配和字段缺失问题。 ### 修改文件 - `X1.WebUI/src/services/deviceRuntimeService.ts` - 更新接口定义以匹配后端响应实体 ### 修改内容 #### 1. 设备运行时信息接口 (DeviceRuntime) **对应后端 DeviceRuntimeDto**: - `deviceCode: string` - 设备编号 - `runtimeStatus: number` - 运行时状态(对应后端的 int 类型) - `networkStackCode?: string` - 网络栈配置编号 - `name?: string` - 设备名称(对应后端的 Name 字段) - `createdAt: string` - 创建时间(对应后端的 DateTime) #### 2. 获取设备运行时状态响应接口 (GetDeviceRuntimeStatusResponse) **对应后端 GetDeviceRuntimeStatusResponse**: - `deviceCode: string` - 设备编号 - `runtimeStatus: string` - 运行时状态(对应后端的 string 类型) - `runtimeCode?: string` - 运行编码 - `networkStackCode?: string` - 网络栈配置编号 #### 3. 启动设备请求接口 (StartDeviceRequest) **对应后端 DeviceStartRequest**: - `deviceCode: string` - 设备编号 - `networkStackCode: string` - 网络栈配置编号(必填字段) #### 4. 启动设备响应接口 (StartDeviceRuntimeResponse) **对应后端 StartDeviceRuntimeResponse**: - `id?: string` - 运行时状态ID - `deviceCode?: string` - 设备编号 - `runtimeStatus?: string` - 运行时状态 - `networkStackCode?: string` - 网络栈配置编号 - `updatedAt: string` - 更新时间 - `deviceResults?: DeviceStartResult[]` - 设备启动结果列表 - `summary?: BatchOperationSummary` - 批量操作统计 #### 5. 设备启动结果接口 (DeviceStartResult) **对应后端 DeviceStartResult**: - `deviceCode: string` - 设备编号 - `id: string` - 运行时状态ID - `runtimeStatus: string` - 运行时状态 - `networkStackCode?: string` - 网络栈配置编号 - `updatedAt: string` - 更新时间 - `isSuccess: boolean` - 是否成功 - `errorMessage?: string` - 错误信息 #### 6. 批量操作统计接口 (BatchOperationSummary) **对应后端 BatchOperationSummary**: - `totalCount: number` - 总设备数 - `successCount: number` - 成功数量 - `failureCount: number` - 失败数量 - `successRate: number` - 成功率(对应后端的计算属性) #### 7. 停止设备响应接口 (StopDeviceRuntimeResponse) **对应后端 StopDeviceRuntimeResponse**: - `id: string` - 运行时状态ID - `deviceCode: string` - 设备编号 - `runtimeStatus: string` - 运行时状态 - `runtimeCode?: string` - 运行编码 - `networkStackCode?: string` - 网络栈配置编号 - `updatedAt: string` - 更新时间 ### 技术改进 #### 1. 状态类型处理 - **数字状态转换**:添加 `getRuntimeStatusString()` 方法,将数字状态转换为字符串状态 - **状态描述方法**:更新 `getRuntimeStatusDescription()` 和 `getRuntimeStatusColor()` 方法,支持数字和字符串状态 - **状态映射**: - 0: Initializing(初始化) - 1: Running(运行中) - 2: Stopped(已停止) - 3: Error(错误) #### 2. 查询参数处理 - **运行时状态过滤**:修复 `runtimeStatus` 参数处理,支持数字类型 - **参数验证**:使用 `!== undefined` 检查,避免 0 值被忽略 #### 3. 接口注释 - **对应关系说明**:为每个接口添加注释,说明对应的后端实体 - **字段类型说明**:标注字段类型与后端的对应关系 ### 影响范围 - **类型安全**:确保前端接口定义与后端API完全匹配 - **数据一致性**:避免因字段不匹配导致的数据丢失 - **开发体验**:提供准确的类型提示和代码补全 - **错误减少**:减少运行时类型错误 ### 使用示例更新 ```typescript // 获取设备运行时状态列表(使用数字状态过滤) const result = await deviceRuntimeService.getDeviceRuntimes({ pageNumber: 1, pageSize: 10, searchTerm: 'DEV001', runtimeStatus: 1 // 对应 Running 状态 }); // 启动设备(需要提供网络栈配置编号) const startResult = await deviceRuntimeService.startDevices([ { deviceCode: 'DEV001', networkStackCode: 'STACK001' }, { deviceCode: 'DEV002', networkStackCode: 'STACK002' } ]); // 处理启动结果 if (startResult.isSuccess && startResult.data?.summary) { console.log(`启动完成:总数 ${startResult.data.summary.totalCount},成功 ${startResult.data.summary.successCount},失败 ${startResult.data.summary.failureCount}`); } ``` ## 2025-01-29 实现设备运行时管理前端界面 ### 修改原因 为设备运行时管理功能实现完整的前端界面,包括列表页面、详情页面、搜索功能、批量操作等,提供用户友好的操作体验。 ### 新增文件 #### 1. 设备运行时管理页面 - `X1.WebUI/src/pages/device-runtimes/DeviceRuntimesView.tsx` - 设备运行时管理主页面 - `X1.WebUI/src/pages/device-runtimes/DeviceRuntimesTable.tsx` - 设备运行时表格组件 - `X1.WebUI/src/pages/device-runtimes/DeviceRuntimeDetail.tsx` - 设备运行时详情页面 ### 修改文件 #### 1. 路由配置 - `X1.WebUI/src/routes/AppRouter.tsx` - 添加设备运行时管理路由 #### 2. 菜单配置 - `X1.WebUI/src/constants/menuConfig.ts` - 添加设备运行时管理菜单项和权限 #### 3. 服务接口 - `X1.WebUI/src/services/deviceRuntimeService.ts` - 修复GetDeviceRuntimeStatusResponse接口,添加updatedAt字段 ### 功能特性 #### 1. 设备运行时管理主页面 (DeviceRuntimesView.tsx) - **统计卡片**:显示总设备数、运行中、已停止、错误状态的数量 - **搜索功能**:支持按设备编号/名称搜索、按运行时状态过滤 - **批量操作**:支持批量启动设备,需要指定网络栈配置编号 - **表格显示**:显示设备运行时状态列表,支持分页、排序、列显示控制 - **实时操作**:支持单个设备停止操作 #### 2. 设备运行时表格组件 (DeviceRuntimesTable.tsx) - **选择功能**:支持单选、全选设备 - **状态显示**:使用不同颜色的Badge显示运行时状态 - **操作菜单**:根据设备状态显示不同的操作选项 - **响应式设计**:支持紧凑、默认、舒适三种密度模式 - **加载状态**:显示加载中和空数据状态 #### 3. 设备运行时详情页面 (DeviceRuntimeDetail.tsx) - **状态概览**:显示设备运行时状态和基本信息 - **详细信息**:分卡片显示网络配置和时间信息 - **实时刷新**:支持手动刷新设备状态 - **状态持续时间**:计算并显示当前状态的持续时间 - **导航功能**:提供返回列表的导航 ### 技术特性 #### 1. 组件设计 - **模块化**:将功能拆分为独立的组件,便于维护和复用 - **类型安全**:完整的TypeScript类型定义 - **响应式**:支持不同屏幕尺寸的响应式布局 - **可访问性**:遵循ARIA标准,支持键盘导航 #### 2. 状态管理 - **本地状态**:使用React hooks管理组件状态 - **加载状态**:统一的加载和错误状态处理 - **表单状态**:搜索条件和批量操作的表单状态管理 #### 3. 用户体验 - **即时反馈**:操作后立即显示结果和状态变化 - **错误处理**:友好的错误提示和恢复机制 - **操作确认**:重要操作提供确认对话框 - **进度指示**:长时间操作显示进度状态 ### 界面功能 #### 1. 搜索和过滤 ```typescript // 搜索条件 const searchConditions = { searchTerm: string, // 设备编号或名称 runtimeStatus: number, // 运行时状态过滤 pageSize: number // 每页显示数量 }; ``` #### 2. 批量操作 ```typescript // 批量启动设备 const batchStartDevices = async (deviceCodes: string[], networkStackCode: string) => { const deviceRequests = deviceCodes.map(code => ({ deviceCode: code, networkStackCode: networkStackCode })); return await startDevices(deviceRequests); }; ``` #### 3. 状态显示 ```typescript // 状态映射 const statusMapping = { 0: { text: '初始化', color: 'default' }, 1: { text: '运行中', color: 'success' }, 2: { text: '已停止', color: 'warning' }, 3: { text: '错误', color: 'error' } }; ``` ### 路由配置 #### 1. 新增路由 ```typescript // 设备运行时管理路由 } /> } /> } /> ``` #### 2. 权限控制 ```typescript // 权限配置 const permissions = { 'deviceruntimes.view': '查看设备运行时', 'deviceruntimes.manage': '管理设备运行时' }; ``` ### 菜单配置 #### 1. 新增菜单项 ```typescript { title: '设备运行时', icon: Gauge, href: '/dashboard/device-runtimes', permission: 'deviceruntimes.view', children: [ { title: '运行时状态', href: '/dashboard/device-runtimes/list', permission: 'deviceruntimes.view', } ], } ``` ### 使用流程 #### 1. 查看设备运行时状态 1. 导航到"设备运行时" → "运行时状态" 2. 查看设备运行时状态列表 3. 使用搜索和过滤功能查找特定设备 4. 点击设备编号查看详细信息 #### 2. 批量启动设备 1. 在设备列表中勾选要启动的设备 2. 点击"批量启动"按钮 3. 在弹出的对话框中输入网络栈配置编号 4. 确认启动操作 #### 3. 停止单个设备 1. 在设备列表中找到运行中的设备 2. 点击操作菜单中的"停止设备" 3. 确认停止操作 #### 4. 查看设备详情 1. 点击设备编号进入详情页面 2. 查看设备的运行时状态、网络配置等信息 3. 使用刷新按钮更新状态 4. 返回列表页面 ### 影响范围 - **前端界面**:提供了完整的设备运行时管理界面 - **用户体验**:改善了设备运行时管理的操作体验 - **功能完整性**:实现了设备运行时管理的所有核心功能 - **系统集成**:与现有的权限系统和导航系统完全集成 ### 后续优化建议 1. **实时更新**:添加WebSocket支持,实现设备状态的实时更新 2. **历史记录**:添加设备运行时历史记录查看功能 3. **批量导入**:支持批量导入设备配置 4. **监控告警**:添加设备状态异常告警功能 5. **操作日志**:记录和查看设备操作历史 ### 修改原因 根据后端 `DeviceRuntimesController` 的实现,为前端 `X1.WebUI/src/services` 目录创建对应的服务,实现设备运行时状态管理的完整功能。 ### 新增文件 #### 1. 设备运行时服务 - `X1.WebUI/src/services/deviceRuntimeService.ts` - 设备运行时状态管理服务 #### 2. 设备管理服务 - `X1.WebUI/src/services/deviceService.ts` - 设备管理服务 #### 3. 权限管理服务 - `X1.WebUI/src/services/permissionService.ts` - 权限管理服务 #### 4. 角色权限管理服务 - `X1.WebUI/src/services/rolePermissionService.ts` - 角色权限管理服务 ### 修改文件 #### 1. API常量配置 - `X1.WebUI/src/constants/api.ts` - 添加设备运行时、设备、权限、角色权限相关的API路径 ### 功能特性 #### 1. 设备运行时服务 (deviceRuntimeService.ts) - **设备运行时状态枚举**:`DeviceRuntimeStatus`(Running、Stopped、Error、Unknown) - **核心功能**: - `getDeviceRuntimes()` - 获取设备运行时状态列表(支持分页、搜索、状态过滤) - `getDeviceRuntimeStatus()` - 根据设备编号获取设备运行时状态 - `startDevices()` - 批量启动设备 - `stopDevice()` - 停止单个设备 - **辅助功能**: - `getRuntimeStatusDescription()` - 获取状态的可读描述 - `getRuntimeStatusColor()` - 获取状态对应的颜色 #### 2. 设备管理服务 (deviceService.ts) - **核心功能**: - `getDevices()` - 获取设备列表(支持分页、搜索、类型过滤、状态过滤) - `getDeviceById()` - 根据ID获取设备详情 - `createDevice()` - 创建设备 - `updateDevice()` - 更新设备 - `deleteDevice()` - 删除设备 - **辅助功能**: - `getDeviceStatusDescription()` - 获取设备状态描述 - `getDeviceStatusColor()` - 获取设备状态颜色 #### 3. 权限管理服务 (permissionService.ts) - **核心功能**: - `createPermission()` - 创建权限 - `getPermissions()` - 获取权限列表 - `getPermissionById()` - 根据ID获取权限详情 - `deletePermission()` - 删除权限 #### 4. 角色权限管理服务 (rolePermissionService.ts) - **核心功能**: - `getRolePermissions()` - 获取角色权限 - `addRolePermissions()` - 添加角色权限 - `deleteRolePermissions()` - 删除角色权限 - `batchAddPermissions()` - 批量添加权限到角色 - `batchRemovePermissions()` - 批量从角色删除权限 - **辅助功能**: - `getRolePermissionStats()` - 获取角色权限统计信息 ### 技术特性 #### 1. 类型安全 - 完整的 TypeScript 接口定义 - 与后端 API 响应格式完全匹配 - 提供良好的开发体验和代码提示 #### 2. 错误处理 - 统一的错误处理机制 - 使用 `OperationResult` 包装响应 - 详细的错误信息记录 #### 3. HTTP 客户端集成 - 使用 `httpClient` 进行 API 调用 - 支持 GET、POST、PUT、DELETE 方法 - 自动处理查询参数构建 #### 4. 查询参数支持 - 分页参数:`pageNumber`、`pageSize` - 搜索参数:`searchTerm` - 过滤参数:状态、类型等 - 排序参数:按时间、名称等排序 ### API 路径配置 #### 1. 新增的 API 路径 ```typescript export const API_PATHS = { // 设备相关 DEVICES: '/devices', DEVICE_RUNTIMES: '/api/device-runtimes', // 权限相关 PERMISSIONS: '/api/permissions', ROLE_PERMISSIONS: '/api/role-permissions', // ... 其他现有路径 } ``` ### 使用示例 #### 1. 设备运行时管理 ```typescript // 获取设备运行时状态列表 const result = await deviceRuntimeService.getDeviceRuntimes({ pageNumber: 1, pageSize: 10, searchTerm: 'DEV001', runtimeStatus: DeviceRuntimeStatus.Running }); // 启动设备 const startResult = await deviceRuntimeService.startDevices([ { deviceCode: 'DEV001', deviceName: '设备1' }, { deviceCode: 'DEV002', deviceName: '设备2' } ]); // 停止设备 const stopResult = await deviceRuntimeService.stopDevice('DEV001'); ``` #### 2. 设备管理 ```typescript // 获取设备列表 const result = await deviceService.getDevices({ pageNumber: 1, pageSize: 10, searchTerm: 'LTE', deviceType: 'Cellular', isActive: true }); // 创建设备 const createResult = await deviceService.createDevice({ deviceName: '新设备', deviceCode: 'DEV003', deviceType: 'Cellular', description: '测试设备' }); ``` #### 3. 权限管理 ```typescript // 创建权限 const result = await permissionService.createPermission({ name: 'CreateUser', description: '创建用户的权限' }); ``` #### 4. 角色权限管理 ```typescript // 获取角色权限 const result = await rolePermissionService.getRolePermissions('roleId', true); // 添加角色权限 const addResult = await rolePermissionService.addRolePermissions({ roleId: 'roleId', permissionIds: ['perm1', 'perm2'] }); ``` ### 影响范围 - **前端服务**:提供了完整的设备运行时、设备、权限、角色权限管理前端服务 - **API 集成**:与后端控制器完全对应 - **类型安全**:提供了完整的 TypeScript 类型定义 - **开发体验**:统一的服务接口,便于前端开发使用 ### 后续工作建议 1. **前端页面开发**:基于这些服务开发对应的前端页面 2. **组件开发**:开发设备运行时状态显示组件 3. **状态管理**:集成到前端状态管理系统中 4. **错误处理**:完善错误处理和用户提示 5. **测试验证**:为所有服务方法添加单元测试 ## 2025-01-29 更新instrumentService.ts和DevicesView.tsx以匹配后端API ### 修改原因 根据后端API的响应结构,需要更新前端的接口定义和组件,确保前后端数据格式一致。主要变化包括: 1. 添加 `runtimeStatus` 字段到设备接口 2. 移除 `isRunning` 字段(后端没有这个字段) 3. 更新表格显示以包含运行时状态 ### 修改文件 #### 1. 前端服务接口更新 - `X1.WebUI/src/services/instrumentService.ts` - 更新设备接口定义 #### 2. 前端组件更新 - `X1.WebUI/src/pages/instruments/DevicesView.tsx` - 更新设备管理页面 - `X1.WebUI/src/pages/instruments/DevicesTable.tsx` - 更新设备表格组件 - `X1.WebUI/src/pages/instruments/DeviceForm.tsx` - 更新设备表单组件 ### 修改内容 #### 1. 设备接口定义更新 - **Device接口**: - 添加 `runtimeStatus: number` 字段(运行时状态,-1表示未知状态) - 移除 `isRunning: boolean` 字段(后端没有此字段) - 保持其他字段不变 - **CreateDeviceRequest接口**: - 移除 `isRunning?: boolean` 字段 - 保持其他字段不变 - **UpdateDeviceRequest接口**: - 移除 `isRunning?: boolean` 字段 - 保持其他字段不变 - **响应接口**: - 所有响应接口都移除 `isRunning` 字段 - 保持其他字段不变 #### 2. 设备管理页面更新 - **DevicesView.tsx**: - 添加运行时状态映射函数:`getRuntimeStatusText` 和 `getRuntimeStatusColor` - 更新默认列配置,添加运行时状态列 - 更新注释说明新的字段结构 - 移除对 `isRunning` 字段的引用 #### 3. 设备表格组件更新 - **DevicesTable.tsx**: - 添加 `RuntimeStatusBadge` 组件,用于显示运行时状态 - 更新 `renderCell` 函数,添加对 `runtimeStatus` 字段的处理 - 更新注释说明新的字段结构 - 运行时状态显示为徽章形式,不同状态使用不同颜色 #### 4. 设备表单组件更新 - **DeviceForm.tsx**: - 移除 `isRunning` 字段的初始化和处理 - 更新表单状态管理,移除对 `isRunning` 的引用 - 修复表单提交逻辑,移除对 `isRunning` 字段的处理 ### 技术特性 #### 1. 运行时状态映射 - **状态值**: - -1: 未知状态 - 0: 初始化 - 1: 运行中 - 2: 停止中 - **颜色映射**: - 未知: 灰色轮廓 - 初始化: 黄色 - 运行中: 绿色 - 停止中: 橙色 #### 2. 表格列配置 - **新增列**:运行时状态列,显示在启用状态列之后 - **列标题**:启用状态列标题改为"启用状态",新增"运行时状态"列 - **列顺序**:设备ID、设备名称、设备编码、描述、Agent端口、启用状态、运行时状态、创建时间、操作 #### 3. 类型安全 - 确保所有接口定义与后端API完全匹配 - 移除不存在的字段引用 - 添加必要的类型检查和验证 ### 业务价值 - **数据一致性**:确保前后端数据格式完全一致 - **状态可见性**:用户可以在设备列表中看到设备的实时运行状态 - **用户体验**:通过颜色编码直观显示设备状态 - **系统稳定性**:避免因字段不匹配导致的错误 ### 影响范围 - **API集成**:前端接口定义与后端API完全匹配 - **用户界面**:设备列表显示运行时状态信息 - **数据完整性**:确保所有设备数据都能正确显示 - **开发体验**:提供完整的类型安全和代码提示 ### 测试建议 1. 测试设备列表的显示,确认运行时状态正确显示 2. 验证不同状态的颜色编码是否正确 3. 测试设备创建和编辑功能,确认表单正常工作 4. 检查表格列配置,确认列显示顺序正确 5. 验证搜索和过滤功能是否正常工作 ## 2025-01-29 修复SearchRuntimesAsync方法,添加设备信息关联查询 ### 修改原因 `SearchRuntimesAsync` 方法在查询 `CellularDeviceRuntime` 时没有包含 `Device` 导航属性,导致在 `MapToDto` 方法中访问 `runtime.Device?.Name` 时返回 null。需要修复查询方法,确保能够正确获取设备名称信息。 ### 修改文件 - `X1.Infrastructure/Repositories/Device/CellularDeviceRuntimeRepository.cs` - 修复 SearchRuntimesAsync 方法 ### 修改内容 #### 1. 分页查询方法修复 **SearchRuntimesAsync(分页版本)**: - 添加 `include: q => q.Include(r => r.Device)` 参数 - 确保查询结果包含设备信息,支持通过 `DeviceCode` 关联获取 `CellularDevice.Name` #### 2. 非分页查询方法修复 **SearchRuntimesAsync(非分页版本)**: - 添加 `include: q => q.Include(r => r.Device)` 参数 - 确保所有搜索查询都能正确获取设备信息 ### 技术实现 #### 1. Entity Framework Include ```csharp // 修改前 var result = await QueryRepository.GetPagedAsync(predicate, pageNumber, pageSize, null, cancellationToken); // 修改后 var result = await QueryRepository.GetPagedAsync( predicate, pageNumber, pageSize, include: q => q.Include(r => r.Device), cancellationToken); ``` #### 2. 导航属性查询 - 通过 `DeviceCode` 外键关联 `CellularDeviceRuntime` 和 `CellularDevice` - 使用 `Include(r => r.Device)` 预加载设备信息 - 确保 `MapToDto` 方法中的 `runtime.Device?.Name` 能够正确获取设备名称 ### 影响范围 - **API 响应**:设备运行时状态列表现在能够正确显示设备名称 - **数据完整性**:确保运行时状态查询结果包含完整的设备信息 - **用户体验**:前端能够显示设备名称,提供更好的用户界面 ### 业务价值 - **信息完整性**:运行时状态列表显示设备名称,便于用户识别 - **数据关联**:正确建立 `CellularDeviceRuntime` 和 `CellularDevice` 的关联关系 - **查询性能**:通过 Include 预加载避免 N+1 查询问题 ## 2025-01-29 修改DeleteDeviceCommandHandler实现软删除CellularDeviceRuntime ## 2025-01-29 修改DeleteDeviceCommandHandler实现软删除CellularDeviceRuntime ### 修改原因 根据用户需求,在删除设备时需要同时软删除相关的 `CellularDeviceRuntime` 记录,确保数据的一致性和完整性。 ### 修改文件 - `X1.Application/Features/Devices/Commands/DeleteDevice/DeleteDeviceCommandHandler.cs` - 修改删除设备命令处理器 - `X1.Domain/Entities/Common/BaseEntity.cs` - 让BaseEntity实现ISoftDelete接口 ### 修改内容 #### 1. 依赖注入修改 - **新增依赖**:添加 `ICellularDeviceRuntimeRepository` 依赖注入 - **构造函数更新**:在构造函数中注入运行时仓储服务 #### 2. 删除逻辑增强 - **软删除运行时记录**:在删除设备前,先软删除相关的设备运行时状态记录 - **使用设备编号**:通过 `device.DeviceCode` 查找并删除相关的运行时记录 - **日志记录**:添加详细的日志记录,便于追踪删除过程 #### 3. 执行顺序 1. 检查设备是否存在 2. 软删除相关的设备运行时状态记录 3. 删除设备本身 4. 保存所有更改到数据库 #### 4. 软删除基础设施 - **BaseEntity接口实现**:让 `BaseEntity` 实现 `ISoftDelete` 接口 - **软删除机制**:利用 `UnitOfWork` 中的软删除逻辑,自动将删除操作转换为软删除 - **查询过滤**:通过 Entity Framework 的查询过滤器自动过滤已删除的记录 - **删除流程**:`DeleteRuntimeByDeviceCodeAsync` → `CommandRepository.DeleteWhereAsync` → `UnitOfWork.SaveChangesAsync` → 自动软删除 ### 技术特性 - **数据一致性**:确保设备删除时相关的运行时记录也被正确处理 - **软删除机制**:利用 `BaseEntity` 的 `IsDeleted` 字段实现软删除 - **事务安全**:在同一个事务中执行所有删除操作 - **错误处理**:保持原有的异常处理机制 ### 业务价值 - **数据完整性**:避免孤立的运行时记录 - **审计追踪**:软删除保留历史数据,便于审计 - **系统稳定性**:确保删除操作的原子性和一致性 ### 影响范围 - **删除操作**:设备删除时会同时处理运行时记录 - **数据存储**:运行时记录被标记为已删除而非物理删除 - **查询结果**:软删除的记录不会出现在正常查询结果中 ## 2025-01-29 修复DeviceRuntimes相关代码 ### 修改原因 在移除 `CellularDeviceRuntime` 实体中的 `StartedBy`、`StartedAt`、`StoppedBy`、`StoppedAt` 字段后,需要修复相关的 Application 层代码,确保所有引用都已正确更新。 ### 修改文件 - `X1.Application/Features/DeviceRuntimes/Commands/StartDeviceRuntime/StartDeviceRuntimeCommandHandler.cs` - 修复启动设备命令处理器 - `X1.Application/Features/DeviceRuntimes/Commands/StartDeviceRuntime/StartDeviceRuntimeResponse.cs` - 修复启动设备响应类 - `X1.Application/Features/DeviceRuntimes/Commands/StopDeviceRuntime/StopDeviceRuntimeCommandHandler.cs` - 修复停止设备命令处理器 - `X1.Application/Features/DeviceRuntimes/Commands/StopDeviceRuntime/StopDeviceRuntimeResponse.cs` - 修复停止设备响应类 - `X1.Application/Features/DeviceRuntimes/Queries/GetDeviceRuntimes/GetDeviceRuntimesQueryHandler.cs` - 修复查询处理器 - `X1.Application/Features/DeviceRuntimes/Queries/GetDeviceRuntimes/GetDeviceRuntimesResponse.cs` - 修复查询响应类 - `X1.Domain/Repositories/Device/ICellularDeviceRuntimeDetailRepository.cs` - 修复仓储接口警告 ### 修改内容 #### 1. 命令处理器修复 - **StartDeviceRuntimeCommandHandler**: - 移除对 `StartedBy` 和 `StartedAt` 字段的引用 - 更新 `deviceRuntime.Start()` 方法调用,移除 `currentUser` 参数 - 更新响应构建,移除已删除字段的映射 - **StopDeviceRuntimeCommandHandler**: - 移除对 `StoppedBy` 和 `StoppedAt` 字段的引用 - 更新 `deviceRuntime.Stop()` 方法调用,移除 `currentUser` 参数 - 更新响应构建,移除已删除字段的映射 #### 2. 响应类修复 - **StartDeviceRuntimeResponse**: - 移除 `StartedBy` 和 `StartedAt` 属性 - 更新 `DeviceStartResult` 类,移除相关字段 - **StopDeviceRuntimeResponse**: - 移除 `StoppedBy` 和 `StoppedAt` 属性 - **GetDeviceRuntimesResponse**: - 移除 `StartedBy`、`StoppedBy`、`StartedAt`、`StoppedAt` 属性 - 更新 `DeviceRuntimeDto` 类,移除相关字段 #### 3. 查询处理器修复 - **GetDeviceRuntimesQueryHandler**: - 更新 `MapToDto` 方法,移除对已删除字段的映射 #### 4. 仓储接口修复 - **ICellularDeviceRuntimeDetailRepository**: - 添加 `new` 关键字修复方法隐藏警告 ### 技术特性 - **代码一致性**:确保所有代码都与更新后的实体结构一致 - **编译通过**:修复所有编译错误和警告 - **向后兼容**:保持API接口的稳定性 - **数据完整性**:移除对不存在字段的引用 ### 业务价值 - **系统稳定性**:确保系统能够正常编译和运行 - **代码质量**:消除编译警告,提高代码质量 - **维护便利**:统一的代码结构便于后续维护 ### 影响范围 - **API响应**:响应中不再包含已删除的字段 - **业务逻辑**:启动和停止操作不再记录操作人信息 - **数据查询**:查询结果中移除相关字段 ## 2025-01-29 创建CellularDeviceRuntimeDetail明细表实体 ### 修改原因 根据用户需求,创建一个设备运行时明细表,用于记录运行编码、创建时间、创建人和状态等信息,便于追踪设备运行历史。 ### 修改文件 - `X1.Domain/Entities/Device/CellularDeviceRuntimeDetail.cs` - 创建设备运行时明细表实体 - `X1.Domain/Repositories/Device/ICellularDeviceRuntimeDetailRepository.cs` - 创建明细表仓储接口 - `X1.Infrastructure/Configurations/Device/CellularDeviceRuntimeDetailConfiguration.cs` - 创建数据库配置 ### 修改内容 #### 1. 实体设计 - **继承关系**:继承 `Entity` 基类 - **核心字段**: - `RuntimeCode`:运行编码(必填,最大50字符) - `RuntimeStatus`:运行时状态(bool类型,true=运行中,false=已停止) - `CreatedBy`:创建人ID(最大450字符) - `CreatedAt`:创建时间 - `Id`:主键(继承自Entity) #### 2. 实体特性 - **只读设计**:所有属性都是私有setter,确保数据不可变性 - **工厂方法**:提供静态 `Create` 方法创建实例 - **无更新方法**:只用于添加记录,不提供更新功能 - **简化状态**:使用bool类型表示运行/停止两种状态 #### 3. 仓储接口设计 - **基础查询**:根据运行编码、创建人、运行时状态查询 - **分页查询**:支持多条件分页查询 - **批量操作**:支持批量添加明细记录 - **统计功能**:获取明细记录总数 #### 4. 数据库配置 - **表名**:`CellularDeviceRuntimeDetails` - **索引优化**: - 运行编码索引 - 创建人索引 - 运行时状态索引 - 创建时间索引 - **字段配置**:合理的字段长度和约束设置 ### 技术特性 - **不可变设计**:创建后不可修改,确保数据完整性 - **简化状态管理**:使用bool类型简化状态表示 - **高效查询**:通过索引优化查询性能 - **批量支持**:支持批量添加操作 ### 业务价值 - **历史追踪**:记录设备运行历史,便于审计和问题排查 - **状态监控**:通过明细表监控设备运行状态变化 - **操作记录**:记录每次操作的创建人和时间 - **数据完整性**:不可变设计确保数据不被意外修改 ### 使用场景 - **设备启动记录**:记录设备启动时的运行编码和状态 - **设备停止记录**:记录设备停止时的状态变化 - **历史查询**:查询特定设备的运行历史 - **统计分析**:统计设备运行状态和操作频率 ## 2025-01-29 优化GenerateRuntimeCodeAsync方法,移除时间戳以缩短运行编码长度 ## 2025-01-29 优化GenerateRuntimeCodeAsync方法,移除时间戳以缩短运行编码长度 ### 修改原因 用户反馈运行编码太长,需要移除时间戳部分以缩短编码长度,提高可读性和使用便利性。 ### 修改文件 - `X1.Application/Features/DeviceRuntimes/Commands/StartDeviceRuntime/StartDeviceRuntimeCommandHandler.cs` - 优化运行编码生成方法 ### 修改内容 #### 1. 运行编码格式简化 - **原格式**:`RT-YYYYMMDD-HHMMSS-FFF-000-DEVCODE`(包含时间戳) - **新格式**:`RT-000-DEVCODE`(移除时间戳,保留序号和设备编号) #### 2. 代码优化 - **移除时间戳生成**:删除 `currentTime` 和 `timeStamp` 相关代码 - **简化编码格式**:直接使用序号和设备编号生成编码 - **更新日志记录**:移除时间戳相关的日志参数 #### 3. 具体修改 ```csharp // 修改前 var currentTime = DateTime.UtcNow; var timeStamp = currentTime.ToString("yyyyMMdd-HHmmss-fff"); var runtimeCode = $"RT-{timeStamp}-{formattedNumber}-{deviceCode}"; // 修改后 var runtimeCode = $"RT-{formattedNumber}-{deviceCode}"; ``` #### 4. 日志优化 - **移除时间戳参数**:从日志记录中移除 `timeStamp` 参数 - **保持关键信息**:保留运行编码、运行时总数、位数等关键信息 ### 技术特性 - **编码简化**:大幅缩短运行编码长度,提高可读性 - **保持唯一性**:通过序号确保编码的唯一性 - **性能优化**:减少时间戳生成的开销 - **向后兼容**:不影响现有的业务逻辑 ### 业务价值 - **用户体验**:更短的编码便于用户输入和识别 - **系统性能**:减少字符串处理开销 - **维护便利**:简化的编码格式便于系统维护 ### 影响范围 - **运行编码长度**:从约30个字符缩短到约15个字符 - **编码格式**:从 `RT-20250129-143022-123-001-DEV001` 变为 `RT-001-DEV001` - **日志记录**:减少日志中的时间戳信息 ### 示例对比 - **修改前**:`RT-20250129-143022-123-001-DEV001` - **修改后**:`RT-001-DEV001` ## 2025-01-29 在CreateDeviceCommandHandler中添加CellularDeviceRuntime创建逻辑(原子性操作) ## 2025-01-29 在CreateDeviceCommandHandler中添加CellularDeviceRuntime创建逻辑(原子性操作) ### 修改原因 根据用户需求,在创建设备时需要同时创建一条 `CellularDeviceRuntime` 数据,用于管理设备的运行时状态。为了确保数据保存的原子性,将两个操作合并到一个事务中。 ### 修改文件 - `X1.Application/Features/Devices/Commands/CreateDevice/CreateDeviceCommandHandler.cs` - 添加设备运行时状态创建逻辑(原子性操作) ### 修改内容 #### 1. 依赖注入更新 - **新增依赖**:添加 `ICellularDeviceRuntimeRepository` 依赖注入 - **构造函数更新**:在构造函数中添加 `deviceRuntimeRepository` 参数 - **字段声明**:添加 `_deviceRuntimeRepository` 私有字段 #### 2. 业务逻辑重构 - **原子性操作**:将设备创建和运行时状态创建合并到一个方法中 - **事务管理**:通过 `IUnitOfWork.SaveChangesAsync()` 确保原子性保存 - **错误处理**:如果任一操作失败,整个事务回滚,确保数据一致性 #### 3. 方法重构 - **删除方法**: - `CreateAndSaveDeviceAsync` - 原设备创建方法 - `CreateAndSaveDeviceRuntimeAsync` - 原运行时状态创建方法 - **新增方法**: - `CreateAndSaveDeviceWithRuntimeAsync` - 合并的设备创建和运行时状态创建方法 #### 4. 原子性操作流程 1. **创建设备实体**:使用 `CellularDevice.Create()` 创建设备 2. **创建运行时状态实体**:使用 `CellularDeviceRuntime.Create()` 创建运行时状态 3. **添加到仓储**:将两个实体分别添加到对应的仓储 4. **原子性保存**:调用 `_unitOfWork.SaveChangesAsync()` 一次性保存所有更改 5. **错误处理**:如果保存失败,整个事务回滚 #### 5. 运行时状态配置 - **初始状态**:新创建的设备运行时状态设置为 `DeviceRuntimeStatus.Initializing` - **网络栈配置**:初始时 `NetworkStackCode` 为 `null` - **创建者信息**:记录创建运行时状态的用户ID - **时间戳**:自动设置创建和更新时间 ### 技术特性 - **事务安全**:通过工作单元模式确保数据一致性 - **原子性操作**:设备和运行时状态创建要么全部成功,要么全部失败 - **错误回滚**:任一操作失败时自动回滚整个事务 - **日志记录**:完整的操作日志,便于问题排查 - **状态管理**:统一的设备运行时状态管理 ### 业务价值 - **数据一致性**:确保设备和运行时状态的数据一致性 - **状态跟踪**:为每个设备提供运行时状态跟踪 - **监控能力**:支持设备运行状态的实时监控 - **系统稳定性**:通过原子性操作提高系统稳定性 ### 影响范围 - **设备创建流程**:设备创建时会同时创建运行时状态(原子性操作) - **数据库操作**:增加运行时状态表的插入操作,但保证原子性 - **错误处理**:统一的错误处理,确保数据一致性 - **日志记录**:增加运行时状态创建相关的日志 ### 原子性保证 - **事务边界**:整个创建过程在一个事务中完成 - **回滚机制**:如果运行时状态创建失败,设备创建也会回滚 - **数据完整性**:确保不会出现只有设备没有运行时状态的情况 - **一致性保证**:通过数据库事务确保ACID特性 ### 后续工作建议 1. **测试验证**:测试设备创建和运行时状态创建的完整流程 2. **事务测试**:测试事务回滚机制是否正常工作 3. **性能监控**:监控原子性操作对性能的影响 4. **错误处理验证**:验证各种错误情况下的回滚机制 ## 2025-01-29 实现CellularDeviceRuntime的Application层功能 ### 修改原因 根据用户需求,为CellularDeviceRuntime实现Application层的修改和查询功能,主要包括Start和Stop操作,以及相关的查询功能。 ### 修改文件 #### 1. 命令功能 - `X1.Application/Features/DeviceRuntimes/Commands/StartDeviceRuntime/StartDeviceRuntimeCommand.cs` - 启动设备命令 - `X1.Application/Features/DeviceRuntimes/Commands/StartDeviceRuntime/StartDeviceRuntimeResponse.cs` - 启动设备响应 - `X1.Application/Features/DeviceRuntimes/Commands/StartDeviceRuntime/StartDeviceRuntimeCommandHandler.cs` - 启动设备命令处理器 - `X1.Application/Features/DeviceRuntimes/Commands/StopDeviceRuntime/StopDeviceRuntimeCommand.cs` - 停止设备命令 - `X1.Application/Features/DeviceRuntimes/Commands/StopDeviceRuntime/StopDeviceRuntimeResponse.cs` - 停止设备响应 - `X1.Application/Features/DeviceRuntimes/Commands/StopDeviceRuntime/StopDeviceRuntimeCommandHandler.cs` - 停止设备命令处理器 #### 2. 查询功能 - `X1.Application/Features/DeviceRuntimes/Queries/GetDeviceRuntimes/GetDeviceRuntimesQuery.cs` - 获取设备运行时状态列表查询 - `X1.Application/Features/DeviceRuntimes/Queries/GetDeviceRuntimes/GetDeviceRuntimesResponse.cs` - 获取设备运行时状态列表响应 - `X1.Application/Features/DeviceRuntimes/Queries/GetDeviceRuntimes/GetDeviceRuntimesQueryHandler.cs` - 获取设备运行时状态列表查询处理器 - `X1.Application/Features/DeviceRuntimes/Queries/GetDeviceRuntimeStatus/GetDeviceRuntimeStatusQuery.cs` - 获取设备运行时状态查询 - `X1.Application/Features/DeviceRuntimes/Queries/GetDeviceRuntimeStatus/GetDeviceRuntimeStatusResponse.cs` - 获取设备运行时状态响应 - `X1.Application/Features/DeviceRuntimes/Queries/GetDeviceRuntimeStatus/GetDeviceRuntimeStatusQueryHandler.cs` - 获取设备运行时状态查询处理器 #### 3. 控制器 - `X1.Presentation/Controllers/DeviceRuntimesController.cs` - 设备运行时状态管理控制器 ### 修改内容 #### 1. 启动设备功能 (StartDeviceRuntime) - **命令参数**: - `DeviceCode`:设备编号(必填) - `NetworkStackCode`:网络栈配置编号(必填) - `RuntimeCode`:运行编码(必填) - **业务逻辑**: - 验证设备运行时状态是否存在 - 检查设备是否已经在运行中 - 验证用户身份 - 调用实体的Start方法更新状态 - 保存更改到数据库 - **响应数据**: - 运行时状态ID、设备编号、运行时状态 - 运行编码、网络栈配置编号 - 运行人ID、开始时间、更新时间 #### 2. 停止设备功能 (StopDeviceRuntime) - **命令参数**: - `DeviceCode`:设备编号(必填) - **业务逻辑**: - 验证设备运行时状态是否存在 - 检查设备是否在运行中 - 验证用户身份 - 调用实体的Stop方法更新状态 - 保存更改到数据库 - **响应数据**: - 运行时状态ID、设备编号、运行时状态 - 停止人ID、停止时间、更新时间 #### 3. 查询功能 - **列表查询**: - 支持分页查询(页码、每页数量) - 支持关键词搜索(设备编号、运行编码、网络栈配置编号) - 支持运行时状态过滤 - 支持网络栈配置编号过滤 - 返回包含设备信息的完整数据 - **详情查询**: - 根据设备编号查询单个设备运行时状态 - 返回包含设备信息的完整数据 #### 4. API接口设计 - **GET /api/device-runtimes**:获取设备运行时状态列表 - **GET /api/device-runtimes/{deviceCode}**:根据设备编号获取设备运行时状态 - **POST /api/device-runtimes/{deviceCode}/start**:启动设备 - **POST /api/device-runtimes/{deviceCode}/stop**:停止设备 ### 技术特性 - **CQRS模式**:命令和查询职责分离 - **MediatR**:使用中介者模式处理命令和查询 - **依赖注入**:通过构造函数注入依赖服务 - **日志记录**:完整的操作日志记录 - **错误处理**:统一的错误处理和响应格式 - **数据验证**:输入参数验证和业务规则验证 ### 业务价值 - **设备管理**:提供完整的设备启动/停止管理功能 - **状态跟踪**:实时跟踪设备运行时状态 - **操作审计**:记录设备操作的操作人和操作时间 - **数据查询**:支持灵活的设备运行时状态查询 ### 安全特性 - **身份验证**:所有接口都需要用户身份验证 - **权限控制**:通过Authorize特性控制访问权限 - **参数验证**:输入参数验证防止恶意输入 - **业务规则**:状态检查防止非法操作 ### 影响范围 - **API接口**:新增设备运行时状态管理相关的API接口 - **业务逻辑**:新增设备启动/停止的业务逻辑 - **数据访问**:通过仓储层访问设备运行时状态数据 - **前端集成**:为前端提供设备运行时状态管理接口 ### 后续工作建议 1. **单元测试**:为所有命令和查询处理器编写单元测试 2. **集成测试**:测试API接口的完整功能 3. **前端开发**:开发设备运行时状态管理的前端界面 4. **文档编写**:编写API接口文档和使用说明 5. **性能优化**:根据实际使用情况优化查询性能 ## 2025-01-29 优化GetRuntimeByDeviceCodeAsync方法返回最新记录 ### 修改原因 根据用户需求,`GetRuntimeByDeviceCodeAsync`方法需要返回按创建时间排序的最新一条记录,而不是任意一条记录。 ### 修改文件 - `X1.Infrastructure/Repositories/Device/CellularDeviceRuntimeRepository.cs` - 优化GetRuntimeByDeviceCodeAsync方法 ### 修改内容 #### 1. 方法实现优化 - **原实现**:使用`FirstOrDefaultAsync`直接查询,返回任意一条匹配记录 - **新实现**:使用`FindAsync`查询所有匹配记录,然后按`CreatedAt`降序排序,返回第一条记录 #### 2. 查询逻辑 ```csharp var runtimes = await QueryRepository.FindAsync(r => r.DeviceCode == deviceCode, cancellationToken: cancellationToken); return runtimes.OrderByDescending(r => r.CreatedAt).FirstOrDefault(); ``` #### 3. 性能考虑 - **内存排序**:在应用层进行排序,适用于记录数量较少的情况 - **数据库排序**:如果记录数量较多,建议在数据库层进行排序优化 ### 技术特性 - **数据准确性**:确保返回的是最新创建的运行时状态记录 - **向后兼容**:方法签名保持不变,不影响现有调用 - **错误处理**:保持原有的空值处理逻辑 ### 业务价值 - **状态准确性**:获取设备的最新运行时状态,而不是历史状态 - **数据一致性**:确保查询结果的一致性,避免返回过时的状态信息 - **用户体验**:提供更准确的设备状态信息 ### 影响范围 - **查询结果**:现在返回的是按创建时间排序的最新记录 - **性能影响**:对于有多个运行时状态记录的设备,会有轻微的性能影响 - **API行为**:API返回的数据更加准确和有意义 ### 后续工作建议 1. **性能监控**:监控查询性能,特别是对于有大量历史记录的设备 2. **索引优化**:考虑在数据库层面添加`(DeviceCode, CreatedAt)`的复合索引 3. **数据清理**:考虑清理过时的运行时状态记录,减少数据量 ## 2024-12-19 仪器客户端接口规范化重构 ### 修改文件 - `X1.DynamicClientCore/Features/IBaseInstrumentClient.cs` - 规范化基础仪器客户端接口 - `X1.DynamicClientCore/Features/IInstrumentProtocolClient.cs` - 规范化仪器协议客户端接口 - `X1.DynamicClientCore/Features/IInstrumentHttpClient.cs` - 创建仪器HTTP客户端接口 - `X1.DynamicClientCore/Features/Service/InstrumentProtocolClient.cs` - 更新实现类方法名 ### 修改内容 #### 1. IBaseInstrumentClient 接口规范化 - **添加完整注释**:为接口和方法添加详细的XML文档注释 - **方法命名规范化**:`GetDeviceSerialNumber` → `GetDeviceSerialNumberAsync` - **参数文档**:为所有参数添加详细的说明文档 - **异常文档**:添加可能抛出的异常类型说明 - **接口说明**:添加接口用途和设计理念的说明 #### 2. IInstrumentProtocolClient 接口规范化 - **添加完整注释**:为接口和所有方法添加详细的XML文档注释 - **方法命名规范化**: - `StartNetwork` → `StartNetworkAsync` - `StopNetwork` → `StopNetworkAsync` - **参数命名规范化**:`InstrumentNumber` → `instrumentNumber`(遵循C#命名规范) - **参数文档**:为所有参数添加详细的说明文档 - **异常文档**:添加可能抛出的异常类型说明 - **接口说明**:添加接口用途和设计理念的说明 #### 3. IInstrumentHttpClient 接口创建 - **接口设计**:创建组合接口,继承自 `IBaseInstrumentClient` 和 `IInstrumentProtocolClient` - **功能组合**:提供完整的仪器设备通信服务 - **接口说明**:添加详细的接口用途和设计理念说明 - **方法继承**:明确说明继承的方法和功能 #### 4. InstrumentProtocolClient 实现类更新 - **方法名更新**:更新所有方法名以匹配接口定义 - **接口实现**:改为实现 `IInstrumentHttpClient` 接口 - **方法签名**:确保方法签名与接口定义完全一致 ### 技术特性 - **命名规范**:遵循C#异步方法命名规范(Async后缀) - **接口设计**:使用接口组合模式,提供灵活的功能组合 - **文档完整**:为所有接口和方法提供完整的XML文档注释 - **类型安全**:确保接口定义和实现的一致性 - **异常处理**:明确定义可能抛出的异常类型 ### 设计理念 - **职责分离**:基础功能、协议功能、HTTP功能分别定义 - **接口组合**:通过接口继承实现功能组合 - **命名一致性**:统一的命名规范和异步方法约定 - **文档驱动**:完整的文档注释,便于理解和使用 ### 用户体验改进 - **代码可读性**:清晰的接口定义和方法命名 - **开发体验**:完整的IntelliSense支持和文档提示 - **维护性**:清晰的接口层次和职责划分 - **扩展性**:灵活的接口组合,便于功能扩展 ## 2024-12-19 InstrumentProtocolClient 规范化重构 ### 修改文件 - `X1.DynamicClientCore/Features/Service/InstrumentProtocolClient.cs` - 规范化仪器协议客户端实现 ### 修改内容 #### 1. 代码结构优化 - **构造函数规范化**:修复参数命名不一致问题,使用统一的命名规范 - **字段重命名**:`_dynamicHttp` → `_dynamicHttpClient`,`_endpointManager` → `_serviceEndpointManager` - **参数验证**:添加空值检查和异常抛出,确保依赖注入的正确性 - **代码格式**:统一代码格式和缩进,提高可读性 #### 2. 方法规范化 - **GetDeviceSerialNumber方法**: - 添加完整的XML文档注释 - 改进错误处理逻辑,区分不同类型的错误 - 优化日志记录,使用结构化日志 - 修复ApiActionResult字段访问错误(ErrorMessage → Message) - 添加参数验证和异常处理 - **StartNetwork方法**: - 添加完整的XML文档注释 - 添加参数验证(仪器编号不能为空) - 添加异常处理和日志记录 - 添加TODO注释,说明需要实现的业务逻辑 - **StopNetwork方法**: - 添加完整的XML文档注释 - 添加参数验证(仪器编号不能为空) - 添加异常处理和日志记录 - 添加TODO注释,说明需要实现的业务逻辑 #### 3. 错误处理改进 - **分层异常处理**:区分WebSocket异常和其他异常 - **详细错误日志**:提供更详细的错误信息和上下文 - **参数验证**:添加输入参数的空值检查和验证 - **异常传播**:合理处理异常传播,避免不必要的异常捕获 #### 4. 日志记录优化 - **结构化日志**:使用结构化日志记录,提高日志可读性 - **日志级别**:合理使用Debug、Info、Warning、Error级别 - **上下文信息**:添加连接ID、端点名称等上下文信息 - **性能监控**:添加关键操作的性能监控日志 #### 5. 代码质量提升 - **XML文档注释**:为类、方法、参数添加完整的XML文档注释 - **命名规范**:统一变量和方法命名规范 - **代码组织**:优化代码结构,提高可维护性 - **类型安全**:确保类型安全和空值处理 ### 技术特性 - **依赖注入**:正确使用依赖注入模式 - **异步编程**:使用async/await模式,支持取消令牌 - **错误处理**:完整的异常处理和错误恢复机制 - **日志记录**:结构化日志记录,便于监控和调试 - **参数验证**:输入参数验证,确保数据完整性 ### 用户体验改进 - **错误提示**:提供更清晰的错误信息和处理建议 - **性能监控**:通过日志监控系统性能和响应时间 - **调试支持**:详细的调试日志,便于问题排查 - **代码可读性**:清晰的代码结构和注释,便于维护 ### 后续开发建议 - **业务逻辑实现**:根据具体需求实现StartNetwork和StopNetwork方法 - **单元测试**:为重构后的方法添加单元测试 - **集成测试**:测试与其他组件的集成 - **性能优化**:根据实际使用情况优化性能 ## 2024-12-19 RAN配置列表状态开关优化 ### 修改文件 - `X1.WebUI/src/pages/ran-configurations/RANConfigurationsTable.tsx` - 将状态徽章改为状态开关,支持直接修改状态 - `X1.WebUI/src/pages/ran-configurations/RANConfigurationsView.tsx` - 添加状态切换处理逻辑 ### 修改内容 - **状态显示优化**:将状态列从徽章显示改为状态开关显示 - **直接状态修改**:用户可以直接在列表中点击状态开关来启用/禁用配置 - **实时状态更新**:状态修改后立即更新列表显示 - **操作反馈**:提供状态修改成功/失败的提示信息 - **防重复提交**:在状态修改过程中禁用开关,防止重复操作 ### 技术特性 - **状态开关组件**:使用StatusSwitch组件,提供直观的开关界面 - **异步状态更新**:通过API调用更新配置状态 - **错误处理**:完整的错误处理和用户提示 - **加载状态**:在操作过程中显示加载状态 - **数据同步**:状态修改后自动刷新列表数据 ### 用户体验改进 - **直观的状态显示**:状态开关比徽章更直观地显示当前状态 - **便捷的状态修改**:无需打开编辑界面,直接在列表中修改状态 - **即时反馈**:状态修改后立即看到结果 - **操作简化**:减少了打开编辑界面的步骤 - **视觉一致性**:与其他配置管理页面保持一致的交互方式 ## 2024-12-19 修复RAN配置抽屉保存按钮显示问题 ### 修改文件 - `X1.WebUI/src/components/ui/drawer.tsx` - 修复抽屉组件布局问题 - `X1.WebUI/src/pages/ran-configurations/RANConfigurationDrawer.tsx` - 优化抽屉表单布局 - `X1.WebUI/src/pages/ran-configurations/RANConfigurationForm.tsx` - 删除已废弃的表单组件 ### 修改内容 - **修复布局问题**:为DrawerContent添加overflow-y-auto,确保内容可滚动 - **优化表单布局**:调整抽屉表单的flex布局,确保保存按钮正确显示 - **滚动优化**:DrawerContent支持垂直滚动,避免内容溢出 - **移除状态开关**:从抽屉表单中移除状态开关,因为状态修改已在列表中实现 - **修复标签重复**:移除抽屉中的重复标签,使用ConfigContentEditor内部的标签 - **布局简化**:简化配置内容区域的布局结构,确保保存按钮正确显示 - **空间分配**:正确分配flex空间,确保保存按钮始终可见 - **布局重构**:重新设计抽屉的整体布局结构,确保保存按钮正确显示 - **清理废弃文件**:删除已不再使用的RANConfigurationForm.tsx文件 ### 技术特性 - **正确的flex布局**:确保表单内容、配置编辑器和保存按钮都能正确显示 - **滚动支持**:当内容超出抽屉高度时,支持垂直滚动 - **布局稳定性**:修复了保存按钮被隐藏的问题 - **功能分离**:状态修改在列表中,配置内容编辑在抽屉中 - **标签优化**:避免标签重复,使用组件内部的标签显示 - **空间管理**:合理分配垂直空间,确保所有元素都能正确显示 - **布局层次**:正确的HTML结构层次,确保CSS布局正常工作 ### 用户体验改进 - **保存按钮可见**:修复了保存按钮看不到的问题 - **布局稳定**:抽屉内容布局更加稳定和可预测 - **滚动体验**:支持内容滚动,适应不同屏幕高度 - **功能清晰**:状态修改和内容编辑功能分离,避免重复 - **界面简洁**:移除重复标签,界面更加简洁 - **操作便利**:保存按钮始终可见,用户可以方便地保存配置 - **代码清理**:删除废弃的RANConfigurationForm.tsx,保持代码库整洁 ## 2024-12-19 IMS配置改用抽屉组件 ### 修改文件 - `X1.WebUI/src/pages/ims-configurations/IMSConfigurationDrawer.tsx` - 创建IMS配置抽屉组件 - `X1.WebUI/src/pages/ims-configurations/IMSConfigurationsTable.tsx` - 添加状态开关功能 - `X1.WebUI/src/pages/ims-configurations/IMSConfigurationsView.tsx` - 使用抽屉组件替代对话框 - `X1.WebUI/src/pages/ims-configurations/IMSConfigurationForm.tsx` - 删除已废弃的表单组件 ### 修改内容 - **创建抽屉组件**:参考RAN配置实现,创建IMS配置的抽屉组件 - **状态开关集成**:在表格中添加状态开关,支持直接修改IMS配置状态 - **抽屉布局**:使用与RAN配置相同的抽屉布局,确保保存按钮正确显示 - **功能分离**:状态修改在列表中,配置内容编辑在抽屉中 - **代码清理**:删除废弃的IMSConfigurationForm.tsx文件 ### 技术特性 - **抽屉布局**:右侧滑出的抽屉,提供更大的编辑空间 - **状态管理**:表格中的状态开关,支持直接切换启用/禁用状态 - **配置编辑器**:使用ConfigContentEditor组件,支持大文本编辑 - **响应式设计**:抽屉支持滚动,适应不同屏幕高度 - **统一体验**:与RAN配置保持一致的交互体验 ### 用户体验改进 - **更大编辑空间**:抽屉提供比对话框更大的编辑区域 - **直接状态修改**:在列表中直接切换状态,无需进入编辑模式 - **一致的操作体验**:与RAN配置保持相同的操作方式 - **更好的视觉反馈**:状态开关提供直观的启用/禁用状态显示 ## 2024-12-19 Core Network配置改用抽屉组件 ### 修改文件 - `X1.WebUI/src/pages/core-network-configs/CoreNetworkConfigDrawer.tsx` - 创建Core Network配置抽屉组件 - `X1.WebUI/src/pages/core-network-configs/CoreNetworkConfigsTable.tsx` - 添加状态开关功能 - `X1.WebUI/src/pages/core-network-configs/CoreNetworkConfigsView.tsx` - 使用抽屉组件替代对话框 - `X1.WebUI/src/pages/core-network-configs/CoreNetworkConfigForm.tsx` - 删除已废弃的表单组件 ### 修改内容 - **创建抽屉组件**:参考RAN配置实现,创建Core Network配置的抽屉组件 - **状态开关集成**:在表格中添加状态开关,支持直接修改Core Network配置状态 - **抽屉布局**:使用与RAN配置相同的抽屉布局,确保保存按钮正确显示 - **功能分离**:状态修改在列表中,配置内容编辑在抽屉中 - **代码清理**:删除废弃的CoreNetworkConfigForm.tsx文件 ### 技术特性 - **抽屉布局**:右侧滑出的抽屉,提供更大的编辑空间 - **状态管理**:表格中的状态开关,支持直接切换启用/禁用状态 - **配置编辑器**:使用ConfigContentEditor组件,支持大文本编辑 - **响应式设计**:抽屉支持滚动,适应不同屏幕高度 - **统一体验**:与RAN配置和IMS配置保持一致的交互体验 ### 用户体验改进 - **更大编辑空间**:抽屉提供比对话框更大的编辑区域 - **直接状态修改**:在列表中直接切换状态,无需进入编辑模式 - **一致的操作体验**:与RAN配置和IMS配置保持相同的操作方式 - **更好的视觉反馈**:状态开关提供直观的启用/禁用状态显示 ## 2024-12-19 RAN配置创建改用抽屉组件 ### 修改文件 - `X1.WebUI/src/components/ui/drawer.tsx` - 新增抽屉组件 - `X1.WebUI/src/pages/ran-configurations/RANConfigurationDrawer.tsx` - 新增RAN配置抽屉表单组件 - `X1.WebUI/src/pages/ran-configurations/RANConfigurationsView.tsx` - 修改为使用抽屉组件 - `X1.WebUI/src/components/ui/ConfigContentEditor.tsx` - 优化配置内容编辑器,支持高度自适应 ### 修改内容 - **创建抽屉组件**:实现右侧滑出的抽屉组件,提供更大的编辑空间 - **RAN配置抽屉表单**:专门为RAN配置设计的抽屉表单,支持配置内容的编辑 - **替换对话框**:将原有的对话框创建/编辑方式改为抽屉方式 - **优化编辑体验**:为配置内容提供更大的编辑区域,支持自适应高度 - **修复定位问题**:修复抽屉组件显示位置错误的问题,确保从右侧正确滑出 - **配置内容自适应**:配置内容编辑器现在能够占满抽屉中的剩余空间 ### 技术特性 - **抽屉组件**:600px宽度,支持动画效果,右侧滑出 - **配置内容编辑器**:使用ConfigContentEditor组件,支持搜索高亮功能和高度自适应 - **状态开关**:使用StatusSwitch组件,提供更好的视觉反馈 - **表单验证**:保持原有的表单验证逻辑 - **响应式设计**:支持90%视口宽度的最大限制 - **正确定位**:使用fixed定位和transform动画,确保抽屉从右侧正确滑出 - **弹性布局**:使用flex布局,配置内容编辑器自动占满剩余空间 ### 用户体验改进 - **更大的编辑空间**:抽屉提供比对话框更大的编辑区域 - **更好的配置内容编辑**:配置内容编辑器自动占满剩余空间,提供最大编辑区域 - **保持上下文**:抽屉不会完全遮挡主界面,用户可以看到背景内容 - **流畅的动画**:右侧滑入滑出动画提供良好的交互体验 - **正确的显示位置**:抽屉从右侧正确滑出,不会显示在错误位置 - **自适应高度**:配置内容编辑器根据抽屉高度自动调整,充分利用可用空间 ## 2024-12-19 网络栈配置菜单图标修改 ### 修改文件 - `X1.WebUI/src/constants/menuConfig.ts` - 修改网络栈配置菜单项的图标 ### 修改内容 - 导入 `Network` 图标:在 lucide-react 导入中添加 `Network` - 修改网络栈配置菜单项图标:将 `icon: Gauge` 改为 `icon: Network` - 使网络栈配置菜单项与仪表管理菜单项使用不同的图标,提高视觉区分度 ### 技术说明 - 仪表管理菜单项继续使用 `Gauge` 图标 - 网络栈配置菜单项使用 `Network` 图标,更符合网络配置的功能定位 - 提高了菜单的视觉层次和用户体验 ## 2024-12-19 配置表格Key属性统一修复 ### 修改文件 - `X1.WebUI/src/pages/ran-configurations/RANConfigurationsTable.tsx` - 修复React Key属性警告 - `X1.WebUI/src/pages/ims-configurations/IMSConfigurationsTable.tsx` - 修复React Key属性警告 - `X1.WebUI/src/pages/core-network-configs/CoreNetworkConfigsTable.tsx` - 修复React Key属性警告 ### 问题修复 - **Key属性警告**:修复了所有配置表格中缺少唯一key属性的React警告 - **唯一标识**:为每个TableCell添加了基于配置ID和列键的唯一key - **操作按钮Key**:重构操作列中的按钮渲染,使用map方法确保每个按钮都有唯一key - **容器Key清理**:移除了TableHeader和TableBody上不必要的key属性 - **性能优化**:确保React能够正确识别和更新列表项 ### 技术细节 - 将 `key={column.key}` 修改为 `key={`${configuration.raN_ConfigurationId}-${column.key}`}`、`key={`${configuration.ims_ConfigurationId}-${column.key}`}` 和 `key={`${config.CoreNetworkConfigId}-${column.key}`}` - 重构操作列按钮渲染:使用数组map方法替代静态JSX,确保每个按钮都有唯一key - 使用动态key:将TableHeader和TableBody的key改为 `key={`header-${Date.now()}`}` 和 `key={`body-${Date.now()}`}` - 确保每个表格单元格和子元素都有唯一的key属性 - 避免React渲染时的key冲突问题 - 修复actions列中span元素的key:使用 `key={`${configuration.id}-${item.key}`}` 格式 - 修复TableHead的key:使用 `key={`header-${col.key}-${index}`}` 格式,包含索引确保唯一性 - 修复TableRow的key:使用 `key={`${configuration.id}-${index}`}` 格式,包含索引确保唯一性 ### 重构说明 - 将操作列中的两个静态span元素改为数组map渲染 - 每个按钮对象包含key、className、onClick和text属性 - 通过map方法确保每个渲染的元素都有唯一的key属性 - 使用动态时间戳作为容器元素的key,避免写死的key值 - 为actions列中的span元素添加更唯一的key,包含配置ID和操作类型 - 为TableHead添加更唯一的key,包含列key和索引,避免重复key冲突 - 为TableRow添加更唯一的key,包含配置ID和索引,确保每行都有唯一标识 ## 2024-12-19 修复Dialog可访问性警告 ### 问题描述 - Radix UI Dialog组件要求 `DialogContent` 必须包含 `DialogTitle` 以确保屏幕阅读器可访问性 - 项目中多个Dialog组件缺少 `DialogTitle`,导致可访问性警告 ### 修复内容 1. **Dialog组件导出**: - 在 `dialog.tsx` 中添加 `DialogTitle` 和 `DialogDescription` 的导出 2. **RAN配置视图**: - 添加 `DialogTitle` 导入 - 为创建和编辑对话框添加标题:"创建RAN配置" 和 "编辑RAN配置" 3. **IMS配置视图**: - 添加 `DialogTitle` 导入 - 为创建和编辑对话框添加标题:"创建IMS配置" 和 "编辑IMS配置" 4. **核心网络配置视图**: - 添加 `DialogTitle` 导入 - 为创建和编辑对话框添加标题:"创建核心网络配置" 和 "编辑核心网络配置" ### 技术说明 - 确保所有Dialog组件都符合Radix UI的可访问性要求 - 为屏幕阅读器用户提供更好的体验 - 添加语义化的对话框标题,提高用户体验 - 使用一致的样式:`text-lg font-semibold mb-4` ## 2024-12-19 修复配置字段名不匹配问题 ### 问题描述 - 前端接口定义与后端API返回的数据字段名不匹配 - 导致前端访问配置ID时出现 undefined 错误 ### RAN配置修复内容 1. **修复前端接口定义**: - `RANConfiguration` 接口:`id` → `raN_ConfigurationId` - `CreateRANConfigurationResponse` 接口:`id` → `raN_ConfigurationId` - `UpdateRANConfigurationRequest` 接口:`id` → `raN_ConfigurationId` - `UpdateRANConfigurationResponse` 接口:`id` → `raN_ConfigurationId` 2. **修复表格组件**: - `RANConfigurationsTable.tsx`:`configuration.id` → `configuration.raN_ConfigurationId` - 表格行key:`key={configuration.id}` → `key={configuration.raN_ConfigurationId}` - 表格单元格key:`key={`${configuration.id}-${column.key}`}` → `key={`${configuration.raN_ConfigurationId}-${column.key}`}` 3. **修复视图组件**: - `RANConfigurationsView.tsx`:删除和更新操作中的字段引用 - `configuration.id` → `configuration.raN_ConfigurationId` - `selectedConfiguration.id` → `selectedConfiguration.raN_ConfigurationId` ### IMS配置修复内容 1. **修复前端接口定义**: - `IMSConfiguration` 接口:`imsConfigurationId` → `ims_ConfigurationId` - `CreateIMSConfigurationResponse` 接口:`imsConfigurationId` → `ims_ConfigurationId` - `UpdateIMSConfigurationRequest` 接口:`imsConfigurationId` → `ims_ConfigurationId` - `UpdateIMSConfigurationResponse` 接口:`imsConfigurationId` → `ims_ConfigurationId` 2. **修复表格组件**: - `IMSConfigurationsTable.tsx`:`configuration.imsConfigurationId` → `configuration.ims_ConfigurationId` - 表格行key:`key={configuration.imsConfigurationId}` → `key={configuration.ims_ConfigurationId}` - 表格单元格key:`key={`${configuration.imsConfigurationId}-${column.key}`}` → `key={`${configuration.ims_ConfigurationId}-${column.key}`}` 3. **修复视图组件**: - `IMSConfigurationsView.tsx`:删除和更新操作中的字段引用 - `configuration.imsConfigurationId` → `configuration.ims_ConfigurationId` - `selectedConfiguration.imsConfigurationId` → `selectedConfiguration.ims_ConfigurationId` ### 核心网络配置修复内容 1. **修复前端接口定义**: - `CoreNetworkConfig` 接口:`coreNetworkConfigId` → `CoreNetworkConfigId` - `CreateCoreNetworkConfigResponse` 接口:`coreNetworkConfigId` → `CoreNetworkConfigId` - `UpdateCoreNetworkConfigRequest` 接口:`coreNetworkConfigId` → `CoreNetworkConfigId` - `UpdateCoreNetworkConfigResponse` 接口:`coreNetworkConfigId` → `CoreNetworkConfigId` 2. **修复表格组件**: - `CoreNetworkConfigsTable.tsx`:`config.coreNetworkConfigId` → `config.CoreNetworkConfigId` - 表格行key:`key={config.coreNetworkConfigId}` → `key={config.CoreNetworkConfigId}` - 表格单元格key:`key={`${config.coreNetworkConfigId}-${column.key}`}` → `key={`${config.CoreNetworkConfigId}-${column.key}`}` 3. **修复视图组件**: - `CoreNetworkConfigsView.tsx`:删除和更新操作中的字段引用 - `config.coreNetworkConfigId` → `config.CoreNetworkConfigId` - `selectedConfig.coreNetworkConfigId` → `selectedConfig.CoreNetworkConfigId` ### 技术说明 - 统一前后端字段命名规范 - 确保前端接口定义与后端API返回数据格式一致 - 修复所有相关的字段引用 - 避免运行时出现 undefined 错误 - 注意后端返回的字段名大小写: - RAN配置:`raN_ConfigurationId` - IMS配置:`ims_ConfigurationId` - 核心网络配置:`CoreNetworkConfigId` ## 2024-12-19 配置表单统一集成配置内容编辑器 ### 修改文件 - `X1.WebUI/src/pages/ims-configurations/IMSConfigurationForm.tsx` - 集成配置内容编辑器 - `X1.WebUI/src/pages/core-network-configs/CoreNetworkConfigForm.tsx` - 集成配置内容编辑器 ### 功能统一 - **IMS配置表单**:使用新的配置内容编辑器替换原有的Textarea - **核心网络配置表单**:使用新的配置内容编辑器替换原有的Textarea - **功能一致性**:所有配置表单现在都支持搜索高亮功能 ### 技术实现 - 导入 `ConfigContentEditor` 组件 - 替换原有的配置内容输入区域 - 移除JSON格式限制的提示文本 - 保持表单的其他功能不变 ### 用户体验 - **统一体验**:所有配置表单现在都有相同的编辑体验 - **搜索功能**:支持在配置内容中搜索和高亮显示匹配项 - **格式灵活**:不再强制要求JSON格式,支持任意格式的配置内容 ## 2024-12-19 RAN配置表格Key属性修复 ### 修改文件 - `X1.WebUI/src/pages/ran-configurations/RANConfigurationsTable.tsx` - 修复React Key属性警告 ### 问题修复 - **Key属性警告**:修复了表格单元格缺少唯一key属性的React警告 - **唯一标识**:为每个TableCell添加了基于配置ID和列键的唯一key - **操作按钮Key**:重构操作列中的按钮渲染,使用map方法确保每个按钮都有唯一key - **性能优化**:确保React能够正确识别和更新列表项 ### 技术细节 - 将 `key={column.key}` 修改为 `key={`${configuration.ranConfigurationId}-${column.key}`}` - 重构操作列按钮渲染:使用数组map方法替代静态JSX,确保每个按钮都有唯一key - 确保每个表格单元格和子元素都有唯一的key属性 - 避免React渲染时的key冲突问题 ### 重构说明 - 将操作列中的两个静态span元素改为数组map渲染 - 每个按钮对象包含key、className、onClick和text属性 - 通过map方法确保每个渲染的元素都有唯一的key属性 ## 2024-12-19 配置内容编辑器组件简化 ### 修改文件 - `X1.WebUI/src/components/ui/ConfigContentEditor.tsx` - 简化配置内容编辑器组件 ### 功能调整 #### 1. 移除的功能 - **复制功能**:移除了复制到剪贴板的功能 - **导出功能**:移除了导出为文件的功能 - **导入功能**:移除了从文件导入的功能 - **模板管理**:移除了模板注册、查询、修改、删除功能 #### 2. 新增的功能 - **搜索高亮**:支持在配置内容中搜索并高亮显示匹配项 - **实时搜索**:输入搜索关键词时实时高亮所有匹配项 - **导航功能**:支持上一个/下一个匹配项的快速导航 - **匹配计数**:显示当前搜索关键词的匹配数量 #### 3. 搜索功能特性 - **高亮显示**:使用黄色背景高亮所有匹配的文本 - **大小写不敏感**:搜索时忽略大小写 - **正则表达式转义**:自动转义特殊字符,支持普通文本搜索 - **循环搜索**:到达末尾时自动从头开始,到达开头时自动从末尾开始 #### 4. 用户体验 - **简洁界面**:只保留搜索按钮,界面更加简洁 - **快速访问**:点击搜索按钮即可打开搜索栏 - **键盘友好**:搜索栏自动获得焦点,支持回车键操作 - **视觉反馈**:匹配项数量实时显示 ### 技术实现 - **高亮层**:使用绝对定位的透明层显示高亮效果 - **正则匹配**:使用正则表达式进行大小写不敏感的匹配 - **选择导航**:通过 setSelectionRange 实现光标定位 - **状态管理**:使用 useState 管理搜索状态和高亮内容 ### 使用方式 ```tsx ``` ### 界面布局 - **工具栏**:只包含搜索按钮 - **搜索栏**:可展开的搜索输入框和导航按钮 - **编辑器**:主要的文本编辑区域,支持高亮显示 - **高亮层**:覆盖在编辑器上的透明高亮层 ## 2024-12-19 RAN配置页面展开按钮移除 ### 修改文件 - `X1.WebUI/src/pages/ran-configurations/RANConfigurationsView.tsx` ### 修改内容 #### 1. 移除展开/收起功能 - 删除了 `ChevronDownIcon` 和 `ChevronUpIcon` 的导入 - 移除了 `showAdvanced` 状态变量 - 删除了 `advancedFields` 高级字段配置 - 将 `firstRowFields` 重命名为 `searchFields` #### 2. 简化搜索栏结构 - 移除了展开/收起按钮 - 只保留基本的搜索字段:搜索关键词和状态 - 简化了表单布局,固定为3列网格布局 - 移除了每页数量选择功能(该功能已移至分页组件) #### 3. 优化代码结构 - 移除了条件渲染逻辑 - 简化了字段映射和事件处理 - 保持了类型安全和错误处理 ### 功能影响 - **用户体验**:搜索界面更简洁,减少了用户操作复杂度 - **界面布局**:搜索栏高度固定,布局更稳定 - **功能完整性**:核心搜索功能保持不变,分页大小调整功能移至分页组件 ### 技术细节 - 保持了所有必要的搜索功能 - 维持了类型安全和错误处理机制 - 简化了组件状态管理 - 提高了代码可读性和维护性 ## 2024-12-19 网络栈配置管理页面实现 ### 新增文件 - `X1.WebUI/src/pages/network-stack-configs/NetworkStackConfigsView.tsx` - 网络栈配置页面视图组件 - `X1.WebUI/src/pages/network-stack-configs/NetworkStackConfigsTable.tsx` - 网络栈配置表格组件 - `X1.WebUI/src/pages/network-stack-configs/NetworkStackConfigForm.tsx` - 网络栈配置表单组件 ### 修改文件 - `X1.WebUI/src/routes/AppRouter.tsx` - 添加网络栈配置页面路由,将网络栈配置相关页面从仪表管理中分离 - `X1.WebUI/src/constants/menuConfig.ts` - 添加网络栈配置权限和菜单项,将网络栈配置作为独立菜单项 - `X1.WebUI/src/contexts/AuthContext.tsx` - 在 getDefaultPermissions 函数中添加网络栈配置相关权限 ### 功能特性 #### 1. 页面组件结构 - **NetworkStackConfigsView**: 主页面视图,包含搜索、表格、分页等功能 - **NetworkStackConfigsTable**: 数据表格组件,支持列显示控制、密度调整 - **NetworkStackConfigForm**: 创建/编辑表单组件,支持栈ID、RAN ID等字段编辑 #### 2. 搜索功能 - 支持按栈ID和描述搜索 - 支持按激活/非激活状态过滤 - 支持分页大小调整 - 提供展开/收起高级搜索选项 #### 3. 表格功能 - 支持列显示控制(栈ID、RAN ID、描述、状态、创建时间、操作) - 支持表格密度调整(宽松、默认、紧凑) - 栈ID使用等宽字体显示,便于识别 - 状态徽章显示(激活/非激活) - 日期格式化显示 #### 4. 表单功能 - 栈ID输入(必填,编辑时不允许修改) - RAN ID输入(可选) - 描述信息输入(可选) - 激活/非激活状态切换 - 表单验证和提交状态管理 #### 5. 权限控制 - 添加 `networkstackconfigs.view` 和 `networkstackconfigs.manage` 权限 - 路由级别的权限保护 - 菜单项权限控制 #### 6. 用户体验 - 加载状态显示 - 操作成功/失败提示 - 删除确认对话框 - 防重复提交保护 - 响应式设计 - 编辑时栈ID字段禁用,防止误操作 ### 技术实现 #### 1. 组件设计 - 参考协议管理页面的设计模式 - 使用TypeScript确保类型安全 - 采用React Hooks管理状态 - 使用shadcn/ui组件库 #### 2. 数据管理 - 使用网络栈配置服务进行API调用 - 支持分页、搜索、过滤功能 - 完整的CRUD操作支持 #### 3. 路由配置 - 懒加载组件提高性能 - 权限保护路由 - 动画容器包装 #### 4. 样式设计 - 统一的UI风格 - 响应式布局 - 美观的表格和表单设计 - 栈ID使用等宽字体,提高可读性 ### 使用方式 1. 通过菜单 "网络栈配置" 访问页面 2. 支持创建、编辑、删除网络栈配置 3. 支持按栈ID、描述搜索配置 4. 支持按激活状态过滤配置 5. 支持调整表格显示密度和列显示 6. 编辑时栈ID字段自动禁用,防止误操作 ### 路由结构调整 - 将网络栈配置相关页面从 `/dashboard/instruments` 下分离出来 - 创建独立的 `/dashboard/network-stack-configs` 路由组 - 包含以下子路由: - `/dashboard/network-stack-configs/ran-configurations` - RAN配置管理 - `/dashboard/network-stack-configs/ims-configurations` - IMS配置管理 - `/dashboard/network-stack-configs/core-network-configs` - 核心网络配置管理 - `/dashboard/network-stack-configs/network-stack-configs` - 网络栈配置管理 ### 菜单结构调整 - 将网络栈配置从仪表管理菜单中分离出来 - 创建独立的"网络栈配置"顶级菜单项 - 包含四个子菜单项:RAN配置、IMS配置、核心网络配置、网络栈配置 - 使用 `ranconfigurations.view` 权限作为主菜单权限 ### 权限配置 - 在 `AuthContext.tsx` 的 `getDefaultPermissions` 函数中添加了网络栈配置相关权限: - `ranconfigurations.view` 和 `ranconfigurations.manage` - `imsconfigurations.view` 和 `imsconfigurations.manage` - `corenetworkconfigs.view` 和 `corenetworkconfigs.manage` - `networkstackconfigs.view` 和 `networkstackconfigs.manage` - 确保用户登录后能够正确获取网络栈配置相关权限 ## 2024-12-19 核心网络配置管理页面实现 ### 新增文件 - `X1.WebUI/src/pages/core-network-configs/CoreNetworkConfigsView.tsx` - 核心网络配置页面视图组件 - `X1.WebUI/src/pages/core-network-configs/CoreNetworkConfigsTable.tsx` - 核心网络配置表格组件 - `X1.WebUI/src/pages/core-network-configs/CoreNetworkConfigForm.tsx` - 核心网络配置表单组件 ### 修改文件 - `X1.WebUI/src/routes/AppRouter.tsx` - 添加核心网络配置页面路由 - `X1.WebUI/src/constants/menuConfig.ts` - 添加核心网络配置权限和菜单项 ### 功能特性 #### 1. 页面组件结构 - **CoreNetworkConfigsView**: 主页面视图,包含搜索、表格、分页等功能 - **CoreNetworkConfigsTable**: 数据表格组件,支持列显示控制、密度调整 - **CoreNetworkConfigForm**: 创建/编辑表单组件,支持JSON配置内容编辑 #### 2. 搜索功能 - 支持按配置名称和描述搜索 - 支持按启用/禁用状态过滤 - 支持分页大小调整 - 提供展开/收起高级搜索选项 #### 3. 表格功能 - 支持列显示控制(配置名称、描述、状态、创建时间、操作) - 支持表格密度调整(宽松、默认、紧凑) - 配置内容预览(截断显示,鼠标悬停显示完整内容) - 状态徽章显示(启用/禁用) - 日期格式化显示 #### 4. 表单功能 - 配置名称输入(必填) - JSON格式配置内容编辑(必填,支持多行编辑) - 描述信息输入(可选) - 启用/禁用状态切换 - 表单验证和提交状态管理 #### 5. 权限控制 - 添加 `corenetworkconfigs.view` 和 `corenetworkconfigs.manage` 权限 - 路由级别的权限保护 - 菜单项权限控制 #### 6. 用户体验 - 加载状态显示 - 操作成功/失败提示 - 删除确认对话框 - 防重复提交保护 - 响应式设计 ### 技术实现 #### 1. 组件设计 - 参考协议管理页面的设计模式 - 使用TypeScript确保类型安全 - 采用React Hooks管理状态 - 使用shadcn/ui组件库 #### 2. 数据管理 - 使用核心网络配置服务进行API调用 - 支持分页、搜索、过滤功能 - 完整的CRUD操作支持 #### 3. 路由配置 - 懒加载组件提高性能 - 权限保护路由 - 动画容器包装 #### 4. 样式设计 - 统一的UI风格 - 响应式布局 - 美观的表格和表单设计 ### 使用方式 1. 通过菜单 "仪表管理" -> "核心网络配置" 访问页面 2. 支持创建、编辑、删除核心网络配置 3. 支持按名称、描述搜索配置 4. 支持按启用状态过滤配置 5. 支持调整表格显示密度和列显示 ## 2024-12-19 IMS配置管理页面实现 ### 新增文件 - `X1.WebUI/src/pages/ims-configurations/IMSConfigurationsView.tsx` - IMS配置页面视图组件 - `X1.WebUI/src/pages/ims-configurations/IMSConfigurationsTable.tsx` - IMS配置表格组件 - `X1.WebUI/src/pages/ims-configurations/IMSConfigurationForm.tsx` - IMS配置表单组件 ### 修改文件 - `X1.WebUI/src/routes/AppRouter.tsx` - 添加IMS配置页面路由 - `X1.WebUI/src/constants/menuConfig.ts` - 添加IMS配置权限和菜单项 ### 功能特性 #### 1. 页面组件结构 - **IMSConfigurationsView**: 主页面视图,包含搜索、表格、分页等功能 - **IMSConfigurationsTable**: 数据表格组件,支持列显示控制、密度调整 - **IMSConfigurationForm**: 创建/编辑表单组件,支持JSON配置内容编辑 #### 2. 搜索功能 - 支持按配置名称和描述搜索 - 支持按启用/禁用状态过滤 - 支持分页大小调整 - 提供展开/收起高级搜索选项 #### 3. 表格功能 - 支持列显示控制(配置名称、描述、状态、创建时间、操作) - 支持表格密度调整(宽松、默认、紧凑) - 配置内容预览(截断显示,鼠标悬停显示完整内容) - 状态徽章显示(启用/禁用) - 日期格式化显示 #### 4. 表单功能 - 配置名称输入(必填) - JSON格式配置内容编辑(必填,支持多行编辑) - 描述信息输入(可选) - 启用/禁用状态切换 - 表单验证和提交状态管理 #### 5. 权限控制 - 添加 `imsconfigurations.view` 和 `imsconfigurations.manage` 权限 - 路由级别的权限保护 - 菜单项权限控制 #### 6. 用户体验 - 加载状态显示 - 操作成功/失败提示 - 删除确认对话框 - 防重复提交保护 - 响应式设计 ### 技术实现 #### 1. 组件设计 - 参考协议管理页面的设计模式 - 使用TypeScript确保类型安全 - 采用React Hooks管理状态 - 使用shadcn/ui组件库 #### 2. 数据管理 - 使用IMS配置服务进行API调用 - 支持分页、搜索、过滤功能 - 完整的CRUD操作支持 #### 3. 路由配置 - 懒加载组件提高性能 - 权限保护路由 - 动画容器包装 #### 4. 样式设计 - 统一的UI风格 - 响应式布局 - 美观的表格和表单设计 ### 使用方式 1. 通过菜单 "仪表管理" -> "IMS配置" 访问页面 2. 支持创建、编辑、删除IMS配置 3. 支持按名称、描述搜索配置 4. 支持按启用状态过滤配置 5. 支持调整表格显示密度和列显示 ## 2024-12-19 RAN配置管理页面实现 ### 新增文件 - `X1.WebUI/src/pages/ran-configurations/RANConfigurationsView.tsx` - RAN配置页面视图组件 - `X1.WebUI/src/pages/ran-configurations/RANConfigurationsTable.tsx` - RAN配置表格组件 - `X1.WebUI/src/pages/ran-configurations/RANConfigurationForm.tsx` - RAN配置表单组件 ### 修改文件 - `X1.WebUI/src/routes/AppRouter.tsx` - 添加RAN配置页面路由 - `X1.WebUI/src/constants/menuConfig.ts` - 添加RAN配置权限和菜单项 ### 功能特性 #### 1. 页面组件结构 - **RANConfigurationsView**: 主页面视图,包含搜索、表格、分页等功能 - **RANConfigurationsTable**: 数据表格组件,支持列显示控制、密度调整 - **RANConfigurationForm**: 创建/编辑表单组件,支持JSON配置内容编辑 #### 2. 搜索功能 - 支持按配置名称和描述搜索 - 支持按启用/禁用状态过滤 - 支持分页大小调整 - 提供展开/收起高级搜索选项 #### 3. 表格功能 - 支持列显示控制(配置名称、描述、状态、创建时间、操作) - 支持表格密度调整(宽松、默认、紧凑) - 配置内容预览(截断显示,鼠标悬停显示完整内容) - 状态徽章显示(启用/禁用) - 日期格式化显示 #### 4. 表单功能 - 配置名称输入(必填) - JSON格式配置内容编辑(必填,支持多行编辑) - 描述信息输入(可选) - 启用/禁用状态切换 - 表单验证和提交状态管理 #### 5. 权限控制 - 添加 `ranconfigurations.view` 和 `ranconfigurations.manage` 权限 - 路由级别的权限保护 - 菜单项权限控制 #### 6. 用户体验 - 加载状态显示 - 操作成功/失败提示 - 删除确认对话框 - 防重复提交保护 - 响应式设计 ### 技术实现 #### 1. 组件设计 - 参考协议管理页面的设计模式 - 使用TypeScript确保类型安全 - 采用React Hooks管理状态 - 使用shadcn/ui组件库 #### 2. 数据管理 - 使用RAN配置服务进行API调用 - 支持分页、搜索、过滤功能 - 完整的CRUD操作支持 #### 3. 路由配置 - 懒加载组件提高性能 - 权限保护路由 - 动画容器包装 #### 4. 样式设计 - 统一的UI风格 - 响应式布局 - 美观的表格和表单设计 ### 使用方式 1. 通过菜单 "仪表管理" -> "RAN配置" 访问页面 2. 支持创建、编辑、删除RAN配置 3. 支持按名称、描述搜索配置 4. 支持按启用状态过滤配置 5. 支持调整表格显示密度和列显示 ## 2024-12-19 ProtocolMessageHandler 优化 ## 2024-12-19 ProtocolMessageHandler 优化 ### 修改文件 - `X1.WebSocket/Handlers/ProtocolMessageHandler.cs` ### 主要改进 #### 1. 方法重命名 - `ProtocolMessageOutput` → `ProcessProtocolMessageAsync` - 更符合方法命名规范,清晰表达方法功能 #### 2. 代码结构优化 - 将原来的单一方法拆分为多个职责明确的方法: - `ProcessProtocolMessageAsync`: 处理协议消息的主要逻辑 - `ProcessProtocolLogs`: 处理协议日志数组 - `ProcessSingleProtocolLog`: 处理单个协议日志 #### 3. 错误处理改进 - 在 `ProcessProtocolMessageAsync` 方法中添加了完整的异常处理机制 - 区分 JSON 反序列化错误和其他异常 - 提供更详细的错误日志信息 - 移除了 `HandleAsync` 方法中不必要的 try-catch,让异常向上传播 - 优化异常处理策略:记录错误日志后不再抛出异常,避免异常传播 #### 4. 日志记录优化 - 使用结构化日志记录,提高日志可读性 - 添加处理进度和统计信息的日志 - 改进日志级别使用,Debug/Info/Warning/Error 合理分配 - 美化协议日志输出格式,使用【】括号突出字段名称,提高可读性 - 添加空值处理,使用 "N/A" 标识空值 - 时间格式化为易读的时分秒毫秒格式 #### 5. 性能优化 - 添加 JsonSerializerOptions 配置,提高序列化性能 - 移除不必要的异步操作(ProcessProtocolMessage、ProcessProtocolLogs 和 ProcessSingleProtocolLog) - 避免为了异步而异步的代码模式,只在实际需要异步的地方使用 async/await #### 6. 代码质量提升 - 添加详细的 XML 文档注释 - 改进变量命名(MsgData → messageData) - 使用 null 检查和空值验证 - 添加输入参数验证 #### 7. 可维护性改进 - 方法职责单一,便于测试和维护 - 代码结构清晰,易于理解和扩展 - 为未来业务逻辑扩展预留了接口 ### 技术细节 - 使用 JsonSerializerOptions 配置大小写不敏感和驼峰命名 - 添加了消息数量统计和错误计数 - 改进了异常处理的分层结构 - 优化了日志输出的格式和内容 ## 2024-12-19 WebSocketMiddleware ProcessWebSocketMessages 修复 ### 修改文件 - `X1.WebSocket/Middleware/WebSocketMiddleware.cs` ### 主要问题修复 #### 1. 消息缓冲区共享问题 - **问题**:`_messageBuffer` 是类的成员变量,被所有连接共享,导致数据混乱 - **修复**:为每个连接创建独立的 `WebSocketMessageBuffer` 实例 - **影响**:避免多连接间的数据干扰,提高并发安全性 #### 2. 消息超时逻辑错误 - **问题**:`messageStartTime` 在循环中被重置,超时检查逻辑有问题 - **修复**:基于最后接收消息的时间进行超时检查 - **影响**:确保超时机制正确工作,及时检测到超时连接 #### 3. 缓冲区重置时机不当 - **问题**:只有在 `EndOfMessage` 为 true 时才重置缓冲区 - **修复**:在消息完整处理后立即重置缓冲区 - **影响**:避免缓冲区累积过多数据,提高内存使用效率 #### 4. 异常处理不完善 - **问题**:缺少对 WebSocket 连接状态的检查,没有处理连接意外断开的情况 - **修复**:添加连接状态检查和详细的异常处理机制 - **影响**:提高系统稳定性,避免因连接异常导致的崩溃 #### 5. 资源泄漏风险 - **问题**:缓冲区没有正确释放,异常情况下可能导致资源泄漏 - **修复**:使用 `using` 语句确保缓冲区正确释放 - **影响**:防止内存泄漏,提高资源管理效率 ### 技术改进 #### 1. 连接状态验证 - 在处理消息前检查 WebSocket 连接状态 - 及时发现并处理异常连接状态 #### 2. 消息大小验证 - 在处理消息前验证消息大小是否超过限制 - 防止过大消息导致的内存问题 #### 3. 通道状态检查 - 在写入消息前检查通道是否已关闭 - 避免向已关闭的通道写入数据 #### 4. 增强的日志记录 - 添加更详细的调试和错误日志 - 便于问题排查和性能监控 #### 5. 资源管理优化 - 使用 `using` 语句自动管理缓冲区生命周期 - 确保异常情况下资源也能正确释放 ### 性能影响 - 提高并发处理能力,避免连接间的数据竞争 - 减少内存泄漏风险,提高系统稳定性 - 优化超时检测机制,及时释放无效连接 - 改进异常处理,减少系统崩溃概率 ## 2024-12-19 WebSocket 缓冲区管理问题修复 ### 修改文件 - `X1.WebSocket/Middleware/WebSocketMiddleware.cs` ### 问题描述 从日志中发现缓冲区溢出错误: ``` [17:19:07 WRN] 消息缓冲区已满,连接ID:ff70aebb-c0a2-40a3-b478-8aaa00daf50f,缓冲区大小:1048576,消息大小:4096 [17:19:07 WRN] 操作失败,重试 1/3 System.Net.WebSockets.WebSocketException (0x80004005): 消息缓冲区溢出 ``` ### 根本原因分析 #### 1. 缓冲区大小设置错误 - **问题**:缓冲区大小设置为 `_options.MaxMessageSize`(1MB),但这是用来累积分片消息的 - **影响**:当消息分片传输时,缓冲区会累积所有分片直到达到最大大小,导致溢出 #### 2. 分片消息处理逻辑缺失 - **问题**:没有正确处理大型消息的分片传输 - **影响**:分片消息无法正确累积和重组 #### 3. 缓冲区管理逻辑错误 - **问题**:在写入数据前没有检查总大小是否会超过限制 - **影响**:可能导致缓冲区溢出 ### 修复方案 #### 1. 优化缓冲区大小设置 - **修复**:将缓冲区大小设置为 `MaxMessageSize` 的 1.5 倍 - **原因**:确保有足够空间处理分片消息,避免溢出 - **代码**: ```csharp var bufferSize = (int)(_options.MaxMessageSize * 1.5); using var messageBuffer = new WebSocketMessageBuffer(bufferSize); ``` #### 2. 改进缓冲区写入逻辑 - **修复**:在写入前检查总大小是否会超过限制 - **原因**:提前检测溢出风险,避免不必要的写入操作 - **代码**: ```csharp var totalSize = messageBuffer.Size + receiveResult.Count; if (totalSize > _options.MaxMessageSize) { throw new WebSocketException("消息大小超过限制"); } ``` #### 3. 增强分片消息处理 - **修复**:添加分片消息的详细日志记录 - **原因**:便于调试和监控分片消息的处理过程 - **代码**: ```csharp _logger.LogDebug("消息分片已累积,连接ID:{ConnectionId},当前缓冲区大小:{BufferSize}字节", connectionId, messageBuffer.Size); ``` #### 4. 改进错误处理和日志 - **修复**:提供更详细的错误信息和调试日志 - **原因**:便于问题排查和性能监控 - **改进**: - 区分"消息大小超过限制"和"缓冲区写入失败" - 添加缓冲区状态和分片处理过程的详细日志 - 在关键操作点添加调试日志 ### 技术细节 #### 1. 缓冲区大小计算 - 原始大小:`_options.MaxMessageSize`(1MB) - 新大小:`_options.MaxMessageSize * 1.5`(1.5MB) - 原因:为分片消息提供足够的缓冲空间 #### 2. 大小检查策略 - 写入前检查:`totalSize = currentSize + newDataSize` - 最终验证:`messageData.Length > _options.MaxMessageSize` - 双重保护:确保消息大小在合理范围内 #### 3. 分片处理流程 - 累积分片:`messageBuffer.TryWrite(buffer, 0, receiveResult.Count)` - 检查完整性:`receiveResult.EndOfMessage` - 重组消息:`messageBuffer.GetMessage()` - 重置缓冲区:`messageBuffer.Reset()` ### 性能影响 - **内存使用**:缓冲区大小增加 50%,但避免了溢出错误 - **处理效率**:提前检测大小限制,避免无效的写入操作 - **稳定性**:正确处理分片消息,提高系统稳定性 - **可维护性**:详细的日志记录,便于问题排查 ### 测试建议 1. 测试大型消息的分片传输 2. 验证缓冲区大小限制的正确性 3. 检查分片消息的完整重组 4. 监控内存使用情况 5. 验证错误处理的正确性 ## 2024-12-19 WebSocket 错误处理优化 ### 修改文件 - `X1.WebSocket/Middleware/WebSocketMiddleware.cs` ### 问题描述 从日志中发现重试机制在缓冲区满的情况下无效: ``` [17:19:07 WRN] 消息缓冲区已满,连接ID:ff70aebb-c0a2-40a3-b478-8aaa00daf50f,缓冲区大小:1048576,消息大小:4096 [17:19:07 WRN] 操作失败,重试 1/3 [17:19:08 WRN] 操作失败,重试 2/3 [17:19:09 WRN] 操作失败,重试 3/3 [17:19:09 ERR] 消息处理失败,连接ID:ff70aebb-c0a2-40a3-b478-8aaa00daf50f,关闭连接 ``` ### 根本原因分析 #### 1. 重试机制设计缺陷 - **问题**:对于缓冲区满等状态性问题,重试机制没有意义 - **影响**:浪费系统资源,延迟错误处理 #### 2. 异常类型区分不足 - **问题**:没有区分不同类型的异常,所有异常都进行重试 - **影响**:对不可恢复的错误进行无效重试 #### 3. 资源清理不完整 - **问题**:存在未使用的成员变量 `_messageBuffer` - **影响**:代码冗余,可能造成混淆 ### 修复方案 #### 1. 优化异常处理策略 - **修复**:区分 WebSocket 异常和其他异常 - **原因**:WebSocket 异常通常不可恢复,不需要重试 - **代码**: ```csharp catch (WebSocketException ex) { // 对于 WebSocket 异常,直接抛出,不进行重试 _logger.LogError(ex, "WebSocket 消息处理异常,连接ID:{ConnectionId},错误:{Error}", connectionId, ex.Message); throw; } catch (Exception ex) { // 对于其他异常,使用重试机制 // ... } ``` #### 2. 移除未使用的成员变量 - **修复**:移除 `_messageBuffer` 成员变量和初始化代码 - **原因**:清理代码冗余,避免混淆 - **改进**: - 移除成员变量声明:`private readonly WebSocketMessageBuffer _messageBuffer;` - 移除初始化代码:`_messageBuffer = new WebSocketMessageBuffer(_options.MaxMessageSize);` #### 3. 改进错误日志记录 - **修复**:提供更详细的错误分类和日志信息 - **原因**:便于问题排查和性能监控 - **改进**: - 区分 WebSocket 异常和其他异常 - 提供更具体的错误描述 - 减少无效的重试日志 ### 技术细节 #### 1. 异常分类策略 - **WebSocket 异常**:直接抛出,不重试 - 缓冲区溢出 - 消息大小超限 - 连接状态异常 - **其他异常**:使用重试机制 - 网络临时错误 - 系统资源临时不足 #### 2. 重试逻辑优化 - **适用场景**:临时性、可恢复的错误 - **不适用场景**:状态性、不可恢复的错误 - **重试策略**:指数退避,避免系统过载 #### 3. 资源管理改进 - **成员变量清理**:移除未使用的 `_messageBuffer` - **内存优化**:减少不必要的对象创建 - **代码简化**:提高代码可读性和维护性 ### 性能影响 - **响应速度**:减少无效重试,提高错误响应速度 - **资源使用**:减少系统资源浪费 - **稳定性**:更准确的错误处理,提高系统稳定性 - **可维护性**:代码更清晰,便于维护和调试 ### 测试建议 1. 测试缓冲区满时的错误处理 2. 验证不同类型异常的处理策略 3. 检查重试机制的正确性 4. 监控系统资源使用情况 5. 验证错误日志的准确性 ## 2024-12-19 HandleWebSocketConnection 缓冲区大小修复 ### 修改文件 - `X1.WebSocket/Middleware/WebSocketMiddleware.cs` ### 问题描述 - 原实现中 buffer 大小为 4KB(`1024 * 4`),与 WebSocketOptions.MaxMessageSize(如 1MB)不匹配。 - 当接收大消息时,分片次数多,增加缓冲区溢出和性能问题风险。 ### 修复方案 - 将 buffer 大小调整为 `_options.MaxMessageSize`,与最大消息大小保持一致。 - 这样可减少分片次数,提高性能,降低溢出风险。 ### 代码片段 ```csharp // 修复前 var buffer = ArrayPool.Shared.Rent(1024 * 4); // 修复后 var buffer = ArrayPool.Shared.Rent(_options.MaxMessageSize); ``` ### 影响 - 提高了大消息处理的效率和健壮性。 - 降低了分片累积导致的缓冲区溢出风险。 - 代码更符合最佳实践。 ## 2024-12-19 ProcessMessage 检查逻辑优化 ### 修改文件 - `X1.WebSocket/Middleware/WebSocketMiddleware.cs` ### 问题描述 - `ProcessMessage` 方法中存在冗余的大小检查逻辑 - 在已经提前检查 `totalSize` 的情况下,后续的检查理论上不应该失败 - 日志级别使用不当,某些错误情况应该使用 Error 级别 ### 优化方案 #### 1. 优化检查逻辑 - 保留提前的 `totalSize` 检查作为主要验证 - 将后续检查作为安全验证,并调整日志级别为 Error - 添加注释说明检查的层次和目的 #### 2. 改进日志记录 - 将不应该发生的错误情况日志级别调整为 Error - 添加更明确的错误描述,便于问题排查 ### 代码改进 ```csharp // 主要检查:提前验证大小 var totalSize = messageBuffer.Size + receiveResult.Count; if (totalSize > _options.MaxMessageSize) { // 正常的大小超限情况,使用 Warning 级别 _logger.LogWarning("消息大小将超过限制..."); } // 安全验证:理论上不应该失败 if (!messageBuffer.TryWrite(buffer, 0, receiveResult.Count)) { // 不应该发生的情况,使用 Error 级别 _logger.LogError("消息缓冲区写入失败,这不应该发生"); } // 最终验证:双重保护 if (messageData.Length > _options.MaxMessageSize) { // 不应该发生的情况,使用 Error 级别 _logger.LogError("最终消息大小超过限制,这不应该发生"); } ``` ### 影响 - 提高了代码的可读性和维护性 - 更准确的日志级别分类 - 保持了安全检查的完整性 - 便于问题排查和调试 ## 2024-12-19 移除无意义的重试逻辑 ### 修改文件 - `X1.WebSocket/Middleware/WebSocketMiddleware.cs` ### 问题描述 - `ProcessMessage` 方法中的重试逻辑没有实际意义 - 对于 WebSocketException,已经单独 catch 并直接抛出 - 对于其他异常,重试逻辑只是简单地 `throw ex`,没有实际重试操作 - `HandleMessageProcessingFailure` 只会在所有重试都失败后调用,但由于每次都直接抛出异常,实际上不会有任何重试 ### 优化方案 - 移除无意义的重试逻辑 - 简化异常处理流程 - 直接调用 `HandleMessageProcessingFailure` ### 代码改进 ```csharp // 优化前 catch (Exception ex) { _logger.LogError(ex, "消息处理发生未知异常,连接ID:{ConnectionId},错误:{Error}", connectionId, ex.Message); var success = await _errorHandler.HandleWithRetryAsync(async () => { // 这里可以添加重试逻辑,但对于缓冲区问题,重试通常无效 throw ex; // 重新抛出异常 }); if (!success) { await HandleMessageProcessingFailure(webSocket, connectionId, cancellationToken); } } // 优化后 catch (Exception ex) { _logger.LogError(ex, "WebSocket 消息处理发生未知异常,连接ID:{ConnectionId},错误:{Error}", connectionId, ex.Message); await HandleMessageProcessingFailure(webSocket, connectionId, cancellationToken); } ``` ### 影响 - 简化了代码逻辑,提高了可读性 - 减少了不必要的重试开销 - 保持了错误处理的完整性 - 提高了代码执行效率 ## 2024-12-19 WebSocket 缓冲区大小修复 ### 修改文件 - `X1.WebSocket/Models/WebSocketOptions.cs` - `X1.WebSocket/Buffer/WebSocketMessageBuffer.cs` - `X1.WebSocket/Middleware/WebSocketMiddleware.cs` - `X1.WebAPI/Program.cs` ### 问题描述 原始实现中存在严重的设计问题: ```csharp // 问题代码 using var messageBuffer = new WebSocketMessageBuffer(_options.MaxMessageSize); ``` **问题所在:** 1. **`_options.MaxMessageSize` 是服务器端的业务限制**(默认 1MB) 2. **客户端发送的数据大小无法预知**,可能超过服务器限制 3. **缓冲区大小被硬编码为业务限制**,无法处理更大的消息 4. **混淆了"缓冲区容量"和"业务限制"的概念** ### 根本原因分析 #### 1. 概念混淆 - **业务限制**:`MaxMessageSize` 是业务层面的限制,用于防止过大的消息影响系统性能 - **缓冲区容量**:应该为客户端数据提供足够的空间,通常大于业务限制 #### 2. 实际场景问题 ```csharp // 配置中的限制 options.MaxMessageSize = 1024 * 1024; // 1MB // 但客户端可能发送: // - 2MB 的文件 // - 5MB 的图片 // - 10MB 的视频片段 // - 等等... ``` ### 修复方案 #### 1. 改进 WebSocketOptions 配置 ```csharp public class WebSocketOptions { /// /// 最大消息大小(业务限制) /// 超过此大小的消息会被记录警告,但不会导致连接关闭 /// public int MaxMessageSize { get; set; } = 1024 * 1024; // 1MB /// /// 消息缓冲区大小倍数 /// 用于计算实际缓冲区大小:MaxMessageSize * MessageBufferMultiplier /// public int MessageBufferMultiplier { get; set; } = 5; // 5倍 /// /// 计算实际缓冲区大小 /// public int GetActualBufferSize() => MaxMessageSize * MessageBufferMultiplier; } ``` #### 2. 增强 WebSocketMessageBuffer ```csharp public sealed class WebSocketMessageBuffer : IDisposable { // 添加公共属性访问最大缓冲区大小 public int MaxSize => _maxSize; } ``` #### 3. 修改 ProcessWebSocketMessages 方法 ```csharp private async Task ProcessWebSocketMessages(...) { // 使用动态缓冲区大小,为客户端数据提供足够空间 var bufferSize = _options.GetActualBufferSize(); // 5MB using var messageBuffer = new WebSocketMessageBuffer(bufferSize); _logger.LogDebug("创建消息缓冲区,缓冲区大小:{BufferSize}字节,业务限制:{MaxMessageSize}字节", bufferSize, _options.MaxMessageSize); } ``` #### 4. 改进 AccumulateMessageFragment 验证逻辑 ```csharp // 检查累积后的大小是否会超过缓冲区容量 // 这是技术层面的检查,防止缓冲区溢出 var totalSize = messageBuffer.Size + receiveResult.Count; if (totalSize > messageBuffer.MaxSize) { throw new WebSocketException($"消息大小将超过缓冲区容量:{totalSize} > {messageBuffer.MaxSize}字节"); } // 最终验证消息大小是否符合业务限制 // 这是业务层面的检查,超过限制会记录警告但继续处理 if (messageData.Length > _options.MaxMessageSize) { _logger.LogWarning("消息大小超过业务限制,但已完整接收"); // 记录警告但继续处理,确保数据完整性 } ``` #### 5. 更新配置示例 ```csharp builder.Services.AddWebSocketServices(options => { options.MaxConcurrentConnections = 2000; options.MaxMessageSize = 1024 * 1024; // 业务限制:1MB options.MessageBufferMultiplier = 5; // 缓冲区:5MB options.ConnectionTimeout = TimeSpan.FromMinutes(2); options.HeartbeatInterval = TimeSpan.FromSeconds(30); }); ``` ### 技术细节 #### 1. 分层验证策略 - **缓冲区容量检查**:防止技术层面的溢出 - **业务限制检查**:防止业务层面的过大消息 - **分离关注点**:技术问题 vs 业务问题 #### 2. 动态缓冲区大小 - **计算公式**:`MaxMessageSize * MessageBufferMultiplier` - **默认配置**:1MB * 5 = 5MB 缓冲区 - **可配置性**:根据实际需求调整倍数 #### 3. 错误处理策略 - **缓冲区溢出**:抛出异常,关闭连接 - **业务限制超限**:记录警告,继续处理 - **数据完整性**:优先保证数据完整性 ### 性能影响 - **内存使用**:缓冲区大小增加,但避免了数据丢失 - **处理能力**:能够处理更大的客户端数据 - **稳定性**:提高了系统的健壮性 - **可维护性**:清晰的概念分离,便于理解和维护 ### 测试建议 1. 测试不同大小的消息传输 2. 验证缓冲区容量检查的正确性 3. 验证业务限制检查的正确性 4. 测试分片消息的完整重组 5. 监控内存使用情况 ### 总结 这次修复解决了 WebSocket 中间件中缓冲区大小设计的根本问题: - **分离了技术限制和业务限制** - **提供了足够的缓冲区空间处理客户端数据** - **保持了数据完整性** - **提高了系统的健壮性和可维护性** ## 2024-12-19 WebSocketMessageHandlerAdapter 验证逻辑修复 ### 修改文件 - `X1.WebSocket/Handlers/WebSocketMessageHandlerAdapter.cs` ### 问题描述 在 `ValidateMessage` 方法中存在验证逻辑不一致的问题: ```csharp // 问题代码 if (message.Data.Length > _options.MaxMessageSize) { _logger.LogWarning("消息大小超过限制..."); return false; // 拒绝处理消息 } ``` **问题所在:** 1. **与缓冲区大小修复不一致**:我们刚刚修复了缓冲区大小问题,允许处理超过业务限制的消息 2. **数据完整性冲突**:拒绝处理大消息会导致数据丢失 3. **业务逻辑混乱**:业务限制应该是警告而非拒绝处理的理由 ### 根本原因分析 #### 1. 设计理念不一致 - **缓冲区修复**:允许接收大消息,记录警告但继续处理 - **验证逻辑**:拒绝处理大消息,导致数据丢失 - **结果**:修复了接收问题,但处理时仍然拒绝 #### 2. 业务限制的定位错误 - **业务限制**:应该是性能监控和资源管理的参考 - **当前实现**:被当作拒绝处理的硬性条件 - **影响**:无法处理客户端发送的大数据 ### 修复方案 #### 1. 修改验证逻辑 ```csharp // 检查消息大小是否超过缓冲区容量 // 这是技术层面的检查,防止缓冲区溢出 var actualBufferSize = _options.GetActualBufferSize(); if (message.Data.Length > actualBufferSize) { _logger.LogError("消息大小超过缓冲区容量,处理器:{HandlerName},连接ID:{ConnectionId},大小:{Size}字节,缓冲区容量:{BufferSize}字节", Name, message.ConnectionId, message.Data.Length, actualBufferSize); return false; // 超过缓冲区容量时拒绝处理 } // 注意:不检查 MaxMessageSize,因为: // 1. message.Data 已经是完整接收的消息数据 // 2. 在接收阶段已经通过缓冲区容量检查 // 3. 业务限制检查在接收阶段已经完成并记录警告 ``` #### 2. 保持数据完整性 - **移除拒绝逻辑**:不再因为大小超限而拒绝处理 - **保留警告记录**:继续记录业务层面的警告信息 - **确保处理**:保证所有消息都能被正确处理 ### 技术细节 #### 1. 验证策略调整 - **必需验证**:消息为空、连接ID为空、数据为空 - **技术验证**:消息大小超过缓冲区容量(拒绝处理) - **处理策略**:技术验证失败时拒绝,其他情况继续处理 #### 2. 日志级别优化 - **Error 级别**:用于缓冲区容量超限等严重错误 - **Warning 级别**:用于其他验证失败的警告 - **Debug 级别**:用于正常处理的调试信息 #### 3. 业务逻辑一致性 - **接收层**:负责缓冲区容量检查和业务限制检查 - **处理层**:只负责缓冲区容量检查,业务限制已在接收层处理 - **整体策略**:职责分离,避免重复验证 ### 性能影响 - **处理效率**:避免重复验证,提高处理性能 - **职责清晰**:接收层和处理层职责分离 - **稳定性**:保持必要的技术验证,确保系统稳定 - **一致性**:与缓冲区大小修复保持一致 ### 测试建议 1. 测试不同大小消息的处理 2. 验证缓冲区容量检查的正确性 3. 确认消息处理的完整性 4. 检查日志记录的准确性 ### 总结 这次修复确保了 WebSocket 消息处理的职责分离: - **接收层负责完整验证**:缓冲区容量 + 业务限制 - **处理层负责必要验证**:只检查缓冲区容量 - **避免重复验证**:提高性能和代码清晰度 - **保持数据完整性**:确保系统稳定性和一致性 ## 2024-12-19 移除配置管理相关功能 ### 修改概述 根据用户要求,移除了与配置管理相关的所有功能,包括服务、页面组件和路由配置。 ### 删除的文件 - `X1.WebUI/src/services/configService.ts` - 配置管理服务 - `X1.WebUI/src/pages/configs/ConfigsView.tsx` - 配置管理页面组件 - `X1.WebUI/src/pages/configs/ConfigsTable.tsx` - 配置表格组件 ### 修改的文件 #### 1. `X1.WebUI/src/routes/AppRouter.tsx` - 移除了 `ConfigsView` 的 lazy 导入 - 删除了 `/dashboard/instruments/configs` 路由配置 #### 2. `X1.WebUI/src/services/instrumentService.ts` - 移除了对 `configService` 的导出语句 - 保持其他服务的导出不变 #### 3. `X1.WebUI/src/constants/api.ts` - 移除了 `CONFIGS: '/instruments/configs'` API 路径配置 #### 4. `X1.WebUI/src/constants/menuConfig.ts` - 移除了 `configs.view` 和 `configs.manage` 权限类型定义 - 删除了菜单配置中的"配置列表"菜单项 #### 5. `X1.WebUI/src/contexts/AuthContext.tsx` - 移除了默认权限中的 `configs.view` 和 `configs.manage` 权限 ### 影响范围 - **功能影响**:用户无法再访问配置管理功能 - **路由影响**:`/dashboard/instruments/configs` 路径不再可用 - **权限影响**:配置相关的权限检查被移除 - **菜单影响**:仪表管理菜单中不再显示配置列表选项 ### 技术细节 - 所有相关的 TypeScript 类型定义已被移除 - 路由配置已更新,移除了配置相关的路由 - 权限系统已更新,移除了配置相关的权限检查 - 菜单系统已更新,移除了配置相关的菜单项 ### 注意事项 - 如果后端 API 仍然存在配置相关的端点,前端将无法访问 - 建议同时清理后端相关的配置管理功能 - 确保没有其他地方引用已删除的组件或服务 ## 2024-12-19 创建 RAN 配置前端服务 ### 修改概述 参考 `protocolService` 的实现模式,为 `RANConfigurationController` 创建对应的前端服务。 ### 新增文件 - `X1.WebUI/src/services/ranConfigurationService.ts` - RAN 配置管理服务 ### 修改的文件 #### 1. `X1.WebUI/src/constants/api.ts` - 添加了 `RAN_CONFIGURATIONS: '/ranconfigurations'` API 路径配置 #### 2. `X1.WebUI/src/services/ranConfigurationService.ts`(新增) - 实现了完整的 RAN 配置管理服务 - 包含所有 CRUD 操作的接口定义和方法实现 - 参考 `protocolService` 的设计模式和代码结构 ### 功能特性 #### 1. 接口定义 - `RANConfiguration` - RAN 配置实体接口 - `GetRANConfigurationsRequest` - 获取列表请求接口 - `GetRANConfigurationsResponse` - 获取列表响应接口 - `CreateRANConfigurationRequest` - 创建请求接口 - `CreateRANConfigurationResponse` - 创建响应接口 - `UpdateRANConfigurationRequest` - 更新请求接口 - `UpdateRANConfigurationResponse` - 更新响应接口 #### 2. 服务方法 - `getRANConfigurations()` - 获取 RAN 配置列表(支持分页和搜索) - `getRANConfigurationById()` - 根据 ID 获取配置详情 - `createRANConfiguration()` - 创建新的 RAN 配置 - `updateRANConfiguration()` - 更新现有 RAN 配置 - `deleteRANConfiguration()` - 删除 RAN 配置 #### 3. 查询参数支持 - 分页参数:`pageNumber`、`pageSize` - 搜索参数:`searchTerm` - 过滤参数:`isDisabled` ### 技术实现 #### 1. 设计模式 - 采用与 `protocolService` 相同的设计模式 - 使用 TypeScript 接口定义数据结构 - 统一的错误处理和响应格式 #### 2. HTTP 客户端集成 - 使用 `httpClient` 进行 API 调用 - 支持 GET、POST、PUT、DELETE 方法 - 自动处理查询参数构建 #### 3. 类型安全 - 完整的 TypeScript 类型定义 - 与后端 API 响应格式完全匹配 - 提供良好的开发体验和代码提示 ### 使用示例 ```typescript // 获取 RAN 配置列表 const result = await ranConfigurationService.getRANConfigurations({ pageNumber: 1, pageSize: 10, searchTerm: 'LTE' }); // 创建新的 RAN 配置 const createResult = await ranConfigurationService.createRANConfiguration({ name: 'LTE Configuration', configContent: JSON.stringify(configData), description: 'LTE 网络配置' }); ``` ### 影响范围 - **前端服务**:提供了完整的 RAN 配置管理前端服务 - **API 集成**:与后端 `RANConfigurationController` 完全对应 - **类型安全**:提供了完整的 TypeScript 类型定义 - **开发体验**:统一的服务接口,便于前端开发使用 ## 2024-12-19 创建 IMS 配置前端服务 ### 修改概述 参考 `protocolService` 和 `ranConfigurationService` 的实现模式,为 `IMSConfigurationController` 创建对应的前端服务。 ### 新增文件 - `X1.WebUI/src/services/imsConfigurationService.ts` - IMS 配置管理服务 ### 修改的文件 #### 1. `X1.WebUI/src/constants/api.ts` - 添加了 `IMS_CONFIGURATIONS: '/imsconfigurations'` API 路径配置 #### 2. `X1.WebUI/src/services/imsConfigurationService.ts`(新增) - 实现了完整的 IMS 配置管理服务 - 包含所有 CRUD 操作的接口定义和方法实现 - 参考 `protocolService` 和 `ranConfigurationService` 的设计模式和代码结构 ### 功能特性 #### 1. 接口定义 - `IMSConfiguration` - IMS 配置实体接口 - `GetIMSConfigurationsRequest` - 获取列表请求接口 - `GetIMSConfigurationsResponse` - 获取列表响应接口 - `CreateIMSConfigurationRequest` - 创建请求接口 - `CreateIMSConfigurationResponse` - 创建响应接口 - `UpdateIMSConfigurationRequest` - 更新请求接口 - `UpdateIMSConfigurationResponse` - 更新响应接口 #### 2. 服务方法 - `getIMSConfigurations()` - 获取 IMS 配置列表(支持分页和搜索) - `getIMSConfigurationById()` - 根据 ID 获取配置详情 - `createIMSConfiguration()` - 创建新的 IMS 配置 - `updateIMSConfiguration()` - 更新现有 IMS 配置 - `deleteIMSConfiguration()` - 删除 IMS 配置 #### 3. 查询参数支持 - 分页参数:`pageNumber`、`pageSize` - 搜索参数:`searchTerm` - 过滤参数:`isDisabled` ### 技术实现 #### 1. 设计模式 - 采用与 `protocolService` 和 `ranConfigurationService` 相同的设计模式 - 使用 TypeScript 接口定义数据结构 - 统一的错误处理和响应格式 #### 2. HTTP 客户端集成 - 使用 `httpClient` 进行 API 调用 - 支持 GET、POST、PUT、DELETE 方法 - 自动处理查询参数构建 #### 3. 类型安全 - 完整的 TypeScript 类型定义 - 与后端 API 响应格式完全匹配 - 提供良好的开发体验和代码提示 ### 使用示例 ```typescript // 获取 IMS 配置列表 const result = await imsConfigurationService.getIMSConfigurations({ pageNumber: 1, pageSize: 10, searchTerm: 'VoIP' }); // 创建新的 IMS 配置 const createResult = await imsConfigurationService.createIMSConfiguration({ name: 'VoIP Configuration', configContent: JSON.stringify(configData), description: 'VoIP 服务配置' }); ``` ### 影响范围 - **前端服务**:提供了完整的 IMS 配置管理前端服务 - **API 集成**:与后端 `IMSConfigurationController` 完全对应 - **类型安全**:提供了完整的 TypeScript 类型定义 - **开发体验**:统一的服务接口,便于前端开发使用 ## 2024-12-19 创建核心网络配置前端服务 ### 修改概述 参考其他配置服务的实现模式,为 `CoreNetworkConfigsController` 创建对应的前端服务。 ### 新增文件 - `X1.WebUI/src/services/coreNetworkConfigService.ts` - 核心网络配置管理服务 ### 修改的文件 #### 1. `X1.WebUI/src/constants/api.ts` - 添加了 `CORE_NETWORK_CONFIGS: '/corenetworkconfigs'` API 路径配置 #### 2. `X1.WebUI/src/services/coreNetworkConfigService.ts`(新增) - 实现了完整的核心网络配置管理服务 - 包含所有 CRUD 操作的接口定义和方法实现 - 参考其他配置服务的设计模式和代码结构 ### 功能特性 #### 1. 接口定义 - `CoreNetworkConfig` - 核心网络配置实体接口 - `GetCoreNetworkConfigsRequest` - 获取列表请求接口 - `GetCoreNetworkConfigsResponse` - 获取列表响应接口 - `CreateCoreNetworkConfigRequest` - 创建请求接口 - `CreateCoreNetworkConfigResponse` - 创建响应接口 - `UpdateCoreNetworkConfigRequest` - 更新请求接口 - `UpdateCoreNetworkConfigResponse` - 更新响应接口 #### 2. 服务方法 - `getCoreNetworkConfigs()` - 获取核心网络配置列表(支持分页和搜索) - `getCoreNetworkConfigById()` - 根据 ID 获取配置详情 - `createCoreNetworkConfig()` - 创建新的核心网络配置 - `updateCoreNetworkConfig()` - 更新现有核心网络配置 - `deleteCoreNetworkConfig()` - 删除核心网络配置 #### 3. 查询参数支持 - 分页参数:`pageNumber`、`pageSize` - 搜索参数:`searchTerm` - 过滤参数:`isDisabled` ### 技术实现 #### 1. 设计模式 - 采用与其他配置服务相同的设计模式 - 使用 TypeScript 接口定义数据结构 - 统一的错误处理和响应格式 #### 2. HTTP 客户端集成 - 使用 `httpClient` 进行 API 调用 - 支持 GET、POST、PUT、DELETE 方法 - 自动处理查询参数构建 #### 3. 类型安全 - 完整的 TypeScript 类型定义 - 与后端 API 响应格式完全匹配 - 提供良好的开发体验和代码提示 ### 使用示例 ```typescript // 获取核心网络配置列表 const result = await coreNetworkConfigService.getCoreNetworkConfigs({ pageNumber: 1, pageSize: 10, searchTerm: 'EPC' }); // 创建新的核心网络配置 const createResult = await coreNetworkConfigService.createCoreNetworkConfig({ name: 'EPC Configuration', configContent: JSON.stringify(configData), description: '演进分组核心网配置' }); ``` ### 影响范围 - **前端服务**:提供了完整的核心网络配置管理前端服务 - **API 集成**:与后端 `CoreNetworkConfigsController` 完全对应 - **类型安全**:提供了完整的 TypeScript 类型定义 - **开发体验**:统一的服务接口,便于前端开发使用 ## 2024-12-19 创建栈核心网IMS绑定前端服务 ### 修改概述 参考其他配置服务的实现模式,为 `StackCoreIMSBindingsController` 创建对应的前端服务。 ### 新增文件 - `X1.WebUI/src/services/stackCoreIMSBindingService.ts` - 栈核心网IMS绑定管理服务 ### 修改的文件 #### 1. `X1.WebUI/src/constants/api.ts` - 添加了 `STACK_CORE_IMS_BINDINGS: '/stackcoreimsbindings'` API 路径配置 #### 2. `X1.WebUI/src/services/stackCoreIMSBindingService.ts`(新增) - 实现了完整的栈核心网IMS绑定管理服务 - 包含所有 CRUD 操作的接口定义和方法实现 - 参考其他配置服务的设计模式和代码结构 ### 功能特性 #### 1. 接口定义 - `StackCoreIMSBinding` - 栈核心网IMS绑定实体接口 - `GetStackCoreIMSBindingsRequest` - 获取列表请求接口 - `GetStackCoreIMSBindingsResponse` - 获取列表响应接口 - `CreateStackCoreIMSBindingRequest` - 创建请求接口 - `CreateStackCoreIMSBindingResponse` - 创建响应接口 - `UpdateStackCoreIMSBindingRequest` - 更新请求接口 - `UpdateStackCoreIMSBindingResponse` - 更新响应接口 #### 2. 服务方法 - `getStackCoreIMSBindings()` - 获取列表(支持分页、按栈ID/核心网ID/IMS ID过滤) - `getStackCoreIMSBindingById()` - 获取详情 - `createStackCoreIMSBinding()` - 创建绑定关系 - `updateStackCoreIMSBinding()` - 更新绑定关系 - `deleteStackCoreIMSBinding()` - 删除绑定关系 #### 3. 特殊功能 - **复合键支持**:支持栈ID和索引的复合唯一键 - **多维度过滤**:支持按栈ID、核心网配置ID、IMS配置ID进行过滤 - **关系管理**:管理网络栈与核心网/IMS配置之间的绑定关系 ### 技术特点 - **类型安全**:完整的 TypeScript 类型定义 - **错误处理**:统一的错误处理机制 - **查询参数**:支持灵活的查询参数组合 - **RESTful API**:遵循 RESTful API 设计规范 ### 影响范围 - **前端服务**:提供了完整的栈核心网IMS绑定管理前端服务 - **API 集成**:与后端 `StackCoreIMSBindingsController` 完全对应 - **类型安全**:提供了完整的 TypeScript 类型定义 - **开发体验**:统一的服务接口,便于前端开发使用 ## 2024-12-19 创建网络栈配置前端服务 ### 修改概述 参考其他配置服务的实现模式,为 `NetworkStackConfigsController` 创建对应的前端服务。 ### 新增文件 - `X1.WebUI/src/services/networkStackConfigService.ts` - 网络栈配置管理服务 ### 修改的文件 #### 1. `X1.WebUI/src/constants/api.ts` - 添加了 `NETWORK_STACK_CONFIGS: '/networkstackconfigs'` API 路径配置 #### 2. `X1.WebUI/src/services/networkStackConfigService.ts`(新增) - 实现了完整的网络栈配置管理服务 - 包含所有 CRUD 操作的接口定义和方法实现 - 参考其他配置服务的设计模式和代码结构 ### 功能特性 #### 1. 接口定义 - `NetworkStackConfig` - 网络栈配置实体接口 - `GetNetworkStackConfigsRequest` - 获取列表请求接口 - `GetNetworkStackConfigsResponse` - 获取列表响应接口 - `CreateNetworkStackConfigRequest` - 创建请求接口 - `CreateNetworkStackConfigResponse` - 创建响应接口 - `UpdateNetworkStackConfigRequest` - 更新请求接口 - `UpdateNetworkStackConfigResponse` - 更新响应接口 #### 2. 服务方法 - `getNetworkStackConfigs()` - 获取列表(支持分页、搜索、按激活状态和RAN ID过滤) - `getNetworkStackConfigById()` - 获取详情 - `createNetworkStackConfig()` - 创建配置 - `updateNetworkStackConfig()` - 更新配置 - `deleteNetworkStackConfig()` - 删除配置 #### 3. 特殊功能 - **栈ID唯一性**:栈ID作为唯一标识符 - **RAN关联**:支持与RAN配置的关联关系 - **激活状态管理**:支持配置的激活/停用状态管理 - **多维度过滤**:支持按激活状态、RAN ID、搜索关键词进行过滤 ### 技术特点 - **类型安全**:完整的 TypeScript 类型定义 - **错误处理**:统一的错误处理机制 - **查询参数**:支持灵活的查询参数组合 - **RESTful API**:遵循 RESTful API 设计规范 ### 影响范围 - **前端服务**:提供了完整的网络栈配置管理前端服务 - **API 集成**:与后端 `NetworkStackConfigsController` 完全对应 - **类型安全**:提供了完整的 TypeScript 类型定义 - **开发体验**:统一的服务接口,便于前端开发使用 ## 2024-12-19 数据库重新迁移 ### 修改概述 根据用户要求,重新迁移数据库,删除所有现有迁移文件并创建新的初始迁移。 ### 执行步骤 #### 1. 检查现有迁移 - 使用 `dotnet ef migrations list` 命令检查现有迁移 - 发现存在3个迁移文件: - `20250705165102_InitialCreate` - `20250705173130_InitProtocolVersionAndDevice` - `20250705174217_UpdateProtocolVersionAndCellularDevice` #### 2. 回滚数据库 - 使用 `dotnet ef database update 0` 命令将数据库回滚到初始状态 - 成功删除了所有表结构和迁移历史记录 #### 3. 删除迁移文件 - 删除了所有现有的迁移文件: - `20250705174217_UpdateProtocolVersionAndCellularDevice.cs` - `20250705174217_UpdateProtocolVersionAndCellularDevice.Designer.cs` - `20250705173130_InitProtocolVersionAndDevice.cs` - `20250705173130_InitProtocolVersionAndDevice.Designer.cs` - `20250705165102_InitialCreate.cs` - `20250705165102_InitialCreate.Designer.cs` - `AppDbContextModelSnapshot.cs` #### 4. 创建新迁移 - 使用 `dotnet ef migrations add InitialCreate` 命令创建新的初始迁移 - 生成了新的迁移文件: - `20250728081332_InitialCreate.cs` - `20250728081332_InitialCreate.Designer.cs` - `AppDbContextModelSnapshot.cs` #### 5. 应用新迁移 - 使用 `dotnet ef database update` 命令将新迁移应用到数据库 - 成功创建了所有表结构和初始数据 ### 技术细节 #### 1. 迁移文件管理 - 完全清理了旧的迁移历史 - 创建了全新的初始迁移 - 确保数据库结构与当前代码模型完全一致 #### 2. 数据库状态 - 数据库已回滚到初始状态 - 所有表结构已重新创建 - 迁移历史记录已重置 #### 3. 实体模型 - 包含所有当前定义的实体: - 用户和角色管理(AppUser、AppRole、UserRole、Permission、RolePermission) - 设备管理(CellularDevice、ProtocolVersion) - 网络配置(RAN_Configuration、CoreNetworkConfig、IMS_Configuration、NetworkStackConfig、Stack_CoreIMS_Binding) - 日志记录(LoginLog) ### 影响范围 - **数据库结构**:所有表结构已重新创建 - **数据丢失**:所有现有数据已清除 - **迁移历史**:迁移历史记录已重置 - **开发环境**:开发环境数据库已重置为初始状态 ### 注意事项 - 这是一个破坏性操作,所有现有数据已丢失 - 需要重新初始化测试数据 - 生产环境请谨慎执行此操作 - 建议在执行前备份重要数据 ### 后续操作建议 1. 重新初始化测试数据 2. 验证所有实体关系是否正确 3. 测试所有CRUD操作功能 4. 确认数据库约束和索引设置正确 ## 2024-12-19 修复IMS配置字段名称 ### 修复内容 - 将 `ims_ConfigurationId` 改为 `imS_ConfigurationId` 以匹配后端API返回的数据格式 - 修改 `X1.WebUI/src/services/imsConfigurationService.ts` 中的所有接口定义 - 修改 `X1.WebUI/src/pages/ims-configurations/IMSConfigurationsTable.tsx` 中的字段引用 - 修改 `X1.WebUI/src/pages/ims-configurations/IMSConfigurationsView.tsx` 中的字段引用 ### 技术说明 - 确保前端接口定义与后端API返回的JSON数据格式完全一致 - 修复字段名称大小写问题,从 `ims_ConfigurationId` 改为 `imS_ConfigurationId` - 保持与后端数据结构的同步 ## 2024-12-19 修复核心网络配置字段名称 ### 修复内容 - 将 `CoreNetworkConfigId` 改为 `coreNetworkConfigId` 以匹配后端API返回的数据格式 - 修改 `X1.WebUI/src/services/coreNetworkConfigService.ts` 中的所有接口定义 - 修改 `X1.WebUI/src/pages/core-network-configs/CoreNetworkConfigsTable.tsx` 中的字段引用 - 修改 `X1.WebUI/src/pages/core-network-configs/CoreNetworkConfigsView.tsx` 中的字段引用 ### 技术说明 - 确保前端接口定义与后端API返回的JSON数据格式完全一致 - 修复字段名称大小写问题,从 `CoreNetworkConfigId` 改为 `coreNetworkConfigId` - 保持与后端数据结构的同步 ## 2025-07-28 重构网络栈配置表单 ### 重构内容 - **类型安全改进**:修复了表单类型不匹配问题,支持创建和编辑模式的不同类型 - **绑定关系管理**:添加了栈与核心网/IMS绑定关系的完整管理功能 - **表单验证**:添加了基本的表单验证,确保必填字段不为空 - **用户体验优化**:使用卡片布局,改进表单结构和交互体验 - **功能完整性**:支持添加、删除、编辑绑定关系 ### 技术改进 - **类型系统**:使用联合类型 `CreateNetworkStackConfigRequest | UpdateNetworkStackConfigRequest` - **状态管理**:使用 `useEffect` 处理初始数据变化 - **表单验证**:添加网络栈名称的必填验证 - **绑定管理**:实现完整的绑定关系CRUD操作 - **响应式设计**:使用网格布局适配不同屏幕尺寸 ### 新增功能 - **绑定关系管理**: - 添加绑定关系 - 删除绑定关系 - 编辑绑定关系(索引、核心网配置ID、IMS配置ID) - **表单验证**:网络栈名称必填验证 - **用户体验**: - 卡片式布局 - 绑定关系可视化 - 空状态提示 ### 界面改进 - **基本信息卡片**:包含网络栈名称、RAN配置下拉框、描述、激活状态 - **绑定关系卡片**:包含绑定关系列表和添加按钮 - **绑定项**:每个绑定关系显示为独立的卡片项 - **操作按钮**:添加和删除绑定关系的按钮 ### 2025-07-28 改进RAN配置选择 - **下拉框选择**:将RAN ID输入框改为下拉框,从ranConfigurationService获取数据 - **数据加载**:自动加载所有可用的RAN配置(未禁用的) - **用户体验**:提供更直观的RAN配置选择方式 - **数据一致性**:确保选择的RAN配置ID与现有配置一致 - **错误修复**:修复Radix UI Select组件空值错误,使用"none"作为"无"选项的值 - **界面简化**:移除"激活此配置"复选框,默认激活状态 - **服务调用修复**:使用ranConfigurationService.getRANConfigurations()方法替代直接fetch调用 - **搜索功能增强**:为RAN配置下拉框添加搜索功能,支持按名称过滤配置 - **抽屉式界面**:创建NetworkStackConfigDrawer组件,采用抽屉形式替代对话框表单 - **清理冗余文件**:删除不再使用的NetworkStackConfigForm.tsx文件 - **RAN配置显示优化**:下拉框显示格式改为"名称 | 描述"的组合形式,提升用户识别度 - **搜索功能增强**:RAN配置搜索同时匹配名称和描述字段,提供更灵活的搜索体验 - **绑定关系索引优化**:索引自动从1开始递增,删除后自动重新排序,提升用户体验 - **绑定关系配置选择**:核心网配置ID和IMS配置ID改为下拉框,分别从coreNetworkConfigService和imsConfigurationService获取数据,支持搜索功能 - **布局优化**:栈与核心网/IMS绑定关系区域铺满剩余空白,内容支持纵向滚动 - **布局修复**:调整抽屉内容结构,确保绑定关系区域正确占据剩余空间并显示滚动条 - **列表化设计**:将栈与核心网/IMS绑定关系改为列表形式,更紧凑和直观 - **下拉框状态修复**:修复多个绑定项共享下拉框状态的问题,每个绑定项现在有独立的下拉框控制 - **下拉框互斥控制**:确保同时只有一个下拉框打开,点击任何下拉框都会关闭其他所有下拉框 - **自动关闭机制**:当鼠标离开下拉框区域时自动关闭所有下拉框,提升用户体验 - **悬停显示下拉框**:改为鼠标悬停显示下拉框,鼠标离开时自动关闭,提供更直观的交互体验 - **回退到点击交互**:由于悬停交互不够稳定,改回点击交互方式,优化点击外部关闭逻辑 - **滚动条优化**:修复绑定关系区域的滚动条显示问题,确保内容超出时正确显示滚动条 - **强制滚动高度**:为绑定关系区域设置明确的最大高度,确保滚动条正确显示 - **标签右对齐**:将核心网和IMS标签设置为右对齐,提升界面美观度 - **下拉框定位修复**:修复下拉框无法点击的问题,通过正确的定位和层级设置确保下拉框可以正常交互 - **点击外部关闭逻辑优化**:修复点击下拉框内容时意外关闭的问题,确保只有在真正点击外部时才关闭下拉框 - **绑定关系校验**:添加创建时的绑定关系完整性校验,确保每个绑定项都完整填写或完全为空,避免部分填写的情况 - **双重校验逻辑**:区分部分填写和完全空白两种情况,分别提示用户完成填写或移除绑定项 - **内联警告显示**:将校验错误信息显示在取消按钮左边,替代弹窗提示,提供更好的用户体验 - **RAN和绑定关系校验**:确保RAN配置和绑定关系至少选择一个,不能都不填写 ## 2025-07-28 删除未使用的栈核心网IMS绑定服务 ### 删除内容 - **删除文件**:`X1.WebUI/src/services/stackCoreIMSBindingService.ts` - 栈核心网IMS绑定管理服务 - **清理API路径**:从 `X1.WebUI/src/constants/api.ts` 中移除 `STACK_CORE_IMS_BINDINGS` 配置 ### 删除原因 - 该服务没有被任何页面组件引用或使用 - 栈与核心网/IMS绑定关系管理已集成到网络栈配置服务中 - 避免代码冗余和维护负担 ### 技术说明 - 栈与核心网/IMS绑定关系的接口定义已保留在 `networkStackConfigService.ts` 中 - 绑定关系的CRUD操作通过网络栈配置服务进行管理 - 保持了功能的完整性,只是简化了服务架构 ## 2025-07-28 修复网络栈配置服务接口不匹配问题 ### 问题描述 前端 `networkStackConfigService.ts` 中的接口定义与后端API不匹配,导致以下问题: - 字段名称不匹配:前端使用 `stackId`,后端使用 `NetworkStackName` - 搜索参数不匹配:前端使用 `searchTerm`,后端使用 `NetworkStackName` - 响应结构不匹配:前端期望 `items` 字段,后端返回 `NetworkStackConfigs` - 删除响应不匹配:前端期望返回 `boolean`,后端返回 `DeleteNetworkStackConfigResponse` ### 修复内容 #### 1. 修复前端接口定义 - **字段名称统一**: - `stackId` → `networkStackName` - `searchTerm` → `networkStackName` - `items` → `networkStackConfigs` - **新增接口定义**: - 添加 `StackCoreIMSBinding` 接口 - 添加 `CreateStackCoreIMSBindingItem` 接口 - 添加 `UpdateStackCoreIMSBindingItem` 接口 - 添加 `DeleteNetworkStackConfigResponse` 接口 - **更新请求/响应接口**: - 所有接口中的 `stackId` 字段改为 `networkStackName` - 添加 `stackCoreIMSBindings` 字段支持 - 删除操作返回类型改为 `DeleteNetworkStackConfigResponse` #### 2. 修复页面组件 - **NetworkStackConfigsView.tsx**: - 更新搜索字段:`searchTerm` → `networkStackName` - 更新表格列配置:`stackId` → `networkStackName` - 修复所有字段引用和状态管理 - 更新表单提交处理逻辑 - **NetworkStackConfigForm.tsx**: - 更新表单字段:`stackId` → `networkStackName` - 更新标签和占位符文本 - 修复表单状态管理 - **NetworkStackConfigsTable.tsx**: - 更新表格渲染逻辑:`stackId` → `networkStackName` - 修复字段映射关系 #### 3. 技术细节 - **接口一致性**:确保前端接口定义与后端API完全匹配 - **类型安全**:提供完整的TypeScript类型定义 - **功能完整性**:支持栈与核心网/IMS绑定关系管理 - **错误处理**:保持统一的错误处理机制 ### 影响范围 - **前端服务**:网络栈配置服务现在与后端API完全匹配 - **用户界面**:搜索、表格、表单功能正常工作 - **数据完整性**:所有CRUD操作都能正确处理数据 - **开发体验**:提供完整的类型安全和代码提示 ### 测试建议 1. 测试网络栈配置的创建、编辑、删除功能 2. 验证搜索和过滤功能 3. 检查表格显示和分页功能 4. 确认表单验证和提交功能 5. 测试栈与核心网/IMS绑定关系管理 ## 2025-01-29 - 代码提交和.gitignore更新 ### 修改内容 1. **代码提交和推送** - 提交了网络栈配置管理功能的重构代码 - 推送代码到远程仓库 `feature/x1-web-request` 分支 - 同步远程分支更新 2. **更新.gitignore文件** - 添加 `X1.WebAPI/logs/` 目录到忽略列表 - 添加 `*.log` 文件模式到忽略列表 - 从版本控制中移除已跟踪的日志文件 - 提交并推送.gitignore更新 ### 技术细节 - 使用 `git add .` 添加所有修改文件 - 使用 `git commit -m` 提交代码,包含详细的提交信息 - 使用 `git push origin feature/x1-web-request` 推送到远程分支 - 使用 `git rm --cached` 从版本控制中移除日志文件 - 更新.gitignore文件以忽略日志文件 ### 提交信息 ``` feat: 重构网络栈配置管理功能 - 修复networkStackConfigService.ts接口不匹配问题 - 删除未使用的stackCoreIMSBindingService.ts - 重构NetworkStackConfigForm为NetworkStackConfigDrawer - 实现RAN配置下拉框,支持搜索功能 - 移除激活配置复选框,默认激活 - 修复loadRANConfigurations使用正确服务 - 实现核心网和IMS配置下拉框 - 优化绑定关系布局和滚动条显示 - 添加标签右对齐样式 - 修复下拉框定位和点击交互问题 - 实现下拉框互斥控制和自动关闭 - 添加完整的表单校验逻辑 - 实现内联错误提示替代弹窗 chore: 更新.gitignore忽略日志文件 - 添加X1.WebAPI/logs/目录到忽略列表 - 添加*.log文件模式到忽略列表 - 从版本控制中移除已跟踪的日志文件 ## 2024-12-19 添加设备编码字段 ### 修改文件 - `X1.Domain/Entities/Device/CellularDevice.cs` - 在蜂窝设备实体中添加设备编码字段 ### 修改内容 #### 1. 添加设备编码属性 - **字段名称**:`DeviceCode` - **字段类型**:`string` - **约束条件**: - `[Required]` - 必填字段 - `[MaxLength(50)]` - 最大长度50个字符 - **访问修饰符**:`private set` - 只读属性,通过方法修改 #### 2. 更新创建方法 - **方法签名**:`Create` 方法添加 `deviceCode` 参数 - **参数位置**:在 `serialNumber` 参数之后,`description` 参数之前 - **参数验证**:通过 `[Required]` 和 `[MaxLength(50)]` 进行验证 - **属性赋值**:在创建设备时设置 `DeviceCode` 属性 #### 3. 更新更新方法 - **方法签名**:`Update` 方法添加 `deviceCode` 参数 - **参数位置**:在 `serialNumber` 参数之后,`description` 参数之前 - **属性赋值**:在更新设备时设置 `DeviceCode` 属性 ### 技术特性 - **数据完整性**:设备编码作为必填字段,确保每个设备都有唯一标识 - **长度限制**:最大50个字符,适合各种编码格式 - **封装性**:使用私有setter,确保数据只能通过方法修改 - **一致性**:与现有字段(如SerialNumber)保持相同的设计模式 ### 业务价值 - **设备标识**:提供额外的设备标识方式,便于设备管理 - **系统集成**:支持与其他系统的设备编码对接 - **数据追溯**:增强设备数据的可追溯性 - **管理便利**:提供更灵活的设备识别和管理方式 ### 影响范围 - **实体模型**:CellularDevice实体增加了DeviceCode字段 - **创建操作**:所有创建设备的操作都需要提供设备编码 - **更新操作**:所有更新设备信息的操作都需要提供设备编码 - **数据验证**:确保设备编码的完整性和有效性 ### 后续工作建议 1. **数据库迁移**:需要创建数据库迁移来添加DeviceCode字段 2. **API更新**:更新相关的API接口以支持设备编码字段 3. **前端界面**:更新前端界面以显示和编辑设备编码 4. **数据验证**:在应用层添加设备编码的业务验证逻辑 5. **测试用例**:为设备编码字段添加相应的测试用例 ## 2024-12-19 修复设备命令处理器中的deviceCode字段 ### 修改文件 - `X1.Application/Features/Devices/Commands/CreateDevice/CreateDeviceCommand.cs` - 添加设备编码字段 - `X1.Application/Features/Devices/Commands/CreateDevice/CreateDeviceResponse.cs` - 添加设备编码字段 - `X1.Application/Features/Devices/Commands/UpdateDevice/UpdateDeviceCommand.cs` - 添加设备编码字段 - `X1.Application/Features/Devices/Commands/UpdateDevice/UpdateDeviceResponse.cs` - 添加设备编码字段 - `X1.Application/Features/Devices/Commands/CreateDevice/CreateDeviceCommandHandler.cs` - 修复设备编码字段处理 - `X1.Application/Features/Devices/Commands/UpdateDevice/UpdateDeviceCommandHandler.cs` - 修复设备编码字段处理 ### 修改内容 #### 1. 命令类修复 - **CreateDeviceCommand**: - 添加 `DeviceCode` 属性 - 添加 `[Required]` 和 `[MaxLength(50)]` 验证特性 - 位置:在 `SerialNumber` 字段之后,`Description` 字段之前 - **UpdateDeviceCommand**: - 添加 `DeviceCode` 属性 - 添加 `[Required]` 和 `[MaxLength(50)]` 验证特性 - 位置:在 `SerialNumber` 字段之后,`Description` 字段之前 #### 2. 响应类修复 - **CreateDeviceResponse**: - 添加 `DeviceCode` 属性 - 位置:在 `SerialNumber` 字段之后,`Description` 字段之前 - **UpdateDeviceResponse**: - 添加 `DeviceCode` 属性 - 位置:在 `SerialNumber` 字段之后,`Description` 字段之前 #### 3. 命令处理器修复 - **CreateDeviceCommandHandler**: - 在 `CellularDevice.Create()` 方法调用中添加 `deviceCode: request.DeviceCode` 参数 - 在响应构建中添加 `DeviceCode = device.DeviceCode` 字段 - **UpdateDeviceCommandHandler**: - 在 `existingDevice.Update()` 方法调用中添加 `deviceCode: request.DeviceCode` 参数 - 在响应构建中添加 `DeviceCode = existingDevice.DeviceCode` 字段 ### 技术特性 - **数据验证**:设备编码字段为必填,最大长度50个字符 - **参数传递**:正确传递设备编码参数到实体创建和更新方法 - **响应映射**:在响应中包含设备编码字段 - **一致性**:与实体模型中的DeviceCode字段保持一致 ### 业务价值 - **完整性**:确保设备编码在整个创建和更新流程中正确传递 - **验证**:在应用层提供设备编码的验证 - **API一致性**:确保API接口与实体模型保持一致 - **用户体验**:提供完整的设备编码管理功能 ### 影响范围 - **创建操作**:设备创建API现在支持设备编码字段 - **更新操作**:设备更新API现在支持设备编码字段 - **数据验证**:应用层验证确保设备编码的完整性 - **响应数据**:API响应包含设备编码信息 ### 测试建议 1. 测试设备创建API,验证设备编码字段的处理 2. 测试设备更新API,验证设备编码字段的处理 3. 验证设备编码字段的验证规则 4. 确认API响应包含正确的设备编码信息 5. 测试设备编码字段的边界值(空值、最大长度等) ## 2025-07-28 - 自动生成设备编号,移除用户手动输入 ### 修改原因 根据用户需求,设备编号应该自动生成,格式为 `DEV-001-SN`(其中001是序号,SN是序列号),序号从001开始根据数据库中的设备数量自动递增,不需要用户手动输入。 ### 修改文件 - `X1.Application/Features/Devices/Commands/CreateDevice/CreateDeviceCommand.cs` - 移除DeviceCode字段 - `X1.Application/Features/Devices/Commands/CreateDevice/CreateDeviceCommandHandler.cs` - 添加自动生成设备编号逻辑 - `X1.Domain/Repositories/Device/ICellularDeviceRepository.cs` - 添加GetDeviceCountAsync方法 - `X1.Infrastructure/Repositories/Device/CellularDeviceRepository.cs` - 实现GetDeviceCountAsync方法 - `X1.WebUI/src/services/instrumentService.ts` - 移除DeviceCode字段 - `X1.WebUI/src/pages/instruments/DeviceForm.tsx` - 移除设备编码输入字段 - `X1.WebUI/src/pages/instruments/DevicesView.tsx` - 更新类型检查逻辑 ### 修改内容 #### 1. 后端命令类修改 - **CreateDeviceCommand**: - 删除 `DeviceCode` 属性及其验证特性 - 用户不再需要手动输入设备编号 #### 2. 后端命令处理器修改 - **CreateDeviceCommandHandler**: - 添加 `GenerateDeviceCodeAsync` 方法,自动生成设备编号 - 设备编号格式:`DEV-{序号}-{序列号}`,序号为3位数字(001, 002, ...) - 序号根据数据库中的设备总数自动递增 - 在获取序列号成功后,移除并重新添加endpointManager - 修改 `CreateAndSaveDeviceAsync` 方法签名,添加deviceCode参数 #### 3. 仓储接口扩展 - **ICellularDeviceRepository**: - 添加 `GetDeviceCountAsync` 方法 - 用于获取当前设备总数,计算下一个序号 #### 4. 仓储实现 - **CellularDeviceRepository**: - 实现 `GetDeviceCountAsync` 方法 - 使用 `QueryRepository.CountAsync` 获取设备总数 #### 5. 前端接口修改 - **CreateDeviceRequest**: - 删除 `deviceCode` 字段 - 用户不再需要提供设备编号 #### 6. 前端表单修改 - **DeviceForm**: - 移除设备编码输入字段 - 更新表单状态管理,移除deviceCode相关代码 #### 7. 前端页面修改 - **DevicesView**: - 更新类型检查逻辑,移除对deviceCode的检查 - 修复语法错误 ### 技术特性 - **自动编号生成**:根据设备总数自动生成序号 - **格式规范**:设备编号格式为 `DEV-001-SN` - **序号递增**:序号从001开始,每次递增1 - **endpointManager管理**:在获取序列号成功后重新管理endpoint - **用户友好**:用户无需手动输入设备编号 ### 业务价值 - **简化操作**:用户无需手动输入设备编号 - **避免重复**:自动生成的编号确保唯一性 - **规范管理**:统一的编号格式便于管理 - **减少错误**:避免用户输入错误 ### 影响范围 - **创建操作**:设备创建时自动生成设备编号 - **前端界面**:移除设备编码输入字段 - **API接口**:更新请求模型,移除deviceCode字段 - **数据库操作**:添加获取设备总数的方法 ### 设备编号生成逻辑 1. **获取设备总数**:调用 `GetDeviceCountAsync` 获取当前设备数量 2. **计算序号**:设备总数 + 1 3. **格式化序号**:使用 `ToString("D3")` 格式化为3位数字 4. **组装编号**:`DEV-{序号}-{序列号}` ### 注意事项 - 设备编号格式:`DEV-000-SN`、`DEV-001-SN` 等 - 序号从000开始,最大到999 - 如果设备数量超过999,需要扩展序号位数 ## 2025-07-28 - 删除CreateDeviceCommand中的SerialNumber字段,改为通过IP地址自动获取 ### 修改原因 根据用户需求,设备序列号不应该由用户手动填写,而应该通过设备的IP地址自动获取。 ### 修改文件 - `X1.Application/Features/Devices/Commands/CreateDevice/CreateDeviceCommand.cs` - 删除SerialNumber字段 - `X1.Application/Features/Devices/Commands/CreateDevice/CreateDeviceCommandHandler.cs` - 添加通过IP获取序列号的逻辑 - `X1.Application/Features/Devices/Commands/UpdateDevice/UpdateDeviceCommand.cs` - 删除SerialNumber字段 - `X1.Application/Features/Devices/Commands/UpdateDevice/UpdateDeviceCommandHandler.cs` - 移除序列号验证和更新逻辑 - `X1.DynamicClientCore/Extensions/ServiceCollectionExtensions.cs` - 注册IBaseInstrumentClient服务 - `X1.WebUI/src/services/instrumentService.ts` - 更新前端接口定义 - `X1.WebUI/src/pages/instruments/DeviceForm.tsx` - 更新前端表单 - `X1.WebUI/src/pages/instruments/DevicesView.tsx` - 更新前端页面 ### 修改内容 #### 1. 后端命令类修改 - **CreateDeviceCommand**: - 删除 `SerialNumber` 属性及其验证特性 - 保留 `DeviceCode` 属性用于设备标识 - **UpdateDeviceCommand**: - 删除 `SerialNumber` 属性及其验证特性 - 保留 `DeviceCode` 属性用于设备标识 #### 2. 后端命令处理器修改 - **CreateDeviceCommandHandler**: - 添加 `IBaseInstrumentClient` 依赖注入 - 在创建设备前通过IP地址和端口获取设备序列号 - 使用 `ServiceEndpoint` 配置设备连接信息 - 调用 `GetDeviceSerialNumberAsync` 方法获取序列号 - 添加序列号获取失败的错误处理 - 更新日志记录,移除对SerialNumber的引用 - **UpdateDeviceCommandHandler**: - 移除序列号验证逻辑 - 在更新设备时保持原有序列号不变 - 更新日志记录,移除对SerialNumber的引用 #### 3. 前端接口修改 - **CreateDeviceRequest**: - 删除 `serialNumber` 字段 - 保留 `deviceCode` 字段 - **UpdateDeviceRequest**: - 删除 `serialNumber` 字段 - 添加 `deviceCode` 字段 - **Device**: - 添加 `deviceCode` 字段 - **CreateDeviceResponse**: - 添加 `deviceCode` 字段 - **UpdateDeviceResponse**: - 添加 `deviceCode` 字段 #### 4. 前端表单修改 - **DeviceForm**: - 删除序列号输入字段 - 添加设备编码输入字段 - 更新表单状态管理 #### 5. 服务注册修改 - **ServiceCollectionExtensions**: - 注册 `IBaseInstrumentClient` 服务 - 注册 `IInstrumentHttpClient` 服务 - 使用 `InstrumentProtocolClient` 作为实现类 #### 6. 前端页面修改 - **DevicesView**: - 更新编辑设备时的初始数据传递 - 移除对序列号字段的引用 ### 技术特性 - **自动序列号获取**:通过设备的IP地址和端口自动获取序列号 - **错误处理**:当无法获取序列号时提供友好的错误信息 - **服务集成**:集成 `IBaseInstrumentClient` 服务进行设备通信 - **类型安全**:更新所有相关的TypeScript接口定义 ### 业务价值 - **用户体验**:用户无需手动输入序列号,减少输入错误 - **数据准确性**:序列号直接从设备获取,确保数据准确性 - **自动化**:简化设备创建流程,提高效率 - **一致性**:确保序列号与设备实际状态一致 ### 影响范围 - **创建操作**:设备创建时自动获取序列号 - **更新操作**:设备更新时保持序列号不变 - **前端界面**:移除序列号输入字段,添加设备编码字段 - **API接口**:更新请求和响应模型 - **错误处理**:添加序列号获取失败的处理逻辑 - **服务注册**:注册设备通信相关服务 ### 依赖服务 - `IBaseInstrumentClient`:用于与设备通信获取序列号 - `ServiceEndpoint`:配置设备连接信息 - `GetDeviceSerialNumberAsync`:获取设备序列号的方法 ### 注意事项 - 设备必须能够通过HTTP协议访问 - 设备需要提供 `/System/serial-number` 接口 - 网络连接必须正常才能获取序列号 - 如果获取失败,会返回相应的错误信息 ## 2025-01-29 网络栈配置仓储方法重构 **修改时间**: 2025年1月29日 **修改文件**: - `X1.Domain/Repositories/NetworkProfile/INetworkStackConfigRepository.cs` - `X1.Infrastructure/Repositories/NetworkProfile/NetworkStackConfigRepository.cs` **修改内容**: 1. 重命名方法 `GetNetworkStackConfigByNetworkStackCodeWithBindingNamesAsync` ## 2025-01-29 修改GetNetworkStackConfigByIdWithBindingNamesAsync方法返回NetworkStackConfigBasicDto ### 修改原因 根据用户需求,将 `GetNetworkStackConfigByIdWithBindingNamesAsync` 方法的返回类型从 `NetworkStackConfigWithBindingNamesDto` 改为 `NetworkStackConfigBasicDto`,只返回指定的核心字段。 ### 修改文件 - `X1.Domain/Repositories/NetworkProfile/INetworkStackConfigRepository.cs` - 更新接口方法签名 - `X1.Infrastructure/Repositories/NetworkProfile/NetworkStackConfigRepository.cs` - 更新实现方法 ### 修改内容 #### 1. 接口更新 - **INetworkStackConfigRepository**: - 将 `GetNetworkStackConfigByIdWithBindingNamesAsync` 方法的返回类型从 `IList` 改为 `IList` #### 2. 实现更新 - **NetworkStackConfigRepository**: - 更新方法签名以匹配接口 - 修改SQL查询,只选择 `NetworkStackConfigBasicDto` 需要的字段: - `nsc."NetworkStackName"` - `nsc."NetworkStackCode"` - `nsc."RanId"` - `cnc."Id"` (别名: `CoreNetworkConfigId`) - `ims."Id"` (别名: `IMSConfigId`) - `ran."ConfigContent"` (别名: `RanConfigContent`) - `cnc."ConfigContent"` (别名: `CoreNetworkConfigContent`) - `ims."ConfigContent"` (别名: `IMSConfigContent`) - 更新查询结果映射,使用 `NetworkStackConfigBasicDto` 类型 ### 技术特性 - **字段精简**:只返回用户指定的核心字段 - **性能优化**:减少数据传输量,提高查询性能 - **类型安全**:确保返回数据与DTO定义完全匹配 - **向后兼容**:方法签名保持兼容,只改变返回类型 ### 业务价值 - **数据精确性**:只返回业务需要的核心字段 - **网络效率**:减少不必要的数据传输 - **接口清晰**:明确指定返回的数据结构 - **维护便利**:简化数据结构,便于维护 ### 影响范围 - **API响应**:返回的数据结构更加精简 - **查询性能**:减少字段选择,提高查询效率 - **客户端处理**:客户端需要更新以处理新的数据结构 - **数据完整性**:确保返回的数据包含所有必要的核心信息 → `GetNetworkStackConfigsByCodesAsync` 2. 修复 `GetNetworkStackConfigsByCodesAsync` 方法,添加 `ran.ConfigContent`、`cnc.ConfigContent`、`ims.ConfigContent` 字段 3. 扩展 `NetworkStackConfigWithBindingNamesDto` DTO,添加配置内容字段 4. 同步修复相关方法:`GetNetworkStackConfigByIdWithBindingNamesAsync` 和 `SearchNetworkStackConfigsWithBindingNamesAsync` ### 技术细节 - **DTO扩展**:添加 `RanConfigContent`、`CoreNetworkConfigContent`、`IMSConfigContent` 字段 - **SQL查询优化**:在LEFT JOIN查询中添加配置内容字段的选择 - **方法同步**:确保所有相关方法都返回完整的配置内容信息 - **数据完整性**:确保网络栈配置查询结果包含所有相关的配置内容 ## 2025-01-29 创建NetworkStackConfigBasicDto **修改时间**: 2025年1月29日 **修改文件**: - `X1.Domain/Models/NetworkStackConfigBasicDto.cs` (新增) **修改内容**: 1. 创建新的DTO类 `NetworkStackConfigBasicDto`,包含指定的字段子集: - `NetworkStackName` - 网络栈名称 - `NetworkStackCode` - 网络栈代码 - `RanId` - RAN配置ID - `CoreNetworkConfigId` - 核心网配置ID - `IMSConfigId` - IMS配置ID - `RanConfigContent` - RAN配置内容 - `CoreNetworkConfigContent` - 核心网配置内容 - `IMSConfigContent` - IMS配置内容 ### 技术特性 - **字段精简**:只包含用户指定的核心字段 - **配置内容**:包含所有相关的配置内容字段 - **类型安全**:完整的C#属性定义和XML文档注释 - **命名规范**:遵循C#命名规范和项目约定 为 `GetNetworkStackConfigsByCodesAsync` 2. 修改参数类型从 `string NetworkStackCode` 改为 `string[] networkStackCodes` 3. 更新方法实现以支持多个网络栈编码的查询 4. 添加空数组检查逻辑 5. 使用动态构建的IN查询替代单一条件查询 6. 优化排序逻辑,按网络栈编码和绑定索引排序 **修改原因**: - 原方法名称过长,不符合命名规范 - 支持批量查询多个网络栈编码,提高查询效率 - 改善代码可读性和维护性 **影响范围**: - 需要更新所有调用此方法的代码 - 接口签名变更,需要重新编译相关项目 ## 2025-07-28 - 修复endpointManager重新添加时机bug ### 修改原因 在获取设备序列号成功后,原来的代码立即重新添加了服务端点,但此时设备数据还没有保存到数据库。这可能导致服务端点与数据库中的设备数据不一致的问题。 ### 修改文件 - `X1.Application/Features/Devices/Commands/CreateDevice/CreateDeviceCommandHandler.cs` - 修复endpointManager重新添加时机 ### 修改内容 #### 1. GetDeviceSerialNumberAsync方法修改 - **移除立即重新添加逻辑**: - 在获取序列号成功后,只移除临时服务端点 - 不再立即重新添加服务端点 - 确保临时端点被正确清理 #### 2. CreateAndSaveDeviceAsync方法修改 - **添加延迟重新添加逻辑**: - 在设备成功保存到数据库后,重新添加服务端点 - 使用设备编号(deviceCode)作为端点名称 - 确保服务端点与数据库中的设备数据一致 ### 技术特性 - **正确的执行顺序**:先保存数据,再添加服务端点 - **数据一致性**:确保服务端点与设备数据的一致性 - **错误处理**:如果设备保存失败,不会添加服务端点 - **日志记录**:详细记录服务端点的添加过程 ### 业务价值 - **数据完整性**:确保服务端点与设备数据的一致性 - **系统稳定性**:避免因数据不一致导致的问题 - **可维护性**:清晰的执行流程便于调试和维护 ### 影响范围 - **创建流程**:修改了设备创建时的endpointManager管理逻辑 - **数据一致性**:确保服务端点与设备数据同步 - **错误处理**:改进了异常情况下的资源清理 ### 执行流程 1. **获取序列号**:使用临时服务端点获取设备序列号 2. **清理临时端点**:移除临时服务端点 3. **保存设备数据**:将设备信息保存到数据库 4. **添加正式端点**:使用设备编号作为名称添加正式服务端点 ### 注意事项 - 临时服务端点使用时间戳生成名称,避免冲突 - 正式服务端点使用设备编号作为名称,便于管理 - 只有在设备数据保存成功后才会添加正式服务端点 ## 2025-07-28 - 修复设备编号生成逻辑,从000开始 ### 修改原因 根据用户需求,设备编号应该从000开始,类似001、002的格式,而不是从1开始。 ### 修改文件 - `X1.Application/Features/Devices/Commands/CreateDevice/CreateDeviceCommandHandler.cs` - 修改CalculateRequiredDigits方法和GenerateDeviceCodeAsync方法 ### 修改内容 #### 1. CalculateRequiredDigits方法修改 - **最小位数设置**:将最小位数从1改为3,确保从000开始 - **逻辑优化**:使用 `Math.Max(calculatedDigits, 3)` 确保至少3位数 - **注释更新**:更新注释说明从000开始,至少3位数 #### 2. GenerateDeviceCodeAsync方法修改 - **注释更新**:更新注释说明从000开始,确保至少3位数 - **格式说明**:更新设备编号格式说明为 DEV-000-SN, DEV-001-SN, DEV-002-SN 等 ### 技术特性 - **从000开始**:设备编号从DEV-000-SN开始,而不是DEV-1-SN - **至少3位数**:确保序号至少有3位数字,格式统一 - **动态扩展**:当设备数量超过999时,自动扩展为4位数(1000、1001等) - **格式一致**:所有设备编号都遵循统一的格式规范 ### 业务价值 - **格式规范**:统一的设备编号格式,便于管理和识别 - **用户友好**:从000开始的编号更符合用户习惯 - **可扩展性**:支持大量设备的编号需求 - **一致性**:所有设备编号都遵循相同的格式规则 ### 设备编号格式示例 - 第1个设备:DEV-000-SN - 第2个设备:DEV-001-SN - 第3个设备:DEV-002-SN - ... - 第1000个设备:DEV-1000-SN - 第1001个设备:DEV-1001-SN ### 影响范围 - **设备创建**:新创建的设备将使用从000开始的编号格式 - **编号生成**:设备编号生成逻辑已更新 - **格式统一**:所有设备编号都遵循新的格式规范 ### 注意事项 - 现有设备的编号不会自动更新 - 新创建的设备将使用新的编号格式 - 编号格式支持扩展到更多位数(当设备数量超过999时) ## 2025-07-28 - 优化临时服务端点名称生成,使用GUID替代时间戳 ### 修改原因 使用时间戳生成临时服务端点名称可能存在冲突风险,特别是在高并发场景下。使用GUID可以确保端点名称的唯一性。 ### 修改文件 - `X1.Application/Features/Devices/Commands/CreateDevice/CreateDeviceCommandHandler.cs` - 修改CreateServiceEndpoint方法 ### 修改内容 #### 1. CreateServiceEndpoint方法修改 - **名称生成方式**:从时间戳改为GUID - **格式变更**:`DEV-{DateTime.Now:yyyyMMddHHmmss}` → `DEV-{Guid.NewGuid():N}` - **唯一性保证**:GUID确保每个临时端点名称都是唯一的 ### 技术特性 - **唯一性保证**:GUID提供全局唯一性,避免名称冲突 - **并发安全**:在高并发场景下不会出现重复名称 - **格式简洁**:使用 `:N` 格式去除GUID中的连字符,生成32位字符串 - **性能优化**:GUID生成比时间戳更高效 ### 业务价值 - **系统稳定性**:避免因端点名称冲突导致的问题 - **并发支持**:支持多用户同时创建设备 - **可靠性提升**:确保每个临时端点都能正确创建和管理 ### 临时端点名称示例 - 修改前:`DEV-20250728143022` - 修改后:`DEV-a1b2c3d4e5f678901234567890123456` ### 影响范围 - **临时端点创建**:临时服务端点名称生成方式已更新 - **并发处理**:支持更好的并发创建设备场景 - **系统稳定性**:提高了端点管理的可靠性 ## 2025-07-28 - 移除设备表单中的启用和启动复选框 ### 修改原因 根据用户需求,设备表单中不需要显示"启用设备"和"启动设备"这两个复选框,这些状态应该通过其他方式管理。 ### 修改文件 - `X1.WebUI/src/pages/instruments/DeviceForm.tsx` - 移除启用和启动复选框 ### 修改内容 #### 1. 表单状态管理修改 - **初始状态设置**: - `isEnabled` 默认设置为 `true` - `isRunning` 默认设置为 `false` - 这些值不再从 `initialData` 中获取 #### 2. 表单界面修改 - **移除复选框组件**: - 删除"启用设备"复选框及其相关代码 - 删除"启动设备"复选框及其相关代码 - 保留其他表单字段不变 #### 3. 表单提交逻辑 - **创建模式**:提交所有字段,包括默认的启用和启动状态 - **编辑模式**:只提交可修改的字段,启用和启动状态保持默认值 ### 技术特性 - **默认状态**:设备创建时默认启用,默认不启动 - **界面简化**:移除不必要的复选框,简化用户界面 - **状态管理**:启用和启动状态通过默认值管理 - **功能保持**:其他表单功能保持不变 ### 业务价值 - **用户体验**:简化设备创建和编辑界面 - **操作简化**:减少用户需要选择的选项 - **界面清晰**:专注于设备的基本信息配置 - **一致性**:所有设备使用统一的默认状态 ### 影响范围 - **设备创建**:新设备默认启用,默认不启动 - **设备编辑**:编辑时不再显示启用和启动选项 - **界面布局**:表单界面更加简洁 - **状态管理**:启用和启动状态通过系统默认值管理 ### 注意事项 - 设备创建后默认启用状态为true - 设备创建后默认启动状态为false - 用户无法通过表单界面修改这些状态 - 如果需要修改这些状态,需要通过其他方式(如设备管理列表) ### 技术特性 - **简化设计**:移除冗余字段,减少数据重复 - **统一状态管理**:使用单一的 `RuntimeStatus` 枚举管理所有运行时状态 - **启用状态管理**:独立的 `IsEnabled` 字段管理设备启用状态 - **时间推断**:通过 `UpdatedAt` 字段推断设备最后活动时间 ### 业务价值 - **概念清晰**:消除 `IsRunning` 和 `ConnectionStatus` 的概念重叠 - **状态统一**:使用统一的 `DeviceRuntimeStatus` 枚举管理所有状态 - **设计简化**:减少字段数量,降低复杂度 - **维护便利**:避免状态不同步问题,提高系统稳定性 ### 状态管理逻辑 - **设备在线**:`RuntimeStatus = Running`,`UpdatedAt` 反映最后活动时间 - **设备离线**:`RuntimeStatus = Stopped` 或 `Error` - **设备禁用**:`IsEnabled = false` - **心跳检测**:通过 `UpdatedAt` 和 `RuntimeStatus` 判断设备状态 ### 影响范围 - **数据库结构**:移除 `LastHeartbeat` 字段,更新相关索引 - **实体模型**:简化 `CellularDeviceRuntime` 实体结构 - **状态管理**:统一使用 `DeviceRuntimeStatus` 枚举 - **查询逻辑**:更新所有相关的查询方法 - **业务逻辑**:简化状态管理逻辑,提高系统稳定性 ### 后续工作建议 1. **数据库迁移**:创建迁移移除 `LastHeartbeat` 字段 2. **API更新**:更新相关的API接口以支持新的状态管理 3. **前端更新**:更新前端界面以使用新的状态字段 4. **测试验证**:全面测试新的状态管理功能 5. **文档更新**:更新相关文档说明新的状态管理逻辑 ## 2025-01-29 连表获取CellularDeviceRuntime的RuntimeStatus字段 ### 修改原因 根据用户需求,在获取设备列表时需要同时获取设备的运行时状态信息,通过连表查询 `CellularDeviceRuntime` 表获取 `RuntimeStatus` 字段。 ### 修改文件 #### 1. 仓储接口修改 - `X1.Domain/Repositories/Device/ICellularDeviceRepository.cs` - 添加 `SearchDevicesWithRuntimeAsync` 方法 #### 2. 仓储实现修改 - `X1.Infrastructure/Repositories/Device/CellularDeviceRepository.cs` - 实现 `SearchDevicesWithRuntimeAsync` 方法,使用左连接查询 #### 3. 响应模型修改 - `X1.Application/Features/Devices/Queries/GetDeviceById/GetDeviceByIdResponse.cs` - 添加 `RuntimeStatus` 字段 #### 4. 查询处理器修改 - `X1.Application/Features/Devices/Queries/GetDevices/GetDevicesQueryHandler.cs` - 使用新的连表查询方法 ### 修改内容 #### 1. 新增仓储方法 - **SearchDevicesWithRuntimeAsync**: - 支持分页查询设备列表 - 使用 `Include(d => d.Runtime)` 进行左连接查询 - 返回设备信息和对应的运行时状态信息 - 支持关键词搜索功能 #### 2. 响应模型扩展 - **GetDeviceByIdResponse**: - 添加 `RuntimeStatus` 字段,类型为 `int` - 当设备没有运行时状态时返回 `-1`(表示未知状态) - 当设备有运行时状态时返回枚举值的整数表示 #### 3. 查询逻辑优化 - **GetDevicesQueryHandler**: - 使用 `SearchDevicesWithRuntimeAsync` 替代原有的 `SearchDevicesAsync` - 在构建响应时映射运行时状态信息 - 保持原有的分页和搜索功能 ### 技术实现 #### 1. 数据库查询优化 - 使用 Entity Framework 的 `Include` 方法进行左连接 - 通过 `DeviceCode` 外键关联 `CellularDevice` 和 `CellularDeviceRuntime` 表 - 保持查询性能,避免 N+1 查询问题 #### 2. 数据映射 - 使用元组 `(CellularDevice Device, CellularDeviceRuntime? Runtime)` 返回查询结果 - 在应用层进行数据映射,将运行时状态转换为整数 - 处理空值情况,确保 API 响应的一致性 #### 3. 向后兼容 - 保持原有接口的兼容性 - 新增字段为必填字段,类型为 `int` - 运行时状态为空时返回 `-1`(表示未知状态),客户端可以安全处理 ### 影响范围 - **API 响应**:设备列表接口现在包含运行时状态信息 - **前端显示**:可以显示设备的当前运行状态 - **性能影响**:轻微的性能提升,因为减少了额外的查询请求 - **数据一致性**:确保设备状态信息的实时性 ## 2025-01-29 修复设备搜索和获取方法,添加DeviceCode搜索支持和运行时状态 ### 修改原因 1. 设备搜索方法中缺少对 `DeviceCode` 字段的搜索支持 2. `GetDeviceById` 查询处理器需要获取设备的运行时状态信息 3. 确保所有设备相关的查询都能正确使用导航属性 ### 修改文件 #### 1. 仓储接口修改 - `X1.Domain/Repositories/Device/ICellularDeviceRepository.cs` - 添加 `GetDeviceByIdWithRuntimeAsync` 方法 #### 2. 仓储实现修改 - `X1.Infrastructure/Repositories/Device/CellularDeviceRepository.cs` - 修复搜索方法并添加新的获取方法 #### 3. 查询处理器修改 - `X1.Application/Features/Devices/Queries/GetDeviceById/GetDeviceByIdQueryHandler.cs` - 使用包含运行时状态的查询方法 ### 修改内容 #### 1. 搜索方法优化 - **SearchDevicesAsync**(两个重载版本): - 在搜索条件中添加 `d.DeviceCode.Contains(keyword)` 支持 - 现在支持按设备编码进行搜索 - **SearchDevicesWithRuntimeAsync**: - 在搜索条件中添加 `d.DeviceCode.Contains(keyword)` 支持 - 确保连表查询时也能按设备编码搜索 #### 2. 新增获取方法 - **GetDeviceByIdWithRuntimeAsync**: - 根据ID获取设备信息,包含运行时状态 - 使用 `Include(d => d.Runtime)` 进行左连接查询 - 返回完整的设备信息,包括运行时状态 #### 3. 查询处理器更新 - **GetDeviceByIdQueryHandler**: - 使用 `GetDeviceByIdWithRuntimeAsync` 替代 `GetDeviceByIdAsync` - 在响应中包含 `RuntimeStatus` 字段 - 当设备没有运行时状态时返回 `-1`(表示未知状态) ### 技术实现 #### 1. 搜索条件完善 ```csharp predicate = d => d.Name.Contains(keyword) || d.SerialNumber.Contains(keyword) || d.DeviceCode.Contains(keyword) || // 新增 d.Description.Contains(keyword); ``` #### 2. 导航属性查询 ```csharp return await QueryRepository.FirstOrDefaultAsync( d => d.Id == id, include: q => q.Include(d => d.Runtime), cancellationToken: cancellationToken); ``` #### 3. 运行时状态映射 ```csharp RuntimeStatus = device.Runtime?.RuntimeStatus != null ? (int)device.Runtime.RuntimeStatus : -1 ``` ### 影响范围 - **搜索功能**:现在支持按设备编码搜索设备 - **API 响应**:单个设备查询接口现在包含运行时状态信息 - **数据一致性**:确保所有设备查询都能正确获取关联的运行时状态 - **用户体验**:提供更完整的设备信息,包括实时运行状态 ### 业务价值 - **搜索增强**:用户可以通过设备编码快速找到特定设备 - **状态可见性**:单个设备详情页面显示实时运行状态 - **数据完整性**:确保设备信息的完整性和一致性 - **系统健壮性**:正确处理导航属性和关联数据 ## 2025-01-29 简化DeviceRuntimeDto,只保留必要字段 ### 修改原因 根据用户需求,简化 `DeviceRuntimeDto` 类,只保留必要的字段: - DeviceCode(设备编号) - RuntimeStatus(运行时状态,使用int类型) - NetworkStackCode(网络栈配置编号) - Name(设备名称) - CreatedAt(创建时间) ### 修改文件 #### 1. 响应模型修改 - `X1.Application/Features/DeviceRuntimes/Queries/GetDeviceRuntimes/GetDeviceRuntimesResponse.cs` - 简化 `DeviceRuntimeDto` 类 #### 2. 查询处理器修改 - `X1.Application/Features/DeviceRuntimes/Queries/GetDeviceRuntimes/GetDeviceRuntimesQueryHandler.cs` - 更新 `MapToDto` 方法 ### 修改内容 #### 1. DeviceRuntimeDto 简化 **移除的字段**: - Id(运行时状态ID) - RuntimeCode(运行编码) - UpdatedAt(更新时间) - Device(设备信息对象) **保留的字段**: - DeviceCode(设备编号) - RuntimeStatus(运行时状态,改为int类型) - NetworkStackCode(网络栈配置编号) - Name(设备名称,新增) - CreatedAt(创建时间) #### 2. MapToDto 方法优化 ```csharp private static DeviceRuntimeDto MapToDto(CellularDeviceRuntime runtime) { return new DeviceRuntimeDto { DeviceCode = runtime.DeviceCode, RuntimeStatus = (int)runtime.RuntimeStatus, NetworkStackCode = runtime.NetworkStackCode, Name = runtime.Device?.Name, CreatedAt = runtime.CreatedAt }; } ``` ### 技术实现 #### 1. 类型转换 - `RuntimeStatus` 从 `string` 改为 `int`,直接使用枚举的整数值 - 使用 `runtime.Device?.Name` 安全访问设备名称 #### 2. 数据简化 - 移除了复杂的嵌套对象 `DeviceInfoDto` - 只保留最核心的运行时状态信息 - 减少了数据传输量,提高API响应性能 ### 影响范围 - **API 响应**:设备运行时状态列表接口返回更简洁的数据结构 - **前端处理**:前端可以更直接地使用运行时状态信息 - **性能优化**:减少了不必要的数据传输,提高响应速度 - **数据一致性**:确保返回的数据结构简洁明了 ### 业务价值 - **数据精简**:只返回业务必需的核心字段 - **类型统一**:RuntimeStatus使用int类型,便于前端处理 - **性能提升**:减少数据传输量,提高API响应速度 - **维护便利**:简化数据结构,降低维护复杂度 ## 2025-01-29 为CellularDeviceRuntimeDetail实体添加DeviceCode和NetworkStackCode字段 ### 修改原因 根据用户需求,`CellularDeviceRuntimeDetail` 实体需要添加 `DeviceCode` 和 `NetworkStackCode` 字段,用于标识该运行时明细记录属于哪个设备以及使用的网络栈配置。 ### 修改文件 - `X1.Domain/Entities/Device/CellularDeviceRuntimeDetail.cs` - 添加DeviceCode和NetworkStackCode字段 ### 修改内容 #### 1. 添加DeviceCode属性 - **字段名称**:`DeviceCode` - **字段类型**:`string` - **约束条件**: - `[Required]` - 必填字段 - `[MaxLength(50)]` - 最大长度50个字符 - **访问修饰符**:`private set` - 只读属性,通过方法修改 - **位置**:在 `RuntimeCode` 字段之前 #### 2. 添加NetworkStackCode属性 - **字段名称**:`NetworkStackCode` - **字段类型**:`string` - **约束条件**: - `[Required]` - 必填字段 - `[MaxLength(50)]` - 最大长度50个字符 - **访问修饰符**:`private set` - 只读属性,通过方法修改 - **位置**:在 `RuntimeCode` 字段之后 #### 3. 更新Create方法 - **方法签名**:`Create` 方法添加 `deviceCode` 和 `networkStackCode` 参数 - **参数位置**:`deviceCode` 在 `runtimeCode` 参数之前,`networkStackCode` 在 `runtimeCode` 参数之后 - **参数验证**:通过 `[Required]` 和 `[MaxLength(50)]` 进行验证 - **属性赋值**:在创建明细记录时设置 `DeviceCode` 和 `NetworkStackCode` 属性 ### 技术特性 - **数据完整性**:设备编码和网络栈配置编号作为必填字段,确保每个运行时明细记录都能关联到具体设备和网络栈配置 - **长度限制**:最大50个字符,适合各种编码格式 - **封装性**:使用私有setter,确保数据只能通过方法修改 - **一致性**:与现有字段保持相同的设计模式 ### 业务价值 - **设备关联**:通过设备编码关联运行时明细记录与具体设备 - **网络栈关联**:通过网络栈配置编号关联运行时明细记录与网络栈配置 - **数据追溯**:增强运行时明细数据的可追溯性 - **查询便利**:支持按设备编码和网络栈配置编号查询相关的运行时明细记录 - **管理便利**:提供更灵活的设备运行时明细管理方式 ### 影响范围 - **实体模型**:CellularDeviceRuntimeDetail实体增加了DeviceCode和NetworkStackCode字段 - **创建操作**:所有创建运行时明细记录的操作都需要提供设备编码和网络栈配置编号 - **数据验证**:确保设备编码和网络栈配置编号的完整性和有效性 - **查询逻辑**:支持按设备编码和网络栈配置编号查询运行时明细记录 ### 后续工作建议 1. **数据库迁移**:需要创建数据库迁移来添加DeviceCode和NetworkStackCode字段 2. **仓储更新**:更新相关的仓储方法以支持设备编码和网络栈配置编号字段 3. **API更新**:更新相关的API接口以支持设备编码和网络栈配置编号字段 4. **前端界面**:更新前端界面以显示和编辑设备编码和网络栈配置编号 5. **测试用例**:为设备编码和网络栈配置编号字段添加相应的测试用例 ## 2025-01-29 调整设备运行时管理路由位置并更新权限配置 ### 修改原因 根据用户需求,将设备运行时管理路由从独立路由调整为放在 `instruments` 路由内部,与 `list` 同一层级,同时更新相关的权限配置。 ### 修改文件 #### 1. 路由配置调整 - `X1.WebUI/src/routes/AppRouter.tsx` - 将设备运行时管理路由移动到 instruments 路由内部 #### 2. 菜单配置调整 - `X1.WebUI/src/constants/menuConfig.ts` - 将设备运行时管理菜单项移动到仪表管理下面 #### 3. 权限配置更新 - `X1.WebUI/src/contexts/AuthContext.tsx` - 在 getDefaultPermissions 函数中添加设备运行时管理权限 ### 修改内容 #### 1. 路由结构调整 - **原路由结构**: ``` /dashboard/device-runtimes/list /dashboard/device-runtimes/detail/:deviceCode ``` - **新路由结构**: ``` /dashboard/instruments/device-runtimes/list /dashboard/instruments/device-runtimes/detail/:deviceCode ``` #### 2. 菜单结构调整 - **原菜单结构**:设备运行时作为独立顶级菜单项 - **新菜单结构**:设备运行时作为仪表管理的子菜单项 - **菜单路径更新**:`/dashboard/device-runtimes/list` → `/dashboard/instruments/device-runtimes/list` #### 3. 权限配置更新 - **新增权限**: - `deviceruntimes.view` - 查看设备运行时权限 - `deviceruntimes.manage` - 管理设备运行时权限 - **权限位置**:添加到 `getDefaultPermissions` 函数中,确保用户登录后能够正确获取设备运行时管理权限 ### 技术特性 - **路由嵌套**:设备运行时管理现在嵌套在 instruments 路由下 - **权限继承**:设备运行时管理继承仪表管理的基础权限结构 - **菜单层次**:清晰的菜单层次结构,设备运行时管理属于仪表管理范畴 - **向后兼容**:保持所有现有功能不变,只是调整了路由和菜单结构 ### 业务价值 - **逻辑分组**:将设备运行时管理归类到仪表管理下,符合业务逻辑 - **用户体验**:更清晰的菜单结构,用户更容易找到相关功能 - **权限管理**:统一的权限管理结构,便于权限分配和管理 - **系统一致性**:保持系统整体架构的一致性 ### 影响范围 - **路由访问**:设备运行时管理页面的访问路径发生变化 - **菜单导航**:用户需要通过仪表管理菜单访问设备运行时管理 - **权限控制**:设备运行时管理权限已正确配置 - **用户体验**:更符合用户预期的菜单结构 ### 使用方式 1. 用户登录后,在左侧菜单中点击"仪表管理" 2. 在仪表管理子菜单中点击"运行时状态" 3. 进入设备运行时管理页面:`/dashboard/instruments/device-runtimes/list` 4. 点击设备编号可查看详情:`/dashboard/instruments/device-runtimes/detail/:deviceCode` ### 注意事项 - 原有的直接访问路径 `/dashboard/device-runtimes/*` 已失效 - 需要更新任何硬编码的链接或书签 - 权限检查仍然正常工作,确保安全性 - 所有设备运行时管理功能保持不变 ## 2025-01-29 修复 device-runtimes 界面组件和依赖问题 ### 修改原因 修复 device-runtimes 界面中缺失的组件和依赖问题,确保界面能够正常运行。 ### 新增文件 #### 1. UI 组件 - `X1.WebUI/src/components/ui/card.tsx` - 创建 card 组件,包含 Card、CardHeader、CardTitle、CardContent、CardFooter 等子组件 - `X1.WebUI/src/components/ui/separator.tsx` - 创建 separator 组件,基于 @radix-ui/react-separator - `X1.WebUI/src/components/ui/dropdown-menu.tsx` - 创建 dropdown-menu 组件,包含完整的下拉菜单功能 ### 修改文件 #### 1. Dialog 组件扩展 - `X1.WebUI/src/components/ui/dialog.tsx` - 添加 DialogHeader 组件导出 #### 2. 设备运行时表格组件 - `X1.WebUI/src/pages/device-runtimes/DeviceRuntimesTable.tsx` - 修复图标导入,将 MoreHorizontalIcon 改为 DotsHorizontalIcon #### 3. 设备运行时视图组件 - `X1.WebUI/src/pages/device-runtimes/DeviceRuntimesView.tsx` - 修复服务方法调用,使用 deviceRuntimeService 实例方法 ### 修复内容 #### 1. 组件创建 - **Card 组件**:提供卡片布局功能,支持标题、内容、页脚等区域 - **Separator 组件**:提供分隔线功能,支持水平和垂直方向 - **Dropdown Menu 组件**:提供下拉菜单功能,支持菜单项、复选框、单选按钮等 #### 2. 图标修复 - **图标名称修正**:将不存在的 MoreHorizontalIcon 改为正确的 DotsHorizontalIcon - **导入修复**:确保所有图标都能正确导入和使用 #### 3. 服务调用修复 - **方法调用修正**:将直接函数调用改为使用 deviceRuntimeService 实例方法 - **导入清理**:移除不存在的函数导入,只保留类型和服务实例 ### 技术特性 #### 1. 组件设计 - **类型安全**:所有组件都使用 TypeScript 类型定义 - **可访问性**:遵循 ARIA 标准,支持屏幕阅读器 - **响应式**:支持不同屏幕尺寸的响应式布局 - **主题支持**:支持深色/浅色主题切换 #### 2. 图标系统 - **Radix UI 图标**:使用 @radix-ui/react-icons 提供的图标 - **一致性**:确保图标名称与库中实际存在的图标一致 - **可扩展性**:支持添加更多图标 #### 3. 服务架构 - **实例方法**:使用服务实例的方法而不是独立函数 - **类型安全**:完整的 TypeScript 类型支持 - **错误处理**:统一的错误处理机制 ### 影响范围 - **UI 组件**:新增了三个重要的 UI 组件 - **图标系统**:修复了图标导入问题 - **服务调用**:统一了服务调用方式 - **开发体验**:提供了更好的类型安全和代码提示 ### 后续工作建议 1. **组件测试**:为新创建的组件添加单元测试 2. **文档编写**:为组件添加使用文档和示例 3. **主题优化**:进一步完善主题支持 4. **性能优化**:优化组件的渲染性能 ## 2025-01-29 修复 Select 组件空值错误 ### 修改原因 修复 Select 组件中空值选项导致的错误:"A must have a value prop that is not an empty string"。 ### 修改文件 - `X1.WebUI/src/pages/device-runtimes/DeviceRuntimesView.tsx` - 修复运行时状态选择器的空值问题 ### 修改内容 #### 1. 选项值修复 - **空值选项**:将 `{ value: '', label: '全部状态' }` 改为 `{ value: 'all', label: '全部状态' }` - **SelectItem 修复**:将 `全部状态` 改为 `全部状态` #### 2. 值处理逻辑修复 - **默认值**:将 `value={runtimeStatus?.toString() || ''}` 改为 `value={runtimeStatus?.toString() || 'all'}` - **值变化处理**:将 `onValueChange={(value) => setRuntimeStatus(value ? parseInt(value) : undefined)}` 改为 `onValueChange={(value) => setRuntimeStatus(value === 'all' ? undefined : parseInt(value))}` ### 技术说明 - **Radix UI 限制**:Radix UI 的 Select 组件不允许空字符串作为选项值 - **特殊值处理**:使用 'all' 作为特殊值表示"全部状态" - **逻辑转换**:在值变化时将 'all' 转换为 undefined,保持业务逻辑不变 ### 影响范围 - **用户界面**:Select 组件现在可以正常工作,不再报错 - **业务逻辑**:功能保持不变,只是内部值处理方式调整 - **用户体验**:界面更加稳定,不会出现错误提示 ## 2025-01-29 修复 deviceRuntimeService 方法绑定问题 ### 修改原因 修复 `deviceRuntimeService` 中方法调用时的 `this` 上下文丢失问题,导致 `getRuntimeStatusString` 方法无法正确访问。 ### 修改文件 - `X1.WebUI/src/services/deviceRuntimeService.ts` - 修复方法绑定问题 ### 修改内容 #### 1. 方法定义修复 - **箭头函数**:将 `getRuntimeStatusDescription` 和 `getRuntimeStatusColor` 方法改为箭头函数 - **this 绑定**:确保方法在传递时保持正确的 `this` 上下文 - **方法顺序**:将 `getRuntimeStatusString` 方法移到前面,确保在调用前已定义 #### 2. 技术改进 - **上下文保持**:使用箭头函数确保 `this` 始终指向 `DeviceRuntimeService` 实例 - **方法传递**:支持将方法作为函数参数传递给其他组件 - **错误修复**:解决 "Cannot read properties of undefined" 错误 ### 技术说明 - **问题原因**:当方法被作为函数传递时,`this` 上下文会丢失 - **解决方案**:使用箭头函数确保 `this` 绑定到类实例 - **性能影响**:箭头函数在实例化时创建,但避免了运行时绑定问题 ### 影响范围 - **错误修复**:解决了运行时状态描述和颜色获取的错误 - **功能恢复**:设备运行时状态显示功能正常工作 - **代码稳定性**:提高了方法调用的可靠性 ## 2025-01-29 - 修复设备运行时表格单元格居中对齐问题 ### 修改原因 设备运行时表格的单元格内容没有居中对齐,与其他表格组件的显示效果不一致,影响用户体验。 ### 修改文件 - `X1.WebUI/src/pages/device-runtimes/DeviceRuntimesTable.tsx` - 修复表格单元格对齐 ### 修改内容 #### 1. 表头居中对齐 - **添加居中对齐**:为所有 `TableHead` 元素添加 `text-center` 类 - **保持密度样式**:继续使用 `densityStyles` 控制行高 - **视觉一致性**:与协议版本表格保持一致的显示效果 #### 2. 表格单元格居中对齐 - **添加居中对齐**:为所有 `TableCell` 元素添加 `text-center` 类 - **保持密度样式**:继续使用 `densityStyles` 控制行高 - **内容对齐**:所有单元格内容现在都居中对齐 ### 技术说明 - **CSS类应用**:使用 `cn("text-center", densityStyles[density])` 组合样式类 - **一致性**:与协议版本表格使用相同的对齐方式 - **响应式设计**:保持密度样式的响应式特性 - **用户体验**:提供统一的表格显示效果 ### 影响范围 - **视觉效果**:表格单元格内容现在居中对齐 - **一致性**:与其他表格组件保持一致的显示效果 - **用户体验**:提供更好的视觉体验和可读性 - **设计统一**:保持整个系统的表格设计一致性 ## 2025-01-29 - 优化设备运行时操作菜单逻辑 ### 修改原因 根据用户需求,操作菜单应该根据设备运行时状态显示不同的操作选项:当设备处于未知状态或停止状态时可以启动,当设备处于运行状态时可以停止。 ### 修改文件 - `X1.WebUI/src/pages/device-runtimes/DeviceRuntimesTable.tsx` - 修改操作菜单逻辑 - `X1.WebUI/src/pages/device-runtimes/DeviceRuntimesView.tsx` - 添加启动单个设备处理函数 ### 修改内容 #### 1. 操作菜单逻辑优化 - **运行中状态(runtimeStatus === 1)**:显示"停止设备"选项,点击红色图标 - **其他状态(未知-1、初始化0、已停止2、错误3)**:显示"启动设备"选项,点击绿色图标 - **移除禁用状态**:不再显示禁用的"设备未运行"选项 #### 2. 接口扩展 - **新增回调函数**:添加 `onStartDevice` 回调函数到 `DeviceRuntimesTableProps` 接口 - **组件参数更新**:在 `DeviceRuntimesTable` 组件中添加 `onStartDevice` 参数 #### 3. 启动设备处理 - **临时实现**:由于单个设备启动需要选择网络栈配置,暂时提示用户使用批量启动功能 - **用户引导**:提供清晰的用户提示,引导用户使用正确的功能 ### 技术说明 - **状态判断**:根据 `runtimeStatus` 值判断显示的操作选项 - **颜色区分**:启动操作使用绿色,停止操作使用红色 - **用户体验**:提供直观的操作反馈和用户引导 - **功能完整性**:保持批量启动和单个停止功能的完整性 ### 影响范围 - **操作逻辑**:操作菜单现在根据设备状态显示相应的操作选项 - **用户体验**:提供更直观和合理的操作选择 - **功能引导**:引导用户使用正确的功能进行设备启动 - **视觉反馈**:通过颜色区分不同的操作类型 ## 2025-01-29 - 修复设备运行时表格选择框对齐问题 ### 修改原因 用户反馈选择框(勾选框)没有居中对齐,需要修复表格中标题行和内容行的选择框对齐问题。 ### 修改文件 - `X1.WebUI/src/pages/device-runtimes/DeviceRuntimesTable.tsx` - 修复选择框对齐 ### 修改内容 #### 1. 选择框列对齐修复 - **表头选择框**:为 `TableHead` 添加 `text-center` 类,使全选复选框居中对齐 - **内容行选择框**:为 `TableCell` 添加 `text-center` 类,使单个选择复选框居中对齐 #### 2. 样式统一 - **对齐一致性**:确保选择框列与其他列的对齐方式保持一致 - **视觉体验**:提供更好的表格视觉效果和用户体验 ### 技术说明 - **CSS类应用**:使用 Tailwind CSS 的 `text-center` 类实现居中对齐 - **表格结构**:保持表格结构完整性,只修改对齐样式 - **响应式设计**:确保在不同屏幕尺寸下选择框都能正确对齐 ### 影响范围 - **视觉效果**:选择框现在与其他列内容居中对齐 - **用户体验**:提供更整洁和一致的表格显示效果 - **设计统一**:保持整个表格的对齐一致性 ## 2025-01-29 - 优化设备运行时操作列显示方式 ### 修改原因 用户希望操作列直接显示启动和停止按钮,而不是使用下拉菜单,提供更直观的操作体验。 ### 修改文件 - `X1.WebUI/src/pages/device-runtimes/DeviceRuntimesTable.tsx` - 修改操作列显示方式 ### 修改内容 #### 1. 操作列显示方式优化 - **移除下拉菜单**:不再使用 `DropdownMenu` 组件,直接显示操作按钮 - **直接按钮显示**:根据设备状态直接显示启动或停止按钮 - **图标按钮**:使用纯图标按钮,节省空间并提高视觉效果 #### 2. 按钮样式优化 - **启动按钮**:绿色图标,悬停时显示绿色背景 - **停止按钮**:红色图标,悬停时显示红色背景 - **工具提示**:添加 `title` 属性提供操作说明 - **居中对齐**:按钮在操作列中居中对齐 #### 3. 代码清理 - **移除未使用导入**:删除不再使用的 `DropdownMenu` 相关导入 - **简化代码结构**:移除复杂的下拉菜单逻辑,使用简单的条件渲染 ### 技术说明 - **条件渲染**:根据 `runtimeStatus` 值决定显示启动或停止按钮 - **样式设计**:使用 `variant="ghost"` 和自定义颜色类实现按钮样式 - **用户体验**:提供直观的图标按钮,减少操作步骤 - **响应式设计**:按钮在不同屏幕尺寸下都能正确显示 ### 影响范围 - **操作体验**:用户可以直接点击按钮进行操作,无需打开下拉菜单 - **视觉效果**:操作列更加简洁,图标按钮更加直观 - **交互效率**:减少操作步骤,提高用户操作效率 - **代码维护**:简化了操作列的实现逻辑 ## 2025-01-29 - 优化批量启动对话框网络栈配置选择 ### 修改原因 用户希望将网络栈配置改为搜索下拉框选择,数据来源是 `networkStackConfigService.ts`,提供更好的搜索和选择体验。 ### 修改文件 - `X1.WebUI/src/pages/device-runtimes/DeviceRuntimesView.tsx` - 修改网络栈配置选择方式 ### 修改内容 #### 1. 搜索下拉框实现 - **移除Select组件**:不再使用简单的 `Select` 组件,改为自定义搜索下拉框 - **搜索功能**:支持按网络栈名称、编号和描述进行搜索 - **实时过滤**:输入搜索关键词时实时过滤匹配的配置项 - **显示优化**:显示网络栈名称、编号和描述信息 #### 2. 状态管理 - **搜索状态**:添加 `networkStackSearchTerm` 状态管理搜索关键词 - **过滤状态**:添加 `filteredNetworkStackConfigs` 状态管理过滤后的配置列表 - **下拉框状态**:添加 `isNetworkStackDropdownOpen` 状态管理下拉框开关 #### 3. 交互优化 - **点击外部关闭**:添加点击外部区域关闭下拉框的功能 - **搜索重置**:选择配置后自动清空搜索关键词并重置过滤列表 - **无结果提示**:当搜索无结果时显示友好的提示信息 #### 4. 样式设计 - **下拉框样式**:使用与系统一致的样式设计 - **悬停效果**:配置项悬停时显示高亮效果 - **描述显示**:在配置项下方显示描述信息(如果有) ### 技术说明 - **数据来源**:使用 `networkStackConfigService.getNetworkStackConfigs()` 获取配置数据 - **搜索逻辑**:支持多字段搜索(名称、编号、描述) - **性能优化**:使用本地过滤,避免频繁的API调用 - **用户体验**:提供直观的搜索和选择体验 ### 影响范围 - **用户体验**:提供更便捷的网络栈配置搜索和选择功能 - **功能完整性**:保持批量启动功能的完整性 - **交互效率**:通过搜索功能快速定位目标配置 - **视觉一致性**:与系统其他搜索下拉框保持一致的视觉风格 ## 2025-01-29 - 优化设备运行时表格网络栈配置列 ### 修改原因 用户希望网络栈配置列显示为下拉框,只有当选择了网络栈配置值的时候才能启动设备,提供更直观的配置选择和启动控制。 ### 修改文件 - `X1.WebUI/src/pages/device-runtimes/DeviceRuntimesTable.tsx` - 修改网络栈配置列显示方式 - `X1.WebUI/src/pages/device-runtimes/DeviceRuntimesView.tsx` - 添加网络栈配置变更处理 ### 修改内容 #### 1. 网络栈配置列下拉框实现 - **搜索下拉框**:将网络栈配置列改为可搜索的下拉框 - **实时搜索**:支持按名称、编号和描述进行实时搜索 - **配置显示**:显示网络栈名称和编号的组合信息 - **选择功能**:点击配置项可选择对应的网络栈配置 #### 2. 启动按钮控制逻辑 - **条件启动**:只有当设备选择了网络栈配置时,启动按钮才可用 - **视觉反馈**:未选择配置时按钮显示为灰色禁用状态 - **提示信息**:鼠标悬停时显示相应的提示信息 - **错误处理**:尝试启动未配置设备时显示错误提示 #### 3. 状态管理优化 - **下拉框状态**:管理每个设备的下拉框开关状态 - **搜索状态**:管理每个设备的搜索关键词 - **过滤状态**:管理每个设备的过滤结果 - **点击外部关闭**:点击外部区域自动关闭所有下拉框 #### 4. 单个设备启动功能 - **完整实现**:实现单个设备的启动功能 - **配置验证**:启动前验证是否已选择网络栈配置 - **API调用**:调用设备启动API进行实际启动操作 - **结果反馈**:显示启动成功或失败的提示信息 ### 技术说明 - **组件接口扩展**:添加 `networkStackConfigs` 和 `onNetworkStackChange` 属性 - **状态管理**:使用对象形式管理多个设备的状态 - **搜索算法**:支持多字段模糊搜索 - **用户体验**:提供直观的配置选择和启动控制 ### 影响范围 - **表格交互**:网络栈配置列现在支持下拉选择 - **启动控制**:只有配置了网络栈的设备才能启动 - **用户体验**:提供更直观的配置管理和启动流程 - **功能完整性**:单个设备启动功能现在完全可用 ## 2025-01-29 - 修复网络栈配置下拉框样式问题 ### 修改原因 用户反馈网络栈配置下拉框的样式不正确,存在红色圆点等视觉问题,需要修复样式以保持界面的一致性。 ### 修改文件 - `X1.WebUI/src/pages/device-runtimes/DeviceRuntimesTable.tsx` - 修复表格中网络栈配置下拉框样式 - `X1.WebUI/src/pages/device-runtimes/DeviceRuntimesView.tsx` - 修复批量启动对话框中的网络栈配置下拉框样式 ### 修改内容 #### 1. 文本颜色修复 - **表格下拉框**:为文本添加 `text-foreground` 类,确保文本颜色正确 - **对话框下拉框**:为文本添加 `text-foreground` 类,保持颜色一致性 #### 2. 搜索输入框样式优化 - **移除边框**:为搜索输入框添加 `border-0 focus:ring-0 focus:border-0` 类 - **简化样式**:移除不必要的边框和焦点环,使搜索框更简洁 - **统一外观**:确保搜索框与下拉框整体样式协调 #### 3. 视觉一致性 - **颜色统一**:确保所有文本使用正确的主题颜色 - **边框处理**:移除搜索框的重复边框,避免视觉冲突 - **焦点状态**:简化焦点状态的视觉反馈 ### 技术说明 - **CSS类应用**:使用 Tailwind CSS 类修复样式问题 - **主题适配**:确保样式与系统主题保持一致 - **视觉层次**:优化视觉层次,避免不必要的视觉元素 ### 影响范围 - **视觉效果**:修复了红色圆点等样式问题 - **界面一致性**:保持下拉框与系统其他组件的视觉一致性 - **用户体验**:提供更清洁和专业的界面外观 - **主题适配**:确保在不同主题下都能正确显示 ## 2025-01-29 - 修复网络栈配置下拉框定位问题 ### 修改原因 用户反馈下拉框不应该占用当前行的空间,应该覆盖在其他内容之上,需要修复下拉框的定位方式。 ### 修改文件 - `X1.WebUI/src/pages/device-runtimes/DeviceRuntimesTable.tsx` - 修复下拉框定位逻辑 ### 修改内容 #### 1. 定位方式优化 - **固定定位**:将下拉框改为 `fixed` 定位,不再占用表格行空间 - **动态计算位置**:根据点击元素的位置动态计算下拉框显示位置 - **高层级显示**:使用 `z-[9999]` 确保下拉框显示在最上层 #### 2. 位置计算逻辑 - **点击事件处理**:在点击事件中获取元素的位置信息 - **坐标计算**:计算下拉框应该显示的位置坐标 - **状态管理**:添加 `dropdownPositions` 状态管理每个下拉框的位置 #### 3. 交互优化 - **精确定位**:下拉框现在精确显示在触发元素下方 - **不占用空间**:下拉框不再影响表格的布局和行高 - **响应式定位**:支持滚动时的位置调整 ### 技术说明 - **getBoundingClientRect**:使用 DOM API 获取元素位置信息 - **fixed 定位**:使用固定定位避免影响文档流 - **事件处理**:在点击事件中传递事件对象以获取位置信息 - **状态管理**:使用对象形式管理多个下拉框的位置状态 ### 影响范围 - **布局优化**:下拉框不再占用表格行空间 - **视觉效果**:下拉框现在浮在内容上方,提供更好的视觉层次 - **用户体验**:提供更流畅和直观的下拉选择体验 - **交互响应**:下拉框位置更精确,响应更及时 ## 2025-01-29 - 修复网络栈配置显示问题 ### 修改原因 用户反馈 `DeviceRuntimesView.tsx` 中的网络栈配置下拉框没有数据,但 `NetworkStackConfigsTable.tsx` 是有数据的,需要确保网络栈配置能正确显示网络栈名称。 ### 修改文件 - `X1.WebUI/src/pages/device-runtimes/DeviceRuntimesTable.tsx` - 修复网络栈配置显示逻辑 - `X1.WebUI/src/pages/device-runtimes/DeviceRuntimesView.tsx` - 修复批量启动对话框中的网络栈配置显示 ### 修改内容 #### 1. 显示逻辑优化 - **表格列显示**:当找到匹配的网络栈配置时显示名称和编号,未找到时显示编号和提示 - **对话框显示**:批量启动对话框中的网络栈配置显示逻辑与表格保持一致 - **错误处理**:当网络栈配置不存在时提供友好的错误提示 #### 2. 数据匹配逻辑 - **配置查找**:根据 `networkStackCode` 在 `networkStackConfigs` 中查找匹配的配置 - **显示优先级**:优先显示网络栈名称,其次显示编号 - **兜底显示**:当配置不存在时显示编号和"未找到配置"提示 #### 3. 用户体验改进 - **清晰提示**:明确显示当前选择的网络栈配置状态 - **错误反馈**:当配置不存在时提供明确的错误信息 - **一致性**:表格和对话框中的显示逻辑保持一致 ### 技术说明 - **数据源**:使用 `networkStackConfigService.getNetworkStackConfigs()` 获取配置数据 - **匹配逻辑**:使用 `find()` 方法根据 `networkStackCode` 匹配配置 - **显示格式**:统一使用"名称 (编号)"的显示格式 - **错误处理**:提供友好的错误提示而不是显示"未知配置" ### 影响范围 - **数据显示**:网络栈配置现在能正确显示网络栈名称 - **用户体验**:提供更清晰和准确的配置信息显示 - **错误处理**:当配置不存在时提供明确的错误提示 - **一致性**:表格和对话框中的显示逻辑保持一致 ## 2025-01-29 - 限制运行中设备的网络栈配置修改 ### 修改原因 用户要求当设备启动之后,网络栈配置不能再修改,需要限制运行中设备的网络栈配置编辑功能。 ### 修改文件 - `X1.WebUI/src/pages/device-runtimes/DeviceRuntimesTable.tsx` - 限制运行中设备的网络栈配置下拉框 - `X1.WebUI/src/pages/device-runtimes/DeviceRuntimesView.tsx` - 限制运行中设备的网络栈配置变更 ### 修改内容 #### 1. 下拉框状态控制 - **运行中设备**:当 `runtimeStatus === 1` 时,下拉框显示为禁用状态 - **视觉反馈**:禁用状态下使用灰色背景和降低透明度 - **交互限制**:禁用状态下不允许点击打开下拉框 #### 2. 下拉框显示控制 - **条件显示**:只有非运行中的设备才显示下拉框选项 - **状态检查**:在显示下拉框前检查设备运行状态 - **安全防护**:防止运行中设备意外修改配置 #### 3. 配置变更限制 - **状态验证**:在配置变更前检查设备运行状态 - **错误提示**:当尝试修改运行中设备配置时显示错误提示 - **操作阻止**:阻止对运行中设备的配置修改操作 #### 4. 用户体验优化 - **清晰状态**:通过视觉样式明确区分可编辑和不可编辑状态 - **友好提示**:提供明确的错误提示说明为什么不能修改 - **一致性**:保持界面交互逻辑的一致性 ### 技术说明 - **状态判断**:使用 `runtimeStatus === 1` 判断设备是否运行中 - **条件渲染**:使用条件渲染控制下拉框的显示和交互 - **样式控制**:使用 Tailwind CSS 类控制禁用状态的样式 - **事件处理**:在事件处理函数中添加状态检查逻辑 ### 影响范围 - **功能限制**:运行中的设备无法修改网络栈配置 - **视觉反馈**:运行中设备的网络栈配置列显示为禁用状态 - **用户体验**:提供清晰的视觉和交互反馈 - **数据安全**:防止运行中设备的配置被意外修改 ## 2025-01-29 - 删除未使用的DeviceRuntimeDetail.tsx文件 ### 修改原因 经过检查发现 `DeviceRuntimeDetail.tsx` 文件虽然存在且有路由配置,但实际上没有被使用。在 `DeviceRuntimesView.tsx` 和 `DeviceRuntimesTable.tsx` 中都没有任何导航到详情页面的链接或按钮,表格中的操作菜单只包含"停止设备"和"设备未运行"选项,没有"查看详情"选项。 ### 修改文件 #### 1. 删除文件 - `X1.WebUI/src/pages/device-runtimes/DeviceRuntimeDetail.tsx` - 删除未使用的设备运行时详情页面组件 #### 2. 修改路由配置 - `X1.WebUI/src/routes/AppRouter.tsx` - 移除DeviceRuntimeDetail组件的导入和路由配置 ### 修改内容 #### 1. 删除DeviceRuntimeDetail.tsx文件 - 删除了276行的设备运行时详情页面组件 - 该组件包含设备运行时状态显示、网络配置信息、时间信息等功能 - 但由于没有入口链接,用户无法访问此页面 #### 2. 更新路由配置 - 移除 `const DeviceRuntimeDetail = lazy(() => import('@/pages/device-runtimes/DeviceRuntimeDetail'));` 导入语句 - 删除 `/device-runtimes/detail/:deviceCode` 路由配置 - 保留 `/device-runtimes/list` 路由,确保设备运行时列表页面正常工作 ### 技术说明 - **路由清理**:移除了未使用的路由配置,简化路由结构 - **代码清理**:删除了未使用的组件文件,减少代码冗余 - **功能完整性**:设备运行时管理功能仍然完整,只是移除了未使用的详情页面 - **编译错误修复**:修复了因删除组件导致的编译错误 ### 影响范围 - **功能影响**:用户无法再访问设备运行时详情页面 - **路由影响**:`/device-runtimes/detail/:deviceCode` 路径不再可用 - **代码维护**:减少了未使用的代码,提高代码库的整洁性 - **编译状态**:修复了编译错误,确保项目能够正常构建 ### 后续建议 1. **功能评估**:如果将来需要设备运行时详情功能,可以重新实现 2. **用户反馈**:收集用户反馈,确认是否需要详情页面功能 3. **替代方案**:考虑在列表页面中直接显示详细信息,而不是单独的详情页面 4. **代码审查**:定期检查类似的未使用代码,保持代码库的整洁性 ## 2025-01-29 - 修复批量启动按钮主题兼容性问题 ### 修改原因 批量启动按钮使用了硬编码的绿色样式(`bg-green-600 hover:bg-green-700 text-white`),与系统的主题切换不兼容,在深色主题下显示效果不佳。 ### 修改文件 - `X1.WebUI/src/pages/device-runtimes/DeviceRuntimesView.tsx` - 修复批量启动按钮的主题兼容性 ### 修改内容 #### 1. 批量启动按钮样式修复 - **移除硬编码样式**:删除 `className="bg-green-600 hover:bg-green-700 text-white"` - **使用主题变量**:改为使用 `variant="default"`,让按钮自动适配当前主题 - **保持功能不变**:按钮的禁用状态和点击功能保持不变 #### 2. 确认启动按钮样式修复 - **移除硬编码样式**:删除 `className="bg-green-600 hover:bg-green-700"` - **使用主题变量**:改为使用 `variant="default"`,确保与主题系统一致 - **保持功能不变**:按钮的禁用状态和提交功能保持不变 ### 技术说明 - **主题兼容性**:使用 `variant="default"` 让按钮自动适配浅色/深色主题 - **设计一致性**:与系统其他按钮保持一致的视觉风格 - **可维护性**:移除硬编码样式,提高代码的可维护性 - **用户体验**:在不同主题下都能提供良好的视觉体验 ### 影响范围 - **视觉效果**:批量启动按钮现在与主题系统完全兼容 - **用户体验**:在浅色和深色主题下都有良好的显示效果 - **代码质量**:移除了硬编码样式,提高了代码质量 - **设计一致性**:与系统其他组件保持一致的视觉风格 ## 2025-01-29 修复GetNetworkStackConfigsByCodesAsync方法添加ConfigContent字段 ### 修改原因 根据用户需求,`GetNetworkStackConfigsByCodesAsync` 方法需要获取 `ran.ConfigContent`、`cnc.ConfigContent` 和 `ims.ConfigContent` 字段,以便在前端显示完整的配置内容信息。 ### 修改文件 - `X1.Domain/Models/NetworkStackConfigWithBindingNamesDto.cs` - 添加ConfigContent字段 - `X1.Infrastructure/Repositories/NetworkProfile/NetworkStackConfigRepository.cs` - 修复SQL查询 ### 修改内容 #### 1. DTO模型扩展 - **NetworkStackConfigWithBindingNamesDto**: - 添加 `RanConfigContent?: string` - RAN配置内容 - 添加 `CoreNetworkConfigContent?: string` - 核心网配置内容 - 添加 `IMSConfigContent?: string` - IMS配置内容 #### 2. SQL查询修复 - **GetNetworkStackConfigsByCodesAsync方法**: - 在SELECT语句中添加 `ran."ConfigContent" AS "RanConfigContent"` - 在SELECT语句中添加 `cnc."ConfigContent" AS "CoreNetworkConfigContent"` - 在SELECT语句中添加 `ims."ConfigContent" AS "IMSConfigContent"` #### 3. 相关方法同步修复 - **GetNetworkStackConfigByIdWithBindingNamesAsync方法**: - 同步添加相同的ConfigContent字段到SQL查询中 - **SearchNetworkStackConfigsWithBindingNamesAsync方法**: - 同步添加相同的ConfigContent字段到SQL查询中 ### 技术特性 - **数据完整性**:现在能够获取完整的配置内容信息 - **字段映射**:正确映射数据库字段到DTO属性 - **一致性**:所有相关方法都包含相同的ConfigContent字段 - **类型安全**:使用可空字符串类型,避免空值问题 ### 业务价值 - **配置内容显示**:前端可以显示RAN、核心网、IMS的完整配置内容 - **数据关联**:提供网络栈配置与相关配置内容的完整关联信息 - **调试支持**:便于开发人员查看和调试配置内容 - **用户体验**:用户可以在一个查询中获取所有相关的配置信息 ### 影响范围 - **API响应**:网络栈配置查询现在包含完整的配置内容 - **前端显示**:前端可以显示配置内容信息 - **数据查询**:提供更完整的配置关联数据 - **系统集成**:支持配置内容的完整传递和处理 ### 后续工作建议 1. 更新前端界面以显示配置内容信息 2. 添加配置内容的格式化显示功能 3. 考虑添加配置内容的搜索功能 4. 优化大配置内容的显示方式