Files
smart-crop-ui/src/LOAD_DEVICE_UNBIND_UPDATE.md

17 KiB
Raw Blame History

🔧 负载管理解绑操作升级说明

📅 更新时间

2025-10-16

🎯 更新内容

负载管理中的设备解绑(拆卸)操作从浏览器原生的 confirm() 对话框升级为系统内的 AlertDialog 二次确认提示。

📊 修改对比

修改前

使用浏览器原生对话框:

<Button
  variant="ghost"
  size="sm"
  onClick={() => {
    if (confirm('确定要拆卸此设备吗?')) {
      handleUnmount(device.id);
    }
  }}
>
  <Unlink className="w-4 h-4" />
</Button>

问题:

  • 样式无法自定义,与系统风格不统一
  • 浏览器原生弹窗,体验不佳
  • 移动端显示效果差
  • 无法添加详细说明信息
  • 不符合现代UI/UX设计规范

视觉效果:

┌──────────────────────────────┐
│  [?]  确定要拆卸此设备吗?       │
│                              │
│        [取消]    [确定]        │
└──────────────────────────────┘
浏览器原生样式,无法定制

修改后

使用系统 AlertDialog 组件:

// 1. 点击按钮触发确认对话框
<Button
  variant="ghost"
  size="sm"
  onClick={() => handleUnmountClick(device.id)}
>
  <Unlink className="w-4 h-4" />
</Button>

// 2. AlertDialog 确认对话框
<AlertDialog open={showUnmountConfirm} onOpenChange={setShowUnmountConfirm}>
  <AlertDialogContent>
    <AlertDialogHeader>
      <AlertDialogTitle>确认拆卸设备</AlertDialogTitle>
      <AlertDialogDescription>
        确定要拆卸此设备吗?拆卸后设备状态将变为"已拆卸",可以重新挂载到其他农机上。
      </AlertDialogDescription>
    </AlertDialogHeader>
    <AlertDialogFooter>
      <AlertDialogCancel onClick={() => setPendingUnmountId(null)}>
        取消
      </AlertDialogCancel>
      <AlertDialogAction onClick={confirmUnmount} className="bg-red-600 hover:bg-red-700">
        确认拆卸
      </AlertDialogAction>
    </AlertDialogFooter>
  </AlertDialogContent>
</AlertDialog>

优势:

  • 样式统一,符合系统设计风格
  • 可以添加详细的说明信息
  • 响应式设计,移动端友好
  • 按钮颜色可自定义(红色警告色)
  • 更好的用户体验和可访问性

视觉效果:

┌────────────────────────────────────────────┐
│  确认拆卸设备                               │
│                                            │
│  确定要拆卸此设备吗?拆卸后设备状态将        │
│  变为"已拆卸",可以重新挂载到其他农机上。   │
│                                            │
│                    [取消]  [确认拆卸] 🔴    │
└────────────────────────────────────────────┘
系统风格,绿色农业主题,红色警告按钮

🔄 实现流程

操作流程图

用户点击拆卸按钮
    ↓
调用 handleUnmountClick(deviceId)
    ↓
设置 pendingUnmountId = deviceId
    ↓
显示 AlertDialog (showUnmountConfirm = true)
    ↓
        ┌──────────────────┐
        │  用户点击"取消"   │ → 关闭对话框,清空 pendingUnmountId
        └──────────────────┘
        │  用户点击"确认拆卸"
        ↓
调用 confirmUnmount()
    ↓
更新设备状态为 "unmounted"
    ↓
保存到 localStorage
    ↓
显示成功提示
    ↓
关闭对话框,清空 pendingUnmountId

核心函数

1. 点击拆卸按钮

const handleUnmountClick = (deviceId: string) => {
  setPendingUnmountId(deviceId);
  setShowUnmountConfirm(true);
};

功能:

  • 记录待拆卸的设备ID
  • 显示确认对话框

2. 确认拆卸

