生产管理系统前端 - 更新瓦力提交的产品原型到参考目录

This commit is contained in:
2025-10-23 10:57:14 +08:00
parent 83523dad64
commit 28229ce795
354 changed files with 147599 additions and 7892 deletions

View File

@@ -0,0 +1,677 @@
# 🔧 负载管理解绑操作升级说明
## 📅 更新时间
2025-10-16
## 🎯 更新内容
将**负载管理**中的设备解绑(拆卸)操作从浏览器原生的 `confirm()` 对话框升级为系统内的 AlertDialog 二次确认提示。
## 📊 修改对比
### 修改前 ❌
**使用浏览器原生对话框**:
```typescript
<Button
variant="ghost"
size="sm"
onClick={() => {
if (confirm('确定要拆卸此设备吗?')) {
handleUnmount(device.id);
}
}}
>
<Unlink className="w-4 h-4" />
</Button>
```
**问题**:
- ❌ 样式无法自定义,与系统风格不统一
- ❌ 浏览器原生弹窗,体验不佳
- ❌ 移动端显示效果差
- ❌ 无法添加详细说明信息
- ❌ 不符合现代UI/UX设计规范
**视觉效果**:
```
┌──────────────────────────────┐
│ [?] 确定要拆卸此设备吗? │
│ │
│ [取消] [确定] │
└──────────────────────────────┘
浏览器原生样式,无法定制
```
### 修改后 ✅
**使用系统 AlertDialog 组件**:
```typescript
// 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. 点击拆卸按钮
```typescript
const handleUnmountClick = (deviceId: string) => {
setPendingUnmountId(deviceId);
setShowUnmountConfirm(true);
};
```
**功能**:
- 记录待拆卸的设备ID
- 显示确认对话框
#### 2. 确认拆卸
```typescript
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 组件
```typescript
// 新增导入
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from '../../ui/alert-dialog';
```
#### 2. 添加状态管理
```typescript
// 新增状态
const [showUnmountConfirm, setShowUnmountConfirm] = useState(false);
const [pendingUnmountId, setPendingUnmountId] = useState<string | null>(null);
```
#### 3. 重构拆卸逻辑
```typescript
// 修改前
const handleUnmount = (deviceId: string) => {
// 直接拆卸逻辑
};
// 修改后
const handleUnmountClick = (deviceId: string) => {
// 触发确认对话框
};
const confirmUnmount = () => {
// 确认后执行拆卸
};
```
#### 4. 更新按钮事件
```typescript
// 修改前
onClick={() => {
if (confirm('确定要拆卸此设备吗?')) {
handleUnmount(device.id);
}
}}
// 修改后
onClick={() => handleUnmountClick(device.id)}
```
#### 5. 添加 AlertDialog 组件
```typescript
<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 样式特点
#### 标题
```
确认拆卸设备
```
- 清晰的操作说明
- 标准字体大小
#### 描述
```
确定要拆卸此设备吗?拆卸后设备状态将变为"已拆卸"
可以重新挂载到其他农机上。
```
- 详细的操作说明
- 告知用户操作后果
- 提示后续可用操作
#### 按钮样式
**取消按钮**:
```tsx
<AlertDialogCancel>
取消
</AlertDialogCancel>
```
- 默认灰色样式
- 左侧位置
- 安全操作
**确认按钮**:
```tsx
<AlertDialogAction className="bg-red-600 hover:bg-red-700">
确认拆卸
</AlertDialogAction>
```
- 🔴 红色警告色(`bg-red-600`
- 🔴 悬停加深(`hover:bg-red-700`
- 右侧位置
- 危险操作提示
### 响应式设计
**桌面端**:
```
┌────────────────────────────────────────────┐
│ 确认拆卸设备 │
│ │
│ 确定要拆卸此设备吗?拆卸后设备状态将 │
│ 变为"已拆卸",可以重新挂载到其他农机上。 │
│ │
│ [取消] [确认拆卸] 🔴 │
└────────────────────────────────────────────┘
宽度适中,居中显示
```
**移动端**:
```
┌──────────────────────────┐
│ 确认拆卸设备 │
│ │
│ 确定要拆卸此设备吗? │
│ 拆卸后设备状态将变为 │
│ "已拆卸",可以重新挂 │
│ 载到其他农机上。 │
│ │
│ [取消] │
│ [确认拆卸] 🔴 │
└──────────────────────────┐
自适应宽度,按钮垂直排列
```
## 💡 功能特性
### 1. 安全确认
**防误操作**:
- ✅ 两步确认流程
- ✅ 清晰的操作说明
- ✅ 红色警告按钮
- ✅ 可以取消操作
### 2. 用户体验
**友好提示**:
- ✅ 说明操作后果
- ✅ 提示后续可用操作
- ✅ 成功提示Toast
- ✅ 平滑的动画效果
### 3. 数据处理
**完整记录**:
```typescript
{
...device,
status: 'unmounted', // 状态改为已拆卸
unmountedAt: '2025-10-16T...', // 记录拆卸时间
updatedAt: '2025-10-16T...', // 更新时间戳
}
```
### 4. 状态管理
**清晰的状态流转**:
```
挂载中 (mounted)
点击拆卸按钮
显示确认对话框
↓ [确认]
已拆卸 (unmounted)
```
## 📋 完整示例
### 场景:拆卸北斗终端
#### 1. 初始状态
```
┌─────────────────────────────────────────────────────┐
│ 约翰迪尔拖拉机 [挂载设备] │
│ JD6B-1504 │
├─────────────────────────────────────────────────────┤
│ 设备名称 │ 设备类型 │ 序列号 │ 操作 │
│ 北斗终端-001 │ 北斗终端 │ BD2001234567│ [🔗] │
└─────────────────────────────────────────────────────┘
```
#### 2. 点击拆卸按钮
```javascript
handleUnmountClick('device-1')
setPendingUnmountId('device-1')
setShowUnmountConfirm(true)
```
#### 3. 显示确认对话框
```
┌────────────────────────────────────────────┐
│ 确认拆卸设备 │
│ │
│ 确定要拆卸此设备吗?拆卸后设备状态将 │
│ 变为"已拆卸",可以重新挂载到其他农机上。 │
│ │
│ [取消] [确认拆卸] 🔴 │
└────────────────────────────────────────────┘
```
#### 4. 点击"确认拆卸"
```javascript
confirmUnmount()
更新设备状态为 'unmounted'
localStorage.setItem(...)
toast.success('设备拆卸成功')
```
#### 5. 拆卸后状态
```
┌─────────────────────────────────────────────────────┐
│ 约翰迪尔拖拉机 [挂载设备] │
│ JD6B-1504 │
├─────────────────────────────────────────────────────┤
│ 暂无挂载设备 │
│ │
└─────────────────────────────────────────────────────┘
统计数据更新:
- 总设备数: 1
- 已挂载: 0 ⬇️
- 已拆卸: 1 ⬆️
```
## 🔍 与其他确认对话框的对比
### 驾驶员任务管理
**已使用 AlertDialog**:
- ✅ 接收任务确认
- ✅ 取消任务确认
- ✅ 完成任务确认
- ✅ 终止任务确认
### 负载管理(本次更新)
**新增 AlertDialog**:
- ✅ 拆卸设备确认
### 一致性
所有危险操作都使用相同的确认模式:
```typescript
// 统一的 AlertDialog 结构
<AlertDialog>
<AlertDialogHeader>
<AlertDialogTitle>操作标题</AlertDialogTitle>
<AlertDialogDescription>详细说明</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>取消</AlertDialogCancel>
<AlertDialogAction className="bg-red-600">确认</AlertDialogAction>
</AlertDialogFooter>
</AlertDialog>
```
**统一特点**:
- ✅ 相同的组件结构
- ✅ 一致的交互逻辑
- ✅ 统一的视觉风格
- ✅ 标准的状态管理
## ✅ 验证清单
### 功能验证
- [x] 点击拆卸按钮显示 AlertDialog
- [x] 点击"取消"关闭对话框,不执行拆卸
- [x] 点击"确认拆卸"执行拆卸操作
- [x] 拆卸成功显示 Toast 提示
- [x] 设备状态更新为"已拆卸"
- [x] 统计数据实时更新
### 视觉验证
- [x] 对话框样式符合系统风格
- [x] "确认拆卸"按钮为红色警告色
- [x] 描述文字清晰易懂
- [x] 响应式布局正常
- [x] 动画效果流畅
### 数据验证
- [x] 设备状态正确更新
- [x] 拆卸时间正确记录
- [x] localStorage 数据一致
- [x] 页面数据即时更新
### 交互验证
- [x] 键盘操作支持ESC关闭
- [x] 点击遮罩层关闭
- [x] 多次操作状态正确
- [x] 无内存泄漏
## 🎉 升级收益
### 用户体验提升
**修改前**:
- ❌ 突兀的浏览器弹窗
- ❌ 信息展示有限
- ❌ 样式不统一
- ❌ 移动端体验差
**修改后**:
- ✅ 优雅的系统对话框
- ✅ 详细的操作说明
- ✅ 统一的视觉风格
- ✅ 响应式友好
### 开发维护提升
**修改前**:
- ❌ 浏览器API无法自定义
- ❌ 不符合现代UI规范
- ❌ 难以测试
**修改后**:
- ✅ React组件易于维护
- ✅ 符合系统设计规范
- ✅ 方便单元测试
- ✅ 代码结构清晰
### 系统一致性
**统一的确认模式**:
- ✅ 所有危险操作使用 AlertDialog
- ✅ 相同的交互逻辑
- ✅ 一致的视觉体验
- ✅ 标准的状态管理
## 📊 使用统计
### 系统内 AlertDialog 使用情况
| 模块 | 功能 | 状态 |
|------|------|------|
| 驾驶员任务管理 | 接收任务 | ✅ 已使用 |
| 驾驶员任务管理 | 取消任务 | ✅ 已使用 |
| 驾驶员任务管理 | 完成任务 | ✅ 已使用 |
| 驾驶员任务管理 | 终止任务 | ✅ 已使用 |
| **负载管理** | **拆卸设备** | ✅ **本次新增** |
### confirm() 使用情况
| 模块 | 功能 | 状态 |
|------|------|------|
| 负载管理 | 拆卸设备 | ✅ 已移除 |
| 其他模块 | - | 待检查 |
## 🔮 后续优化建议
### 1. 批量操作支持
**建议**: 支持批量拆卸设备
```typescript
const [selectedDevices, setSelectedDevices] = useState<string[]>([]);
const confirmBatchUnmount = () => {
// 批量拆卸逻辑
};
```
### 2. 拆卸原因记录
**建议**: 记录拆卸原因
```typescript
interface UnmountReason {
reason: string;
remarks?: string;
}
```
### 3. 撤销操作
**建议**: 提供拆卸撤销功能
```typescript
const undoUnmount = (deviceId: string) => {
// 撤销拆卸,恢复为挂载状态
};
```
### 4. 历史记录
**建议**: 记录完整的挂载/拆卸历史
```typescript
interface MountHistory {
action: 'mount' | 'unmount';
timestamp: string;
operator: string;
remarks?: string;
}
```
## 📝 注意事项
### 1. 状态管理
**重要**: 确保正确清理状态
```typescript
// ✅ 正确:取消时清理状态
<AlertDialogCancel onClick={() => setPendingUnmountId(null)}>
取消
</AlertDialogCancel>
// ❌ 错误:未清理状态
<AlertDialogCancel>
取消
</AlertDialogCancel>
```
### 2. 操作权限
**建议**: 根据用户角色控制拆卸权限
```typescript
const canUnmount = currentUser.role === 'admin' || currentUser.role === 'technician';
<Button
disabled={!canUnmount}
onClick={() => handleUnmountClick(device.id)}
>
<Unlink className="w-4 h-4" />
</Button>
```
### 3. 数据验证
**确保**: 只能拆卸已挂载的设备
```typescript
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
**影响范围**: 负载管理 - 设备拆卸功能