15 KiB
15 KiB
驾驶员任务管理 - AlertDialog 二次确认更新
📅 更新时间
2025-10-16
🎯 更新概述
将驾驶员任务管理中的关键操作从浏览器原生 confirm 弹窗升级为系统内的 AlertDialog 组件,提供更统一、更美观的用户体验。
✨ 主要变更
1. 替换浏览器原生确认
变更前 ❌:
if (confirm(`确定要取消任务 ${task.taskNumber} 吗?`)) {
handleUpdateStatus(taskId, '已取消');
}
- 使用浏览器原生
confirm()函数 - 样式无法定制
- 与系统UI风格不一致
变更后 ✅:
<AlertDialog open={showCancelConfirm}>
<AlertDialogContent>
<AlertDialogTitle>确认取消任务</AlertDialogTitle>
<AlertDialogDescription>...</AlertDialogDescription>
<AlertDialogFooter>
<AlertDialogCancel>我再想想</AlertDialogCancel>
<AlertDialogAction>确认取消</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
- 使用 ShadCN AlertDialog 组件
- 统一的系统UI风格
- 可定制的样式和交互
2. 涉及的操作
✅ 接收任务
触发条件: 点击待接收任务的"接收"按钮(CheckCircle 图标)
确认对话框:
- 标题: 确认接收任务
- 内容: 确定要接收任务 T202510160001 吗?接收后将由您负责执行此任务。
- 按钮:
- 取消(灰色)
- 确认接收(绿色,bg-green-600)
操作流程:
点击接收按钮
↓
显示 AlertDialog
↓
用户确认
↓
任务状态: 待接收 → 已接收
↓
Toast 提示: "任务状态更新成功"
❌ 取消任务
触发条件: 点击待接收或已接收任务的"取消"按钮(XCircle 图标,红色)
确认对话框:
- 标题: 确认取消任务
- 内容: 确定要取消任务 T202510160001 吗?取消后将无法恢复,请谨慎操作。
- 按钮:
- 我再想想(灰色)
- 确认取消(红色,bg-red-600)
操作流程:
点击取消按钮
↓
显示 AlertDialog(红色警告)
↓
用户确认
↓
任务状态: 待接收/已接收 → 已取消
↓
Toast 提示: "任务状态更新成功"
✅ 完成任务
触发条件: 点击进行中任务的"完成"按钮
确认对话框:
- 标题: 确认完成任务
- 内容: 确定要将任务 T202510160001 标记为已完成吗?完成后将自动记录实际结束时间并计算工时。
- 按钮:
- 取消(灰色)
- 确认完成(紫色,bg-purple-600)
操作流程:
点击完成按钮
↓
显示 AlertDialog
↓
用户确认
↓
任务状态: 进行中 → 已完成
记录结束时间
计算工时
↓
Toast 提示: "任务状态更新成功"
🎨 视觉设计
AlertDialog 样式规范
接收任务对话框
┌─────────────────────────────────────┐
│ 确认接收任务 │
├─────────────────────────────────────┤
│ 确定要接收任务 T202510160001 吗? │
│ 接收后将由您负责执行此任务。 │
├─────────────────────────────────────┤
│ [取消] [确认接收] │
│ └─ 绿色 │
└─────────────────────────────────────┘
取消任务对话框
┌─────────────────────────────────────┐
│ 确认取消任务 │
├─────────────────────────────────────┤
│ 确定要取消任务 T202510160001 吗? │
│ ⚠️ 取消后将无法恢复,请谨慎操作。 │
│ └─ 红色加粗强调 │
├─────────────────────────────────────┤
│ [我再想想] [确认取消] │
│ └─ 红色 │
└─────────────────────────────────────┘
完成任务对话框
┌─────────────────────────────────────┐
│ 确认完成任务 │
├─────────────────────────────────────┤
│ 确定要将任务 T202510160001 标记为 │
│ 已完成吗? │
│ 完成后将自动记录实际结束时间并计算 │
│ 工时。 │
├─────────────────────────────────────┤
│ [取消] [确认完成] │
│ └─ 紫色 │
└─────────────────────────────────────┘
颜色规范
| 操作 | 按钮颜色 | Tailwind 类 | 语义 |
|---|---|---|---|
| 接收任务 | 绿色 | bg-green-600 hover:bg-green-700 | 正向操作 |
| 取消任务 | 红色 | bg-red-600 hover:bg-red-700 | 危险操作 |
| 完成任务 | 紫色 | bg-purple-600 hover:bg-purple-700 | 完成状态 |
📁 修改文件
1. /components/machinery/driver/DriverTask.tsx
新增导入
import { AlertDialog, AlertDialogAction, AlertDialogCancel,
AlertDialogContent, AlertDialogDescription, AlertDialogFooter,
AlertDialogHeader, AlertDialogTitle } from '../../ui/alert-dialog';
新增状态
// AlertDialog 状态
const [showAcceptConfirm, setShowAcceptConfirm] = useState(false);
const [showCancelConfirm, setShowCancelConfirm] = useState(false);
const [showCompleteConfirm, setShowCompleteConfirm] = useState(false);
const [pendingTaskId, setPendingTaskId] = useState<string | null>(null);
新增函数
// 接收任务确认
const handleAcceptTask = (taskId: string) => {
setPendingTaskId(taskId);
setShowAcceptConfirm(true);
};
const confirmAcceptTask = () => {
if (pendingTaskId) {
handleUpdateStatus(pendingTaskId, '已接收');
}
setShowAcceptConfirm(false);
setPendingTaskId(null);
};
// 取消任务确认
const handleCancelTask = (taskId: string) => {
setPendingTaskId(taskId);
setShowCancelConfirm(true);
};
const confirmCancelTask = () => {
if (pendingTaskId) {
handleUpdateStatus(pendingTaskId, '已取消');
}
setShowCancelConfirm(false);
setPendingTaskId(null);
};
// 完成任务确认
const handleCompleteTask = (taskId: string) => {
setPendingTaskId(taskId);
setShowCompleteConfirm(true);
};
const confirmCompleteTask = () => {
if (pendingTaskId) {
handleUpdateStatus(pendingTaskId, '已完成');
}
setShowCompleteConfirm(false);
setPendingTaskId(null);
};
更新按钮点击事件
// 接收按钮
onClick={() => handleAcceptTask(task.id)} // 原: handleUpdateStatus(task.id, '已接收')
// 取消按钮
onClick={() => handleCancelTask(task.id)} // 保持不变,但内部逻辑改为显示对话框
// 完成按钮
onClick={() => handleCompleteTask(task.id)} // 原: handleUpdateStatus(task.id, '已完成')
新增 AlertDialog 组件
在组件 return 的末尾(所有 Dialog 之后)添加三个 AlertDialog。
🔄 工作流程
状态管理流程
用户点击操作按钮
↓
设置 pendingTaskId
↓
显示对应的 AlertDialog
↓
用户选择:
├─ 点击取消 → 关闭对话框,清空 pendingTaskId
└─ 点击确认 → 执行操作,更新任务状态,关闭对话框,清空 pendingTaskId
代码执行流程
// 1. 用户点击接收按钮
<Button onClick={() => handleAcceptTask(task.id)}>
// 2. 触发 handleAcceptTask
const handleAcceptTask = (taskId: string) => {
setPendingTaskId(taskId); // 保存任务ID
setShowAcceptConfirm(true); // 显示对话框
};
// 3. AlertDialog 显示
<AlertDialog open={showAcceptConfirm}>
// 4. 用户点击确认
<AlertDialogAction onClick={confirmAcceptTask}>
// 5. 执行确认操作
const confirmAcceptTask = () => {
if (pendingTaskId) {
handleUpdateStatus(pendingTaskId, '已接收'); // 更新状态
}
setShowAcceptConfirm(false); // 关闭对话框
setPendingTaskId(null); // 清空任务ID
};
🎯 用户体验提升
变更前 vs 变更后
| 特性 | 浏览器 confirm | AlertDialog |
|---|---|---|
| 样式统一性 | ❌ 浏览器原生,不可定制 | ✅ 系统统一UI风格 |
| 视觉美观 | ❌ 简陋的弹窗 | ✅ 现代化设计 |
| 信息展示 | ❌ 单行文本 | ✅ 多行详细说明 |
| 按钮文字 | ❌ 固定"确定/取消" | ✅ 自定义文字 |
| 颜色提示 | ❌ 无颜色区分 | ✅ 根据操作类型着色 |
| 动画效果 | ❌ 无动画 | ✅ 流畅的淡入淡出 |
| 移动端适配 | ❌ 适配较差 | ✅ 响应式设计 |
| 键盘操作 | ✅ 支持 Enter/Esc | ✅ 支持 Enter/Esc |
| 可访问性 | ⚠️ 基础支持 | ✅ 完整的 ARIA 支持 |
提升要点
1. 视觉统一 🎨
- 对话框样式与系统其他部分保持一致
- 使用系统配色方案(绿色、红色、紫色)
- 圆角、阴影、间距符合设计规范
2. 信息清晰 📋
- 任务编号高亮: 使用
font-semibold和对应颜色 - 多行说明: 清晰说明操作的后果
- 危险操作警告: 红色加粗文字强调不可逆操作
3. 交互友好 🤝
- 自定义按钮文字: "我再想想"比"取消"更人性化
- 颜色语义: 绿色=正向,红色=危险,紫色=完成
- 悬停效果: hover 状态颜色变深
4. 响应式设计 📱
- AlertDialog 自动适配不同屏幕尺寸
- 移动端优化的触摸区域
- 内容自适应布局
📊 操作对比表
接收任务
| 项目 | 原生 confirm | AlertDialog |
|---|---|---|
| 标题 | 无 | "确认接收任务" |
| 内容 | "确定要接收任务吗?" | 任务编号 + 详细说明 |
| 取消按钮 | "取消" | "取消" |
| 确认按钮 | "确定" | "确认接收"(绿色) |
取消任务
| 项目 | 原生 confirm | AlertDialog |
|---|---|---|
| 标题 | 无 | "确认取消任务" |
| 内容 | "确定要取消任务 T202510160001 吗?取消后将无法恢复。" | 任务编号 + 红色警告文字 |
| 取消按钮 | "取消" | "我再想想"(更友好) |
| 确认按钮 | "确定" | "确认取消"(红色) |
完成任务
| 项目 | 原生 confirm | AlertDialog |
|---|---|---|
| 标题 | 无 | "确认完成任务" |
| 内容 | (之前没有确认) | 任务编号 + 工时说明 |
| 取消按钮 | - | "取消" |
| 确认按钮 | - | "确认完成"(紫色) |
🔧 技术实现
状态管理
使用 4 个 React State:
const [showAcceptConfirm, setShowAcceptConfirm] = useState(false); // 接收确认对话框
const [showCancelConfirm, setShowCancelConfirm] = useState(false); // 取消确认对话框
const [showCompleteConfirm, setShowCompleteConfirm] = useState(false); // 完成确认对话框
const [pendingTaskId, setPendingTaskId] = useState<string | null>(null); // 待操作任务ID
为什么使用 pendingTaskId?
问题: 需要在对话框中显示任务信息,并在确认后操作该任务
解决方案:
- 点击按钮时保存任务ID到
pendingTaskId - 在对话框中通过
tasks.find(t => t.id === pendingTaskId)获取任务信息 - 确认后使用
pendingTaskId执行操作 - 操作完成后清空
pendingTaskId
组件结构
<AlertDialog open={showXxxConfirm} onOpenChange={setShowXxxConfirm}>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>标题</AlertDialogTitle>
<AlertDialogDescription>
{/* 动态获取任务信息 */}
{pendingTaskId && tasks.find(t => t.id === pendingTaskId) && (
<>任务编号:{tasks.find(t => t.id === pendingTaskId)?.taskNumber}</>
)}
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>取消</AlertDialogCancel>
<AlertDialogAction onClick={confirmXxx}>确认</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
✅ 测试要点
功能测试
接收任务:
- 点击待接收任务的"接收"按钮
- 弹出绿色主题的确认对话框
- 显示正确的任务编号
- 点击"取消"关闭对话框,任务状态不变
- 点击"确认接收"任务状态变为"已接收"
- 显示 Toast 提示"任务状态更新成功"
取消任务:
- 点击待接收/已接收任务的"取消"按钮
- 弹出红色主题的确认对话框
- 显示红色警告文字
- 点击"我再想想"关闭对话框,任务状态不变
- 点击"确认取消"任务状态变为"已取消"
- 显示 Toast 提示"任务状态更新成功"
完成任务:
- 点击进行中任务的"完成"按钮
- 弹出紫色主题的确认对话框
- 显示工时说明
- 点击"取消"关闭对话框,任务状态不变
- 点击"确认完成"任务状态变为"已完成"
- 自动记录结束时间和计算工时
- 显示 Toast 提示"任务状态更新成功"
UI 测试
- 对话框居中显示
- 背景遮罩半透明
- 按钮颜色正确(绿/红/紫)
- hover 效果正常
- 任务编号高亮显示
- 文字排版整齐
交互测试
- 点击遮罩关闭对话框
- 按 Esc 键关闭对话框
- 按 Enter 键确认操作
- 连续操作不会出现问题
- 对话框关闭动画流畅
响应式测试
- 大屏幕(≥1920px)显示正常
- 中屏幕(1024-1919px)显示正常
- 小屏幕(<1024px)显示正常
- 移动端显示正常
📚 相关文档
- 任务状态更新:
/TASK_STATUS_UPDATE.md - 任务管理指南:
/components/machinery/driver/TASK_MANAGEMENT_GUIDE.md - AlertDialog 更新汇总:
/ALERT_DIALOG_UPDATE_SUMMARY.md - AlertDialog 组件:
/components/ui/alert-dialog.tsx
🎉 总结
通过将浏览器原生 confirm 升级为系统内的 AlertDialog 组件,我们实现了:
✨ 视觉统一 - 与系统UI风格完全一致
✨ 信息丰富 - 清晰展示任务信息和操作后果
✨ 交互友好 - 人性化的按钮文字和颜色提示
✨ 体验流畅 - 动画效果和响应式设计
✨ 安全可靠 - 危险操作有明确警告
现在,驾驶员任务管理的所有关键操作都有了统一、美观、友好的二次确认机制!🎊
更新人: AI助手
更新日期: 2025-10-16
版本: v1.4
影响范围: 驾驶员任务管理 - 接收/取消/完成操作