const confirmUnmount = () => {
  if (pendingUnmountId) {
    const updatedDevices = devices.map(d => {
      if (d.id === pendingUnmountId && d.status === 'mounted') {
        return {
          ...d,
          status: 'unmounted' as const,
          unmountedAt: new Date().toISOString(),
          updatedAt: new Date().toISOString(),
        };
      }
      return d;
    });

    setDevices(updatedDevices);
    localStorage.setItem('smart_agriculture_mounted_devices', JSON.stringify(updatedDevices));
    toast.success('设备拆卸成功');
  }
  setShowUnmountConfirm(false);
  setPendingUnmountId(null);
};

功能:

  • 更新设备状态为 "unmounted"
  • 记录拆卸时间
  • 保存到 localStorage
  • 显示成功提示
  • 清理状态

📁 修改文件

核心文件

  1. /components/machinery/load/LoadDevice.tsx

详细变更

1. 导入 AlertDialog 组件

// 新增导入
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from '../../ui/alert-dialog';

2. 添加状态管理

// 新增状态
const [showUnmountConfirm, setShowUnmountConfirm] = useState(false);
const [pendingUnmountId, setPendingUnmountId] = useState<string | null>(null);

3. 重构拆卸逻辑

// 修改前
const handleUnmount = (deviceId: string) => {
  // 直接拆卸逻辑
};

// 修改后
const handleUnmountClick = (deviceId: string) => {
  // 触发确认对话框
};

const confirmUnmount = () => {
  // 确认后执行拆卸
};

4. 更新按钮事件

// 修改前
onClick={() => {
  if (confirm('确定要拆卸此设备吗?')) {
    handleUnmount(device.id);
  }
}}

// 修改后
onClick={() => handleUnmountClick(device.id)}

5. 添加 AlertDialog 组件

<AlertDialog open={showUnmountConfirm} onOpenChange={setShowUnmountConfirm}>
  <AlertDialogContent>
    <AlertDialogHeader>
      <AlertDialogTitle>确认拆卸设备</AlertDialogTitle>
      <AlertDialogDescription>
        确定要拆卸此设备吗?拆卸后设备状态将变为"已拆卸",可以重新挂载到其他农机上。
      </AlertDialogDescription>
    </AlertDialogHeader>
    <AlertDialogFooter>
      <AlertDialogCancel onClick={() => setPendingUnmountId(null)}>
        取消
      </AlertDialogCancel>
      <AlertDialogAction onClick={confirmUnmount} className="bg-red-600 hover:bg-red-700">
        确认拆卸
      </AlertDialogAction>
    </AlertDialogFooter>
  </AlertDialogContent>
</AlertDialog>

🎨 视觉设计

AlertDialog 样式特点

标题

确认拆卸设备
  • 清晰的操作说明
  • 标准字体大小

描述

确定要拆卸此设备吗?拆卸后设备状态将变为"已拆卸"
可以重新挂载到其他农机上。
  • 详细的操作说明
  • 告知用户操作后果
  • 提示后续可用操作

按钮样式

取消按钮:

<AlertDialogCancel>
  取消
</AlertDialogCancel>
  • 默认灰色样式
  • 左侧位置
  • 安全操作

确认按钮:

<AlertDialogAction className="bg-red-600 hover:bg-red-700">
  确认拆卸
