323 lines
14 KiB
TypeScript
323 lines
14 KiB
TypeScript
import { ArrowLeft, Clock, AlertTriangle, ArrowRight, Trash2 } from "lucide-react";
|
||
import { useNavigate } from "react-router";
|
||
import { useState } from "react";
|
||
|
||
export default function RepairOrderDetail() {
|
||
const navigate = useNavigate();
|
||
const [regenerateAuth, setRegenerateAuth] = useState(false);
|
||
const [pushFirmware, setPushFirmware] = useState(false);
|
||
|
||
const processingTimeline = [
|
||
{ time: "2024-03-08 09:00", operator: "张工程师", action: "创建工单", description: "客户报修,设备无法开机" },
|
||
{ time: "2024-03-08 10:30", operator: "李工程师", action: "故障诊断", description: "初步诊断为主控板故障" },
|
||
{ time: "2024-03-08 14:00", operator: "王工程师", action: "板卡更换", description: "更换主控板,测试正常" },
|
||
{ time: "2024-03-08 16:00", operator: "李工程师", action: "测试完成", description: "功能测试通过,等待客户确认" },
|
||
];
|
||
|
||
return (
|
||
<div className="p-6">
|
||
{/* Page Header */}
|
||
<div className="mb-6">
|
||
<div className="flex items-center gap-4 mb-2">
|
||
<button
|
||
onClick={() => navigate(-1)}
|
||
className="p-2 rounded hover:bg-gray-100 transition-colors"
|
||
style={{ color: 'rgba(0, 0, 0, 0.65)' }}
|
||
>
|
||
<ArrowLeft size={20} />
|
||
</button>
|
||
<h2 className="text-2xl font-semibold">维修工单详情</h2>
|
||
<span className="text-xl" style={{ color: 'rgba(0, 0, 0, 0.45)' }}>WO-2024-0001</span>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Work Order Info Card */}
|
||
<div className="bg-white p-6 rounded-lg mb-6" style={{ boxShadow: '0 1px 2px rgba(0, 0, 0, 0.05)' }}>
|
||
<h3 className="text-lg font-semibold mb-6">工单信息</h3>
|
||
<div className="grid grid-cols-3 gap-x-12 gap-y-6">
|
||
<div>
|
||
<div className="text-sm mb-2" style={{ color: 'rgba(0, 0, 0, 0.45)' }}>工单ID</div>
|
||
<div>WO-2024-0001</div>
|
||
</div>
|
||
<div>
|
||
<div className="text-sm mb-2" style={{ color: 'rgba(0, 0, 0, 0.45)' }}>工单状态</div>
|
||
<span
|
||
className="inline-block px-2 py-1 rounded text-xs"
|
||
style={{ backgroundColor: '#E6F7FF', color: '#1890FF', border: '1px solid #91D5FF' }}
|
||
>
|
||
处理中
|
||
</span>
|
||
</div>
|
||
<div>
|
||
<div className="text-sm mb-2" style={{ color: 'rgba(0, 0, 0, 0.45)' }}>优先级</div>
|
||
<span
|
||
className="inline-block px-2 py-1 rounded text-xs"
|
||
style={{ backgroundColor: '#FFF1F0', color: '#FF4D4F', border: '1px solid #FFCCC7' }}
|
||
>
|
||
高
|
||
</span>
|
||
</div>
|
||
<div>
|
||
<div className="text-sm mb-2" style={{ color: 'rgba(0, 0, 0, 0.45)' }}>创建时间</div>
|
||
<div>2024-03-08 09:00</div>
|
||
</div>
|
||
<div>
|
||
<div className="text-sm mb-2" style={{ color: 'rgba(0, 0, 0, 0.45)' }}>负责人</div>
|
||
<div>李工程师</div>
|
||
</div>
|
||
<div>
|
||
<div className="text-sm mb-2" style={{ color: 'rgba(0, 0, 0, 0.45)' }}>预计完成时间</div>
|
||
<div>2024-03-09 18:00</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Device Info Card */}
|
||
<div className="bg-white p-6 rounded-lg mb-6" style={{ boxShadow: '0 1px 2px rgba(0, 0, 0, 0.05)' }}>
|
||
<h3 className="text-lg font-semibold mb-6">设备信息</h3>
|
||
<div className="grid grid-cols-3 gap-x-12 gap-y-6">
|
||
<div>
|
||
<div className="text-sm mb-2" style={{ color: 'rgba(0, 0, 0, 0.45)' }}>设备SN号</div>
|
||
<div>GD30-2025-000001</div>
|
||
</div>
|
||
<div>
|
||
<div className="text-sm mb-2" style={{ color: 'rgba(0, 0, 0, 0.45)' }}>设备型号</div>
|
||
<div>GD30 地质探测仪</div>
|
||
</div>
|
||
<div>
|
||
<div className="text-sm mb-2" style={{ color: 'rgba(0, 0, 0, 0.45)' }}>固件版本</div>
|
||
<div>v2.3.5</div>
|
||
</div>
|
||
<div>
|
||
<div className="text-sm mb-2" style={{ color: 'rgba(0, 0, 0, 0.45)' }}>客户名称</div>
|
||
<div>北京地质研究院</div>
|
||
</div>
|
||
<div>
|
||
<div className="text-sm mb-2" style={{ color: 'rgba(0, 0, 0, 0.45)' }}>联系方式</div>
|
||
<div>010-12345678</div>
|
||
</div>
|
||
<div>
|
||
<div className="text-sm mb-2" style={{ color: 'rgba(0, 0, 0, 0.45)' }}>购买日期</div>
|
||
<div>2025-02-01</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Fault Info Card */}
|
||
<div className="bg-white p-6 rounded-lg mb-6" style={{ boxShadow: '0 1px 2px rgba(0, 0, 0, 0.05)' }}>
|
||
<h3 className="text-lg font-semibold mb-6">故障信息</h3>
|
||
<div className="grid grid-cols-2 gap-x-12 gap-y-6">
|
||
<div>
|
||
<div className="text-sm mb-2" style={{ color: 'rgba(0, 0, 0, 0.45)' }}>故障类型</div>
|
||
<div>硬件故障</div>
|
||
</div>
|
||
<div>
|
||
<div className="text-sm mb-2" style={{ color: 'rgba(0, 0, 0, 0.45)' }}>故障症状</div>
|
||
<div>设备无法开机,指示灯不亮</div>
|
||
</div>
|
||
<div className="col-span-2">
|
||
<div className="text-sm mb-2" style={{ color: 'rgba(0, 0, 0, 0.45)' }}>故障描述</div>
|
||
<div className="p-3 rounded" style={{ backgroundColor: '#FAFAFA', color: 'rgba(0, 0, 0, 0.65)' }}>
|
||
设备在野外作业时突然关机,之后无法重新启动。检查电源连接正常,充电器工作正常,初步判断为主控板损坏。
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Processing Timeline Card */}
|
||
<div className="bg-white p-6 rounded-lg mb-6" style={{ boxShadow: '0 1px 2px rgba(0, 0, 0, 0.05)' }}>
|
||
<h3 className="text-lg font-semibold mb-6">处理记录</h3>
|
||
<div className="relative">
|
||
{/* Timeline line */}
|
||
<div
|
||
className="absolute left-6 top-6 bottom-6 w-0.5"
|
||
style={{ backgroundColor: '#F0F0F0' }}
|
||
></div>
|
||
|
||
<div className="space-y-6">
|
||
{processingTimeline.map((entry, index) => (
|
||
<div key={index} className="flex gap-4">
|
||
<div className="flex flex-col items-center flex-shrink-0">
|
||
<div
|
||
className="w-12 h-12 rounded-full flex items-center justify-center relative z-10"
|
||
style={{ backgroundColor: '#E6F7FF', border: '2px solid #1890FF' }}
|
||
>
|
||
<Clock size={20} style={{ color: '#1890FF' }} />
|
||
</div>
|
||
</div>
|
||
<div className="flex-1 pt-2">
|
||
<div className="flex items-center gap-3 mb-2">
|
||
<span className="font-medium">{entry.action}</span>
|
||
<span className="text-sm" style={{ color: 'rgba(0, 0, 0, 0.45)' }}>{entry.time}</span>
|
||
<span className="text-sm" style={{ color: 'rgba(0, 0, 0, 0.45)' }}>操作人:{entry.operator}</span>
|
||
</div>
|
||
<div className="text-sm" style={{ color: 'rgba(0, 0, 0, 0.65)' }}>
|
||
{entry.description}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Board Replacement Card */}
|
||
<div className="bg-white p-6 rounded-lg mb-6" style={{ boxShadow: '0 1px 2px rgba(0, 0, 0, 0.05)' }}>
|
||
<h3 className="text-lg font-semibold mb-6">板卡更换记录</h3>
|
||
<div className="p-4 rounded-lg" style={{ backgroundColor: '#FAFAFA' }}>
|
||
<div className="flex items-center justify-between">
|
||
<div>
|
||
<div className="text-sm mb-2" style={{ color: 'rgba(0, 0, 0, 0.45)' }}>旧板卡</div>
|
||
<div className="font-medium">主控板 MB20231215001</div>
|
||
</div>
|
||
<ArrowRight size={24} style={{ color: '#1890FF' }} />
|
||
<div>
|
||
<div className="text-sm mb-2" style={{ color: 'rgba(0, 0, 0, 0.45)' }}>新板卡</div>
|
||
<div className="font-medium">主控板 MB20240308001</div>
|
||
</div>
|
||
<div className="text-right">
|
||
<div className="text-sm mb-2" style={{ color: 'rgba(0, 0, 0, 0.45)' }}>更换时间</div>
|
||
<div style={{ color: 'rgba(0, 0, 0, 0.65)' }}>2024-03-08 14:00</div>
|
||
</div>
|
||
<div className="text-right">
|
||
<div className="text-sm mb-2" style={{ color: 'rgba(0, 0, 0, 0.45)' }}>操作人</div>
|
||
<div>王工程师</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* License Processing Card */}
|
||
<div className="bg-white p-6 rounded-lg mb-6" style={{ boxShadow: '0 1px 2px rgba(0, 0, 0, 0.05)' }}>
|
||
<h3 className="text-lg font-semibold mb-6">授权处理</h3>
|
||
<div className="space-y-3">
|
||
<label className="flex items-center gap-3 cursor-pointer">
|
||
<input
|
||
type="checkbox"
|
||
className="w-5 h-5 rounded"
|
||
style={{ accentColor: '#1890FF' }}
|
||
checked={regenerateAuth}
|
||
onChange={(e) => setRegenerateAuth(e.target.checked)}
|
||
/>
|
||
<span>重新生成授权文件(板卡更换后需重新绑定授权)</span>
|
||
</label>
|
||
<label className="flex items-center gap-3 cursor-pointer">
|
||
<input
|
||
type="checkbox"
|
||
className="w-5 h-5 rounded"
|
||
style={{ accentColor: '#1890FF' }}
|
||
checked={pushFirmware}
|
||
onChange={(e) => setPushFirmware(e.target.checked)}
|
||
/>
|
||
<span>推送适配固件(如更换板卡型号不同,需推送兼容固件)</span>
|
||
</label>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Scrap Processing Card */}
|
||
<div className="bg-white p-6 rounded-lg mb-6" style={{ boxShadow: '0 1px 2px rgba(0, 0, 0, 0.05)' }}>
|
||
<h3 className="text-lg font-semibold mb-6">报废处理</h3>
|
||
|
||
{/* Warning Banner */}
|
||
<div
|
||
className="mb-6 p-4 rounded-lg flex items-start gap-3"
|
||
style={{ backgroundColor: '#FFF1F0', border: '1px solid #FFCCC7' }}
|
||
>
|
||
<AlertTriangle size={20} style={{ color: '#FF4D4F', flexShrink: 0, marginTop: 2 }} />
|
||
<div>
|
||
<div className="font-medium" style={{ color: '#CF1322' }}>警告:报废操作不可逆</div>
|
||
<div className="text-sm mt-1" style={{ color: '#FF4D4F' }}>
|
||
报废后设备将无法恢复使用,请谨慎操作
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="grid grid-cols-2 gap-x-12 gap-y-6 mb-6">
|
||
<div>
|
||
<label className="block text-sm mb-2" style={{ color: 'rgba(0, 0, 0, 0.85)' }}>
|
||
报废原因 <span style={{ color: '#FF4D4F' }}>*</span>
|
||
</label>
|
||
<select
|
||
className="w-full px-3 py-2 border rounded"
|
||
style={{ borderColor: '#D9D9D9', backgroundColor: '#fff' }}
|
||
>
|
||
<option>请选择报废原因</option>
|
||
<option>主板损坏无法修复</option>
|
||
<option>多个核心部件损坏</option>
|
||
<option>维修成本超过设备价值</option>
|
||
<option>设备老化严重</option>
|
||
</select>
|
||
</div>
|
||
<div>
|
||
<label className="block text-sm mb-2" style={{ color: 'rgba(0, 0, 0, 0.85)' }}>
|
||
残值评估 (元)
|
||
</label>
|
||
<input
|
||
type="number"
|
||
className="w-full px-3 py-2 border rounded"
|
||
style={{ borderColor: '#D9D9D9' }}
|
||
placeholder="输入残值评估金额"
|
||
defaultValue="500"
|
||
/>
|
||
</div>
|
||
<div className="col-span-2">
|
||
<label className="block text-sm mb-2" style={{ color: 'rgba(0, 0, 0, 0.85)' }}>
|
||
可回收物料
|
||
</label>
|
||
<div className="p-3 rounded border" style={{ borderColor: '#D9D9D9', backgroundColor: '#FAFAFA' }}>
|
||
<div className="flex flex-wrap gap-2">
|
||
<span className="px-3 py-1 rounded text-sm" style={{ backgroundColor: '#E6F7FF', color: '#1890FF' }}>
|
||
采集板 AC20240308002
|
||
</span>
|
||
<span className="px-3 py-1 rounded text-sm" style={{ backgroundColor: '#E6F7FF', color: '#1890FF' }}>
|
||
测控板 CT20240308003
|
||
</span>
|
||
<span className="px-3 py-1 rounded text-sm" style={{ backgroundColor: '#E6F7FF', color: '#1890FF' }}>
|
||
电源模块 PS20240308004
|
||
</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Scrap Process Flow */}
|
||
<div
|
||
className="p-4 rounded-lg flex items-center gap-3"
|
||
style={{ backgroundColor: '#E6F7FF', border: '1px solid #91D5FF' }}
|
||
>
|
||
<div className="text-sm" style={{ color: '#0050B3' }}>
|
||
<span className="font-medium">报废流程:</span>
|
||
申请报废 → 创建报废单 → 报废审批 → 物料回收 → 入库
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Action Bar */}
|
||
<div
|
||
className="flex items-center justify-end gap-3 p-4 bg-white rounded-lg sticky bottom-0"
|
||
style={{ boxShadow: '0 -2px 8px rgba(0, 0, 0, 0.05)' }}
|
||
>
|
||
<button
|
||
className="px-6 py-2 rounded"
|
||
style={{ border: '1px solid #D9D9D9', color: 'rgba(0, 0, 0, 0.85)' }}
|
||
>
|
||
取消
|
||
</button>
|
||
<button
|
||
className="px-6 py-2 rounded text-white"
|
||
style={{ backgroundColor: '#1890FF' }}
|
||
>
|
||
关闭工单
|
||
</button>
|
||
<button
|
||
className="px-6 py-2 rounded flex items-center gap-2"
|
||
style={{ border: '1px solid #FF4D4F', color: '#FF4D4F' }}
|
||
>
|
||
<Trash2 size={16} />
|
||
申请报废
|
||
</button>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|