|
|
@@ -331,7 +331,7 @@ export default function Dashboard() {
|
|
|
setStatistics(statisticsData);
|
|
|
} catch (error: any) {
|
|
|
console.error('获取驾驶舱统计数据失败:', error);
|
|
|
- toast.error(error.message || '获取统计数据失败');
|
|
|
+ toast.error(error.message || t('cockpit.getStatsFailed'));
|
|
|
} finally {
|
|
|
setLoading(false);
|
|
|
}
|
|
|
@@ -384,7 +384,7 @@ export default function Dashboard() {
|
|
|
setManagerWorkCount(data || {});
|
|
|
} catch (error: any) {
|
|
|
console.error('获取管理员工作统计失败:', error);
|
|
|
- toast.error(error.message || '获取管理员工作统计失败');
|
|
|
+ toast.error(error.message || t('cockpit.getManagerWorkStatsFailed'));
|
|
|
setManagerWorkCount({});
|
|
|
}
|
|
|
};
|
|
|
@@ -406,7 +406,7 @@ export default function Dashboard() {
|
|
|
console.log('获取管理员工作列表成功,设置的数据:', data, '数据长度:', data.length);
|
|
|
} catch (error: any) {
|
|
|
console.error('获取管理员工作列表失败:', error);
|
|
|
- toast.error(error.message || '获取管理员工作列表失败');
|
|
|
+ toast.error(error.message || t('cockpit.getManagerWorkListFailed'));
|
|
|
setManagerWorkList([]);
|
|
|
}
|
|
|
};
|
|
|
@@ -429,7 +429,7 @@ export default function Dashboard() {
|
|
|
setManagerDayWorkCount(data);
|
|
|
} catch (error: any) {
|
|
|
console.error('获取管理员每日工作统计失败:', error);
|
|
|
- toast.error(error.message || '获取管理员每日工作统计失败');
|
|
|
+ toast.error(error.message || t('cockpit.getManagerDayStatsFailed'));
|
|
|
setManagerDayWorkCount([]);
|
|
|
}
|
|
|
};
|
|
|
@@ -1143,7 +1143,7 @@ export default function Dashboard() {
|
|
|
|
|
|
if (!task.nodeId) {
|
|
|
console.warn('Dashboard: 节点ID不存在', task);
|
|
|
- message.warning('节点ID不存在');
|
|
|
+ message.warning(t('cockpit.nodeIdNotExist'));
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
@@ -1305,11 +1305,11 @@ export default function Dashboard() {
|
|
|
}, 100);
|
|
|
} else {
|
|
|
console.warn('Dashboard: formData 中缺少 conf 或 fields', { conf: !!conf, fields: !!fields });
|
|
|
- message.warning('表单数据不完整');
|
|
|
+ message.warning(t('cockpit.formDataIncomplete'));
|
|
|
}
|
|
|
} catch (e) {
|
|
|
console.error('Dashboard: 解析 formData 失败', e);
|
|
|
- message.error('解析表单数据失败: ' + (e instanceof Error ? e.message : String(e)));
|
|
|
+ message.error(t('cockpit.parseFormDataFailed') + ': ' + (e instanceof Error ? e.message : String(e)));
|
|
|
} finally {
|
|
|
setFormLoading(false);
|
|
|
}
|
|
|
@@ -1327,7 +1327,7 @@ export default function Dashboard() {
|
|
|
const numericFormId = typeof formId === 'string' ? parseInt(formId, 10) : formId;
|
|
|
if (isNaN(numericFormId)) {
|
|
|
console.error('Dashboard: formId 不是有效数字', formId);
|
|
|
- message.error('表单ID无效');
|
|
|
+ message.error(t('cockpit.formIdInvalid'));
|
|
|
setFormLoading(false);
|
|
|
return;
|
|
|
}
|
|
|
@@ -1428,11 +1428,11 @@ export default function Dashboard() {
|
|
|
}
|
|
|
} else {
|
|
|
console.warn('Dashboard: 表单详情缺少配置或字段', { conf: !!conf, fields: !!fields });
|
|
|
- message.warning('表单配置不完整');
|
|
|
+ message.warning(t('cockpit.formConfigIncomplete'));
|
|
|
}
|
|
|
} catch (e) {
|
|
|
console.error('Dashboard: 获取表单详情失败', e);
|
|
|
- message.error('获取表单详情失败: ' + (e instanceof Error ? e.message : String(e)));
|
|
|
+ message.error(t('cockpit.getFormDetailFailed') + ': ' + (e instanceof Error ? e.message : String(e)));
|
|
|
} finally {
|
|
|
setFormLoading(false);
|
|
|
}
|
|
|
@@ -1451,7 +1451,7 @@ export default function Dashboard() {
|
|
|
console.log('Dashboard: 弹框已打开', { detailVisible: true, detailData: detailDataWithWorkInfo });
|
|
|
} catch (error: any) {
|
|
|
console.error('Dashboard: 获取节点详情失败', error);
|
|
|
- toast.error(error.message || '获取节点详情失败');
|
|
|
+ toast.error(error.message || t('cockpit.getNodeDetailFailed'));
|
|
|
if (!taskDetailData) {
|
|
|
setTaskDetailData({
|
|
|
id: task.nodeId,
|
|
|
@@ -1472,20 +1472,20 @@ export default function Dashboard() {
|
|
|
|
|
|
// 获取任务状态文本(使用字典)
|
|
|
const getTaskStatusText = (status: string | number | undefined): string => {
|
|
|
- if (!status) return '未知';
|
|
|
+ if (!status) return t('cockpit.unknown');
|
|
|
const statusStr = String(status).toLowerCase();
|
|
|
const statusItem = approvalStatusDictList.find(item => String(item.value).toLowerCase() === statusStr);
|
|
|
if (statusItem) {
|
|
|
- return statusItem.label || '未知';
|
|
|
+ return statusItem.label || t('cockpit.unknown');
|
|
|
}
|
|
|
// 如果没有找到字典值,使用默认映射
|
|
|
const statusMap: Record<string, string> = {
|
|
|
- 'pending': '待审核',
|
|
|
- 'approved': '已通过',
|
|
|
- 'rejected': '已驳回',
|
|
|
- 'unaudited': '未审核',
|
|
|
+ 'pending': t('cockpit.pendingAudit'),
|
|
|
+ 'approved': t('cockpit.approved'),
|
|
|
+ 'rejected': t('cockpit.rejected'),
|
|
|
+ 'unaudited': t('cockpit.unaudited'),
|
|
|
};
|
|
|
- return statusMap[statusStr] || '未知';
|
|
|
+ return statusMap[statusStr] || t('cockpit.unknown');
|
|
|
};
|
|
|
|
|
|
// 获取任务状态样式(审批状态)
|
|
|
@@ -1555,44 +1555,44 @@ export default function Dashboard() {
|
|
|
// 获取作业状态标签样式
|
|
|
const getStatusBadge = (status: string) => {
|
|
|
const statusMap: Record<string, { label: string; className: string }> = {
|
|
|
- '待执行': { label: '待执行', className: 'bg-gray-100 text-gray-700 border-gray-200' },
|
|
|
- 'pending': { label: '待执行', className: 'bg-gray-100 text-gray-700 border-gray-200' },
|
|
|
- 'PENDING': { label: '待执行', className: 'bg-gray-100 text-gray-700 border-gray-200' },
|
|
|
- '进行中': { label: '进行中', className: 'bg-blue-100 text-blue-700 border-blue-200' },
|
|
|
- 'in_progress': { label: '进行中', className: 'bg-blue-100 text-blue-700 border-blue-200' },
|
|
|
- 'IN_PROGRESS': { label: '进行中', className: 'bg-blue-100 text-blue-700 border-blue-200' },
|
|
|
- '已完成': { label: '已完成', className: 'bg-green-100 text-green-700 border-green-200' },
|
|
|
- 'completed': { label: '已完成', className: 'bg-green-100 text-green-700 border-green-200' },
|
|
|
- 'COMPLETED': { label: '已完成', className: 'bg-green-100 text-green-700 border-green-200' },
|
|
|
- '逾期': { label: '逾期', className: 'bg-red-100 text-red-700 border-red-200' },
|
|
|
- 'overdue': { label: '逾期', className: 'bg-red-100 text-red-700 border-red-200' },
|
|
|
- 'OVERDUE': { label: '逾期', className: 'bg-red-100 text-red-700 border-red-200' },
|
|
|
+ '待执行': { label: t('cockpit.pending'), className: 'bg-gray-100 text-gray-700 border-gray-200' },
|
|
|
+ 'pending': { label: t('cockpit.pending'), className: 'bg-gray-100 text-gray-700 border-gray-200' },
|
|
|
+ 'PENDING': { label: t('cockpit.pending'), className: 'bg-gray-100 text-gray-700 border-gray-200' },
|
|
|
+ '进行中': { label: t('cockpit.inProgress'), className: 'bg-blue-100 text-blue-700 border-blue-200' },
|
|
|
+ 'in_progress': { label: t('cockpit.inProgress'), className: 'bg-blue-100 text-blue-700 border-blue-200' },
|
|
|
+ 'IN_PROGRESS': { label: t('cockpit.inProgress'), className: 'bg-blue-100 text-blue-700 border-blue-200' },
|
|
|
+ '已完成': { label: t('cockpit.completed'), className: 'bg-green-100 text-green-700 border-green-200' },
|
|
|
+ 'completed': { label: t('cockpit.completed'), className: 'bg-green-100 text-green-700 border-green-200' },
|
|
|
+ 'COMPLETED': { label: t('cockpit.completed'), className: 'bg-green-100 text-green-700 border-green-200' },
|
|
|
+ '逾期': { label: t('cockpit.overdue'), className: 'bg-red-100 text-red-700 border-red-200' },
|
|
|
+ 'overdue': { label: t('cockpit.overdue'), className: 'bg-red-100 text-red-700 border-red-200' },
|
|
|
+ 'OVERDUE': { label: t('cockpit.overdue'), className: 'bg-red-100 text-red-700 border-red-200' },
|
|
|
};
|
|
|
|
|
|
- return statusMap[status] || { label: status || '未知', className: 'bg-gray-100 text-gray-700 border-gray-200' };
|
|
|
+ return statusMap[status] || { label: status || t('cockpit.unknown'), className: 'bg-gray-100 text-gray-700 border-gray-200' };
|
|
|
};
|
|
|
|
|
|
// 从ticketName中提取作业类型
|
|
|
const getJobType = (ticketName: string): string => {
|
|
|
if (ticketName.includes('换产') || ticketName.includes('投产')) {
|
|
|
- return '投产';
|
|
|
+ return t('cockpit.production');
|
|
|
} else if (ticketName.includes('维修')) {
|
|
|
- return '维修';
|
|
|
+ return t('cockpit.maintenance');
|
|
|
} else if (ticketName.includes('PM')) {
|
|
|
return 'PM';
|
|
|
}
|
|
|
- return '未知';
|
|
|
+ return t('cockpit.unknown');
|
|
|
};
|
|
|
|
|
|
// 获取作业状态显示文本和样式(从字典获取)
|
|
|
const getJobStatusInfo = (status: string | number | undefined) => {
|
|
|
if (!status) {
|
|
|
- return { label: '未知', className: 'bg-gray-100 text-gray-700 border-gray-200' };
|
|
|
+ return { label: t('cockpit.unknown'), className: 'bg-gray-100 text-gray-700 border-gray-200' };
|
|
|
}
|
|
|
|
|
|
// 从字典中查找状态文本
|
|
|
const statusItem = jobStatusDictList.find(item => String(item.value) === String(status));
|
|
|
- const statusText = statusItem ? (statusItem.label || '') : String(status || '未知');
|
|
|
+ const statusText = statusItem ? (statusItem.label || '') : String(status || t('cockpit.unknown'));
|
|
|
const statusTextLower = statusText.toLowerCase();
|
|
|
|
|
|
// 根据状态文本判断样式
|
|
|
@@ -1627,7 +1627,7 @@ export default function Dashboard() {
|
|
|
if (loading) {
|
|
|
return (
|
|
|
<div className="flex items-center justify-center h-96">
|
|
|
- <div className="text-gray-500">加载中...</div>
|
|
|
+ <div className="text-gray-500">{t('cockpit.loading')}</div>
|
|
|
</div>
|
|
|
);
|
|
|
}
|
|
|
@@ -1676,14 +1676,14 @@ export default function Dashboard() {
|
|
|
}}
|
|
|
>
|
|
|
<div className="flex items-start justify-between mb-3">
|
|
|
- <div className="text-sm text-gray-500 font-medium">待发布作业</div>
|
|
|
+ <div className="text-sm text-gray-500 font-medium">{t('cockpit.pendingJobs')}</div>
|
|
|
<div className="p-3 rounded-xl flex items-center justify-center flex-shrink-0" style={{ backgroundColor: 'rgba(188, 185, 183, 0.2)' }}>
|
|
|
<Clock className="w-6 h-6 text-black-700" strokeWidth={2} />
|
|
|
</div>
|
|
|
</div>
|
|
|
<div>
|
|
|
<div className="text-2xl font-bold text-gray-900 leading-none">
|
|
|
- {managerWorkCount.unreleasedCount ?? statistics.pendingJobsCount ?? 0} <span className="text-base font-normal text-gray-500">项</span>
|
|
|
+ {managerWorkCount.unreleasedCount ?? statistics.pendingJobsCount ?? 0} <span className="text-base font-normal text-gray-500">{t('cockpit.items')}</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
@@ -1704,14 +1704,14 @@ export default function Dashboard() {
|
|
|
}}
|
|
|
>
|
|
|
<div className="flex items-start justify-between mb-3">
|
|
|
- <div className="text-sm text-gray-500 font-medium">进行中作业</div>
|
|
|
+ <div className="text-sm text-gray-500 font-medium">{t('cockpit.inProgressJobs')}</div>
|
|
|
<div className="p-3 rounded-xl flex items-center justify-center flex-shrink-0" style={{ backgroundColor: 'rgba(59, 130, 246, 0.2)' }}>
|
|
|
<PlayCircle className="w-6 h-6 text-blue-700" strokeWidth={2} />
|
|
|
</div>
|
|
|
</div>
|
|
|
<div>
|
|
|
<div className="text-2xl font-bold text-gray-900 leading-none">
|
|
|
- {managerWorkCount.runningCount ?? statistics.inProgressJobsCount ?? 0} <span className="text-base font-normal text-gray-500">项</span>
|
|
|
+ {managerWorkCount.runningCount ?? statistics.inProgressJobsCount ?? 0} <span className="text-base font-normal text-gray-500">{t('cockpit.items')}</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
@@ -1732,14 +1732,14 @@ export default function Dashboard() {
|
|
|
}}
|
|
|
>
|
|
|
<div className="flex items-start justify-between mb-3">
|
|
|
- <div className="text-sm text-gray-500 font-medium">已完成作业</div>
|
|
|
+ <div className="text-sm text-gray-500 font-medium">{t('cockpit.completedJobs')}</div>
|
|
|
<div className="p-3 rounded-xl flex items-center justify-center flex-shrink-0" style={{ backgroundColor: 'rgba(34, 197, 94, 0.2)' }}>
|
|
|
<CheckCircle className="w-6 h-6 text-green-700" strokeWidth={2} />
|
|
|
</div>
|
|
|
</div>
|
|
|
<div>
|
|
|
<div className="text-2xl font-bold text-gray-900 leading-none">
|
|
|
- {managerWorkCount.completedCount ?? statistics.completedJobsCount ?? 0} <span className="text-base font-normal text-gray-500">项</span>
|
|
|
+ {managerWorkCount.completedCount ?? statistics.completedJobsCount ?? 0} <span className="text-base font-normal text-gray-500">{t('cockpit.items')}</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
@@ -1748,7 +1748,7 @@ export default function Dashboard() {
|
|
|
{showOverdueJobs && (
|
|
|
<div className="flex-1 bg-white rounded-lg border border-red-200 p-4 shadow-sm hover:shadow-md transition-shadow relative overflow-hidden">
|
|
|
<div className="flex items-start justify-between mb-3">
|
|
|
- <div className="text-sm text-gray-500 font-medium">逾期作业</div>
|
|
|
+ <div className="text-sm text-gray-500 font-medium">{t('cockpit.overdueJobs')}</div>
|
|
|
<div className="p-3 rounded-xl flex items-center justify-center flex-shrink-0" style={{ backgroundColor: 'rgba(239, 68, 68, 0.2)' }}>
|
|
|
<AlertTriangle className="w-6 h-6 text-red-700" strokeWidth={2} />
|
|
|
</div>
|
|
|
@@ -1756,14 +1756,14 @@ export default function Dashboard() {
|
|
|
<div className="flex items-center justify-between">
|
|
|
<div>
|
|
|
<div className="text-2xl font-bold text-gray-900 leading-none">
|
|
|
- {statistics.overdueJobsCount ?? 0} <span className="text-base font-normal text-gray-500">项</span>
|
|
|
+ {statistics.overdueJobsCount ?? 0} <span className="text-base font-normal text-gray-500">{t('cockpit.items')}</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
<button
|
|
|
onClick={() => setShowOverdueJobs(false)}
|
|
|
className="text-red-600 text-sm font-medium hover:text-red-700 transition-colors"
|
|
|
>
|
|
|
- 隐藏
|
|
|
+ {t('cockpit.hide')}
|
|
|
</button>
|
|
|
</div>
|
|
|
</div>
|
|
|
@@ -1774,7 +1774,7 @@ export default function Dashboard() {
|
|
|
<Card
|
|
|
title={
|
|
|
<div className="flex items-center justify-between">
|
|
|
- <span>作业列表 (含任务明细)</span>
|
|
|
+ <span>{t('cockpit.jobListWithTasks')}</span>
|
|
|
<button
|
|
|
onClick={() => {
|
|
|
// 通过 sessionStorage 传递参数,让 Dashboard 自动切换到作业管理菜单
|
|
|
@@ -1799,14 +1799,14 @@ export default function Dashboard() {
|
|
|
onMouseEnter={(e) => e.currentTarget.style.color = '#1d4ed8'}
|
|
|
onMouseLeave={(e) => e.currentTarget.style.color = '#2563eb'}
|
|
|
>
|
|
|
- 查看全部作业
|
|
|
+ {t('cockpit.viewAllJobs')}
|
|
|
</button>
|
|
|
</div>
|
|
|
}
|
|
|
>
|
|
|
<div className="border border-gray-200 rounded-lg overflow-hidden">
|
|
|
{managerDataLoading ? (
|
|
|
- <div className="p-8 text-center text-gray-500">加载中...</div>
|
|
|
+ <div className="p-8 text-center text-gray-500">{t('cockpit.loading')}</div>
|
|
|
) : managerWorkList.length > 0 ? (
|
|
|
<Collapse
|
|
|
activeKey={Array.from(expandedJobs).map(id => String(id))}
|
|
|
@@ -1852,7 +1852,7 @@ export default function Dashboard() {
|
|
|
const isSelected = selectedJob === job.id;
|
|
|
const statusInfo = getTaskStatusInfo(job.status);
|
|
|
const jobName = job.name || job.orderNo || job.code || `作业#${job.id}`;
|
|
|
- const responsiblePerson = job.initiatorName || job.initiator || '未分配';
|
|
|
+ const responsiblePerson = job.initiatorName || job.initiator || t('cockpit.unassigned');
|
|
|
|
|
|
return (
|
|
|
<Panel
|
|
|
@@ -1888,7 +1888,7 @@ export default function Dashboard() {
|
|
|
<span className={`text-sm truncate block ${
|
|
|
isSelected ? '' : 'text-gray-900'
|
|
|
}`} style={isSelected ? { color: '#2563eb' } : { color: '#111827' }}>
|
|
|
- <span>作业发起人:</span>{responsiblePerson}
|
|
|
+ <span>{t('cockpit.jobInitiator')}:</span>{responsiblePerson}
|
|
|
</span>
|
|
|
</div>
|
|
|
{/* 整体进度 - 固定宽度和位置,右对齐 */}
|
|
|
@@ -1896,7 +1896,7 @@ export default function Dashboard() {
|
|
|
<span className={`text-sm whitespace-nowrap ${
|
|
|
isSelected ? '' : 'text-gray-900'
|
|
|
}`} style={isSelected ? { color: '#2563eb' } : { color: '#111827' }}>
|
|
|
- <span>整体进度:</span>{calculateJobProgress(job)}%
|
|
|
+ <span>{t('cockpit.overallProgress')}:</span>{calculateJobProgress(job)}%
|
|
|
</span>
|
|
|
</div>
|
|
|
{/* 右侧弹性空间 */}
|
|
|
@@ -1917,16 +1917,16 @@ export default function Dashboard() {
|
|
|
<div className="px-3 pb-3 pt-3 bg-white">
|
|
|
<div className="overflow-x-auto">
|
|
|
{taskLoadingMap.get(job.id!) ? (
|
|
|
- <div className="px-4 py-8 text-center text-sm text-gray-500">加载中...</div>
|
|
|
+ <div className="px-4 py-8 text-center text-sm text-gray-500">{t('cockpit.loading')}</div>
|
|
|
) : (
|
|
|
<table className="w-full border-collapse">
|
|
|
<thead>
|
|
|
<tr className="bg-gray-50 border-b border-gray-200">
|
|
|
- <th className="px-4 py-3 text-left text-xs font-medium text-gray-700">任务名称</th>
|
|
|
- <th className="px-4 py-3 text-left text-xs font-medium text-gray-700">任务负责人</th>
|
|
|
- <th className="px-4 py-3 text-left text-xs font-medium text-gray-700">开始时间</th>
|
|
|
- <th className="px-4 py-3 text-left text-xs font-medium text-gray-700">状态</th>
|
|
|
- <th className="px-4 py-3 text-center text-xs font-medium text-gray-700">操作</th>
|
|
|
+ <th className="px-4 py-3 text-left text-xs font-medium text-gray-700">{t('cockpit.taskName')}</th>
|
|
|
+ <th className="px-4 py-3 text-left text-xs font-medium text-gray-700">{t('cockpit.taskOwner')}</th>
|
|
|
+ <th className="px-4 py-3 text-left text-xs font-medium text-gray-700">{t('cockpit.startTime')}</th>
|
|
|
+ <th className="px-4 py-3 text-left text-xs font-medium text-gray-700">{t('cockpit.status')}</th>
|
|
|
+ <th className="px-4 py-3 text-center text-xs font-medium text-gray-700">{t('cockpit.action')}</th>
|
|
|
</tr>
|
|
|
</thead>
|
|
|
<tbody className="bg-white">
|
|
|
@@ -1994,7 +1994,7 @@ export default function Dashboard() {
|
|
|
})}
|
|
|
</Collapse>
|
|
|
) : (
|
|
|
- <div className="p-8 text-center text-gray-500">暂无作业数据</div>
|
|
|
+ <div className="p-8 text-center text-gray-500">{t('cockpit.noJobData')}</div>
|
|
|
)}
|
|
|
</div>
|
|
|
</Card>
|
|
|
@@ -2003,7 +2003,7 @@ export default function Dashboard() {
|
|
|
{/* 全系统作业完成趋势图表 */}
|
|
|
<div className="bg-white rounded-lg shadow-sm border border-gray-200 p-6">
|
|
|
<h3 className="text-lg font-semibold text-gray-900 mb-6">
|
|
|
- 全系统作业完成趋势 (最近30天)
|
|
|
+ {t('cockpit.systemJobCompleteTrend')}
|
|
|
</h3>
|
|
|
<div className="h-80">
|
|
|
<ResponsiveContainer width="100%" height="100%">
|
|
|
@@ -2069,7 +2069,7 @@ export default function Dashboard() {
|
|
|
strokeWidth={2}
|
|
|
fill="url(#colorCompleted)"
|
|
|
dot={{ fill: '#3b82f6', r: 4, strokeWidth: 2, stroke: '#fff' }}
|
|
|
- name="每日完成作业数"
|
|
|
+ name={t('cockpit.dailyCompletedCount')}
|
|
|
/>
|
|
|
</AreaChart>
|
|
|
</ResponsiveContainer>
|
|
|
@@ -2078,14 +2078,14 @@ export default function Dashboard() {
|
|
|
|
|
|
{/* 物料管理部分 */}
|
|
|
<div className="bg-white rounded-lg shadow-sm border border-gray-200 p-6">
|
|
|
- <h3 className="text-lg font-semibold text-gray-900 mb-4">物料管理</h3>
|
|
|
+ <h3 className="text-lg font-semibold text-gray-900 mb-4">{t('cockpit.materialManagement')}</h3>
|
|
|
<div className="flex gap-4">
|
|
|
{/* 可用物料 - 绿色 */}
|
|
|
<div className="flex-1 bg-green-50 rounded-lg border border-green-200 p-5 text-center">
|
|
|
<div className="text-3xl font-bold text-green-900 mb-2">
|
|
|
{statistics.availableMaterialsCount || 0}
|
|
|
</div>
|
|
|
- <div className="text-sm text-green-700">可用物料</div>
|
|
|
+ <div className="text-sm text-green-700">{t('cockpit.availableMaterials')}</div>
|
|
|
</div>
|
|
|
|
|
|
{/* 借用中物料 - 橙色 */}
|
|
|
@@ -2093,7 +2093,7 @@ export default function Dashboard() {
|
|
|
<div className="text-3xl font-bold text-orange-900 mb-2">
|
|
|
{statistics.loanMaterialsCount || 0}
|
|
|
</div>
|
|
|
- <div className="text-sm text-orange-700">借用中物料</div>
|
|
|
+ <div className="text-sm text-orange-700">{t('cockpit.borrowedMaterials')}</div>
|
|
|
</div>
|
|
|
|
|
|
{/* 异常物料 - 红色 */}
|
|
|
@@ -2101,7 +2101,7 @@ export default function Dashboard() {
|
|
|
<div className="text-3xl font-bold text-red-900 mb-2">
|
|
|
{statistics.exceptionMaterialsCount || 0}
|
|
|
</div>
|
|
|
- <div className="text-sm text-red-700">异常物料</div>
|
|
|
+ <div className="text-sm text-red-700">{t('cockpit.exceptionMaterials')}</div>
|
|
|
</div>
|
|
|
|
|
|
{/* 待归还物料 - 灰色 */}
|
|
|
@@ -2109,7 +2109,7 @@ export default function Dashboard() {
|
|
|
<div className="text-3xl font-bold text-gray-900 mb-2">
|
|
|
{statistics.returnMaterialsCount || 0}
|
|
|
</div>
|
|
|
- <div className="text-sm text-gray-600">待归还物料</div>
|
|
|
+ <div className="text-sm text-gray-600">{t('cockpit.returnPendingMaterials')}</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
@@ -2120,7 +2120,7 @@ export default function Dashboard() {
|
|
|
<div className="flex items-center justify-between">
|
|
|
<div className="flex items-center gap-2">
|
|
|
<List className="w-5 h-5 text-gray-600" />
|
|
|
- <span>物料状态列表</span>
|
|
|
+ <span>{t('cockpit.materialStatusList')}</span>
|
|
|
</div>
|
|
|
<button
|
|
|
className="text-sm font-medium border-0 bg-transparent p-0 cursor-pointer"
|
|
|
@@ -2128,7 +2128,7 @@ export default function Dashboard() {
|
|
|
onMouseEnter={(e) => e.currentTarget.style.color = '#1d4ed8'}
|
|
|
onMouseLeave={(e) => e.currentTarget.style.color = '#2563eb'}
|
|
|
>
|
|
|
- 查看全部物料
|
|
|
+ {t('cockpit.viewAllMaterials')}
|
|
|
</button>
|
|
|
</div>
|
|
|
}
|
|
|
@@ -2137,12 +2137,12 @@ export default function Dashboard() {
|
|
|
<table className="w-full border-collapse">
|
|
|
<thead>
|
|
|
<tr className="bg-gray-50 border-b border-gray-200">
|
|
|
- <th className="px-4 py-3 text-left text-xs font-medium text-gray-700">物料编号</th>
|
|
|
- <th className="px-4 py-3 text-left text-xs font-medium text-gray-700">物料名称</th>
|
|
|
- <th className="px-4 py-3 text-left text-xs font-medium text-gray-700">物料类型</th>
|
|
|
- <th className="px-4 py-3 text-left text-xs font-medium text-gray-700">状态</th>
|
|
|
- <th className="px-4 py-3 text-left text-xs font-medium text-gray-700">借用人员</th>
|
|
|
- <th className="px-4 py-3 text-center text-xs font-medium text-gray-700">操作</th>
|
|
|
+ <th className="px-4 py-3 text-left text-xs font-medium text-gray-700">{t('cockpit.materialCode')}</th>
|
|
|
+ <th className="px-4 py-3 text-left text-xs font-medium text-gray-700">{t('cockpit.materialName')}</th>
|
|
|
+ <th className="px-4 py-3 text-left text-xs font-medium text-gray-700">{t('cockpit.materialType')}</th>
|
|
|
+ <th className="px-4 py-3 text-left text-xs font-medium text-gray-700">{t('cockpit.status')}</th>
|
|
|
+ <th className="px-4 py-3 text-left text-xs font-medium text-gray-700">{t('cockpit.borrower')}</th>
|
|
|
+ <th className="px-4 py-3 text-center text-xs font-medium text-gray-700">{t('cockpit.action')}</th>
|
|
|
</tr>
|
|
|
</thead>
|
|
|
<tbody className="bg-white">
|
|
|
@@ -2152,7 +2152,7 @@ export default function Dashboard() {
|
|
|
<td className="px-4 py-3 whitespace-nowrap text-sm text-gray-900">隔离锁具 (通用型)</td>
|
|
|
<td className="px-4 py-3 whitespace-nowrap text-sm text-gray-600">锁具</td>
|
|
|
<td className="px-4 py-3 whitespace-nowrap text-sm">
|
|
|
- <span className="px-2 py-0.5 rounded text-xs font-medium bg-yellow-100 text-gray-900">借用中</span>
|
|
|
+ <span className="px-2 py-0.5 rounded text-xs font-medium bg-yellow-100 text-gray-900">{t('cockpit.borrowed')}</span>
|
|
|
</td>
|
|
|
<td className="px-4 py-3 whitespace-nowrap text-sm text-gray-600">张三</td>
|
|
|
<td className="px-4 py-3 whitespace-nowrap text-sm text-center">
|
|
|
@@ -2163,7 +2163,7 @@ export default function Dashboard() {
|
|
|
onMouseEnter={(e) => e.currentTarget.style.backgroundColor = '#0958d9'}
|
|
|
onMouseLeave={(e) => e.currentTarget.style.backgroundColor = '#1677ff'}
|
|
|
>
|
|
|
- 查看
|
|
|
+ {t('cockpit.view')}
|
|
|
</button>
|
|
|
<button
|
|
|
className="px-3 py-1.5 text-xs font-medium rounded transition-colors"
|
|
|
@@ -2171,7 +2171,7 @@ export default function Dashboard() {
|
|
|
onMouseEnter={(e) => e.currentTarget.style.backgroundColor = '#d46b08'}
|
|
|
onMouseLeave={(e) => e.currentTarget.style.backgroundColor = '#fa8c16'}
|
|
|
>
|
|
|
- 催还
|
|
|
+ {t('cockpit.urgeReturn')}
|
|
|
</button>
|
|
|
</div>
|
|
|
</td>
|
|
|
@@ -2181,7 +2181,7 @@ export default function Dashboard() {
|
|
|
<td className="px-4 py-3 whitespace-nowrap text-sm text-gray-900">警示标签 (大号)</td>
|
|
|
<td className="px-4 py-3 whitespace-nowrap text-sm text-gray-600">标签</td>
|
|
|
<td className="px-4 py-3 whitespace-nowrap text-sm">
|
|
|
- <span className="px-2 py-0.5 rounded text-xs font-medium bg-red-100 text-red-700">异常</span>
|
|
|
+ <span className="px-2 py-0.5 rounded text-xs font-medium bg-red-100 text-red-700">{t('cockpit.exception')}</span>
|
|
|
</td>
|
|
|
<td className="px-4 py-3 whitespace-nowrap text-sm text-gray-600">-</td>
|
|
|
<td className="px-4 py-3 whitespace-nowrap text-sm text-center">
|
|
|
@@ -2192,7 +2192,7 @@ export default function Dashboard() {
|
|
|
onMouseEnter={(e) => e.currentTarget.style.backgroundColor = '#0958d9'}
|
|
|
onMouseLeave={(e) => e.currentTarget.style.backgroundColor = '#1677ff'}
|
|
|
>
|
|
|
- 查看
|
|
|
+ {t('cockpit.view')}
|
|
|
</button>
|
|
|
<button
|
|
|
className="px-3 py-1.5 text-xs font-medium rounded transition-colors"
|
|
|
@@ -2200,7 +2200,7 @@ export default function Dashboard() {
|
|
|
onMouseEnter={(e) => e.currentTarget.style.backgroundColor = '#cf1322'}
|
|
|
onMouseLeave={(e) => e.currentTarget.style.backgroundColor = '#ff4d4f'}
|
|
|
>
|
|
|
- 处理异常
|
|
|
+ {t('cockpit.handleException')}
|
|
|
</button>
|
|
|
</div>
|
|
|
</td>
|
|
|
@@ -2210,7 +2210,7 @@ export default function Dashboard() {
|
|
|
<td className="px-4 py-3 whitespace-nowrap text-sm text-gray-900">断电测试仪</td>
|
|
|
<td className="px-4 py-3 whitespace-nowrap text-sm text-gray-600">仪器</td>
|
|
|
<td className="px-4 py-3 whitespace-nowrap text-sm">
|
|
|
- <span className="px-2 py-0.5 rounded text-xs font-medium bg-green-100 text-gray-900">可用</span>
|
|
|
+ <span className="px-2 py-0.5 rounded text-xs font-medium bg-green-100 text-gray-900">{t('cockpit.available')}</span>
|
|
|
</td>
|
|
|
<td className="px-4 py-3 whitespace-nowrap text-sm text-gray-600">-</td>
|
|
|
<td className="px-4 py-3 whitespace-nowrap text-sm text-center">
|
|
|
@@ -2221,7 +2221,7 @@ export default function Dashboard() {
|
|
|
onMouseEnter={(e) => e.currentTarget.style.backgroundColor = '#0958d9'}
|
|
|
onMouseLeave={(e) => e.currentTarget.style.backgroundColor = '#1677ff'}
|
|
|
>
|
|
|
- 查看
|
|
|
+ {t('cockpit.view')}
|
|
|
</button>
|
|
|
<button
|
|
|
className="px-3 py-1.5 text-xs font-medium rounded transition-colors"
|
|
|
@@ -2229,7 +2229,7 @@ export default function Dashboard() {
|
|
|
onMouseEnter={(e) => e.currentTarget.style.backgroundColor = '#389e0d'}
|
|
|
onMouseLeave={(e) => e.currentTarget.style.backgroundColor = '#52c41a'}
|
|
|
>
|
|
|
- 申领
|
|
|
+ {t('cockpit.claim')}
|
|
|
</button>
|
|
|
</div>
|
|
|
</td>
|
|
|
@@ -2239,7 +2239,7 @@ export default function Dashboard() {
|
|
|
<td className="px-4 py-3 whitespace-nowrap text-sm text-gray-900">隔离锁具 (防爆型)</td>
|
|
|
<td className="px-4 py-3 whitespace-nowrap text-sm text-gray-600">锁具</td>
|
|
|
<td className="px-4 py-3 whitespace-nowrap text-sm">
|
|
|
- <span className="px-2 py-0.5 rounded text-xs font-medium bg-red-100 text-red-700">待归还</span>
|
|
|
+ <span className="px-2 py-0.5 rounded text-xs font-medium bg-red-100 text-red-700">{t('cockpit.returnPending')}</span>
|
|
|
</td>
|
|
|
<td className="px-4 py-3 whitespace-nowrap text-sm text-gray-600">李四</td>
|
|
|
<td className="px-4 py-3 whitespace-nowrap text-sm text-center">
|
|
|
@@ -2250,7 +2250,7 @@ export default function Dashboard() {
|
|
|
onMouseEnter={(e) => e.currentTarget.style.backgroundColor = '#0958d9'}
|
|
|
onMouseLeave={(e) => e.currentTarget.style.backgroundColor = '#1677ff'}
|
|
|
>
|
|
|
- 查看
|
|
|
+ {t('cockpit.view')}
|
|
|
</button>
|
|
|
<button
|
|
|
className="px-3 py-1.5 text-xs font-medium rounded transition-colors"
|
|
|
@@ -2258,7 +2258,7 @@ export default function Dashboard() {
|
|
|
onMouseEnter={(e) => e.currentTarget.style.backgroundColor = '#d46b08'}
|
|
|
onMouseLeave={(e) => e.currentTarget.style.backgroundColor = '#fa8c16'}
|
|
|
>
|
|
|
- 催还
|
|
|
+ {t('cockpit.urgeReturn')}
|
|
|
</button>
|
|
|
</div>
|
|
|
</td>
|
|
|
@@ -2273,26 +2273,26 @@ export default function Dashboard() {
|
|
|
title={
|
|
|
<div className="flex items-center gap-2">
|
|
|
<Rocket className="w-5 h-5 text-gray-600" />
|
|
|
- <span>物料管理快捷操作</span>
|
|
|
+ <span>{t('cockpit.materialQuickActions')}</span>
|
|
|
</div>
|
|
|
}
|
|
|
>
|
|
|
<div className="flex gap-4">
|
|
|
<button className="flex-1 bg-white border border-gray-200 rounded-lg p-4 hover:bg-gray-50 hover:border-gray-300 transition-all flex flex-col items-center justify-center gap-2">
|
|
|
<Plus className="w-6 h-6 text-gray-600" />
|
|
|
- <span className="text-sm font-medium text-gray-700">新增物料</span>
|
|
|
+ <span className="text-sm font-medium text-gray-700">{t('cockpit.addMaterial')}</span>
|
|
|
</button>
|
|
|
<button className="flex-1 bg-white border border-gray-200 rounded-lg p-4 hover:bg-gray-50 hover:border-gray-300 transition-all flex flex-col items-center justify-center gap-2">
|
|
|
<RefreshCw className="w-6 h-6 text-gray-600" />
|
|
|
- <span className="text-sm font-medium text-gray-700">刷新物料状态</span>
|
|
|
+ <span className="text-sm font-medium text-gray-700">{t('cockpit.refreshMaterialStatus')}</span>
|
|
|
</button>
|
|
|
<button className="flex-1 bg-white border border-gray-200 rounded-lg p-4 hover:bg-gray-50 hover:border-gray-300 transition-all flex flex-col items-center justify-center gap-2">
|
|
|
<AlertCircle className="w-6 h-6 text-gray-600" />
|
|
|
- <span className="text-sm font-medium text-gray-700">处理异常物料</span>
|
|
|
+ <span className="text-sm font-medium text-gray-700">{t('cockpit.handleExceptionMaterials')}</span>
|
|
|
</button>
|
|
|
<button className="flex-1 bg-white border border-gray-200 rounded-lg p-4 hover:bg-gray-50 hover:border-gray-300 transition-all flex flex-col items-center justify-center gap-2">
|
|
|
<FileText className="w-6 h-6 text-gray-600" />
|
|
|
- <span className="text-sm font-medium text-gray-700">物料台账导出</span>
|
|
|
+ <span className="text-sm font-medium text-gray-700">{t('cockpit.materialExport')}</span>
|
|
|
</button>
|
|
|
</div>
|
|
|
</Card>
|
|
|
@@ -2341,7 +2341,7 @@ export default function Dashboard() {
|
|
|
flexShrink: 0
|
|
|
}}></div>
|
|
|
<h2 className="text-xl font-semibold mb-2" style={{ color: '#025fff', marginBottom: 0 }}>
|
|
|
- {taskDetailData.workName || taskDetailData.name || '任务详情'}
|
|
|
+ {taskDetailData.workName || taskDetailData.name || t('cockpit.taskDetail')}
|
|
|
</h2>
|
|
|
<span
|
|
|
className="inline-flex px-3 py-1 rounded-full text-xs font-medium"
|
|
|
@@ -2351,10 +2351,10 @@ export default function Dashboard() {
|
|
|
</span>
|
|
|
</div>
|
|
|
<div className="text-sm flex gap-4" style={{ color: '#898f9a', marginTop: '12px' }}>
|
|
|
- <span>工单编号:{taskDetailData.orderNo || '-'}</span>
|
|
|
- <span>作业发起人:{taskDetailData.initiatorName || '-'}</span>
|
|
|
- <span>任务负责人:{taskDetailData.workerUserName || '-'}</span>
|
|
|
- <span>开始时间:{taskDetailData.workTime ? dateFormatter(taskDetailData.workTime) : '-'}</span>
|
|
|
+ <span>{t('cockpit.orderNo')}:{taskDetailData.orderNo || '-'}</span>
|
|
|
+ <span>{t('cockpit.jobInitiatorLabel')}:{taskDetailData.initiatorName || '-'}</span>
|
|
|
+ <span>{t('cockpit.taskOwnerLabel')}:{taskDetailData.workerUserName || '-'}</span>
|
|
|
+ <span>{t('cockpit.startTime')}:{taskDetailData.workTime ? dateFormatter(taskDetailData.workTime) : '-'}</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
|