</AlertDialogAction>
  • 🔴 红色警告色(bg-red-600
  • 🔴 悬停加深(hover:bg-red-700
  • 右侧位置
  • 危险操作提示

响应式设计

桌面端:

┌────────────────────────────────────────────┐
│  确认拆卸设备                               │
│                                            │
│  确定要拆卸此设备吗?拆卸后设备状态将        │
│  变为"已拆卸",可以重新挂载到其他农机上。   │
│                                            │
│                    [取消]  [确认拆卸] 🔴    │
└────────────────────────────────────────────┘
宽度适中,居中显示

移动端:

┌──────────────────────────┐
│  确认拆卸设备             │
│                          │
│  确定要拆卸此设备吗?     │
│  拆卸后设备状态将变为     │
│  "已拆卸",可以重新挂    │
│  载到其他农机上。         │
│                          │
│      [取消]              │
│      [确认拆卸] 🔴        │
└──────────────────────────┐
自适应宽度,按钮垂直排列

💡 功能特性

1. 安全确认

防误操作:

  • 两步确认流程
  • 清晰的操作说明
  • 红色警告按钮
  • 可以取消操作

2. 用户体验

友好提示:

  • 说明操作后果
  • 提示后续可用操作
  • 成功提示Toast
  • 平滑的动画效果

3. 数据处理

完整记录:

{
  ...device,
  status: 'unmounted',           // 状态改为已拆卸
  unmountedAt: '2025-10-16T...',  // 记录拆卸时间
  updatedAt: '2025-10-16T...',    // 更新时间戳
}

4. 状态管理

清晰的状态流转:

挂载中 (mounted)
    ↓
点击拆卸按钮
    ↓
显示确认对话框
    ↓ [确认]
已拆卸 (unmounted)

📋 完整示例

场景:拆卸北斗终端

1. 初始状态

┌─────────────────────────────────────────────────────┐
│ 约翰迪尔拖拉机                          [挂载设备]    │
│ JD6B-1504                                           │
├─────────────────────────────────────────────────────┤
│ 设备名称        │ 设备类型  │ 序列号      │ 操作    │
│ 北斗终端-001    │ 北斗终端  │ BD2001234567│ [🔗]   │
└─────────────────────────────────────────────────────┘

2. 点击拆卸按钮

handleUnmountClick('device-1')

setPendingUnmountId('device-1')

setShowUnmountConfirm(true)

3. 显示确认对话框

┌────────────────────────────────────────────┐
│  确认拆卸设备                               │
│                                            │
│  确定要拆卸此设备吗?拆卸后设备状态将        │
│  变为"已拆卸",可以重新挂载到其他农机上。   │
│                                            │
│                    [取消]  [确认拆卸] 🔴    │
└────────────────────────────────────────────┘

4. 点击"确认拆卸"

confirmUnmount()

更新设备状态为 'unmounted'

localStorage.setItem(...)

toast.success('设备拆卸成功') 

5. 拆卸后状态

┌─────────────────────────────────────────────────────┐
│ 约翰迪尔拖拉机                          [挂载设备]    │
│ JD6B-1504                                           │
├─────────────────────────────────────────────────────┤
│            暂无挂载设备                             │
│                                                     │
└─────────────────────────────────────────────────────┘

统计数据更新:
- 总设备数: 1
- 已挂载: 0 ⬇️
- 已拆卸: 1 ⬆️

🔍 与其他确认对话框的对比

驾驶员任务管理

已使用 AlertDialog:

  • 接收任务确认
  • 取消任务确认
  • 完成任务确认
  • 终止任务确认

负载管理(本次更新)

新增 AlertDialog:

  • 拆卸设备确认

一致性

所有危险操作都使用相同的确认模式:

// 统一的 AlertDialog 结构
<AlertDialog>
  <AlertDialogHeader>
    <AlertDialogTitle>操作标题</AlertDialogTitle>
    <AlertDialogDescription>详细说明</AlertDialogDescription>
  </AlertDialogHeader>
  <AlertDialogFooter>
    <AlertDialogCancel>取消</AlertDialogCancel>
    <AlertDialogAction className="bg-red-600">确认</AlertDialogAction>
  </AlertDialogFooter>
</AlertDialog>

统一特点:

  • 相同的组件结构
  • 一致的交互逻辑
  • 统一的视觉风格
  • 标准的状态管理

验证清单

功能验证

  • 点击拆卸按钮显示 AlertDialog
  • 点击"取消"关闭对话框,不执行拆卸
  • 点击"确认拆卸"执行拆卸操作
  • 拆卸成功显示 Toast 提示
  • 设备状态更新为"已拆卸"
  • 统计数据实时更新

视觉验证

  • 对话框样式符合系统风格
  • "确认拆卸"按钮为红色警告色
  • 描述文字清晰易懂
  • 响应式布局正常
  • 动画效果流畅

数据验证

  • 设备状态正确更新
  • 拆卸时间正确记录
  • localStorage 数据一致
  • 页面数据即时更新

交互验证

  • 键盘操作支持ESC关闭
  • 点击遮罩层关闭
  • 多次操作状态正确
  • 无内存泄漏

🎉 升级收益

用户体验提升

修改前:

  • 突兀的浏览器弹窗
  • 信息展示有限
  • 样式不统一
  • 移动端体验差

修改后:

  • 优雅的系统对话框
  • 详细的操作说明
  • 统一的视觉风格
  • 响应式友好

开发维护提升

修改前:

  • 浏览器API无法自定义
  • 不符合现代UI规范
  • 难以测试

修改后:

  • React组件易于维护
  • 符合系统设计规范
  • 方便单元测试
  • 代码结构清晰

系统一致性

统一的确认模式:

  • 所有危险操作使用 AlertDialog
  • 相同的交互逻辑
  • 一致的视觉体验
  • 标准的状态管理

📊 使用统计

系统内 AlertDialog 使用情况

模块 功能 状态
驾驶员任务管理 接收任务 已使用
驾驶员任务管理 取消任务 已使用
驾驶员任务管理 完成任务 已使用
驾驶员任务管理 终止任务 已使用
负载管理 拆卸设备 本次新增

confirm() 使用情况

模块 功能 状态
负载管理 拆卸设备 已移除
其他模块 - 待检查

🔮 后续优化建议

1. 批量操作支持

建议: 支持批量拆卸设备

const [selectedDevices, setSelectedDevices] = useState<string[]>([]);

const confirmBatchUnmount = () => {
  // 批量拆卸逻辑
};

2. 拆卸原因记录

建议: 记录拆卸原因

interface UnmountReason {
  reason: string;
  remarks?: string;
}

3. 撤销操作

建议: 提供拆卸撤销功能

const undoUnmount = (deviceId: string) => {
  // 撤销拆卸,恢复为挂载状态
};

4. 历史记录

建议: 记录完整的挂载/拆卸历史

interface MountHistory {
  action: 'mount' | 'unmount';
  timestamp: string;
  operator: string;
  remarks?: string;
}

📝 注意事项

1. 状态管理

重要: 确保正确清理状态

// ✅ 正确:取消时清理状态
<AlertDialogCancel onClick={() => setPendingUnmountId(null)}>
  取消
</AlertDialogCancel>

// ❌ 错误:未清理状态
<AlertDialogCancel>
  取消
</AlertDialogCancel>

2. 操作权限

建议: 根据用户角色控制拆卸权限

const canUnmount = currentUser.role === 'admin' || currentUser.role === 'technician';

<Button
  disabled={!canUnmount}
  onClick={() => handleUnmountClick(device.id)}
>
  <Unlink className="w-4 h-4" />
</Button>

3. 数据验证

确保: 只能拆卸已挂载的设备

const confirmUnmount = () => {
  if (pendingUnmountId) {
    const device = devices.find(d => d.id === pendingUnmountId);
    if (device?.status !== 'mounted') {
      toast.error('只能拆卸已挂载的设备');
      return;
    }
    // 执行拆卸
  }
};

🎓 总结

成功将负载管理的设备拆卸操作从浏览器原生 confirm() 升级为系统内的 AlertDialog 二次确认提示,提升了用户体验和系统一致性。

核心改进:

  1. 引入 AlertDialog 组件
  2. 重构状态管理和事件处理
  3. 添加详细的操作说明
  4. 使用红色警告按钮
  5. 保持系统视觉风格统一

用户收益:

  • 🎨 更好的视觉体验
  • 📱 更友好的移动端支持
  • 💡 更清晰的操作指引
  • 🛡️ 更安全的操作确认

开发收益:

  • 🧩 更易维护的代码结构
  • 🔄 更统一的确认模式
  • 更方便的测试
  • 📚 更好的代码可读性

更新人: AI助手
更新日期: 2025-10-16
版本: v1.0
影响范围: 负载管理 - 设备拆卸功能