feat(i18n): 实现多语言支持并更新相关组件

refactor: 重构组件以使用i18n动态文本
style: 调整代码格式和结构
docs: 更新多语言翻译文件
This commit is contained in:
砂糖
2025-12-29 11:16:35 +08:00
parent 4fa6a1f59a
commit fa37b697e6
20 changed files with 1645 additions and 619 deletions

View File

@@ -3,7 +3,7 @@
<!-- 控制区 -->
<div class="control-bar">
<div class="chart-selector">
<label>图表视图</label>
<label>{{ $t('track.chartView') }}</label>
<select v-model="currentChart" @change="handleChartChange">
<option v-for="chart in chartTypes" :key="chart.value" :value="chart.value">
{{ chart.label }}
@@ -12,7 +12,7 @@
</div>
<div class="connection-status" :class="{ connected: isConnected }">
连接状态{{ isConnected ? '已连接' : '连接中...' }}
{{ $t('track.connectionStatus') }}{{ isConnected ? $t('track.connected') : $t('track.connecting') }}
</div>
</div>
@@ -36,12 +36,6 @@ export default {
isConnected: false,
// 图表相关
chartTypes: [
{ value: 'entry', label: '入口数据监控' },
{ value: 'furnace', label: '炉温数据监控' },
{ value: 'coat', label: '涂层数据监控' },
{ value: 'exit', label: '出口数据监控' }
],
currentChart: 'entry', // 默认显示入口数据图表
chartInstance: null, // 当前图表实例
@@ -82,6 +76,15 @@ export default {
currentChartLabel() {
const chart = this.chartTypes.find(item => item.value === this.currentChart);
return chart ? chart.label : '';
},
// 图表类型使用i18n动态生成
chartTypes() {
return [
{ value: 'entry', label: this.$t('track.entryDataMonitor') },
{ value: 'furnace', label: this.$t('track.furnaceDataMonitor') },
{ value: 'coat', label: this.$t('track.coatDataMonitor') },
{ value: 'exit', label: this.$t('track.exitDataMonitor') }
];
}
},
mounted() {
@@ -90,7 +93,7 @@ export default {
// 建立WebSocket连接固定为track_measure
this.connectWebSocket();
// 监听窗口大小变化
window.addEventListener('resize', this.handleWindowResize);
window.addEventListener('resize', this.handleResize);
},
unmounted() {
// 清理资源

View File

@@ -12,6 +12,7 @@ export default {
username: 'Username',
password: 'Password',
remember: 'Remember me',
rememberPassword: 'Remember password',
forgetPassword: 'Forgot password',
submit: 'Submit',
reset: 'Reset',
@@ -38,13 +39,437 @@ export default {
remark: 'Remark',
pleaseSelect: 'Please select',
pleaseInput: 'Please input',
pleaseEnter: 'Please enter'
pleaseEnter: 'Please enter',
usernamePlaceholder: 'Please enter username',
passwordPlaceholder: 'Please enter password',
enterUsername: 'Please enter your account',
enterPassword: 'Please enter your password',
enterVerificationCode: 'Please enter verification code',
loading: 'Loading...'
},
dashboard: {
welcome: 'Welcome to Galvanizing Line & Production Process Management System',
todayData: 'Today\'s Data',
totalData: 'Total Data',
onlineUsers: 'Online Users',
systemInfo: 'System Information'
}
systemInfo: 'System Information',
alarmInfo: 'System Alarm Information',
rollChangeInfo: 'Roll Change Information',
productionPlan: 'Production Plan',
processTracking: 'Process Tracking',
productionPlanDesc: 'Production Plan Management...',
logRecord: 'Log Record',
logRecordDesc: 'Log Record Management...',
rollManagement: 'Roll Management',
rollManagementDesc: 'Roll Management...',
shutdownManagement: 'Shutdown Management',
shutdownManagementDesc: 'Shutdown Management...',
occurTime: 'Occur Time',
alarmModule: 'Alarm Module',
alarmType: 'Alarm Type',
rollChangeId: 'Roll Change ID',
rollId: 'Roll ID',
unit: 'Unit',
shift: 'Shift',
crew: 'Crew',
standId: 'Stand ID',
position: 'Position',
diameter: 'Diameter',
roughness: 'Roughness',
crown: 'Crown',
composition: 'Composition',
seqId: 'Sequence ID',
coilId: 'Coil ID',
unitCode: 'Unit Code',
planId: 'Plan ID',
planType: 'Plan Type',
steelGrade: 'Steel Grade',
exitCoilId: 'Exit Coil ID',
orderNo: 'Order No',
customerCode: 'Customer Code',
onlineDate: 'Online Date',
startDate: 'Start Date',
endDate: 'End Date',
furInDate: 'Furnace In Date',
furOutDate: 'Furnace Out Date',
explorePossibilities: 'Explore Unlimited Possibilities of Production and Information',
innovationTechFuture: 'Innovation · Technology · Future',
getLogDataFailed: 'Failed to get log data, please try again later'
},
log: {
startTime: 'Start Time',
endTime: 'End Time',
alarmType: 'Alarm Type',
alarmModule: 'Alarm Module',
alarmContent: 'Alarm Content',
alarmStatus: 'Alarm Status',
serialNumber: 'Serial Number',
occurTime: 'Occur Time',
status: 'Status',
confirmTime: 'Confirm Time',
chooseStartTime: 'Choose Start Time',
chooseEndTime: 'Choose End Time',
chooseAlarmType: 'Please select alarm type',
chooseAlarmModule: 'Please select alarm module',
chooseAlarmStatus: 'Please select alarm status',
enterAlarmContent: 'Please enter alarm content',
systemAlarm: 'System Alarm',
deviceAlarm: 'Device Alarm',
networkAlarm: 'Network Alarm',
securityAlarm: 'Security Alarm',
monitorModule: 'Monitor Module',
adminModule: 'Admin Module',
analysisModule: 'Analysis Module',
storageModule: 'Storage Module',
untreated: 'Untreated',
processed: 'Processed',
ignored: 'Ignored',
historyDetail: 'History Detail',
notConfirmed: 'Not Confirmed',
startTimeNotLaterThanEndTime: 'Start time cannot be later than end time',
confirmSuccess: 'Confirm Success'
},
pdo: {
coilid: 'Coil ID',
startDate: 'Start Date',
endDate: 'End Date',
query: 'Query',
reset: 'Reset',
add: 'Add',
finishedCoil: 'Finished Coil',
basicInfo: 'Basic Information',
materialInfo: 'Material Information',
productInfo: 'Product Information',
status: 'Status',
steelGrade: 'Steel Grade',
productType: 'Product Type',
customer: 'Customer',
thickness: 'Thickness',
width: 'Width',
length: 'Length',
weight: 'Weight',
print: 'Print',
operate: 'Operate',
delete: 'Delete',
noData: 'No Data',
selected: 'Selected:',
pleaseSelect: 'Please select the card above to view details',
statisticsSummary: 'Statistics Summary',
addPdo: 'Add PDO',
editPdo: 'Edit PDO',
labelPrint: 'Label Print',
confirmDelete: 'Confirm Delete',
deleteSuccess: 'Delete Success',
deleteFailed: 'Delete Failed',
saveSuccess: 'Save Success',
saveFailed: 'Save Failed',
getDataFailed: 'Failed to get data',
pleaseInputCoilid: 'Please input coil ID',
chooseStartDate: 'Choose Start Date',
chooseEndDate: 'Choose End Date',
entryMatId: 'Entry Coil',
planNo: 'Plan No'
},
roller: {
historySearch: 'History Search',
byTime: 'By Time',
startTime: 'Start Time',
endTime: 'End Time',
selectDate: 'Select Date',
selectTime: 'Select Time',
byChangeId: 'By Change ID',
changeId: 'Change ID',
pleaseSelect: 'Please Select',
byRollId: 'By Roll ID',
rollId: 'Roll ID',
query: 'Query',
reset: 'Reset',
onlineRollers: 'Online Rollers',
standbyRollers: 'Standby Rollers',
backup: 'Backup',
online: 'Online',
positionType: 'Position/Type',
diameter: 'Diameter',
roughness: 'Roughness',
crown: 'Crown',
pleaseSelectRollId: 'Please select roll ID',
pleaseInputDiameter: 'Please input diameter',
pleaseInputRoughness: 'Please input roughness',
pleaseInputCrown: 'Please input crown',
workRoll: 'Work Roll',
backupRoll: 'Backup Roll',
intermediateRoll: 'Intermediate Roll',
top: 'Top',
bottom: 'Bottom',
standId: 'Stand ID',
position: 'Position',
type: 'Type',
changeType: 'Change Type',
changeTime: 'Change Time',
installTime: 'Install Time',
dismantleTime: 'Dismantle Time',
detailedInfo: 'Detailed Information',
grindCount: 'Grind Count',
rolledWeight: 'Rolled Weight',
rolledCount: 'Rolled Count',
rolledLength: 'Rolled Length',
totalRolledWeight: 'Total Rolled Weight',
totalRolledLength: 'Total Rolled Length',
totalRolledCount: 'Total Rolled Count',
composition: 'Composition',
loading: 'Loading...',
getChangeIdListFailed: 'Failed to get change ID list',
getRollIdListFailed: 'Failed to get roll ID list',
getDataFailed: 'Failed to get data',
exportSuccess: 'Export Success'
},
plan: {
addPlan: 'Add Plan',
refresh: 'Refresh',
producing: 'Producing',
coilid: 'Coil ID',
steelGrade: 'Steel Grade',
thickness: 'Thickness',
width: 'Width',
weight: 'Weight',
edit: 'Edit',
delete: 'Delete',
productionQueue: 'Production Queue',
ready: 'Ready',
new: 'New',
online: 'Online',
noProductionPlan: 'No Production Plan',
history: 'History',
completed: 'Completed',
noHistory: 'No History',
planDetailAndProcessParams: 'Plan Detail and Process Parameters',
basicInfo: 'Basic Information',
processParams: 'Process Parameters',
noProcessParams: 'No Process Parameters Data',
pleaseSelectPlan: 'Please select a plan from the left to view details',
generateProcessParams: 'Generate Process Parameters (It is recommended to fill in the basic information first and then check this option)',
cancel: 'Cancel',
save: 'Save',
planId: 'Plan ID',
yieldPoint: 'Yield Point',
length: 'Length (mm)',
outerDiameter: 'Outer Diameter (mm)',
elongation: 'Elongation (%)',
spmRollforce: 'SPM Rolling Force',
exitLengthTar: 'Exit Target Length',
exitThickTar: 'Exit Target Thickness',
exitWidthTar: 'Exit Target Width',
confirmDelete: 'Confirm Delete',
confirm: 'Confirm',
deleteSuccess: 'Delete Success',
deleteFailed: 'Delete Failed',
updateSuccess: 'Update Plan Success',
addSuccess: 'Add Plan Success',
updateFailed: 'Update Failed',
addFailed: 'Add Failed',
processParamsCreated: 'Process Parameters Created Successfully',
getDataFailed: 'Failed to get data, please try again',
startTimeNotLaterThanEndTime: 'Start time cannot be later than end time'
},
report: {
stop: {
title: 'Stop Report',
subtitle: 'Please select a time range to view data',
stopTag: 'Stop',
pleaseSelectDateRange: 'Please select query date range',
startDate: 'Start Date',
endDate: 'End Date',
chooseStartDate: 'Choose Start Date',
chooseEndDate: 'Choose End Date',
query: 'Query',
reset: 'Reset',
reportType: 'Report Type: ',
timeRange: 'Time Range: ',
reselectTime: 'Reselect Time',
coilid: 'Coil ID',
shift: 'Shift ID',
area: 'Area',
startTime: 'Start Time',
endTime: 'End Time',
duration: 'Duration [minutes]',
stopType: 'Stop Type',
remark: 'Remark'
}
},
stop: {
startTime: 'Start Time',
endTime: 'End Time',
chooseStartTime: 'Choose Start Time',
chooseEndTime: 'Choose End Time',
query: 'Query',
reset: 'Reset',
stopId: 'Stop ID',
coilid: 'Coil ID',
basicInfo: 'Basic Information',
stopType: 'Stop Type',
shift: 'Shift',
crew: 'Crew',
area: 'Area',
equipmentInfo: 'Equipment Information',
equipment: 'Equipment',
unit: 'Unit',
duration: 'Duration',
timeInfo: 'Time Information',
startDate: 'Start Time',
endDate: 'End Time',
stopReason: 'Stop Reason',
edit: 'Edit',
delete: 'Delete',
noData: 'No Data',
addStopRecord: 'Add Stop Record',
editStopRecord: 'Edit Stop Record',
pleaseInputCoilid: 'Please input coil ID',
pleaseSelectShift: 'Please select shift',
morningShift: 'Morning Shift',
afternoonShift: 'Afternoon Shift',
nightShift: 'Night Shift',
pleaseInputCrew: 'Please input crew',
pleaseInputArea: 'Please input area',
pleaseInputUnit: 'Please input unit',
pleaseInputEquipment: 'Please input equipment',
pleaseSelectStopType: 'Please select stop type',
plannedStop: 'Planned Stop',
breakdownStop: 'Breakdown Stop',
maintenanceStop: 'Maintenance Stop',
other: 'Other',
pleaseInputStopReason: 'Please input stop reason',
cancel: 'Cancel',
save: 'Save',
confirmDelete: 'Confirm Delete',
confirm: 'Confirm',
delete: 'Delete',
deleteSuccess: 'Delete Success',
deleteFailed: 'Delete Failed',
getDataFailed: 'Failed to get data, please try again later',
startTimeNotLaterThanEndTime: 'Start time cannot be later than end time'
},
track: {
deviceList: 'Device List',
loading: 'Loading Status',
websocketConnectionStatus: 'WebSocket Connection Status',
entrySection: 'Entry Section',
furnaceSection: 'Furnace Section',
coatingSection: 'Coating Section',
exitSection: 'Exit Section',
otherSection: 'Other Section',
productionPlan: 'Production Plan',
noProductionPlan: 'No Production Plan',
planId: 'Plan ID',
coilid: 'Coil ID',
steelGrade: 'Steel Grade',
sequence: 'Sequence',
productionPlanDetail: 'Production Plan Detail',
currentPosition: 'Current Position',
seqid: 'Sequence ID',
status: 'Status',
entryThickness: 'Entry Thickness',
entryWidth: 'Entry Width',
entryWeight: 'Entry Weight',
entryLength: 'Entry Length',
orderNo: 'Order No',
unitCode: 'Unit Code',
planType: 'Plan Type',
timeInfo: 'Time Information',
onlineDate: 'Online Date',
startDate: 'Start Time',
endDate: 'End Time',
recentOperation: 'Recent Operation',
manualOperation: 'Manual Operation',
autoOperation: 'Auto Operation',
operationType: 'Operation Type',
por: 'POR',
tr: 'TR',
virtualCoil: 'Virtual Coil',
operation: 'Operation',
coilOnline: 'Coil Online',
manualUnload: 'Manual Unload',
allReturn: 'All Return',
halfReturn: 'Half Return',
unloadAndBlock: 'Unload and Block',
basicInfo: 'Basic Information',
positionName: 'Position Name',
positionCode: 'Position Code',
realTimeData: 'Real-time Data',
adjustmentTool: 'Adjustment Tool',
currentPosition: 'Current Position',
targetPosition: 'Target Position',
confirmAdjustment: 'Confirm Adjustment',
calculationSetupResult: 'Calculation Setup Result',
calculationSuccess: 'Calculation Success',
calculationFailed: 'Calculation Failed',
passno: 'Pass No',
entryThick: 'Entry Thickness(mm)',
exitThick: 'Exit Thickness(mm)',
reduction: 'Reduction(%)',
rollSpeed: 'Roll Speed',
rollForce: 'Roll Force(kN)',
entryTension: 'Entry Tension',
exitTension: 'Exit Tension',
noCalculationResult: 'No Calculation Result',
porIdx: 'POR Index',
trIdx: 'TR Index',
pleaseInputPlanId: 'Please input plan ID',
pleaseInputCoilid: 'Please input coil ID',
operationType: 'Operation Type',
returnMatId: 'Return Coil ID',
pleaseInputReturnMatId: 'Please input return coil ID',
returnWeight: 'Return Weight',
pleaseInputReturnWeight: 'Please input return weight',
producing: 'Producing',
product: 'Production Completed',
payOver: 'Throw Tail',
throwTail: 'Throw Tail',
onlineNotice: 'Coil Online Notice',
unloadNotice: 'Unload Operation Notice',
producingNotice: 'Production Status Change',
productNotice: 'Production Completed Notice',
payOverNotice: 'Pay Over Operation Notice',
throwTailNotice: 'Throw Tail Operation Notice',
allReturnNotice: 'All Return Notice',
halfReturnNotice: 'Half Return Notice',
blockNotice: 'Block Operation Notice',
operationNotice: 'Operation Notice',
returnRemark: 'Return Remark',
coilLength: 'Coil Length',
outputCoilLength: 'Output Coil Length',
pleaseInputOutputCoilLength: 'Please input output coil length',
tensionPorBr1: 'POR Tension 1#',
tensionPorBr2: 'POR Tension 2#',
stripSpeed: 'Strip Speed',
weldStatus: 'Welder Status',
celLength: 'Entry Looper Position',
celCapacity: 'Entry Looper Capacity',
tensionCel: 'Entry Looper Tension',
cleaningVoltage: 'Cleaning Voltage',
cleaningCurrent: 'Cleaning Current',
alkaliConcentration: 'Alkali Concentration',
alkaliTemperature: 'Alkali Temperature',
phfExitStripTemp: 'PH Furnace Exit Temp',
potTemperature: 'Pot Temperature',
gasConsumption: 'Gas Consumption',
rtfExitStripTemp: 'Heating Section Exit Temp',
zincPotPower: 'Zinc Pot Power',
jcsExitStripTemp: 'Cooling Section Exit Temp',
coolingTowerStripTemp: 'Cooling Tower Temp',
scsExitStripTemp: 'Soaking Section Exit Temp',
tensionBr5Tm: 'BR5-TM Tension',
stripSpeedTmExit: 'TM Exit Speed',
tmElongation: 'Skin Pass Elongation',
tensionTlBr7: 'TL-BR7 Tension',
tlElongation: 'Tension Leveling Elongation',
cxlLength: 'Exit Looper Position',
cxlCapacity: 'Exit Looper Capacity',
tensionCxl: 'Exit Looper Tension',
inspectionStatus: 'Inspection Status',
coilLength: 'Coil Length',
speedExitSection: 'Exit Section Speed',
tensionBr9Tr: 'BR9-TR Tension',
avrCoatingWeightTop: 'Top Coating Weight',
avrCoatingWeightBottom: 'Bottom Coating Weight'
},
}

View File

@@ -10,13 +10,16 @@ Vue.use(VueI18n)
const locale = process.env.VUE_APP_I18N_LOCALE || 'zh-CN'
// 合并系统语言包和Element UI语言包
const zhCN = require('./zh-CN').default || require('./zh-CN')
const enUS = require('./en-US').default || require('./en-US')
const messages = {
'zh-CN': {
...require('./zh-CN'),
...zhCN,
...zhLocale
},
'en-US': {
...require('./en-US'),
...enUS,
...enLocale
}
}

View File

@@ -12,6 +12,7 @@ export default {
username: '用户名',
password: '密码',
remember: '记住我',
rememberPassword: '记住密码',
forgetPassword: '忘记密码',
submit: '提交',
reset: '重置',
@@ -38,13 +39,437 @@ export default {
remark: '备注',
pleaseSelect: '请选择',
pleaseInput: '请输入',
pleaseEnter: '请输入'
pleaseEnter: '请输入',
usernamePlaceholder: '请输入用户名',
passwordPlaceholder: '请输入密码',
enterUsername: '请输入您的账号',
enterPassword: '请输入您的密码',
enterVerificationCode: '请输入验证码',
loading: '加载中...'
},
dashboard: {
welcome: '欢迎使用镀锌机组及生产工艺管理系统',
todayData: '今日数据',
totalData: '累计数据',
onlineUsers: '在线用户',
systemInfo: '系统信息'
}
systemInfo: '系统信息',
alarmInfo: '系统告警信息',
rollChangeInfo: '换辊信息',
productionPlan: '生产计划',
processTracking: '过程跟踪',
productionPlanDesc: '生产计划管理...',
logRecord: '日志记录',
logRecordDesc: '日志记录管理...',
rollManagement: '轧辊管理',
rollManagementDesc: '轧辊管理...',
shutdownManagement: '停机管理',
shutdownManagementDesc: '停机管理...',
occurTime: '发生时间',
alarmModule: '报警模块',
alarmType: '报警类型',
rollChangeId: '换辊号',
rollId: '轧辊号',
unit: '机组',
shift: '班次',
crew: '班组',
standId: '机架号',
position: '位置',
diameter: '直径',
roughness: '粗糙度',
crown: '凸度',
composition: '成分',
seqId: '顺序号',
coilId: '钢卷号',
unitCode: '机组号',
planId: '计划号',
planType: '计划类型',
steelGrade: '钢种',
exitCoilId: '出口卷号',
orderNo: '订单号',
customerCode: '客户代码',
onlineDate: '上线时间',
startDate: '开始时间',
endDate: '结束时间',
furInDate: '进炉时间',
furOutDate: '出炉时间',
explorePossibilities: '探索生产与信息的无限可能',
innovationTechFuture: '创新 · 科技 · 未来',
getLogDataFailed: '获取日志数据失败,请稍后重试'
},
log: {
startTime: '开始时间',
endTime: '结束时间',
alarmType: '报警类型',
alarmModule: '报警模块',
alarmContent: '警报内容',
alarmStatus: '报警状态',
serialNumber: '序号',
occurTime: '发生时间',
status: '状态',
confirmTime: '确认时间',
chooseStartTime: '选择开始时间',
chooseEndTime: '选择结束时间',
chooseAlarmType: '请选择报警类型',
chooseAlarmModule: '请选择报警模块',
chooseAlarmStatus: '请选择报警状态',
enterAlarmContent: '请输入警报内容',
systemAlarm: '系统报警',
deviceAlarm: '设备报警',
networkAlarm: '网络报警',
securityAlarm: '安全报警',
monitorModule: '监控模块',
adminModule: '管理模块',
analysisModule: '分析模块',
storageModule: '存储模块',
untreated: '未处理',
processed: '已处理',
ignored: '已忽略',
historyDetail: '历史记录详情',
notConfirmed: '未确认',
startTimeNotLaterThanEndTime: '开始时间不能晚于结束时间',
confirmSuccess: '确认成功'
},
pdo: {
coilid: '钢卷号',
startDate: '开始日期',
endDate: '结束日期',
query: '查询',
reset: '重置',
add: '补录',
finishedCoil: '成品卷',
basicInfo: '基本信息',
materialInfo: '来料信息',
productInfo: '成品信息',
status: '状态',
steelGrade: '钢种',
productType: '产品类型',
customer: '客户',
thickness: '厚度',
width: '宽度',
length: '长度',
weight: '重量',
print: '打印',
operate: '操作',
delete: '删除',
noData: '暂无数据',
selected: '已选中:',
pleaseSelect: '请选择上方卡片查看详情',
statisticsSummary: '统计汇总',
addPdo: '新增实绩',
editPdo: '编辑实绩',
labelPrint: '标签打印',
confirmDelete: '确认删除',
deleteSuccess: '删除成功',
deleteFailed: '删除失败',
saveSuccess: '保存成功',
saveFailed: '保存失败',
getDataFailed: '获取数据失败',
pleaseInputCoilid: '请输入钢卷号',
chooseStartDate: '选择开始日期',
chooseEndDate: '选择结束日期',
entryMatId: '来料卷',
planNo: '计划号'
},
roller: {
historySearch: '历史检索',
byTime: '按时间',
startTime: '开始时间',
endTime: '结束时间',
selectDate: '选择日期',
selectTime: '选择时间',
byChangeId: '按换辊号',
changeId: '换辊号',
pleaseSelect: '请选择',
byRollId: '按轧辊号',
rollId: '轧辊号',
query: '查询',
reset: '重置',
onlineRollers: '在线辊',
standbyRollers: '准备辊',
backup: '备辊',
online: '上线',
positionType: '位置/类型',
diameter: '直径',
roughness: '粗糙度',
crown: '凹度',
pleaseSelectRollId: '请选择轧辊号',
pleaseInputDiameter: '请输入直径',
pleaseInputRoughness: '请输入粗糙度',
pleaseInputCrown: '请输入凹度',
workRoll: '工作辊',
backupRoll: '支撑辊',
intermediateRoll: '中间辊',
top: '上',
bottom: '下',
standId: '机架号',
position: '位置',
type: '类型',
changeType: '换辊类型',
changeTime: '换辊时间',
installTime: '安装时间',
dismantleTime: '拆卸时间',
detailedInfo: '详细信息',
grindCount: '磨削次数',
rolledWeight: '轧制重量',
rolledCount: '轧制数量',
rolledLength: '轧制长度',
totalRolledWeight: '总轧制重量',
totalRolledLength: '总轧制长度',
totalRolledCount: '总轧制数量',
composition: '成分',
loading: '加载中...',
getChangeIdListFailed: '获取换辊号列表失败',
getRollIdListFailed: '获取轧辊号列表失败',
getDataFailed: '获取数据失败',
exportSuccess: '导出成功'
},
plan: {
addPlan: '新增计划',
refresh: '刷新',
producing: '生产中',
coilid: '钢卷号',
steelGrade: '钢种',
thickness: '厚度',
width: '宽度',
weight: '重量',
edit: '编辑',
delete: '删除',
productionQueue: '生产队列',
ready: '就绪',
new: '新建',
online: '在机',
noProductionPlan: '暂无生产计划',
history: '历史记录',
completed: '已完成',
noHistory: '暂无历史记录',
planDetailAndProcessParams: '计划详情与工艺参数',
basicInfo: '基础信息',
processParams: '工艺参数',
noProcessParams: '暂无工艺参数数据',
pleaseSelectPlan: '请从左侧选择一个计划查看详情',
generateProcessParams: '生成工艺参数(建议先填写完成基础信息再勾选此选项)',
cancel: '取消',
save: '保存',
planId: '计划号',
yieldPoint: '屈服点',
length: '长度(mm)',
outerDiameter: '外径(mm)',
elongation: '延伸率(%)',
spmRollforce: 'SPM轧制力',
exitLengthTar: '出口目标长度',
exitThickTar: '出口目标厚度',
exitWidthTar: '出口目标宽度',
confirmDelete: '确认删除',
confirm: '确认',
deleteSuccess: '删除成功',
deleteFailed: '删除失败',
updateSuccess: '更新计划成功',
addSuccess: '新增计划成功',
updateFailed: '更新失败',
addFailed: '新增失败',
processParamsCreated: '工艺参数创建成功',
getDataFailed: '获取数据失败,请重试',
startTimeNotLaterThanEndTime: '开始时间不能晚于结束时间'
},
report: {
stop: {
title: '停机报表',
subtitle: '请选择时间范围后查看数据',
stopTag: '停机',
pleaseSelectDateRange: '请选择查询日期范围',
startDate: '开始日期',
endDate: '结束日期',
chooseStartDate: '选择开始日期',
chooseEndDate: '选择结束日期',
query: '查询',
reset: '重置',
reportType: '报表类型:',
timeRange: '时间范围:',
reselectTime: '重新选择时间',
coilid: '钢卷号',
shift: '班次号',
area: '组',
startTime: '开始时间',
endTime: '结束时间',
duration: '持续时间[分钟]',
stopType: '停机类型',
remark: '备注'
}
},
stop: {
startTime: '开始时间',
endTime: '结束时间',
chooseStartTime: '选择开始时间',
chooseEndTime: '选择结束时间',
query: '查询',
reset: '重置',
stopId: '停机ID',
coilid: '钢卷号',
basicInfo: '基本信息',
stopType: '停机类型',
shift: '班',
crew: '组',
area: '区域',
equipmentInfo: '设备信息',
equipment: '设备',
unit: '机组',
duration: '停机时长',
timeInfo: '时间信息',
startDate: '开始时间',
endDate: '结束时间',
stopReason: '停机原因',
edit: '编辑',
delete: '删除',
noData: '暂无数据',
addStopRecord: '新增停机记录',
editStopRecord: '编辑停机记录',
pleaseInputCoilid: '请输入钢卷号',
pleaseSelectShift: '请选择班次',
morningShift: '早班',
afternoonShift: '中班',
nightShift: '晚班',
pleaseInputCrew: '请输入组号',
pleaseInputArea: '请输入区域',
pleaseInputUnit: '请输入机组',
pleaseInputEquipment: '请输入设备',
pleaseSelectStopType: '请选择停机类型',
plannedStop: '计划停机',
breakdownStop: '故障停机',
maintenanceStop: '维护停机',
other: '其他',
pleaseInputStopReason: '请输入停机原因',
cancel: '取消',
save: '保存',
confirmDelete: '确认删除',
confirm: '确定',
delete: '取消',
deleteSuccess: '删除成功',
deleteFailed: '删除失败',
getDataFailed: '获取数据失败,请稍后重试',
startTimeNotLaterThanEndTime: '开始时间不能晚于结束时间'
},
track: {
deviceList: '设备列表',
loading: '加载状态',
websocketConnectionStatus: 'WebSocket 连接状态指示',
entrySection: '入口段区域',
furnaceSection: '熔炉段区域',
coatingSection: '涂层段区域',
exitSection: '出口段区域',
otherSection: '其他段',
productionPlan: '生产计划',
noProductionPlan: '暂无生产计划',
planId: '计划ID',
coilid: '钢卷号',
steelGrade: '钢种',
sequence: '顺序',
productionPlanDetail: '生产计划详情',
currentPosition: '当前位置',
seqid: '顺序号',
status: '状态',
entryThickness: '入口厚度',
entryWidth: '入口宽度',
entryWeight: '入口重量',
entryLength: '入口长度',
orderNo: '订单号',
unitCode: '机组号',
planType: '计划类型',
timeInfo: '时间信息',
onlineDate: '上线时间',
startDate: '开始时间',
endDate: '结束时间',
recentOperation: '最近操作',
manualOperation: '手动操作',
autoOperation: '自动操作',
operationType: '操作类型',
por: '开卷机',
tr: '卷取机',
virtualCoil: '虚拟卷',
operation: '操作',
coilOnline: '钢卷上线',
manualUnload: '手动卸卷',
allReturn: '整卷回退',
halfReturn: '半卷回退',
unloadAndBlock: '卸卷并封闭',
basicInfo: '基本信息',
positionName: '位置名称',
positionCode: '位置代号',
realTimeData: '设备实时数据',
adjustmentTool: '调整工具',
currentPosition: '当前位置',
targetPosition: '目标位置',
confirmAdjustment: '确认调整',
calculationSetupResult: '计算设定结果',
calculationSuccess: '计算成功',
calculationFailed: '计算失败',
passno: '道次号',
entryThick: '入口厚度(mm)',
exitThick: '出口厚度(mm)',
reduction: '压下率(%)',
rollSpeed: '轧制速度',
rollForce: '轧制力(kN)',
entryTension: '入口张力',
exitTension: '出口张力',
noCalculationResult: '无计算结果数据',
porIdx: '开卷机编号',
trIdx: '卷取机编号',
pleaseInputPlanId: '请输入计划ID',
pleaseInputCoilid: '请输入钢卷号',
operationType: '操作类型',
returnMatId: '回退卷号',
pleaseInputReturnMatId: '请输入回退卷号',
returnWeight: '回退重量',
pleaseInputReturnWeight: '请输入回退重量',
producing: '生产中',
product: '生产完成',
payOver: '甩尾',
throwTail: '甩尾',
onlineNotice: '钢卷上线通知',
unloadNotice: '卸卷操作通知',
producingNotice: '生产状态变更',
productNotice: '生产完成通知',
payOverNotice: '甩尾操作提示',
throwTailNotice: '甩尾操作提示',
allReturnNotice: '整卷回退通知',
halfReturnNotice: '半卷回退通知',
blockNotice: '封闭操作通知',
operationNotice: '操作通知',
returnRemark: '回退备注',
coilLength: '钢卷长度',
outputCoilLength: '产出钢卷长度',
pleaseInputOutputCoilLength: '请输入产出钢卷长度',
tensionPorBr1: '开卷张力1#',
tensionPorBr2: '开卷张力2#',
stripSpeed: '带钢速度',
weldStatus: '焊机状态',
celLength: '入口活套位置',
celCapacity: '入口活套套量',
tensionCel: '入口活套张力',
cleaningVoltage: '清洗电压',
cleaningCurrent: '清洗电流',
alkaliConcentration: '碱液浓度',
alkaliTemperature: '碱液温度',
phfExitStripTemp: 'PH炉出口温度',
potTemperature: '锌锅温度',
gasConsumption: '燃气消耗',
rtfExitStripTemp: '加热段出口温度',
zincPotPower: '锌锅功率',
jcsExitStripTemp: '冷却段出口温度',
coolingTowerStripTemp: '冷却塔温度',
scsExitStripTemp: '均衡段出口温度',
tensionBr5Tm: 'BR5-TM张力',
stripSpeedTmExit: 'TM出口速度',
tmElongation: '光整延伸率',
tensionTlBr7: 'TL-BR7张力',
tlElongation: '拉矫延伸率',
cxlLength: '出口活套位置',
cxlCapacity: '出口活套套量',
tensionCxl: '出口活套张力',
inspectionStatus: '检查状态',
coilLength: '钢卷长度',
speedExitSection: '出口段速度',
tensionBr9Tr: 'BR9-TR张力',
avrCoatingWeightTop: '顶部涂重',
avrCoatingWeightBottom: '底部涂重'
},
}

View File

@@ -8,8 +8,8 @@
</div>
<div class="main-title">
<p>探索生产与信息的无限可能</p>
<p class="subtitle">创新 · 科技 · 未来</p>
<p>{{ $t('dashboard.explorePossibilities') }}</p>
<p class="subtitle">{{ $t('dashboard.innovationTechFuture') }}</p>
</div>
</div>

View File

@@ -14,7 +14,7 @@
<el-row :gutter="5" style="padding: 0 20px 20px;">
<el-col :span="10">
<el-card>
<div slot="header"><span>系统告警信息</span></div>
<div slot="header"><span>{{ $t('dashboard.alarmInfo') }}</span></div>
<!-- 第一个表格绑定API获取的数据和列配置 -->
<MiniTable
v-loading="tableLoading"
@@ -27,7 +27,7 @@
</el-col>
<el-col :span="14">
<el-card>
<div slot="header"><span>换辊信息</span></div>
<div slot="header"><span>{{ $t('dashboard.rollChangeInfo') }}</span></div>
<MiniTable
v-loading="rollHistoryLoading"
:columns="rollHistoryColumns"
@@ -38,7 +38,7 @@
</el-col>
<el-col :span="24">
<el-card>
<div slot="header"><span>生产计划</span></div>
<div slot="header"><span>{{ $t('dashboard.productionPlan') }}</span></div>
<MiniTable
v-loading="planLoading"
:columns="planColumns"
@@ -49,7 +49,7 @@
</el-col>
<el-col :span="24">
<el-card>
<div slot="header"><span>过程跟踪</span></div>
<div slot="header"><span>{{ $t('dashboard.processTracking') }}</span></div>
<TrackMeasure
v-loading="measureLoading"
:columns="measureColumns"
@@ -77,47 +77,6 @@ export default {
components: { CurrentTime, HomeMain, MiniTable, TrackMeasure },
data() {
return {
featureCards: [
{ title: "生产计划", desc: "生产计划管理...", icon: "table", path: "/plan" },
{ title: "日志记录", desc: "日志记录管理...", icon: "log", path: "/log" },
{ title: "轧辊管理", desc: "轧辊管理...", icon: "redis", path: "/roller" },
{ title: "停机管理", desc: "停机管理...", icon: "bug", path: "/stop" },
],
// 表格列配置(与日志字段对应)
alarmColumns: [
{ label: "发生时间", prop: "timestamp", width: "200px" },
{ label: "报警模块", prop: "module", width: "60px" },
{ label: "报警类型", prop: "logtype" },
],
rollHistoryColumns: [
{ label: "换辊号", prop: "changeid" },
{ label: "轧辊号", prop: "rollid" },
{ label: "机组", prop: "seton", width: "80px" },
{ label: "班次", prop: "shift", width: "60px" },
{ label: "班组", prop: "crew", width: "60px" },
{ label: "机架号", prop: "standid", width: "80px" },
{ label: "位置", prop: "position", width: "50px" },
{ label: '直径', prop: 'diameter', width: '100px' },
{ label: '粗糙度', prop: 'rough', width: '100px' },
{ label: '凸度', prop: 'crown', width: '100px' },
{ label: '成分', prop: 'composition', width: '100px' },
],
planColumns: [
{ label: '顺序号', prop: 'seqid', width: '80px' },
{ label: '钢卷号', prop: 'coilid', width: '120px' },
{ label: '机组号', prop: 'unitCode', width: '100px' },
{ label: '计划号', prop: 'planid', width: '120px' },
{ label: '计划类型', prop: 'planType', width: '80px' },
{ label: '钢种', prop: 'steelGrade', width: '120px' },
{ label: '出口卷号', prop: 'exitCoilid', width: '100px' },
{ label: '订单号', prop: 'orderNo', width: '100px' },
{ label: '客户代码', prop: 'custommerCode', width: '100px' },
{ label: '上线时间', prop: 'onlineDate' },
{ label: '开始时间', prop: 'startDate' },
{ label: '结束时间', prop: 'endDate' },
{ label: '进炉时间', prop: 'furInDate' },
{ label: '出炉时间', prop: 'furOutDate' },
],
alarmData: [], // 表格数据从API获取
queryForm: { pageNum: 1, pageSize: 10 }, // 分页参数
tableLoading: false, // 加载状态
@@ -127,6 +86,58 @@ export default {
planLoading: false, // 生产计划数据加载状态
};
},
computed: {
// 功能卡片配置
featureCards() {
return [
{ title: this.$t('dashboard.productionPlan'), desc: this.$t('dashboard.productionPlanDesc'), icon: "table", path: "/plan" },
{ title: this.$t('dashboard.logRecord'), desc: this.$t('dashboard.logRecordDesc'), icon: "log", path: "/log" },
{ title: this.$t('dashboard.rollManagement'), desc: this.$t('dashboard.rollManagementDesc'), icon: "redis", path: "/roller" },
{ title: this.$t('dashboard.shutdownManagement'), desc: this.$t('dashboard.shutdownManagementDesc'), icon: "bug", path: "/stop" },
];
},
// 表格列配置(与日志字段对应)
alarmColumns() {
return [
{ label: this.$t('dashboard.occurTime'), prop: "timestamp", width: "200px" },
{ label: this.$t('dashboard.alarmModule'), prop: "module", width: "60px" },
{ label: this.$t('dashboard.alarmType'), prop: "logtype" },
];
},
rollHistoryColumns() {
return [
{ label: this.$t('dashboard.rollChangeId'), prop: "changeid" },
{ label: this.$t('dashboard.rollId'), prop: "rollid" },
{ label: this.$t('dashboard.unit'), prop: "seton", width: "80px" },
{ label: this.$t('dashboard.shift'), prop: "shift", width: "60px" },
{ label: this.$t('dashboard.crew'), prop: "crew", width: "60px" },
{ label: this.$t('dashboard.standId'), prop: "standid", width: "80px" },
{ label: this.$t('dashboard.position'), prop: "position", width: "50px" },
{ label: this.$t('dashboard.diameter'), prop: 'diameter', width: '100px' },
{ label: this.$t('dashboard.roughness'), prop: 'rough', width: '100px' },
{ label: this.$t('dashboard.crown'), prop: 'crown', width: '100px' },
{ label: this.$t('dashboard.composition'), prop: 'composition', width: '100px' },
];
},
planColumns() {
return [
{ label: this.$t('dashboard.seqId'), prop: 'seqid', width: '80px' },
{ label: this.$t('dashboard.coilId'), prop: 'coilid', width: '120px' },
{ label: this.$t('dashboard.unitCode'), prop: 'unitCode', width: '100px' },
{ label: this.$t('dashboard.planId'), prop: 'planid', width: '120px' },
{ label: this.$t('dashboard.planType'), prop: 'planType', width: '80px' },
{ label: this.$t('dashboard.steelGrade'), prop: 'steelGrade', width: '120px' },
{ label: this.$t('dashboard.exitCoilId'), prop: 'exitCoilid', width: '100px' },
{ label: this.$t('dashboard.orderNo'), prop: 'orderNo', width: '100px' },
{ label: this.$t('dashboard.customerCode'), prop: 'custommerCode', width: '100px' },
{ label: this.$t('dashboard.onlineDate'), prop: 'onlineDate' },
{ label: this.$t('dashboard.startDate'), prop: 'startDate' },
{ label: this.$t('dashboard.endDate'), prop: 'endDate' },
{ label: this.$t('dashboard.furInDate'), prop: 'furInDate' },
{ label: this.$t('dashboard.furOutDate'), prop: 'furOutDate' },
];
},
},
created() {
// 页面加载时调用API获取数据
this.getLogData();
@@ -144,7 +155,7 @@ export default {
.catch((error) => {
this.tableLoading = false;
console.error("获取日志数据失败:", error);
this.$message.error("获取日志数据失败,请稍后重试");
this.$message.error(this.$t('dashboard.getLogDataFailed'));
});
},
getRollHistorytList() {

View File

@@ -3,52 +3,52 @@
<el-card>
<!-- 查询表单 -->
<el-form :inline="true" :model="queryForm" ref="queryForm" label-width="80px">
<el-form-item label="开始时间" prop="startTime">
<el-form-item :label="$t('log.startTime')" prop="startTime">
<el-date-picker v-model="queryForm.startTime" type="datetime" placeholder="选择开始时间"
value-format="yyyy-MM-dd HH:mm:ss" :clearable="true"></el-date-picker>
value-format="yyyy-MM-dd HH:mm:ss" :clearable="true" :placeholder="$t('log.chooseStartTime')"></el-date-picker>
</el-form-item>
<el-form-item label="结束时间" prop="endTime">
<el-form-item :label="$t('log.endTime')" prop="endTime">
<el-date-picker v-model="queryForm.endTime" type="datetime" placeholder="选择结束时间"
value-format="yyyy-MM-dd HH:mm:ss" :clearable="true"></el-date-picker>
value-format="yyyy-MM-dd HH:mm:ss" :clearable="true" :placeholder="$t('log.chooseEndTime')"></el-date-picker>
</el-form-item>
<el-form-item label="报警类型" prop="logtype">
<el-select v-model="queryForm.logtype" placeholder="请选择报警类型" clearable>
<el-option label="系统报警" value="system"></el-option>
<el-option label="设备报警" value="device"></el-option>
<el-option label="网络报警" value="network"></el-option>
<el-option label="安全报警" value="security"></el-option>
<el-form-item :label="$t('log.alarmType')" prop="logtype">
<el-select v-model="queryForm.logtype" :placeholder="$t('log.chooseAlarmType')" clearable>
<el-option :label="$t('log.systemAlarm')" value="system"></el-option>
<el-option :label="$t('log.deviceAlarm')" value="device"></el-option>
<el-option :label="$t('log.networkAlarm')" value="network"></el-option>
<el-option :label="$t('log.securityAlarm')" value="security"></el-option>
</el-select>
</el-form-item>
<el-form-item label="报警模块" prop="module">
<el-select v-model="queryForm.module" placeholder="请选择报警模块" clearable>
<el-option label="监控模块" value="monitor"></el-option>
<el-option label="管理模块" value="admin"></el-option>
<el-option label="分析模块" value="analysis"></el-option>
<el-option label="存储模块" value="storage"></el-option>
<el-form-item :label="$t('log.alarmModule')" prop="module">
<el-select v-model="queryForm.module" :placeholder="$t('log.chooseAlarmModule')" clearable>
<el-option :label="$t('log.monitorModule')" value="monitor"></el-option>
<el-option :label="$t('log.adminModule')" value="admin"></el-option>
<el-option :label="$t('log.analysisModule')" value="analysis"></el-option>
<el-option :label="$t('log.storageModule')" value="storage"></el-option>
</el-select>
</el-form-item>
<el-form-item label="警报内容" prop="logtext">
<el-input v-model="queryForm.logtext" placeholder="请输入警报内容" clearable style="width: 200px;"></el-input>
<el-form-item :label="$t('log.alarmContent')" prop="logtext">
<el-input v-model="queryForm.logtext" :placeholder="$t('log.enterAlarmContent')" clearable style="width: 200px;"></el-input>
</el-form-item>
<el-form-item label="报警状态" prop="status">
<el-select v-model="queryForm.status" placeholder="请选择报警状态" clearable>
<el-option label="未处理" value="0"></el-option>
<el-option label="已处理" value="1"></el-option>
<el-option label="已忽略" value="2"></el-option>
<el-form-item :label="$t('log.alarmStatus')" prop="status">
<el-select v-model="queryForm.status" :placeholder="$t('log.chooseAlarmStatus')" clearable>
<el-option :label="$t('log.untreated')" value="0"></el-option>
<el-option :label="$t('log.processed')" value="1"></el-option>
<el-option :label="$t('log.ignored')" value="2"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleQuery" :loading="btnLoading">
<i class="el-icon-search"></i> 查询
<i class="el-icon-search"></i> {{ $t('common.search') }}
</el-button>
<el-button @click="handleReset">
<i class="el-icon-refresh"></i> 重置
<i class="el-icon-refresh"></i> {{ $t('common.reset') }}
</el-button>
</el-form-item>
</el-form>
@@ -56,21 +56,21 @@
<!-- 数据表格 -->
<el-table v-loading="tableLoading" :data="tableData" border style="width: 100%; margin-top: 20px;"
@row-click="handleRowClick" highlight-current-row>
<el-table-column prop="seqid" label="序号" width="80" align="center"></el-table-column>
<el-table-column prop="timestamp" label="发生时间" width="180" align="center"></el-table-column>
<el-table-column prop="module" label="报警模块" align="center">
<el-table-column prop="seqid" :label="$t('log.serialNumber')" width="80" align="center"></el-table-column>
<el-table-column prop="timestamp" :label="$t('log.occurTime')" width="180" align="center"></el-table-column>
<el-table-column prop="module" :label="$t('log.alarmModule')" align="center">
<template slot-scope="scope">
<!-- <el-tag>{{ formatModule(scope.row.module) }}</el-tag> -->
<dict-tag :options="dict.type.main_log_module" :value="scope.row.module" />
</template>
</el-table-column>
<el-table-column prop="logtype" label="报警类型" align="center">
<el-table-column prop="logtype" :label="$t('log.alarmType')" align="center">
<template slot-scope="scope">
<!-- <el-tag :type="getLogTypeTagType(scope.row.logtype)">{{ formatLogType(scope.row.logtype) }}</el-tag> -->
<dict-tag :options="dict.type.main_log_type" :value="scope.row.logtype" />
</template>
</el-table-column>
<el-table-column prop="logtext" label="警报内容" min-width="200"></el-table-column>
<el-table-column prop="logtext" :label="$t('log.alarmContent')" min-width="200"></el-table-column>
<!-- <el-table-column prop="status" label="状态" align="center">
<template slot-scope="scope">
<el-tag :type="getStatusTagType(scope.row.status)">
@@ -103,22 +103,22 @@
</el-card>
<!-- 详情弹窗 -->
<el-dialog title="历史记录详情" :visible.sync="detailDialogVisible" width="60%" :close-on-click-modal="false">
<el-dialog :title="$t('log.historyDetail')" :visible.sync="detailDialogVisible" width="60%" :close-on-click-modal="false">
<el-descriptions column="1" border>
<el-descriptions-item label="序号">{{ currentRow.seqid }}</el-descriptions-item>
<el-descriptions-item label="发生时间">{{ currentRow.timestamp }}</el-descriptions-item>
<el-descriptions-item label="报警模块">{{ formatModule(currentRow.module) }}</el-descriptions-item>
<el-descriptions-item label="报警类型">{{ formatLogType(currentRow.logtype) }}</el-descriptions-item>
<el-descriptions-item label="警报内容">{{ currentRow.logtext }}</el-descriptions-item>
<el-descriptions-item label="状态">
<el-descriptions-item :label="$t('log.serialNumber')">{{ currentRow.seqid }}</el-descriptions-item>
<el-descriptions-item :label="$t('log.occurTime')">{{ currentRow.timestamp }}</el-descriptions-item>
<el-descriptions-item :label="$t('log.alarmModule')">{{ formatModule(currentRow.module) }}</el-descriptions-item>
<el-descriptions-item :label="$t('log.alarmType')">{{ formatLogType(currentRow.logtype) }}</el-descriptions-item>
<el-descriptions-item :label="$t('log.alarmContent')">{{ currentRow.logtext }}</el-descriptions-item>
<el-descriptions-item :label="$t('log.status')">
<el-tag :type="getStatusTagType(currentRow.status)">
{{ formatStatus(currentRow.status) }}
</el-tag>
</el-descriptions-item>
<el-descriptions-item label="确认时间">{{ currentRow.confirmTime || '未确认' }}</el-descriptions-item>
<el-descriptions-item :label="$t('log.confirmTime')">{{ currentRow.confirmTime || $t('log.notConfirmed') }}</el-descriptions-item>
</el-descriptions>
<div slot="footer" class="dialog-footer">
<el-button @click="detailDialogVisible = false">关闭</el-button>
<el-button @click="detailDialogVisible = false">{{ $t('common.close') }}</el-button>
</div>
</el-dialog>
</div>
@@ -175,7 +175,7 @@ export default {
this.tableLoading = false;
this.btnLoading = false;
console.error('获取数据失败:', error);
this.$message.error('获取数据失败,请稍后重试');
this.$message.error(this.$t('log.getLogDataFailed'));
});
},
@@ -184,7 +184,7 @@ export default {
// 验证开始时间不能晚于结束时间
if (this.queryForm.startTime && this.queryForm.endTime &&
new Date(this.queryForm.startTime) > new Date(this.queryForm.endTime)) {
this.$message.warning('开始时间不能晚于结束时间');
this.$message.warning(this.$t('log.startTimeNotLaterThanEndTime'));
return;
}
@@ -228,23 +228,23 @@ export default {
// 格式化报警模块显示
formatModule(module) {
const moduleMap = {
'monitor': '监控模块',
'admin': '管理模块',
'analysis': '分析模块',
'storage': '存储模块'
'monitor': this.$t('log.monitorModule'),
'admin': this.$t('log.adminModule'),
'analysis': this.$t('log.analysisModule'),
'storage': this.$t('log.storageModule')
};
return moduleMap[module] || module || '未知';
return moduleMap[module] || module || this.$t('common.unknown');
},
// 格式化报警类型显示
formatLogType(logtype) {
const logtypeMap = {
'system': '系统报警',
'device': '设备报警',
'network': '网络报警',
'security': '安全报警'
'system': this.$t('log.systemAlarm'),
'device': this.$t('log.deviceAlarm'),
'network': this.$t('log.networkAlarm'),
'security': this.$t('log.securityAlarm')
};
return logtypeMap[logtype] || logtype || '未知';
return logtypeMap[logtype] || logtype || this.$t('common.unknown');
},
// 获取报警类型标签样式
@@ -261,11 +261,11 @@ export default {
// 格式化状态显示
formatStatus(status) {
const statusMap = {
0: '未处理',
1: '已处理',
2: '已忽略'
0: this.$t('log.untreated'),
1: this.$t('log.processed'),
2: this.$t('log.ignored')
};
return statusMap[status] || '未知';
return statusMap[status] || this.$t('common.unknown');
},
// 获取状态标签样式
@@ -283,7 +283,7 @@ export default {
this.loading = true;
alarmAck(seqid)
.then(response => {
this.$message.success('确认成功');
this.$message.success(this.$t('log.confirmSuccess'));
this.getLogData();
})
}

View File

@@ -3,21 +3,21 @@
<!-- 查询表单区域 -->
<div class="pdo-header">
<el-form :inline="true" :model="queryForm" ref="queryForm" label-width="100px" size="small">
<el-form-item label="钢卷号" prop="coilid">
<el-input v-model="queryForm.coilid" placeholder="请输入钢卷号"></el-input>
<el-form-item :label="$t('pdo.coilid')" prop="coilid">
<el-input v-model="queryForm.coilid" :placeholder="$t('pdo.pleaseInputCoilid')"></el-input>
</el-form-item>
<el-form-item label="开始日期" prop="startDate">
<el-date-picker v-model="queryForm.startDate" type="date" placeholder="选择开始日期" value-format="yyyy-MM-dd"
<el-form-item :label="$t('pdo.startDate')" prop="startDate">
<el-date-picker v-model="queryForm.startDate" type="date" :placeholder="$t('pdo.chooseStartDate')" value-format="yyyy-MM-dd"
clearable></el-date-picker>
</el-form-item>
<el-form-item label="结束日期" prop="endDate">
<el-date-picker v-model="queryForm.endDate" type="date" placeholder="选择结束日期" value-format="yyyy-MM-dd"
<el-form-item :label="$t('pdo.endDate')" prop="endDate">
<el-date-picker v-model="queryForm.endDate" type="date" :placeholder="$t('pdo.chooseEndDate')" value-format="yyyy-MM-dd"
clearable></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleQuery" :loading="btnLoading" icon="el-icon-search">查询</el-button>
<el-button @click="handleReset" icon="el-icon-refresh">重置</el-button>
<el-button type="success" @click="handleAdd" icon="el-icon-plus">补录</el-button>
<el-button type="primary" @click="handleQuery" :loading="btnLoading" icon="el-icon-search">{{ $t('pdo.query') }}</el-button>
<el-button @click="handleReset" icon="el-icon-refresh">{{ $t('pdo.reset') }}</el-button>
<el-button type="success" @click="handleAdd" icon="el-icon-plus">{{ $t('pdo.add') }}</el-button>
</el-form-item>
</el-form>
</div>
@@ -30,29 +30,29 @@
<el-card class="parameter-card" shadow="never" :body-style="{ padding: '8px' }"
:class="{ 'card-selected': currentRow.exitMatId === item.exitMatId }" @click.native="handleRowClick(item)">
<div slot="header" class="card-header">
<div class="card-title">成品卷: {{ item.exitMatId || '-' }}</div>
<div class="card-title">{{ $t('pdo.finishedCoil') }}: {{ item.exitMatId || '-' }}</div>
<div class="card-subtitle">{{ item.entryMatId || '-' }} | {{ item.planNo || '-' }}</div>
</div>
<div class="card-body">
<div class="param-groups-row">
<!-- 基本信息 -->
<div class="param-group">
<div class="group-title">基本信息</div>
<div class="group-title">{{ $t('pdo.basicInfo') }}</div>
<div class="param-list">
<div class="param-line">
<span class="param-label">状态:</span>
<span class="param-label">{{ $t('pdo.status') }}:</span>
<span class="param-value">{{ item.status || '-' }}</span>
</div>
<div class="param-line">
<span class="param-label">钢种:</span>
<span class="param-label">{{ $t('pdo.steelGrade') }}:</span>
<span class="param-value">{{ item.steelGrade || '-' }}</span>
</div>
<div class="param-line">
<span class="param-label">产品类型:</span>
<span class="param-label">{{ $t('pdo.productType') }}:</span>
<span class="param-value">{{ item.prodCode || '-' }}</span>
</div>
<div class="param-line">
<span class="param-label">客户:</span>
<span class="param-label">{{ $t('pdo.customer') }}:</span>
<span class="param-value">{{ item.customer || '-' }}</span>
</div>
</div>
@@ -60,22 +60,22 @@
<!-- 来料信息 -->
<div class="param-group">
<div class="group-title">来料信息</div>
<div class="group-title">{{ $t('pdo.materialInfo') }}</div>
<div class="param-list">
<div class="param-line">
<span class="param-label">厚度:</span>
<span class="param-label">{{ $t('pdo.thickness') }}:</span>
<span class="param-value">{{ item.entryThick || '-' }}</span>
</div>
<div class="param-line">
<span class="param-label">宽度:</span>
<span class="param-label">{{ $t('pdo.width') }}:</span>
<span class="param-value">{{ item.entryWidth || '-' }}</span>
</div>
<div class="param-line">
<span class="param-label">长度:</span>
<span class="param-label">{{ $t('pdo.length') }}:</span>
<span class="param-value">{{ item.entryLength || '-' }}</span>
</div>
<div class="param-line">
<span class="param-label">重量:</span>
<span class="param-label">{{ $t('pdo.weight') }}:</span>
<span class="param-value">{{ item.entryWeight || '-' }}</span>
</div>
</div>
@@ -83,22 +83,22 @@
<!-- 成品信息 -->
<div class="param-group">
<div class="group-title">成品信息</div>
<div class="group-title">{{ $t('pdo.productInfo') }}</div>
<div class="param-list">
<div class="param-line">
<span class="param-label">厚度:</span>
<span class="param-label">{{ $t('pdo.thickness') }}:</span>
<span class="param-value">{{ item.exitThickness || '-' }}</span>
</div>
<div class="param-line">
<span class="param-label">宽度:</span>
<span class="param-label">{{ $t('pdo.width') }}:</span>
<span class="param-value">{{ item.exitWidth || '-' }}</span>
</div>
<div class="param-line">
<span class="param-label">长度:</span>
<span class="param-label">{{ $t('pdo.length') }}:</span>
<span class="param-value">{{ item.exitLength || '-' }}</span>
</div>
<div class="param-line">
<span class="param-label">重量:</span>
<span class="param-label">{{ $t('pdo.weight') }}:</span>
<span class="param-value">{{ item.exitNetWeight || '-' }}</span>
</div>
</div>
@@ -106,16 +106,16 @@
</div>
</div>
<div class="card-footer">
<el-button size="mini" type="text" icon="el-icon-view" @click.stop="handlePrint(item)">打印</el-button>
<el-button size="mini" type="text" icon="el-icon-edit" @click.stop="handleEdit(item)">操作</el-button>
<el-button size="mini" type="text" icon="el-icon-view" @click.stop="handlePrint(item)">{{ $t('pdo.print') }}</el-button>
<el-button size="mini" type="text" icon="el-icon-edit" @click.stop="handleEdit(item)">{{ $t('pdo.operate') }}</el-button>
<el-button size="mini" type="text" icon="el-icon-delete" :loading="item.deleteLoading"
@click.stop="handleDelete(item)">删除</el-button>
@click.stop="handleDelete(item)">{{ $t('pdo.delete') }}</el-button>
</div>
</el-card>
</el-col>
</el-row>
<div v-if="tableData.length === 0 && !tableLoading" class="empty-data">
<el-empty description="暂无数据"></el-empty>
<el-empty :description="$t('pdo.noData')"></el-empty>
</div>
</div>
@@ -124,19 +124,19 @@
<div class="statistics-header">
<div class="selected-info" v-if="currentRow && currentRow.entryMatId">
<i class="el-icon-check"></i>
<span class="selected-label">已选中:</span>
<span class="selected-value">成品卷 {{ currentRow.exitMatId }}</span>
<span class="selected-detail" v-if="currentRow.entryMatId">(来料卷: {{ currentRow.entryMatId }})</span>
<span class="selected-label">{{ $t('pdo.selected') }}</span>
<span class="selected-value">{{ $t('pdo.finishedCoil') }} {{ currentRow.exitMatId }}</span>
<span class="selected-detail" v-if="currentRow.entryMatId">({{ $t('pdo.entryMatId') }}: {{ currentRow.entryMatId }})</span>
</div>
<div class="selected-info empty" v-else>
<i class="el-icon-info"></i>
<span>请选择上方卡片查看详情</span>
<span>{{ $t('pdo.pleaseSelect') }}</span>
</div>
</div>
<el-row :gutter="15" class="statistics-content">
<el-col :span="4" class="summary-col">
<div class="summary-wrapper">
<div class="summary-header">统计汇总</div>
<div class="summary-header">{{ $t('pdo.statisticsSummary') }}</div>
<pdo-summary :table-data="tableData" />
</div>
</el-col>
@@ -168,7 +168,7 @@
</el-tabs> -->
</el-dialog>
<el-dialog title="标签打印" :visible.sync="printOpen" width="600px" :close-on-click-modal="false">
<el-dialog :title="$t('pdo.labelPrint')" :visible.sync="printOpen" width="600px" :close-on-click-modal="false">
<div style="display: flex; justify-content: center; align-items: center;">
<pdo-label-print :detail="formData"></pdo-label-print>
</div>
@@ -202,7 +202,7 @@ export default {
tableLoading: false,
btnLoading: false,
dialogVisible: false,
dialogTitle: '新增实绩',
dialogTitle: '',
// 新增:区分「补录(新增)」和「编辑」的状态标识
isAdd: false,
// 传递给子组件的详情数据(父组件仅做数据中转,不直接修改)
@@ -230,7 +230,7 @@ export default {
this.tableData = res.data.map(item => ({ ...item, deleteLoading: false }))
}).catch(err => {
console.error(err)
this.$message.error('获取数据失败')
this.$message.error(this.$t('pdo.getDataFailed'))
}).finally(() => {
this.tableLoading = false
this.btnLoading = false
@@ -258,7 +258,7 @@ export default {
// 补录新增设置isAdd=true初始化空表单
handleAdd() {
this.isAdd = true; // 标记为「补录」
this.dialogTitle = '新增实绩';
this.dialogTitle = this.$t('pdo.addPdo');
// 初始化空表单数据(传递给子组件)
this.formData = {
subId: 0,
@@ -286,7 +286,7 @@ export default {
// 编辑设置isAdd=false赋值行数据
handleEdit(row) {
this.isAdd = false; // 标记为「编辑」
this.dialogTitle = '编辑实绩';
this.dialogTitle = this.$t('pdo.editPdo');
// 深拷贝行数据(避免直接修改表格数据)
this.formData = JSON.parse(JSON.stringify(row));
this.dialogVisible = true
@@ -298,13 +298,13 @@ export default {
},
// 删除(保持不变)
handleDelete(row) {
this.$confirm(`确定删除成品卷 ${row.exitMatId}?`, '确认删除', { type: 'danger' }).then(() => {
this.$confirm(`${this.$t('common.confirm')}${this.$t('pdo.delete')}${this.$t('pdo.finishedCoil')} ${row.exitMatId}?`, this.$t('pdo.confirmDelete'), { type: 'danger' }).then(() => {
row.deleteLoading = true
deletePdo(row.exitMatId, row.planId).then(res => {
if (res.code === 200) {
this.$message.success('删除成功');
this.$message.success(this.$t('pdo.deleteSuccess'));
this.getPdoList()
} else this.$message.error(res.msg || '删除失败')
} else this.$message.error(res.msg || this.$t('pdo.deleteFailed'))
}).finally(() => row.deleteLoading = false)
})
},
@@ -315,10 +315,10 @@ export default {
const request = formData.id ? updatePdo(formData) : addPdo(formData)
request.then(res => {
if (res.code === 200) {
this.$message.success('保存成功');
this.$message.success(this.$t('pdo.saveSuccess'));
this.dialogVisible = false;
this.getPdoList() // 刷新列表
} else this.$message.error(res.msg || '保存失败')
} else this.$message.error(res.msg || this.$t('pdo.saveFailed'))
}).finally(() => {
this.saveLoading = false
})

View File

@@ -3,10 +3,10 @@
<!-- 顶部工具栏 -->
<div class="toolbar">
<el-button type="primary" @click="handleAdd" icon="el-icon-plus" size="small">
新增计划
{{ $t('plan.addPlan') }}
</el-button>
<el-button @click="getList" icon="el-icon-refresh" size="small">
刷新
{{ $t('plan.refresh') }}
</el-button>
</div>
@@ -22,7 +22,7 @@
>
<div class="card-status">
<span class="status-dot status-producing"></span>
<span class="status-text">生产中</span>
<span class="status-text">{{ $t('plan.producing') }}</span>
<!-- 当前位置 -->
<div class="card-position" v-if="getPlanPosition(plan)">
<i class="el-icon-location"></i>
@@ -32,33 +32,33 @@
<div class="card-content">
<div class="card-main">
<div class="plan-id">{{ plan.planid }}</div>
<div class="coil-id">钢卷号: {{ plan.coilid }}</div>
<div class="coil-id">{{ $t('plan.coilid') }}: {{ plan.coilid }}</div>
</div>
<div class="card-details">
<div class="detail-item">
<span class="label">钢种:</span>
<span class="label">{{ $t('plan.steelGrade') }}:</span>
<span class="value">{{ plan.steelGrade }}</span>
</div>
<div class="detail-item">
<span class="label">厚度:</span>
<span class="label">{{ $t('plan.thickness') }}:</span>
<span class="value">{{ plan.entryThick }} mm</span>
</div>
<div class="detail-item">
<span class="label">宽度:</span>
<span class="label">{{ $t('plan.width') }}:</span>
<span class="value">{{ plan.entryWidth }} mm</span>
</div>
<div class="detail-item">
<span class="label">重量:</span>
<span class="label">{{ $t('plan.weight') }}:</span>
<span class="value">{{ plan.entryWeight }} t</span>
</div>
</div>
</div>
<div class="card-actions">
<el-button size="mini" type="text" @click.stop="handleUpdate(plan)" icon="el-icon-edit">
编辑
{{ $t('plan.edit') }}
</el-button>
<el-button size="mini" type="text" @click.stop="handleDelete(plan)" icon="el-icon-delete">
删除
{{ $t('plan.delete') }}
</el-button>
</div>
</el-card>
@@ -75,7 +75,7 @@
<el-tab-pane name="pending">
<span slot="label">
<i class="el-icon-s-order"></i>
生产队列
{{ $t('plan.productionQueue') }}
<el-badge :value="pendingPlans.length" class="tab-badge" />
</span>
<div v-loading="loading" class="plan-list">
@@ -102,9 +102,9 @@
plan.status === 'READY' ? 'primary' : 'info'"
size="mini"
>
{{ plan.status === 'PRODUCING' ? '生产中' :
plan.status === 'ONLINE' ? '在机' :
plan.status === 'READY' ? '就绪' : '新建' }}
{{ plan.status === 'PRODUCING' ? $t('plan.producing') :
plan.status === 'ONLINE' ? $t('plan.online') :
plan.status === 'READY' ? $t('plan.ready') : $t('plan.new') }}
</el-tag>
</div>
<div class="plan-content">
@@ -129,7 +129,7 @@
</div>
</div>
<div v-if="pendingPlans.length === 0" class="empty-text">
暂无生产计划
{{ $t('plan.noProductionPlan') }}
</div>
</div>
</el-tab-pane>
@@ -138,7 +138,7 @@
<el-tab-pane name="history">
<span slot="label">
<i class="el-icon-document-checked"></i>
历史记录
{{ $t('plan.history') }}
<el-badge :value="historyPlans.length" class="tab-badge" />
</span>
<div class="plan-list">
@@ -151,7 +151,7 @@
>
<div class="plan-status">
<span class="status-dot status-history"></span>
<el-tag type="info" size="mini">已完成</el-tag>
<el-tag type="info" size="mini">{{ $t('plan.completed') }}</el-tag>
</div>
<div class="plan-content">
<div class="plan-main">
@@ -174,7 +174,7 @@
</div>
</div>
<div v-if="historyPlans.length === 0" class="empty-text">
暂无历史记录
{{ $t('plan.noHistory') }}
</div>
</div>
</el-tab-pane>
@@ -187,14 +187,14 @@
<div v-if="currentRow" class="detail-section">
<div class="section-header">
<i class="el-icon-data-line"></i>
<span>计划详情与工艺参数</span>
<span>{{ $t('plan.planDetailAndProcessParams') }}</span>
</div>
<!-- 整合的详情卡片 -->
<el-card class="detail-card-unified" shadow="never">
<el-tabs v-model="activeTab" type="border-card">
<!-- 基础信息标签页 -->
<el-tab-pane label="基础信息" name="basic">
<el-tab-pane :label="$t('plan.basicInfo')" name="basic">
<el-descriptions :column="3" border size="small">
<el-descriptions-item label="计划号">{{ currentRow.planid }}</el-descriptions-item>
<el-descriptions-item label="钢卷号">{{ currentRow.coilid }}</el-descriptions-item>
@@ -211,10 +211,10 @@
</el-tab-pane>
<!-- 工艺参数标签页 -->
<el-tab-pane label="工艺参数" name="process" v-loading="setupLoading">
<el-tab-pane :label="$t('plan.processParams')" name="process" v-loading="setupLoading">
<setup-pane v-if="!setupLoading && setupForm" :setup-form="setupForm" />
<div v-if="!setupLoading && !setupForm" class="empty-text">
暂无工艺参数数据
{{ $t('plan.noProcessParams') }}
</div>
</el-tab-pane>
</el-tabs>
@@ -222,7 +222,7 @@
</div>
<div v-else class="empty-section">
<i class="el-icon-info"></i>
<p>请从左侧选择一个计划查看详情</p>
<p>{{ $t('plan.pleaseSelectPlan') }}</p>
</div>
</el-col>
</el-row>
@@ -235,17 +235,17 @@
<el-form :model="form" ref="form" label-width="90px" :rules="rules" size="mini" class="plan-base-form">
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="计划ID" prop="planid">
<el-form-item :label="$t('plan.planId')" prop="planid">
<el-input v-model="form.planid" placeholder="请输入计划ID" maxLength="32"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="钢卷号" prop="coilid">
<el-form-item :label="$t('plan.coilid')" prop="coilid">
<el-input v-model="form.coilid" placeholder="请输入钢卷号" maxLength="32"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="钢种" prop="steelGrade">
<el-form-item :label="$t('plan.steelGrade')" prop="steelGrade">
<el-select v-model="form.steelGrade" placeholder="请选择钢种">
<el-option v-for="item in steelGradeList" :key="item.gradeid" :label="item.name"
:value="item.gradeid"></el-option>
@@ -253,59 +253,59 @@
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="厚度(mm)" prop="entryThick">
<el-form-item :label="$t('plan.thickness')" prop="entryThick">
<el-input v-model="form.entryThick" placeholder="请输入入口厚度" type="number" step="0.01" min="0"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="宽度(mm)" prop="entryWidth">
<el-form-item :label="$t('plan.width')" prop="entryWidth">
<el-input v-model="form.entryWidth" placeholder="请输入入口宽度" type="number" step="1" min="0"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="屈服点" prop="yieldPoint">
<el-form-item :label="$t('plan.yieldPoint')" prop="yieldPoint">
<el-input v-model="form.yieldPoint" placeholder="请输入屈服点" type="number" step="0.01" min="0"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="重量(t)" prop="entryWeight">
<el-form-item :label="$t('plan.weight')" prop="entryWeight">
<el-input v-model="form.entryWeight" placeholder="请输入入口重量" type="number" step="0.01" min="0"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="长度(mm)" prop="entryLength">
<el-form-item :label="$t('plan.length')" prop="entryLength">
<el-input v-model="form.entryLength" placeholder="请输入入口长度" type="number" step="1" min="0"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="外径(mm)" prop="entryOuterDiameter">
<el-form-item :label="$t('plan.outerDiameter')" prop="entryOuterDiameter">
<el-input v-model="form.entryOuterDiameter" placeholder="请输入入口外径" type="number" step="1"
min="0"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="延伸率(%)" prop="spmElongation">
<el-form-item :label="$t('plan.elongation')" prop="spmElongation">
<el-input v-model="form.spmElongation" placeholder="请输入延伸率" type="number" step="0.01" min="0"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="轧制力" prop="spmRollforce">
<el-form-item :label="$t('plan.spmRollforce')" prop="spmRollforce">
<el-input v-model="form.spmRollforce" placeholder="请输入SPM轧制力" type="number" step="0.01"
min="0"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="出口目标长度" prop="exitLengthTar">
<el-form-item :label="$t('plan.exitLengthTar')" prop="exitLengthTar">
<el-input v-model="form.exitLengthTar" placeholder="请输入出口目标长度(mm)" type="number" step="1" min="0"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="出口目标厚度" prop="exitThickTar">
<el-form-item :label="$t('plan.exitThickTar')" prop="exitThickTar">
<el-input v-model="form.exitThickTar" placeholder="请输入出口目标厚度(mm)" type="number" step="0.01" min="0"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="出口目标宽度" prop="exitWidthTar">
<el-form-item :label="$t('plan.exitWidthTar')" prop="exitWidthTar">
<el-input v-model="form.exitWidthTar" placeholder="请输入出口目标宽度(mm)" type="number" step="1" min="0"></el-input>
</el-form-item>
</el-col>
@@ -314,8 +314,8 @@
<div class="plan-dialog-actions">
<el-checkbox v-if="!form.id" v-model="spmFlag"
label="生成工艺参数(建议先填写完成基础信息再勾选此选项)"></el-checkbox>
<el-divider content-position="left" v-if="spmFlag">工艺参数</el-divider>
:label="$t('plan.generateProcessParams')"></el-checkbox>
<el-divider content-position="left" v-if="spmFlag">{{ $t('plan.processParams') }}</el-divider>
<setup-form v-if="spmFlag" ref="setupFormRef" :income="form" :steel-grade-options="steelGradeList"
:plan-history="planList" :show-recommendation-panel="false" @input="handleSetupInput"
@recommendation-change="handleProcessRecommendation" />
@@ -333,8 +333,8 @@
</div>
<!-- 弹窗底部按钮 -->
<div slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="submitForm" :loading="saveLoading">保存</el-button>
<el-button @click="dialogVisible = false">{{ $t('plan.cancel') }}</el-button>
<el-button type="primary" @click="submitForm" :loading="saveLoading">{{ $t('plan.save') }}</el-button>
</div>
</el-dialog>
</div>
@@ -817,7 +817,7 @@ export default {
// 新增计划(重置表单+打开弹窗)
handleAdd() {
this.dialogTitle = "新增计划"; // 设置弹窗标题
this.dialogTitle = this.$t('plan.addPlan'); // 设置弹窗标题
// 重置表单数据(默认值与接口要求对齐)
this.form = {
dummyCoilFlag: 0,
@@ -932,7 +932,7 @@ export default {
// 编辑计划(回显行数据+打开弹窗)
handleUpdate(row) {
this.dialogTitle = "编辑计划"; // 设置弹窗标题
this.dialogTitle = this.$t('plan.edit'); // 设置弹窗标题
// 深拷贝行数据(避免修改原表格数据)
this.form = JSON.parse(JSON.stringify(row));
this.spmFlag = false
@@ -988,10 +988,10 @@ export default {
// 删除计划(单个删除,支持批量扩展)
handleDelete(row) {
// 弹窗确认(危险操作二次确认)
this.$confirm(`确定删除ID: ${row.id} 的计划?`, "确认删除", {
this.$confirm(`确定删除ID: ${row.id} 的计划?`, this.$t('plan.confirmDelete'), {
type: "danger",
confirmButtonText: "确认",
cancelButtonText: "取消"
confirmButtonText: this.$t('plan.confirm'),
cancelButtonText: this.$t('plan.cancel')
})
.then(() => {
row.deleteLoading = true; // 开启行删除按钮加载
@@ -999,13 +999,13 @@ export default {
delPlan([row.id])
.then((res) => {
row.deleteLoading = false; // 关闭加载
this.$message.success("删除成功");
this.$message.success(this.$t('plan.deleteSuccess'));
this.getList(); // 重新加载列表
})
.catch((err) => {
row.deleteLoading = false; // 关闭加载
console.error("删除计划失败:", err);
this.$message.error("删除失败,请重试");
this.$message.error(this.$t('plan.deleteFailed'));
});
})
},
@@ -1024,7 +1024,7 @@ export default {
const start = new Date(formData.startDate);
const end = new Date(formData.endDate);
if (start > end) {
this.$message.warning("开始时间不能晚于结束时间");
this.$message.warning(this.$t('plan.startTimeNotLaterThanEndTime'));
return;
}
}
@@ -1041,11 +1041,11 @@ export default {
this.saveLoading = false; // 关闭加载
console.log("服务器响应:", res);
if (res.code === 200) {
this.$message.success(formData.id ? "更新计划成功" : "新增计划成功");
this.$message.success(formData.id ? this.$t('plan.updateSuccess') : this.$t('plan.addSuccess'));
this.dialogVisible = false; // 关闭弹窗
this.getList(); // 重新加载列表
} else {
this.$message.error(res.msg || (formData.id ? "更新失败" : "新增失败"));
this.$message.error(res.msg || (formData.id ? this.$t('plan.updateFailed') : this.$t('plan.addFailed')));
}
})
.catch((err) => {

View File

@@ -4,35 +4,35 @@
<div class="header-title">
<i class="el-icon-document"></i>
<div class="title-text">
<span>停机报表</span>
<small>请选择时间范围后查看数据</small>
<span>{{ $t('report.stop.title') }}</span>
<small>{{ $t('report.stop.subtitle') }}</small>
</div>
</div>
<el-tag size="small" effect="plain">停机</el-tag>
<el-tag size="small" effect="plain">{{ $t('report.stop.stopTag') }}</el-tag>
</div>
<div class="time-selector-card" v-if="!hasSelectedTime">
<div class="selector-header">
<i class="el-icon-calendar"></i>
<span>请选择查询日期范围</span>
<span>{{ $t('report.stop.pleaseSelectDateRange') }}</span>
</div>
<div class="selector-content">
<el-form :inline="true" size="small">
<el-form-item label="开始日期">
<el-form-item :label="$t('report.stop.startDate')">
<el-date-picker
v-model="timeRange.startTime"
type="date"
placeholder="选择开始日期"
:placeholder="$t('report.stop.chooseStartDate')"
value-format="yyyy-MM-dd"
style="width: 200px;"
:clearable="false"
/>
</el-form-item>
<el-form-item label="结束日期">
<el-form-item :label="$t('report.stop.endDate')">
<el-date-picker
v-model="timeRange.endTime"
type="date"
placeholder="选择结束日期"
:placeholder="$t('report.stop.chooseEndDate')"
value-format="yyyy-MM-dd"
style="width: 200px;"
:clearable="false"
@@ -40,9 +40,9 @@
</el-form-item>
<el-form-item>
<el-button type="primary" :disabled="!canQuery" icon="el-icon-search" @click="handleTimeConfirm">
查询
{{ $t('report.stop.query') }}
</el-button>
<el-button icon="el-icon-refresh" @click="handleTimeReset">重置</el-button>
<el-button icon="el-icon-refresh" @click="handleTimeReset">{{ $t('report.stop.reset') }}</el-button>
</el-form-item>
</el-form>
</div>
@@ -51,18 +51,18 @@
<div class="report-content" v-else>
<div class="content-toolbar">
<div class="toolbar-info">
<span class="info-label">报表类型</span>
<span class="info-value">停机报表</span>
<span class="info-label">{{ $t('report.stop.reportType') }}</span>
<span class="info-value">{{ $t('report.stop.title') }}</span>
<span class="info-divider">|</span>
<span class="info-label">时间范围</span>
<span class="info-label">{{ $t('report.stop.timeRange') }}</span>
<span class="info-range">{{ displayTimeRange }}</span>
</div>
<el-button type="text" icon="el-icon-refresh-left" @click="handleReturn">重新选择时间</el-button>
<el-button type="text" icon="el-icon-refresh-left" @click="handleReturn">{{ $t('report.stop.reselectTime') }}</el-button>
</div>
<ReportBody
v-loading="loading"
title="停机报表"
:title="$t('report.stop.title')"
:summary="reportSummary"
:dataset="reportDetail"
:columns="columns"
@@ -89,16 +89,6 @@ export default {
},
reportSummary: [],
reportDetail: [],
columns: [
{ label: '钢卷号', prop: 'coilid' },
{ label: '班次号', prop: 'shift' },
{ label: '组', prop: 'area' },
{ label: '开始时间', prop: 'startDate' },
{ label: '结束时间', prop: 'endDate' },
{ label: '持续时间[分钟]', prop: 'duration' },
{ label: '停机类型', prop: 'unit' },
{ label: '备注', prop: 'remark' }
]
}
},
computed: {
@@ -109,9 +99,21 @@ export default {
if (!this.canQuery) return '-'
return `${this.timeRange.startTime}${this.timeRange.endTime}`
},
columns() {
return [
{ label: this.$t('report.stop.coilid'), prop: 'coilid' },
{ label: this.$t('report.stop.shift'), prop: 'shift' },
{ label: this.$t('report.stop.area'), prop: 'area' },
{ label: this.$t('report.stop.startTime'), prop: 'startDate' },
{ label: this.$t('report.stop.endTime'), prop: 'endDate' },
{ label: this.$t('report.stop.duration'), prop: 'duration' },
{ label: this.$t('report.stop.stopType'), prop: 'unit' },
{ label: this.$t('report.stop.remark'), prop: 'remark' }
]
},
overviewInfo() {
return {
reportLabel: '停机报表',
reportLabel: this.$t('report.stop.title'),
rangeText: this.displayTimeRange
}
}

View File

@@ -2,39 +2,39 @@
<div class="filter-container">
<div class="filter-panel">
<div class="panel-header">
<h4>历史检索</h4>
<h4>{{ $t('roller.historySearch') }}</h4>
</div>
<div class="filter-item">
<div class="filter-label"> 按时间</div>
<div class="filter-label"> {{ $t('roller.byTime') }}</div>
<div class="filter-content time-range">
<div class="time-label">开始时间</div>
<div class="time-label">{{ $t('roller.startTime') }}</div>
<el-date-picker
v-model="startDate"
type="date"
placeholder="选择日期"
:placeholder="$t('roller.selectDate')"
value-format="yyyy-MM-dd"
style="width: 140px"
></el-date-picker>
<el-time-picker
v-model="startTime"
format="HH:mm"
placeholder="选择时间"
:placeholder="$t('roller.selectTime')"
value-format="HH:mm"
style="width: 140px; margin-left: 5px"
></el-time-picker>
<div class="time-label" style="margin-top: 10px">结束时间</div>
<div class="time-label" style="margin-top: 10px">{{ $t('roller.endTime') }}</div>
<el-date-picker
v-model="endDate"
type="date"
placeholder="选择日期"
:placeholder="$t('roller.selectDate')"
value-format="yyyy-MM-dd"
style="width: 140px"
></el-date-picker>
<el-time-picker
v-model="endTime"
format="HH:mm"
placeholder="选择时间"
:placeholder="$t('roller.selectTime')"
value-format="HH:mm"
style="width: 140px; margin-left: 5px"
></el-time-picker>
@@ -42,10 +42,10 @@
</div>
<div class="filter-item">
<div class="filter-label"> 按换辊号</div>
<div class="filter-label"> {{ $t('roller.byChangeId') }}</div>
<div class="filter-content">
<div class="input-label">换辊号</div>
<el-select filterable v-model="queryParams.changeId" placeholder="请选择" clearable style="width: 240px">
<div class="input-label">{{ $t('roller.changeId') }}</div>
<el-select filterable v-model="queryParams.changeId" :placeholder="$t('roller.pleaseSelect')" clearable style="width: 240px">
<el-option
v-for="item in changeIdOptions"
:key="item"
@@ -57,10 +57,10 @@
</div>
<div class="filter-item">
<div class="filter-label"> 按轧辊号</div>
<div class="filter-label"> {{ $t('roller.byRollId') }}</div>
<div class="filter-content">
<div class="input-label">轧辊号</div>
<el-select filterable v-model="queryParams.rollId" placeholder="请选择" clearable style="width: 240px">
<div class="input-label">{{ $t('roller.rollId') }}</div>
<el-select filterable v-model="queryParams.rollId" :placeholder="$t('roller.pleaseSelect')" clearable style="width: 240px">
<el-option
v-for="item in rollIdOptions"
:key="item"
@@ -72,8 +72,8 @@
</div>
<div class="filter-buttons">
<el-button type="primary" @click="handleSearch"> </el-button>
<el-button @click="resetQuery"> </el-button>
<el-button type="primary" @click="handleSearch">{{ $t('roller.query') }}</el-button>
<el-button @click="resetQuery">{{ $t('roller.reset') }}</el-button>
</div>
</div>
</div>
@@ -116,11 +116,11 @@ export default {
if (res.code === 200 && res.data) {
this.changeIdOptions = res.data
} else {
this.$message.error(res.msg || '获取换辊号列表失败')
this.$message.error(res.msg || this.$t('roller.getChangeIdListFailed'))
}
}).catch(error => {
console.error('获取换辊号列表失败', error)
this.$message.error('获取换辊号列表失败' + (error.message || '未知错误'))
this.$message.error(this.$t('roller.getChangeIdListFailed') + '' + (error.message || '未知错误'))
})
},
@@ -131,11 +131,11 @@ export default {
if (res.code === 200 && res.data) {
this.rollIdOptions = res.data
} else {
this.$message.error(res.msg || '获取轧辊号列表失败')
this.$message.error(res.msg || this.$t('roller.getRollIdListFailed'))
}
}).catch(error => {
console.error('获取轧辊号列表失败', error)
this.$message.error('获取轧辊号列表失败' + (error.message || '未知错误'))
this.$message.error(this.$t('roller.getRollIdListFailed') + '' + (error.message || '未知错误'))
})
},

View File

@@ -12,23 +12,23 @@
@cell-mouse-enter="handleCellEnter"
@row-mouseleave="handleRowLeave"
>
<el-table-column prop="changeid" label="换辊号" align="center" show-overflow-tooltip />
<el-table-column prop="rollid" label="轧辊号" align="center" show-overflow-tooltip />
<el-table-column prop="standid" label="机架号" align="center" show-overflow-tooltip />
<el-table-column label="位置" align="center" prop="position">
<el-table-column prop="changeid" :label="$t('roller.changeId')" align="center" show-overflow-tooltip />
<el-table-column prop="rollid" :label="$t('roller.rollId')" align="center" show-overflow-tooltip />
<el-table-column prop="standid" :label="$t('roller.standId')" align="center" show-overflow-tooltip />
<el-table-column :label="$t('roller.position')" align="center" prop="position">
<template slot-scope="scope">
<dict-tag :options="dict.type.main_roll_position" :value="scope.row.position" />
</template>
</el-table-column>
<el-table-column label="类型" align="center" prop="type" >
<el-table-column :label="$t('roller.type')" align="center" prop="type" >
<template slot-scope="scope">
<dict-tag :options="dict.type.main_roll_type" :value="scope.row.type" />
</template>
</el-table-column>
<el-table-column prop="changeType" label="换辊类型" align="center" show-overflow-tooltip />
<el-table-column prop="changeTime" label="换辊时间" align="center" show-overflow-tooltip />
<el-table-column prop="instalTime" label="安装时间" align="center" show-overflow-tooltip />
<el-table-column prop="deinstalTime" label="拆卸时间" align="center" show-overflow-tooltip />
<el-table-column prop="changeType" :label="$t('roller.changeType')" align="center" show-overflow-tooltip />
<el-table-column prop="changeTime" :label="$t('roller.changeTime')" align="center" show-overflow-tooltip />
<el-table-column prop="instalTime" :label="$t('roller.installTime')" align="center" show-overflow-tooltip />
<el-table-column prop="deinstalTime" :label="$t('roller.dismantleTime')" align="center" show-overflow-tooltip />
</el-table>
<transition name="el-fade-in-linear">
<div
@@ -37,14 +37,14 @@
:style="tooltipStyle"
ref="rowTooltip"
>
<div class="tooltip-title">详细信息</div>
<div class="tooltip-title">{{ $t('roller.detailedInfo') }}</div>
<div class="tooltip-list">
<div
class="tooltip-item"
v-for="field in detailFields"
:key="field.prop"
>
<span class="label">{{ field.label }}</span>
<span class="label">{{ $t(`roller.${field.i18nKey}`) }}</span>
<span class="value">{{ formatTooltipValue(hoveredRow, field) }}</span>
</div>
</div>
@@ -90,26 +90,26 @@ export default {
deinstalTimeRange: []
},
detailFields: [
{ label: '换辊号', prop: 'changeid' },
{ label: '轧辊号', prop: 'rollid' },
{ label: '机架号', prop: 'standid' },
{ label: '位置', prop: 'position', dict: 'main_roll_position' },
{ label: '类型', prop: 'type', dict: 'main_roll_type' },
{ label: '换辊类型', prop: 'changeType' },
{ label: '换辊时间', prop: 'changeTime' },
{ label: '安装时间', prop: 'instalTime' },
{ label: '拆卸时间', prop: 'deinstalTime' },
{ label: '直径', prop: 'diameter' },
{ label: '粗糙度', prop: 'rough' },
{ label: '凸度', prop: 'crown' },
{ label: '成分', prop: 'composition' },
{ label: '磨削次数', prop: 'grindCount' },
{ label: '轧制重量', prop: 'rolledWeight' },
{ label: '轧制数量', prop: 'rolledCount' },
{ label: '轧制长度', prop: 'rolledLength' },
{ label: '总轧制重量', prop: 'totalRolledWeight' },
{ label: '总轧制长度', prop: 'totalRolledLength' },
{ label: '总轧制数量', prop: 'totalRolledCount' }
{ i18nKey: 'changeId', prop: 'changeid' },
{ i18nKey: 'rollId', prop: 'rollid' },
{ i18nKey: 'standId', prop: 'standid' },
{ i18nKey: 'position', prop: 'position', dict: 'main_roll_position' },
{ i18nKey: 'type', prop: 'type', dict: 'main_roll_type' },
{ i18nKey: 'changeType', prop: 'changeType' },
{ i18nKey: 'changeTime', prop: 'changeTime' },
{ i18nKey: 'installTime', prop: 'instalTime' },
{ i18nKey: 'dismantleTime', prop: 'deinstalTime' },
{ i18nKey: 'diameter', prop: 'diameter' },
{ i18nKey: 'roughness', prop: 'rough' },
{ i18nKey: 'crown', prop: 'crown' },
{ i18nKey: 'composition', prop: 'composition' },
{ i18nKey: 'grindCount', prop: 'grindCount' },
{ i18nKey: 'rolledWeight', prop: 'rolledWeight' },
{ i18nKey: 'rolledCount', prop: 'rolledCount' },
{ i18nKey: 'rolledLength', prop: 'rolledLength' },
{ i18nKey: 'totalRolledWeight', prop: 'totalRolledWeight' },
{ i18nKey: 'totalRolledLength', prop: 'totalRolledLength' },
{ i18nKey: 'totalRolledCount', prop: 'totalRolledCount' }
]
}
},
@@ -146,7 +146,7 @@ export default {
const loading = this.$loading({
lock: true,
text: '加载中...',
text: this.$t('roller.loading'),
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
})
@@ -164,14 +164,14 @@ export default {
if (item.deinstalTime) item.deinstalTime = this.formatDate(item.deinstalTime)
})
} else {
this.$message.error(res.msg || '获取数据失败')
this.$message.error(res.msg || this.$t('roller.getDataFailed'))
this.tableData = []
this.pagination.total = 0
}
})
.catch(error => {
console.error('获取轧辊历史数据失败', error)
this.$message.error('获取数据失败' + (error.message || '未知错误'))
this.$message.error(this.$t('roller.getDataFailed') + '' + (error.message || '未知错误'))
this.tableData = []
this.pagination.total = 0
})

View File

@@ -2,7 +2,7 @@
<template>
<div class="online-roll">
<div class="panel-header">
<h4>在线辊</h4>
<h4>{{ $t('roller.onlineRollers') }}</h4>
</div>
<el-table
:data="onlineData"
@@ -14,24 +14,24 @@
:show-overflow-tooltip="true"
style="width: 100%; table-layout: fixed;"
>
<el-table-column prop="rollid" label="轧辊号" show-overflow-tooltip />
<el-table-column label="位置" align="center" prop="position" show-overflow-tooltip>
<el-table-column prop="rollid" :label="$t('roller.rollId')" show-overflow-tooltip />
<el-table-column :label="$t('roller.position')" align="center" prop="position" show-overflow-tooltip>
<template slot-scope="scope">
<dict-tag :options="dict.type.main_roll_position" :value="scope.row.position" />
</template>
</el-table-column>
<el-table-column label="类型" align="center" prop="type" show-overflow-tooltip>
<el-table-column :label="$t('roller.type')" align="center" prop="type" show-overflow-tooltip>
<template slot-scope="scope">
<dict-tag :options="dict.type.main_roll_type" :value="scope.row.type" />
</template>
</el-table-column>
<el-table-column prop="diameter" label="直径" show-overflow-tooltip />
<el-table-column prop="rough" label="粗糙度"show-overflow-tooltip />
<el-table-column prop="crown" label="凸度" show-overflow-tooltip />
<el-table-column prop="rolledLength" label="长度" show-overflow-tooltip />
<el-table-column prop="rolledWeight" label="重量" show-overflow-tooltip />
<el-table-column prop="rolledCount" label="轧制数量" show-overflow-tooltip />
<el-table-column prop="instalTime" label="装机时间" show-overflow-tooltip />
<el-table-column prop="diameter" :label="$t('roller.diameter')" show-overflow-tooltip />
<el-table-column prop="rough" :label="$t('roller.roughness')" show-overflow-tooltip />
<el-table-column prop="crown" :label="$t('roller.crown')" show-overflow-tooltip />
<el-table-column prop="rolledLength" :label="$t('roller.rolledLength')" show-overflow-tooltip />
<el-table-column prop="rolledWeight" :label="$t('roller.rolledWeight')" show-overflow-tooltip />
<el-table-column prop="rolledCount" :label="$t('roller.rolledCount')" show-overflow-tooltip />
<el-table-column prop="instalTime" :label="$t('roller.installTime')" show-overflow-tooltip />
<!-- <el-table-column prop="usableLength" label="可用长度" show-overflow-tooltip />
<el-table-column prop="leftLength" label="剩余长度" show-overflow-tooltip />
<el-table-column prop="usableWeight" label="可用重量" show-overflow-tooltip />

View File

@@ -2,10 +2,10 @@
<template>
<div class="standby-panel" v-loading="loading">
<div class="panel-header">
<h4>准备辊</h4>
<h4>{{ $t('roller.standbyRollers') }}</h4>
<div class="header-actions">
<el-button type="primary" size="mini" icon="el-icon-box" @click="handleBackup">备辊</el-button>
<el-button type="primary" size="mini" icon="el-icon-upload2" @click="handleOnline">上线</el-button>
<el-button type="primary" size="mini" icon="el-icon-box" @click="handleBackup">{{ $t('roller.backup') }}</el-button>
<el-button type="primary" size="mini" icon="el-icon-upload2" @click="handleOnline">{{ $t('roller.online') }}</el-button>
</div>
</div>
<el-table
@@ -17,12 +17,12 @@
:show-overflow-tooltip="true"
style="width: 100%; table-layout: fixed;"
>
<el-table-column label="位置/类型" show-overflow-tooltip>
<el-table-column :label="$t('roller.positionType')" show-overflow-tooltip>
<template #default="scope">
{{ getRollerTitle(scope.row.type, scope.row.position) }}
</template>
</el-table-column>
<el-table-column prop="rollid" label="轧辊号" show-overflow-tooltip>
<el-table-column prop="rollid" :label="$t('roller.rollId')" show-overflow-tooltip>
<template #default="scope">
<el-select
size="mini"
@@ -31,26 +31,26 @@
allow-create
v-model="scope.row.rollid"
style="width: 100%;"
placeholder="请选择轧辊号"
:placeholder="$t('roller.pleaseSelectRollId')"
@change="handleChange(scope.row)"
>
<el-option v-for="item in scope.row.data" :key="item.rollid" :label="item.rollid" :value="item.rollid" />
</el-select>
</template>
</el-table-column>
<el-table-column prop="diameter" label="直径" show-overflow-tooltip>
<el-table-column prop="diameter" :label="$t('roller.diameter')" show-overflow-tooltip>
<template #default="scope">
<el-input style="width: 100%;" size="mini" :disabled="!scope.row.rollid" v-model="scope.row.diameter" placeholder="请输入直径" />
<el-input style="width: 100%;" size="mini" :disabled="!scope.row.rollid" v-model="scope.row.diameter" :placeholder="$t('roller.pleaseInputDiameter')" />
</template>
</el-table-column>
<el-table-column prop="rough" label="粗糙度" show-overflow-tooltip>
<el-table-column prop="rough" :label="$t('roller.roughness')" show-overflow-tooltip>
<template #default="scope">
<el-input style="width: 100%;" size="mini" :disabled="!scope.row.rollid" v-model="scope.row.rough" placeholder="请输入粗糙度" />
<el-input style="width: 100%;" size="mini" :disabled="!scope.row.rollid" v-model="scope.row.rough" :placeholder="$t('roller.pleaseInputRoughness')" />
</template>
</el-table-column>
<el-table-column prop="crown" label="凹度" show-overflow-tooltip>
<el-table-column prop="crown" :label="$t('roller.crown')" show-overflow-tooltip>
<template #default="scope">
<el-input style="width: 100%;" size="mini" :disabled="!scope.row.rollid" v-model="scope.row.crown" placeholder="请输入凹度" />
<el-input style="width: 100%;" size="mini" :disabled="!scope.row.rollid" v-model="scope.row.crown" :placeholder="$t('roller.pleaseInputCrown')" />
</template>
</el-table-column>
</el-table>
@@ -118,13 +118,13 @@ export default {
methods: {
getRollerTitle(type, position) {
const typeDict = {
WORK: '工作辊',
BACKUP: "支撑辊",
INTERMEDIATE: "中间辊",
WORK: this.$t('roller.workRoll'),
BACKUP: this.$t('roller.backupRoll'),
INTERMEDIATE: this.$t('roller.intermediateRoll'),
}
const positionDict = {
TOP: "上",
BOTTOM: "下",
TOP: this.$t('roller.top'),
BOTTOM: this.$t('roller.bottom'),
}
return positionDict[position] + typeDict[type]
},

View File

@@ -4,13 +4,13 @@
<div class="monitor-header">
<div class="header-left">
<div class="status-indicator" :class="{ active: isConnected }"></div>
<h1 class="main-title">过程跟踪实时监控系统</h1>
<h1 class="main-title">{{ $t('track.title') }}</h1>
</div>
<div class="header-right">
<div class="connection-info">
<span class="label">连接状态</span>
<span class="label">{{ $t('track.connectionStatus') }}</span>
<span class="value" :class="{ connected: isConnected }">
{{ isConnected ? '已连接' : '连接中...' }}
{{ isConnected ? $t('track.connected') : $t('track.connecting') }}
</span>
</div>
<div class="time-display">{{ currentTime }}</div>
@@ -20,7 +20,7 @@
<!-- 数据类型选择器 -->
<div class="type-selector-panel">
<div class="selector-wrapper">
<label class="selector-label">数据类型</label>
<label class="selector-label">{{ $t('track.dataType') }}</label>
<el-select v-model="currentType" @change="handleTypeChange" size="small" class="type-select">
<el-option
v-for="type in types"
@@ -35,11 +35,11 @@
</div>
<div class="stats-info">
<div class="stat-item">
<span class="stat-label">数据包</span>
<span class="stat-label">{{ $t('track.packetCount') }}</span>
<span class="stat-value">{{ messageCount }}</span>
</div>
<div class="stat-item">
<span class="stat-label">刷新率</span>
<span class="stat-label">{{ $t('track.refreshRate') }}</span>
<span class="stat-value">{{ refreshRate }} Hz</span>
</div>
</div>
@@ -52,10 +52,10 @@
<div class="panel-header">
<div class="header-title">
<i class="el-icon-s-data"></i>
<span>入口段数据监控</span>
<span>{{ $t('track.entryData') }}</span>
</div>
<div class="panel-badges">
<span class="badge success" v-if="chartData.entry.time.length > 0">实时</span>
<span class="badge success" v-if="chartData.entry.time.length > 0">{{ $t('track.realTime') }}</span>
<span class="badge info">{{ chartData.entry.time.length }}/{{ maxDataPoints }}</span>
</div>
</div>
@@ -63,22 +63,22 @@
<!-- 实时数据卡片 -->
<div class="data-cards">
<div class="data-card">
<div class="card-label">入口张力1</div>
<div class="card-label">{{ $t('track.entryTension1') }}</div>
<div class="card-value">{{ getLatestValue('entry', 'tensionPorBr1') }}</div>
<div class="card-unit">kN</div>
</div>
<div class="data-card">
<div class="card-label">入口张力2</div>
<div class="card-label">{{ $t('track.entryTension2') }}</div>
<div class="card-value">{{ getLatestValue('entry', 'tensionBr1Br2') }}</div>
<div class="card-unit">kN</div>
</div>
<div class="data-card">
<div class="card-label">入口张力3</div>
<div class="card-label">{{ $t('track.entryTension3') }}</div>
<div class="card-value">{{ getLatestValue('entry', 'tensionBr2Br3') }}</div>
<div class="card-unit">kN</div>
</div>
<div class="data-card highlight">
<div class="card-label">带钢速度</div>
<div class="card-label">{{ $t('track.stripSpeed') }}</div>
<div class="card-value">{{ getLatestValue('entry', 'stripSpeed') }}</div>
<div class="card-unit">m/min</div>
</div>
@@ -93,10 +93,10 @@
<div class="panel-header">
<div class="header-title">
<i class="el-icon-sunny"></i>
<span>炉温数据监控</span>
<span>{{ $t('track.furnaceData') }}</span>
</div>
<div class="panel-badges">
<span class="badge success" v-if="chartData.furnace.time.length > 0">实时</span>
<span class="badge success" v-if="chartData.furnace.time.length > 0">{{ $t('track.realTime') }}</span>
<span class="badge info">{{ chartData.furnace.time.length }}/{{ maxDataPoints }}</span>
</div>
</div>
@@ -104,17 +104,17 @@
<!-- 实时数据卡片 -->
<div class="data-cards">
<div class="data-card temperature">
<div class="card-label">PH炉实际温度</div>
<div class="card-label">{{ $t('track.phFurnaceTempActual') }}</div>
<div class="card-value">{{ getLatestValue('furnace', 'phFurnaceTemperatureActual') }}</div>
<div class="card-unit">°C</div>
</div>
<div class="data-card temperature">
<div class="card-label">NOF1炉实际温度</div>
<div class="card-label">{{ $t('track.nof1FurnaceTempActual') }}</div>
<div class="card-value">{{ getLatestValue('furnace', 'nof1FurnaceTemperatureActual') }}</div>
<div class="card-unit">°C</div>
</div>
<div class="data-card">
<div class="card-label">NOF1炉设定温度</div>
<div class="card-label">{{ $t('track.nof1FurnaceTempSet') }}</div>
<div class="card-value">{{ getLatestValue('furnace', 'nof1FurnaceTemperatureSet') }}</div>
<div class="card-unit">°C</div>
</div>
@@ -129,10 +129,10 @@
<div class="panel-header">
<div class="header-title">
<i class="el-icon-brush"></i>
<span>涂层段数据监控</span>
<span>{{ $t('track.coatData') }}</span>
</div>
<div class="panel-badges">
<span class="badge success" v-if="chartData.coat.time.length > 0">实时</span>
<span class="badge success" v-if="chartData.coat.time.length > 0">{{ $t('track.realTime') }}</span>
<span class="badge info">{{ chartData.coat.time.length }}/{{ maxDataPoints }}</span>
</div>
</div>
@@ -140,22 +140,22 @@
<!-- 实时数据卡片 -->
<div class="data-cards">
<div class="data-card">
<div class="card-label">顶部涂层重量</div>
<div class="card-label">{{ $t('track.topCoatWeight') }}</div>
<div class="card-value">{{ getLatestValue('coat', 'avrCoatingWeightTop') }}</div>
<div class="card-unit">g/</div>
</div>
<div class="data-card">
<div class="card-label">底部涂层重量</div>
<div class="card-label">{{ $t('track.bottomCoatWeight') }}</div>
<div class="card-value">{{ getLatestValue('coat', 'avrCoatingWeightBottom') }}</div>
<div class="card-unit">g/</div>
</div>
<div class="data-card">
<div class="card-label">气刀压力</div>
<div class="card-label">{{ $t('track.airKnifePressure') }}</div>
<div class="card-value">{{ getLatestValue('coat', 'airKnifePressure') }}</div>
<div class="card-unit">kPa</div>
</div>
<div class="data-card highlight">
<div class="card-label">出口速度</div>
<div class="card-label">{{ $t('track.exitSpeed') }}</div>
<div class="card-value">{{ getLatestValue('coat', 'stripSpeedTmExit') }}</div>
<div class="card-unit">m/min</div>
</div>
@@ -170,10 +170,10 @@
<div class="panel-header">
<div class="header-title">
<i class="el-icon-document-checked"></i>
<span>出口段数据监控</span>
<span>{{ $t('track.exitData') }}</span>
</div>
<div class="panel-badges">
<span class="badge success" v-if="chartData.exit.time.length > 0">实时</span>
<span class="badge success" v-if="chartData.exit.time.length > 0">{{ $t('track.realTime') }}</span>
<span class="badge info">{{ chartData.exit.time.length }}/{{ maxDataPoints }}</span>
</div>
</div>
@@ -181,17 +181,17 @@
<!-- 实时数据卡片 -->
<div class="data-cards">
<div class="data-card">
<div class="card-label">出口张力1</div>
<div class="card-label">{{ $t('track.exitTension1') }}</div>
<div class="card-value">{{ getLatestValue('exit', 'tensionBr8Br9') }}</div>
<div class="card-unit">kN</div>
</div>
<div class="data-card">
<div class="card-label">出口张力2</div>
<div class="card-label">{{ $t('track.exitTension2') }}</div>
<div class="card-value">{{ getLatestValue('exit', 'tensionBr9Tr') }}</div>
<div class="card-unit">kN</div>
</div>
<div class="data-card highlight">
<div class="card-label">出口速度</div>
<div class="card-label">{{ $t('track.exitSpeed') }}</div>
<div class="card-value">{{ getLatestValue('exit', 'speedExitSection') }}</div>
<div class="card-unit">m/min</div>
</div>
@@ -209,12 +209,12 @@
<i class="el-icon-view"></i>
</div>
<h3 class="card-title">{{ getCurrentTypeLabel() }}</h3>
<p class="card-desc">当前数据类型不支持图表展示原始数据如下</p>
<p class="card-desc">{{ $t('track.noChartSupport') }}</p>
</div>
<div class="raw-data-display">
<div class="raw-data-header">
<span class="raw-title">原始数据</span>
<el-button size="mini" @click="copyRawData" icon="el-icon-document-copy">复制</el-button>
<span class="raw-title">{{ $t('track.rawData') }}</span>
<el-button size="mini" @click="copyRawData" icon="el-icon-document-copy">{{ $t('track.copy') }}</el-button>
</div>
<pre class="raw-content">{{ formattedRawData }}</pre>
</div>
@@ -231,12 +231,12 @@ export default {
return {
socket: null,
types: [
{ value: 'alarm', label: '告警信息', desc: '系统告警与异常' },
{ value: 'track_position', label: '位置跟踪', desc: '钢卷位置信息' },
{ value: 'calc_setup_result', label: '设定计算', desc: '计算结果数据' },
{ value: 'track_measure', label: '过程测量', desc: '实时测量数据' },
{ value: 'track_signal', label: '信号跟踪', desc: '信号状态数据' },
{ value: 'track_matmap', label: '物料映射', desc: '物料映射关系' }
{ value: 'alarm', label: this.$t('track.alarmInfo'), desc: this.$t('track.alarmDesc') },
{ value: 'track_position', label: this.$t('track.positionTrack'), desc: this.$t('track.positionDesc') },
{ value: 'calc_setup_result', label: this.$t('track.calcSetupResult'), desc: this.$t('track.calcDesc') },
{ value: 'track_measure', label: this.$t('track.processMeasure'), desc: this.$t('track.measureDesc') },
{ value: 'track_signal', label: this.$t('track.signalTrack'), desc: this.$t('track.signalDesc') },
{ value: 'track_matmap', label: this.$t('track.matmap'), desc: this.$t('track.matmapDesc') }
],
currentType: 'track_measure',
isConnected: false,
@@ -284,7 +284,7 @@ export default {
},
computed: {
formattedRawData() {
if (!this.rawData) return '等待接收数据...';
if (!this.rawData) return this.$t('track.waitingData');
try {
return JSON.stringify(JSON.parse(this.rawData), null, 2);
} catch (e) {
@@ -334,9 +334,9 @@ export default {
// 复制原始数据
copyRawData() {
navigator.clipboard.writeText(this.formattedRawData).then(() => {
this.$message.success('已复制到剪贴板');
this.$message.success(this.$t('track.copySuccess'));
}).catch(() => {
this.$message.error('复制失败');
this.$message.error(this.$t('track.copyFailed'));
});
},
@@ -385,7 +385,7 @@ export default {
textStyle: { color: '#fff' }
},
legend: {
data: ['入口张力1', '入口张力2', '入口张力3', '带钢速度'],
data: [$t('track.entryTension1'), $t('track.entryTension2'), $t('track.entryTension3'), $t('track.stripSpeed')],
textStyle: { color: '#b0b0b0', fontSize: 12 },
top: 10
},
@@ -406,7 +406,7 @@ export default {
},
series: [
{
name: '入口张力1',
name: this.$t('track.entryTension1'),
type: 'line',
data: [],
smooth: true,
@@ -415,7 +415,7 @@ export default {
areaStyle: { color: 'rgba(0, 212, 255, 0.1)' }
},
{
name: '入口张力2',
name: this.$t('track.entryTension2'),
type: 'line',
data: [],
smooth: true,
@@ -423,7 +423,7 @@ export default {
itemStyle: { color: '#00ff9d' }
},
{
name: '入口张力3',
name: this.$t('track.entryTension3'),
type: 'line',
data: [],
smooth: true,
@@ -431,7 +431,7 @@ export default {
itemStyle: { color: '#ffa502' }
},
{
name: '带钢速度',
name: this.$t('track.stripSpeed'),
type: 'line',
data: [],
smooth: true,
@@ -454,7 +454,7 @@ export default {
textStyle: { color: '#fff' }
},
legend: {
data: ['PH炉实际温度', 'NOF1炉实际温度', 'NOF1炉设定温度'],
data: [$t('track.phFurnaceTempActual'), $t('track.nof1FurnaceTempActual'), $t('track.nof1FurnaceTempSet')],
textStyle: { color: '#b0b0b0', fontSize: 12 },
top: 10
},
@@ -475,7 +475,7 @@ export default {
},
series: [
{
name: 'PH炉实际温度',
name: this.$t('track.phFurnaceTempActual'),
type: 'line',
data: [],
smooth: true,
@@ -484,7 +484,7 @@ export default {
areaStyle: { color: 'rgba(255, 99, 72, 0.1)' }
},
{
name: 'NOF1炉实际温度',
name: this.$t('track.nof1FurnaceTempActual'),
type: 'line',
data: [],
smooth: true,
@@ -492,7 +492,7 @@ export default {
itemStyle: { color: '#ffa502' }
},
{
name: 'NOF1炉设定温度',
name: this.$t('track.nof1FurnaceTempSet'),
type: 'line',
data: [],
smooth: true,
@@ -515,7 +515,7 @@ export default {
textStyle: { color: '#fff' }
},
legend: {
data: ['顶部平均涂层重量', '底部平均涂层重量', '气刀压力', '出口速度'],
data: [$t('track.avrCoatingWeightTop'), $t('track.avrCoatingWeightBottom'), $t('track.airKnifePressure'), $t('track.exitSpeed')],
textStyle: { color: '#b0b0b0', fontSize: 12 },
top: 10
},
@@ -536,7 +536,7 @@ export default {
},
series: [
{
name: '顶部平均涂层重量',
name: this.$t('track.avrCoatingWeightTop'),
type: 'line',
data: [],
smooth: true,
@@ -545,7 +545,7 @@ export default {
areaStyle: { color: 'rgba(0, 255, 157, 0.1)' }
},
{
name: '底部平均涂层重量',
name: this.$t('track.avrCoatingWeightBottom'),
type: 'line',
data: [],
smooth: true,
@@ -553,7 +553,7 @@ export default {
itemStyle: { color: '#00d4ff' }
},
{
name: '气刀压力',
name: this.$t('track.airKnifePressure'),
type: 'line',
data: [],
smooth: true,
@@ -561,7 +561,7 @@ export default {
itemStyle: { color: '#ffa502' }
},
{
name: '出口速度',
name: this.$t('track.exitSpeed'),
type: 'line',
data: [],
smooth: true,
@@ -584,7 +584,7 @@ export default {
textStyle: { color: '#fff' }
},
legend: {
data: ['出口张力1', '出口张力2', '出口速度'],
data: [$t('track.exitTension1'), $t('track.exitTension2'), $t('track.exitSpeed')],
textStyle: { color: '#b0b0b0', fontSize: 12 },
top: 10
},
@@ -605,7 +605,7 @@ export default {
},
series: [
{
name: '出口张力1',
name: this.$t('track.exitTension1'),
type: 'line',
data: [],
smooth: true,
@@ -614,7 +614,7 @@ export default {
areaStyle: { color: 'rgba(0, 212, 255, 0.1)' }
},
{
name: '出口张力2',
name: this.$t('track.exitTension2'),
type: 'line',
data: [],
smooth: true,
@@ -622,7 +622,7 @@ export default {
itemStyle: { color: '#00ff9d' }
},
{
name: '出口速度',
name: this.$t('track.exitSpeed'),
type: 'line',
data: [],
smooth: true,

View File

@@ -6,32 +6,32 @@
<!-- 加载状态 -->
<div v-if="isLoading" class="loading-container">
<el-icon class="is-loading"><i class="el-icon-loading"></i></el-icon>
<span>加载中...</span>
<span>{{ $t('common.loading') }}</span>
</div>
<!-- WebSocket 连接状态指示 -->
<div v-if="!isLoading" class="ws-status-bar">
<el-tooltip content="测量数据" placement="top">
<el-tooltip :content="$t('track.measureData')" placement="top">
<el-badge :is-dot="true" :type="socketStatus.measure ? 'success' : 'danger'">
<i class="el-icon-data-analysis"></i>
</el-badge>
</el-tooltip>
<el-tooltip content="位置追踪" placement="top">
<el-tooltip :content="$t('track.positionTracking')" placement="top">
<el-badge :is-dot="true" :type="socketStatus.position ? 'success' : 'danger'">
<i class="el-icon-location"></i>
</el-badge>
</el-tooltip>
<el-tooltip content="操作信号" placement="top">
<el-tooltip :content="$t('track.operationSignal')" placement="top">
<el-badge :is-dot="true" :type="socketStatus.signal ? 'success' : 'danger'">
<i class="el-icon-bell"></i>
</el-badge>
</el-tooltip>
<el-tooltip content="物料映射" placement="top">
<el-tooltip :content="$t('track.materialMapping')" placement="top">
<el-badge :is-dot="true" :type="socketStatus.matmap ? 'success' : 'danger'">
<i class="el-icon-map-location"></i>
</el-badge>
</el-tooltip>
<el-tooltip content="计算结果" placement="top">
<el-tooltip :content="$t('track.calculationResult')" placement="top">
<el-badge :is-dot="true" :type="socketStatus.calcSetup ? 'success' : 'danger'">
<i class="el-icon-s-marketing"></i>
</el-badge>
@@ -42,8 +42,8 @@
<!-- 入口段区域 -->
<div class="section-area entry-area">
<div class="section-header">
入口段
<span class="section-info" v-if="positionData.entrySpeed">速度: {{ positionData.entrySpeed.toFixed(1) }} m/min</span>
{{ $t('track.entrySection') }}
<span class="section-info" v-if="positionData.entrySpeed">{{ $t('track.speed') }}: {{ positionData.entrySpeed.toFixed(1) }} m/min</span>
</div>
<div class="section-summary" v-if="entrySectionMetrics.length">
<div class="summary-item" v-for="item in entrySectionMetrics" :key="item.label">
@@ -70,8 +70,8 @@
<!-- 熔炉段区域 -->
<div class="section-area furnace-area">
<div class="section-header">
熔炉段
<span class="section-info" v-if="positionData.technologySpeed">速度: {{ positionData.technologySpeed.toFixed(1) }} m/min</span>
{{ $t('track.furnaceSection') }}
<span class="section-info" v-if="positionData.technologySpeed">{{ $t('track.speed') }}: {{ positionData.technologySpeed.toFixed(1) }} m/min</span>
</div>
<div class="section-summary" v-if="furnaceSectionMetrics.length">
<div class="summary-item" v-for="item in furnaceSectionMetrics" :key="item.label">
@@ -97,7 +97,7 @@
<!-- 涂层段区域 -->
<div class="section-area coat-area">
<div class="section-header">涂层段</div>
<div class="section-header">{{ $t('track.coatSection') }}</div>
<div class="section-summary" v-if="coatSectionMetrics.length">
<div class="summary-item" v-for="item in coatSectionMetrics" :key="item.label">
<span class="summary-label">{{ item.label }}</span>
@@ -123,8 +123,8 @@
<!-- 出口段区域 -->
<div class="section-area exit-area">
<div class="section-header">
出口段
<span class="section-info" v-if="positionData.exitSpeed">速度: {{ positionData.exitSpeed.toFixed(1) }} m/min</span>
{{ $t('track.exitSection') }}
<span class="section-info" v-if="positionData.exitSpeed">{{ $t('track.speed') }}: {{ positionData.exitSpeed.toFixed(1) }} m/min</span>
</div>
<div class="section-summary" v-if="exitSectionMetrics.length">
<div class="summary-item" v-for="item in exitSectionMetrics" :key="item.label">
@@ -150,7 +150,7 @@
<!-- 其他段区域 -->
<div class="section-area" v-if="exitOtherDevicesList.length">
<div class="section-header">其他段</div>
<div class="section-header">{{ $t('track.otherSection') }}</div>
<div class="device-grid other-exit-grid">
<div v-for="device in exitOtherDevicesList" :key="device.positionNameEn" class="device-card" :class="{
active: selectedCard && selectedCard.positionNameEn === device.positionNameEn,
@@ -175,10 +175,10 @@
<!-- 生产计划列表 -->
<div class="panel">
<div class="panel-title">
<i class="el-icon-s-order"></i> 生产计划
<i class="el-icon-s-order"></i> {{ $t('track.productionPlan') }}
</div>
<div class="plan-list-vertical">
<el-empty v-if="planQueue.length === 0" description="暂无生产计划" :image-size="80" />
<el-empty v-if="planQueue.length === 0" :description="$t('track.noProductionPlan')" :image-size="80" />
<div
v-else
v-for="(plan, index) in planQueue"
@@ -190,14 +190,14 @@
<div class="plan-item-top">
<div class="plan-order-dot" :class="getPlanOrderClass(plan.status)">{{ index + 1 }}</div>
<div class="plan-title-text">
<div class="plan-id">计划ID{{ plan.planid || '-' }}</div>
<div class="plan-coil">钢卷号{{ plan.coilid || '-' }}</div>
<div class="plan-id">{{ $t('track.planId') }}{{ plan.planid || '-' }}</div>
<div class="plan-coil">{{ $t('track.coilid') }}{{ plan.coilid || '-' }}</div>
</div>
<el-tag :type="getPlanStatusTagType(plan.status)" size="mini">{{ getPlanStatusText(plan.status) }}</el-tag>
</div>
<div class="plan-item-bottom">
<span>钢种{{ plan.steelGrade || '-' }}</span>
<span>顺序{{ plan.seqid || '-' }}</span>
<span>{{ $t('track.steelGrade') }}{{ plan.steelGrade || '-' }}</span>
<span>{{ $t('track.sequence') }}{{ plan.seqid || '-' }}</span>
</div>
</div>
</div>
@@ -206,21 +206,21 @@
<!-- 生产计划详情 -->
<div class="panel" v-if="selectedPlan">
<div class="panel-title">
<i class="el-icon-document"></i> 生产计划详情
<i class="el-icon-document"></i> {{ $t('track.productionPlanDetail') }}
<el-button size="mini" type="text" icon="el-icon-close" @click="selectedPlan = null"></el-button>
</div>
<div class="plan-detail-content">
<!-- 位置信息如果在产线上 -->
<div v-if="selectedPlanPosition" class="position-alert">
<div class="position-icon">
<i class="el-icon-location"></i>
</div>
<div class="position-info">
<div class="position-label">当前位置</div>
<div class="position-name">{{ selectedPlanPosition.positionNameCn }}</div>
<div class="position-code">{{ selectedPlanPosition.positionNameEn }}</div>
</div>
<div v-if="selectedPlanPosition" class="position-alert">
<div class="position-icon">
<i class="el-icon-location"></i>
</div>
<div class="position-info">
<div class="position-label">{{ $t('track.currentPosition') }}</div>
<div class="position-name">{{ selectedPlanPosition.positionNameCn }}</div>
<div class="position-code">{{ selectedPlanPosition.positionNameEn }}</div>
</div>
</div>
<el-descriptions :column="1" border size="small">
<el-descriptions-item label="计划ID">{{ selectedPlan.planid || '-' }}</el-descriptions-item>
@@ -250,8 +250,8 @@
</el-descriptions>
<!-- 时间信息 -->
<div class="plan-time-info" v-if="selectedPlan.onlineDate || selectedPlan.startDate || selectedPlan.endDate">
<div class="info-subtitle">时间信息</div>
<div class="plan-time-info" v-if="selectedPlan.onlineDate || selectedPlan.startDate || selectedPlan.endDate">
<div class="info-subtitle">{{ $t('track.timeInfo') }}</div>
<el-descriptions :column="1" border size="small">
<el-descriptions-item label="上线时间" v-if="selectedPlan.onlineDate">
{{ formatDateTime(selectedPlan.onlineDate) }}
@@ -270,7 +270,7 @@
<!-- 最近操作信号 -->
<div class="panel" v-if="signalData">
<div class="panel-title">
<i class="el-icon-bell"></i> 最近操作
<i class="el-icon-bell"></i> {{ $t('track.recentOperation') }}
<el-tag
:type="getOperationTagType(signalData.operation)"
size="mini"
@@ -304,39 +304,39 @@
</div>
<!-- 操作按钮 -->
<div class="panel">
<div class="panel-title">操作</div>
<div class="panel-title">{{ $t('track.operation') }}</div>
<div class="btn-list">
<el-button class="action-btn" size="small" @click="handleOperate(selectedCard, 'ONLINE')">钢卷上线</el-button>
<el-button class="action-btn" size="small" @click="handleOperate(selectedCard, 'UNLOAD')">手动卸卷</el-button>
<el-button class="action-btn" size="small" @click="handleOperate(selectedCard, 'ONLINE')">{{ $t('track.coilOnline') }}</el-button>
<el-button class="action-btn" size="small" @click="handleOperate(selectedCard, 'UNLOAD')">{{ $t('track.manualUnload') }}</el-button>
<el-button class="action-btn" size="small"
@click="handleOperate(selectedCard, 'ALL_RETURN')">整卷回退</el-button>
@click="handleOperate(selectedCard, 'ALL_RETURN')">{{ $t('track.allReturn') }}</el-button>
<el-button class="action-btn" size="small"
@click="handleOperate(selectedCard, 'HALF_RETURN')">半卷回退</el-button>
<el-button class="action-btn" size="small" @click="handleOperate(selectedCard, 'BLOCK')">卸卷并封闭</el-button>
@click="handleOperate(selectedCard, 'HALF_RETURN')">{{ $t('track.halfReturn') }}</el-button>
<el-button class="action-btn" size="small" @click="handleOperate(selectedCard, 'BLOCK')">{{ $t('track.unloadAndBlock') }}</el-button>
</div>
</div>
<!-- 设备基本信息 -->
<div class="panel" v-if="selectedCard">
<div class="panel-title">基本信息</div>
<div class="panel-title">{{ $t('track.basicInfo') }}</div>
<table class="info-table">
<tr>
<td>位置名称</td>
<td>{{ $t('track.positionName') }}</td>
<td>{{ selectedCard.positionNameCn || '-' }}</td>
</tr>
<tr>
<td>位置代号</td>
<td>{{ $t('track.positionCode') }}</td>
<td>{{ selectedCard.positionNameEn || '-' }}</td>
</tr>
<tr>
<td>钢卷号</td>
<td>{{ $t('track.coilid') }}</td>
<td>{{ selectedCard.matId || '-' }}</td>
</tr>
<tr>
<td>计划ID</td>
<td>{{ $t('track.planId') }}</td>
<td>{{ selectedCard.planId || '-' }}</td>
</tr>
<tr>
<td>计划号</td>
<td>{{ $t('track.planId') }}</td>
<td>{{ selectedCard.planNo || '-' }}</td>
</tr>
</table>
@@ -349,20 +349,20 @@
<!-- 调整工具选择两个位置两个下拉选分别双向绑定 -->
<el-form :model="adjustForm" ref="adjustForm" label-width="80px">
<el-form-item label="当前位置" prop="current">
<el-select v-model="adjustForm.current" placeholder="请选择当前位置">
<el-select v-model="adjustForm.current" :placeholder="$t('common.pleaseSelect')">
<el-option v-for="item in matMapList" :key="item.positionNameEn" :label="item.positionNameCn"
:value="item.positionNameEn"></el-option>
</el-select>
</el-form-item>
<el-form-item label="目标位置" prop="target">
<el-select v-model="adjustForm.target" placeholder="请选择目标位置">
<el-select v-model="adjustForm.target" :placeholder="$t('common.pleaseSelect')">
<el-option v-for="item in matMapList" :key="item.positionNameEn" :label="item.positionNameCn"
:value="item.positionNameEn"></el-option>
</el-select>
</el-form-item>
</el-form>
<el-button type="primary" :disabled="!adjustForm.current || !adjustForm.target"
@click="handleConfirmAdjust">确认调整</el-button>
@click="handleConfirmAdjust">{{ $t('track.confirmAdjustment') }}</el-button>
</div>
</div>
@@ -371,14 +371,14 @@
<!-- 计算结果对话框 -->
<el-dialog
title="计算设定结果"
:title="$t('track.calculationSetupResult')"
:visible.sync="showCalcResultDialog"
width="80%"
v-if="calcSetupResult"
>
<div class="calc-result-header">
<el-tag :type="calcSetupResult.flag ? 'success' : 'danger'">
{{ calcSetupResult.flag ? '计算成功' : '计算失败' }}
{{ calcSetupResult.flag ? $t('track.calculationSuccess') : $t('track.calculationFailed') }}
</el-tag>
<span>Key: {{ calcSetupResult.key }}</span>
</div>
@@ -389,69 +389,69 @@
stripe
max-height="500"
>
<el-table-column prop="passno" label="道次号" width="80" fixed></el-table-column>
<el-table-column prop="entryThick" label="入口厚度(mm)" width="120"></el-table-column>
<el-table-column prop="exitThick" label="出口厚度(mm)" width="120"></el-table-column>
<el-table-column prop="reduction" label="压下率(%)" width="100"></el-table-column>
<el-table-column prop="rollSpeed" label="轧制速度" width="120"></el-table-column>
<el-table-column prop="rollForce" label="轧制力(kN)" width="120"></el-table-column>
<el-table-column prop="entryTension" label="入口张力" width="120"></el-table-column>
<el-table-column prop="exitTension" label="出口张力" width="120"></el-table-column>
<el-table-column prop="passno" :label="$t('track.passno')" width="80" fixed></el-table-column>
<el-table-column prop="entryThick" :label="$t('track.entryThickness')" width="120"></el-table-column>
<el-table-column prop="exitThick" :label="$t('track.exitThickness')" width="120"></el-table-column>
<el-table-column prop="reduction" :label="$t('track.reduction')" width="100"></el-table-column>
<el-table-column prop="rollSpeed" :label="$t('track.rollSpeed')" width="120"></el-table-column>
<el-table-column prop="rollForce" :label="$t('track.rollForce')" width="120"></el-table-column>
<el-table-column prop="entryTension" :label="$t('track.entryTension')" width="120"></el-table-column>
<el-table-column prop="exitTension" :label="$t('track.exitTension')" width="120"></el-table-column>
</el-table>
<div v-else class="empty-msg">无计算结果数据</div>
<div v-else class="empty-msg">{{ $t('track.noCalculationResult') }}</div>
</el-dialog>
<el-dialog :visible.sync="operateMatStatus" :title="getOperateTitle" width="50%">
<el-form :model="operateMatForm" :rules="operateRules" ref="operateForm" label-width="120px">
<el-form-item label="开卷机编号" prop="porIdx">
<el-form-item :label="$t('track.por')" prop="porIdx">
<el-input v-model="operateMatForm.porIdx"></el-input>
</el-form-item>
<el-form-item label="卷取机编号" prop="trIdx">
<el-form-item :label="$t('track.tr')" prop="trIdx">
<el-input v-model="operateMatForm.trIdx"></el-input>
</el-form-item>
<el-form-item label="计划id" prop="planId">
<el-input v-model="operateMatForm.planId" placeholder="请输入计划ID"></el-input>
<el-form-item :label="$t('track.planId')" prop="planId">
<el-input v-model="operateMatForm.planId" :placeholder="$t('track.pleaseInputPlanId')"></el-input>
</el-form-item>
<el-form-item label="钢卷号" prop="entryMatId">
<el-input v-model="operateMatForm.entryMatId" placeholder="请输入钢卷号"></el-input>
<el-form-item :label="$t('track.coilid')" prop="entryMatId">
<el-input v-model="operateMatForm.entryMatId" :placeholder="$t('track.pleaseInputCoilid')"></el-input>
</el-form-item>
<!-- <el-form-item label="计划号" prop="planNo">
<el-input v-model="operateMatForm.planNo" placeholder="请输入计划号"></el-input>
</el-form-item> -->
<el-form-item label="操作类型" prop="operation">
<el-form-item :label="$t('track.operationType')" prop="operation">
<el-select v-model="operateMatForm.operation" disabled>
<el-option label="钢卷上线" value="ONLINE"></el-option>
<el-option label="手动卸卷" value="UNLOAD"></el-option>
<el-option label="整卷回退" value="ALL_RETURN"></el-option>
<el-option label="半卷回退" value="HALF_RETURN"></el-option>
<el-option label="卸卷并封闭" value="BLOCK"></el-option>
<el-option :label="$t('track.coilOnline')" value="ONLINE"></el-option>
<el-option :label="$t('track.manualUnload')" value="UNLOAD"></el-option>
<el-option :label="$t('track.allReturn')" value="ALL_RETURN"></el-option>
<el-option :label="$t('track.halfReturn')" value="HALF_RETURN"></el-option>
<el-option :label="$t('track.unloadAndBlock')" value="BLOCK"></el-option>
<!-- <el-option label="甩尾" value="THROW_TAIL"></el-option> -->
</el-select>
</el-form-item>
<!-- 回退相关字段 -->
<template v-if="['ALL_RETURN', 'HALF_RETURN'].includes(operateMatForm.operation)">
<el-form-item label="回退卷号" prop="returnMatId">
<el-input v-model="operateMatForm.returnMatId" placeholder="请输入回退卷号"></el-input>
<el-form-item :label="$t('track.returnMatId')" prop="returnMatId">
<el-input v-model="operateMatForm.returnMatId" :placeholder="$t('track.pleaseInputReturnMatId')"></el-input>
</el-form-item>
<el-form-item label="回退重量" prop="returnWeight">
<el-input v-model="operateMatForm.returnWeight" placeholder="请输入回退重量"></el-input>
<el-form-item :label="$t('track.returnWeight')" prop="returnWeight">
<el-input v-model="operateMatForm.returnWeight" :placeholder="$t('track.pleaseInputReturnWeight')"></el-input>
</el-form-item>
<el-form-item label="回退备注" prop="returnRemark">
<el-form-item :label="$t('track.returnRemark')" prop="returnRemark">
<el-input v-model="operateMatForm.returnRemark" rows="3"></el-input>
</el-form-item>
</template>
<!-- 产出长度字段 -->
<template v-if="['PRODUCING', 'PRODUCT'].includes(operateMatForm.operation)">
<el-form-item label="产出钢卷长度" prop="coilLength">
<el-input v-model="operateMatForm.coilLength" type="number" placeholder="请输入产出钢卷长度"></el-input>
<el-form-item :label="$t('track.outputCoilLength')" prop="coilLength">
<el-input v-model="operateMatForm.coilLength" type="number" :placeholder="$t('track.pleaseInputOutputCoilLength')"></el-input>
</el-form-item>
</template>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="operateMatStatus = false">取消</el-button>
<el-button type="primary" @click="submitOperateForm">确定</el-button>
<el-button @click="operateMatStatus = false">{{ $t('common.cancel') }}</el-button>
<el-button type="primary" @click="submitOperateForm">{{ $t('common.confirm') }}</el-button>
</div>
</el-dialog>
</div>
@@ -498,39 +498,39 @@ const DEVICE_META = {
}
const PARAM_LABELS = {
tensionPorBr1: '开卷张力1#',
tensionPorBr2: '开卷张力2#',
stripSpeed: '带钢速度',
weldStatus: '焊机状态',
celLength: '入口活套位置',
celCapacity: '入口活套套量',
tensionCel: '入口活套张力',
cleaningVoltage: '清洗电压',
cleaningCurrent: '清洗电流',
alkaliConcentration: '碱液浓度',
alkaliTemperature: '碱液温度',
phfExitStripTemp: 'PH炉出口温度',
potTemperature: '锌锅温度',
gasConsumption: '燃气消耗',
rtfExitStripTemp: '加热段出口温度',
zincPotPower: '锌锅功率',
jcsExitStripTemp: '冷却段出口温度',
coolingTowerStripTemp: '冷却塔温度',
scsExitStripTemp: '均衡段出口温度',
tensionBr5Tm: 'BR5-TM张力',
stripSpeedTmExit: 'TM出口速度',
tmElongation: '光整延伸率',
tensionTlBr7: 'TL-BR7张力',
tlElongation: '拉矫延伸率',
cxlLength: '出口活套位置',
cxlCapacity: '出口活套套量',
tensionCxl: '出口活套张力',
inspectionStatus: '检查状态',
coilLength: '钢卷长度',
speedExitSection: '出口段速度',
tensionBr9Tr: 'BR9-TR张力',
avrCoatingWeightTop: '顶部涂重',
avrCoatingWeightBottom: '底部涂重'
tensionPorBr1: 'tensionPorBr1',
tensionPorBr2: 'tensionPorBr2',
stripSpeed: 'stripSpeed',
weldStatus: 'weldStatus',
celLength: 'celLength',
celCapacity: 'celCapacity',
tensionCel: 'tensionCel',
cleaningVoltage: 'cleaningVoltage',
cleaningCurrent: 'cleaningCurrent',
alkaliConcentration: 'alkaliConcentration',
alkaliTemperature: 'alkaliTemperature',
phfExitStripTemp: 'phfExitStripTemp',
potTemperature: 'potTemperature',
gasConsumption: 'gasConsumption',
rtfExitStripTemp: 'rtfExitStripTemp',
zincPotPower: 'zincPotPower',
jcsExitStripTemp: 'jcsExitStripTemp',
coolingTowerStripTemp: 'coolingTowerStripTemp',
scsExitStripTemp: 'scsExitStripTemp',
tensionBr5Tm: 'tensionBr5Tm',
stripSpeedTmExit: 'stripSpeedTmExit',
tmElongation: 'tmElongation',
tensionTlBr7: 'tensionTlBr7',
tlElongation: 'tlElongation',
cxlLength: 'cxlLength',
cxlCapacity: 'cxlCapacity',
tensionCxl: 'tensionCxl',
inspectionStatus: 'inspectionStatus',
coilLength: 'coilLength',
speedExitSection: 'speedExitSection',
tensionBr9Tr: 'tensionBr9Tr',
avrCoatingWeightTop: 'avrCoatingWeightTop',
avrCoatingWeightBottom: 'avrCoatingWeightBottom'
}
const FIELD_ALIASES = {
@@ -771,17 +771,17 @@ export default {
if (!source) return []
const data = []
// 通用字段:按 DeviceEnum.paramFields 取值
meta.paramFields.forEach(field => {
const value = this.getFieldValueWithAlias(source, field)
if (value !== null && value !== undefined && value !== '') {
data.push({
label: PARAM_LABELS[field] || field,
value: this.formatValue(value),
unit: this.getFieldUnit(field)
})
}
})
// 通用字段:按 DeviceEnum.paramFields 取值
meta.paramFields.forEach(field => {
const value = this.getFieldValueWithAlias(source, field)
if (value !== null && value !== undefined && value !== '') {
data.push({
label: this.$t(`track.${PARAM_LABELS[field] || field}`),
value: this.formatValue(value),
unit: this.getFieldUnit(field)
})
}
})
return data
}
@@ -868,7 +868,7 @@ export default {
const raw = source ? this.getFieldValueWithAlias(source, f) : null
const unit = this.getFieldUnit(f)
return {
label: PARAM_LABELS[f] || f,
label: this.$t(`track.${PARAM_LABELS[f] || f}`),
value: `${this.formatValue(raw)}${unit ? ' ' + unit : ''}`
}
})
@@ -992,7 +992,7 @@ export default {
this.signalData = data
const operationText = this.getOperationText(data.operation)
const autoFlagText = data.autoFlag === 1 ? '[手动]' : '[自动]'
const autoFlagText = data.autoFlag === 1 ? `[${this.$t('track.manualOperation')}]` : `[${this.$t('track.autoOperation')}]`
const config = this.getOperationConfig(data.operation)
// 检测到上线、生产中、生产完成等关键操作时,刷新生产计划队列
@@ -1005,7 +1005,7 @@ export default {
if(!repeatProducing){
this.$notify({
title: `${config.icon} ${config.title}`,
message: `${autoFlagText} ${operationText}\n钢卷号: ${data.entryMatId}\n计划ID: ${data.planId || '-'}`,
message: `${autoFlagText} ${operationText}\n${this.$t('track.coilid')}: ${data.entryMatId}\n${this.$t('track.planId')}: ${data.planId || '-'}`,
type: config.type,
duration: config.duration,
position: 'top-right',
@@ -1017,10 +1017,10 @@ export default {
// 如果需要弹窗确认(甩尾等重要操作)
if (config.needAlert) {
this.$alert(
`钢卷号: ${data.entryMatId}\n计划ID: ${data.planId || '-'}\n操作类型: ${operationText}\n操作方式: ${autoFlagText}`,
`${this.$t('track.coilid')}: ${data.entryMatId}\n${this.$t('track.planId')}: ${data.planId || '-'}\n${this.$t('track.operationType')}: ${operationText}\n${this.$t('track.operationType')}: ${autoFlagText}`,
`${config.icon} ${config.title}`,
{
confirmButtonText: '知道了',
confirmButtonText: this.$t('common.confirm'),
type: config.type,
center: true
}
@@ -1048,10 +1048,10 @@ export default {
this.calcSetupResult = data
if (data.flag) {
this.$message.success(`计算完成 (Key: ${data.key})`)
this.$message.success(`${this.$t('track.calculationSuccess')} (Key: ${data.key})`)
this.showCalcResultDialog = true
} else {
this.$message.error(`计算失败 (Key: ${data.key})`)
this.$message.error(`${this.$t('track.calculationFailed')} (Key: ${data.key})`)
}
},
@@ -1059,15 +1059,15 @@ export default {
getOperationText(operation) {
const operationMap = {
ONLINE: '钢卷上线',
UNLOAD: '卸卷',
PRODUCING: '生产中',
PRODUCT: '生产完成',
PAY_OVER: '甩尾',
THROW_TAIL: '甩尾',
ALL_RETURN: '整卷回退',
HALF_RETURN: '半卷回退',
BLOCK: '卸卷并封闭'
ONLINE: this.$t('track.coilOnline'),
UNLOAD: this.$t('track.manualUnload'),
PRODUCING: this.$t('track.producing'),
PRODUCT: this.$t('track.product'),
PAY_OVER: this.$t('track.payOver'),
THROW_TAIL: this.$t('track.throwTail'),
ALL_RETURN: this.$t('track.allReturn'),
HALF_RETURN: this.$t('track.halfReturn'),
BLOCK: this.$t('track.unloadAndBlock')
}
return operationMap[operation] || operation
},
@@ -1077,63 +1077,63 @@ export default {
const configs = {
ONLINE: {
icon: '🎬',
title: '钢卷上线通知',
title: this.$t('track.onlineNotice'),
type: 'success',
duration: 4000,
needAlert: false
},
UNLOAD: {
icon: '📤',
title: '卸卷操作通知',
title: this.$t('track.unloadNotice'),
type: 'info',
duration: 3000,
needAlert: false
},
PRODUCING: {
icon: '⚙️',
title: '生产状态变更',
title: this.$t('track.producingNotice'),
type: 'success',
duration: 3000,
needAlert: false
},
PRODUCT: {
icon: '✅',
title: '生产完成通知',
title: this.$t('track.productNotice'),
type: 'success',
duration: 4000,
needAlert: false
},
PAY_OVER: {
icon: '⚠️',
title: '甩尾操作提示',
title: this.$t('track.payOverNotice'),
type: 'warning',
duration: 5000,
needAlert: true
},
THROW_TAIL: {
icon: '⚠️',
title: '甩尾操作提示',
title: this.$t('track.throwTailNotice'),
type: 'warning',
duration: 5000,
needAlert: true
},
ALL_RETURN: {
icon: '↩️',
title: '整卷回退通知',
title: this.$t('track.allReturnNotice'),
type: 'warning',
duration: 4000,
needAlert: false
},
HALF_RETURN: {
icon: '↩️',
title: '半卷回退通知',
title: this.$t('track.halfReturnNotice'),
type: 'warning',
duration: 4000,
needAlert: false
},
BLOCK: {
icon: '🚫',
title: '封闭操作通知',
title: this.$t('track.blockNotice'),
type: 'warning',
duration: 3000,
needAlert: false
@@ -1141,7 +1141,7 @@ export default {
}
return configs[operation] || {
icon: '📢',
title: '操作通知',
title: this.$t('track.operationNotice'),
type: 'info',
duration: 3000,
needAlert: false

View File

@@ -13,12 +13,12 @@
<form @submit.prevent="handleLogin">
<div class="input-group">
<input
type="text"
v-model="loginForm.username"
placeholder="请输入用户名"
class="form-input"
required
>
type="text"
v-model="loginForm.username"
:placeholder="$t('common.usernamePlaceholder')"
class="form-input"
required
>
<i class="fas fa-user input-icon"></i>
</div>
@@ -26,7 +26,7 @@
<input
type="password"
v-model="loginForm.password"
placeholder="请输入密码"
:placeholder="$t('common.passwordPlaceholder')"
class="form-input"
required
>
@@ -36,12 +36,12 @@
<div class="form-options">
<label class="remember-me">
<input type="checkbox" v-model="loginForm.rememberMe">
<span>记住密码</span>
<span>{{ $t('common.rememberPassword') }}</span>
</label>
<a href="#" class="forgot-password"></a>
</div>
<button @click="handleLogin" v-loading="loading" class="login-button"> </button>
<button @click="handleLogin" v-loading="loading" class="login-button">{{ $t('common.login') }}</button>
</form>
</div>
</div>
@@ -66,15 +66,6 @@ export default {
code: "",
uuid: ""
},
loginRules: {
username: [
{ required: true, trigger: "blur", message: "请输入您的账号" }
],
password: [
{ required: true, trigger: "blur", message: "请输入您的密码" }
],
code: [{ required: true, trigger: "change", message: "请输入验证码" }]
},
loading: false,
// 验证码开关
captchaEnabled: true,
@@ -83,6 +74,19 @@ export default {
redirect: undefined
}
},
computed: {
loginRules() {
return {
username: [
{ required: true, trigger: "blur", message: this.$t('common.enterUsername') }
],
password: [
{ required: true, trigger: "blur", message: this.$t('common.enterPassword') }
],
code: [{ required: true, trigger: "change", message: this.$t('common.enterVerificationCode') }]
}
}
},
watch: {
$route: {
handler: function(route) {