首页与国际化
This commit is contained in:
@@ -26,8 +26,8 @@ public class DeviceCar extends BaseEntity
|
||||
@Excel(name = "设备名称")
|
||||
private String name ;
|
||||
|
||||
/** 1-AGV 2-CTU 3-SSJ */
|
||||
@Excel(name = "1-AGV 2-CTU 3-SSJ")
|
||||
/** 1-AGV 2-CTU*/
|
||||
@Excel(name = "1-AGV 2-CTU")
|
||||
private String type;
|
||||
|
||||
/** 设备IP */
|
||||
|
||||
@@ -183,5 +183,58 @@ export default {
|
||||
confirm: 'Confirm',
|
||||
search: 'Search',
|
||||
reset: 'Reset',
|
||||
},
|
||||
index: {
|
||||
// Statistics Cards
|
||||
agvDeviceTotal: 'Total AGV Devices',
|
||||
ctuDeviceTotal: 'Total CTU Devices',
|
||||
pendingTasks: 'Pending Tasks',
|
||||
runningTasks: 'Running Tasks',
|
||||
completedTasks: 'Completed Tasks',
|
||||
|
||||
// Chart Titles
|
||||
taskTypeDistribution: 'Task Type Distribution',
|
||||
deviceStatusDistribution: 'Device Status Distribution',
|
||||
|
||||
// Table Titles
|
||||
currentTaskQueue: 'Current Task Queue',
|
||||
runningDeviceList: 'Running Device List',
|
||||
|
||||
// Table Columns
|
||||
requestCode: 'Request Code',
|
||||
taskType: 'Task Type',
|
||||
startPoint: 'Start Point',
|
||||
endPoint: 'End Point',
|
||||
priority: 'Priority',
|
||||
status: 'Status',
|
||||
requestTime: 'Request Time',
|
||||
deviceCode: 'Device Code',
|
||||
deviceName: 'Device Name',
|
||||
type: 'Type',
|
||||
currentTask: 'Current Task',
|
||||
|
||||
// Buttons
|
||||
refresh: 'Refresh',
|
||||
|
||||
// Chart Data
|
||||
running: 'Running',
|
||||
other: 'Other',
|
||||
taskTypeName: 'Task Type',
|
||||
|
||||
// Default Task Types
|
||||
inboundTask: 'Inbound Task',
|
||||
outboundTask: 'Outbound Task',
|
||||
transferTask: 'Transfer Task',
|
||||
|
||||
// Error Messages
|
||||
loadDeviceStatsError: 'Failed to load device statistics',
|
||||
loadTaskStatsError: 'Failed to load task statistics',
|
||||
loadTaskListError: 'Failed to load task list',
|
||||
loadDeviceListError: 'Failed to load device list',
|
||||
loadTaskTypeChartError: 'Failed to load task type chart data',
|
||||
loadDeviceStatusChartError: 'Failed to load device status chart data',
|
||||
|
||||
// Device Types
|
||||
unknown: 'Unknown'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,5 +19,58 @@ export default {
|
||||
tagsView: 'Open Tags-View',
|
||||
fixedHeader: 'Fixed Header',
|
||||
sidebarLogo: 'Sidebar Logo'
|
||||
},
|
||||
index: {
|
||||
// Statisztikai kártyák
|
||||
agvDeviceTotal: 'Összes AGV eszköz',
|
||||
ctuDeviceTotal: 'Összes CTU eszköz',
|
||||
pendingTasks: 'Függő feladatok',
|
||||
runningTasks: 'Futó feladatok',
|
||||
completedTasks: 'Befejezett feladatok',
|
||||
|
||||
// Diagram címek
|
||||
taskTypeDistribution: 'Feladattípus eloszlás',
|
||||
deviceStatusDistribution: 'Eszköz állapot eloszlás',
|
||||
|
||||
// Táblázat címek
|
||||
currentTaskQueue: 'Jelenlegi feladatsor',
|
||||
runningDeviceList: 'Futó eszközök listája',
|
||||
|
||||
// Táblázat oszlopok
|
||||
requestCode: 'Kérés kód',
|
||||
taskType: 'Feladat típus',
|
||||
startPoint: 'Kezdőpont',
|
||||
endPoint: 'Végpont',
|
||||
priority: 'Prioritás',
|
||||
status: 'Állapot',
|
||||
requestTime: 'Kérés ideje',
|
||||
deviceCode: 'Eszköz kód',
|
||||
deviceName: 'Eszköz név',
|
||||
type: 'Típus',
|
||||
currentTask: 'Jelenlegi feladat',
|
||||
|
||||
// Gombok
|
||||
refresh: 'Frissítés',
|
||||
|
||||
// Diagram adatok
|
||||
running: 'Futó',
|
||||
other: 'Egyéb',
|
||||
taskTypeName: 'Feladat típus',
|
||||
|
||||
// Alapértelmezett feladattípusok
|
||||
inboundTask: 'Bejövő feladat',
|
||||
outboundTask: 'Kimenő feladat',
|
||||
transferTask: 'Áthelyezési feladat',
|
||||
|
||||
// Hibaüzenetek
|
||||
loadDeviceStatsError: 'Eszköz statisztikák betöltése sikertelen',
|
||||
loadTaskStatsError: 'Feladat statisztikák betöltése sikertelen',
|
||||
loadTaskListError: 'Feladatlista betöltése sikertelen',
|
||||
loadDeviceListError: 'Eszközlista betöltése sikertelen',
|
||||
loadTaskTypeChartError: 'Feladattípus diagram adatok betöltése sikertelen',
|
||||
loadDeviceStatusChartError: 'Eszköz állapot diagram adatok betöltése sikertelen',
|
||||
|
||||
// Eszköztípusok
|
||||
unknown: 'Ismeretlen'
|
||||
}
|
||||
}
|
||||
@@ -169,12 +169,13 @@ export default {
|
||||
deleteConfirm: '是否确认删除{content}的数据项?'
|
||||
},
|
||||
login: {
|
||||
title: '若依后台管理系统',
|
||||
title: '福莱瑞达WMS系统',
|
||||
logIn: '登录',
|
||||
username: '账号',
|
||||
password: '密码',
|
||||
code: '验证码',
|
||||
rememberMe: '记住密码'
|
||||
rememberMe: '记住密码',
|
||||
accountLogin:'账 户 登 录'
|
||||
},
|
||||
tagsView: {
|
||||
refresh: '刷新',
|
||||
@@ -190,6 +191,7 @@ export default {
|
||||
sidebarLogo: '侧边栏 Logo'
|
||||
},
|
||||
menu: {
|
||||
home:'首页',
|
||||
InboundManagement: "入库管理",
|
||||
//收货单据新增
|
||||
ReceivingDocumentsAdd: '收货单据新增',
|
||||
@@ -1777,4 +1779,57 @@ export default {
|
||||
btnClearAll: '清理全部',
|
||||
|
||||
},
|
||||
index: {
|
||||
// 统计卡片
|
||||
agvDeviceTotal: 'AGV设备总数', // AGV设备总数
|
||||
ctuDeviceTotal: 'CTU设备总数', // CTU设备总数
|
||||
pendingTasks: '待执行任务', // 待执行任务
|
||||
runningTasks: '执行中任务', // 执行中任务
|
||||
completedTasks: '已完成任务', // 已完成任务
|
||||
|
||||
// 图表标题
|
||||
taskTypeDistribution: '任务类型分布', // 任务类型分布
|
||||
deviceStatusDistribution: '设备状态分布', // 设备状态分布
|
||||
|
||||
// 表格标题
|
||||
currentTaskQueue: '当前任务队列', // 当前任务队列
|
||||
runningDeviceList: '正在运行设备列表', // 正在运行设备列表
|
||||
|
||||
// 表格列名
|
||||
requestCode: '请求编号', // 请求编号
|
||||
taskType: '任务类型', // 任务类型
|
||||
startPoint: '起点', // 起点
|
||||
endPoint: '终点', // 终点
|
||||
priority: '优先级', // 优先级
|
||||
status: '状态', // 状态
|
||||
requestTime: '请求时间', // 请求时间
|
||||
deviceCode: '设备编码', // 设备编码
|
||||
deviceName: '设备名称', // 设备名称
|
||||
type: '类型', // 类型
|
||||
currentTask: '当前任务', // 当前任务
|
||||
|
||||
// 按钮
|
||||
refresh: '刷新', // 刷新
|
||||
|
||||
// 图表数据
|
||||
running: '运行', // 运行
|
||||
other: '其他', // 其他
|
||||
taskTypeName: '任务类型', // 任务类型
|
||||
|
||||
// 默认任务类型
|
||||
inboundTask: '入库任务', // 入库任务
|
||||
outboundTask: '出库任务', // 出库任务
|
||||
transferTask: '移库任务', // 移库任务
|
||||
|
||||
// 错误信息
|
||||
loadDeviceStatsError: '加载设备统计失败', // 加载设备统计失败
|
||||
loadTaskStatsError: '加载任务统计失败', // 加载任务统计失败
|
||||
loadTaskListError: '加载任务列表失败', // 加载任务列表失败
|
||||
loadDeviceListError: '加载设备列表失败', // 加载设备列表失败
|
||||
loadTaskTypeChartError: '加载任务类型图表数据失败', // 加载任务类型图表数据失败
|
||||
loadDeviceStatusChartError: '加载设备状态图表数据失败', // 加载设备状态图表数据失败
|
||||
|
||||
// 设备类型
|
||||
unknown: '未知' // 未知
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ export const constantRoutes = [
|
||||
path: 'index',
|
||||
component: () => import('@/views/index'),
|
||||
name: 'Index',
|
||||
meta: { title: i18n.t('viewsMain.title'), icon: 'dashboard', affix: true }
|
||||
meta: { title: i18n.t('menu.home'), icon: 'dashboard', affix: true }
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -1,198 +1,679 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<!--div class="row">
|
||||
<!– 未完成入库任务概览 –>
|
||||
<div class="col-sm-6" style="height: 45vh; padding: 10px;">
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>{{$t('viewsMain.unfinishedInboundTask')}}</span>
|
||||
<!-- 统计卡片 -->
|
||||
<el-row :gutter="20" class="stats-row">
|
||||
<el-col :span="4">
|
||||
<el-card class="stats-card">
|
||||
<div class="stats-content">
|
||||
<div class="stats-icon agv-icon">
|
||||
<i class="el-icon-truck"></i>
|
||||
</div>
|
||||
<div class="stats-info">
|
||||
<div class="stats-number">{{ deviceStats.agvCount }}</div>
|
||||
<div class="stats-label">{{ $t('index.agvDeviceTotal') }}</div> <!-- AGV设备总数 -->
|
||||
</div>
|
||||
</div>
|
||||
<el-table
|
||||
:data="table1Data"
|
||||
style="width: 100%"
|
||||
:height="tableHeight"
|
||||
v-loading="loading1">
|
||||
<el-table-column prop="workValue" :label="$t('viewsMain.taskKey')" /> <!– 任务键值 –>
|
||||
<el-table-column prop="workName" :label="$t('viewsMain.unfinishedInboundTaskName')" /><!– 未完成入库任务 –>
|
||||
<el-table-column prop="workNum" :label="$t('viewsMain.totalUnfinishedCount')" ><!– 全部未完成数量 –>
|
||||
<!– <template slot-scope="scope">–>
|
||||
<!– {{ Number(scope.row.workNum).toFixed(6) }}–>
|
||||
<!– </template>–>
|
||||
</el-table-column>
|
||||
<el-table-column prop="by1" :label="$t('viewsMain.todayUnfinishedCount')"> <!– 今日未完成数量 –>
|
||||
<!– <template slot-scope="scope">
|
||||
{{ Number(scope.row.by1).toFixed(6) }}
|
||||
</template>–>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-card class="stats-card">
|
||||
<div class="stats-content">
|
||||
<div class="stats-icon ctu-icon">
|
||||
<i class="el-icon-s-grid"></i>
|
||||
</div>
|
||||
<div class="stats-info">
|
||||
<div class="stats-number">{{ deviceStats.ctuCount }}</div>
|
||||
<div class="stats-label">{{ $t('index.ctuDeviceTotal') }}</div> <!-- CTU设备总数 -->
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<el-card class="stats-card">
|
||||
<div class="stats-content">
|
||||
<div class="stats-icon queue-icon">
|
||||
<i class="el-icon-time"></i>
|
||||
</div>
|
||||
<div class="stats-info">
|
||||
<div class="stats-number">{{ taskStats.pendingCount }}</div>
|
||||
<div class="stats-label">{{ $t('index.pendingTasks') }}</div> <!-- 待执行任务 -->
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<el-card class="stats-card">
|
||||
<div class="stats-content">
|
||||
<div class="stats-icon running-icon">
|
||||
<i class="el-icon-loading"></i>
|
||||
</div>
|
||||
<div class="stats-info">
|
||||
<div class="stats-number">{{ taskStats.runningCount }}</div>
|
||||
<div class="stats-label">{{ $t('index.runningTasks') }}</div> <!-- 执行中任务 -->
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-card class="stats-card">
|
||||
<div class="stats-content">
|
||||
<div class="stats-icon finish-icon">
|
||||
<i class="el-icon-check"></i>
|
||||
</div>
|
||||
<div class="stats-info">
|
||||
<div class="stats-number">{{ taskStats.finishedCount }}</div>
|
||||
<div class="stats-label">{{ $t('index.completedTasks') }}</div> <!-- 已完成任务 -->
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!– 已完成入库任务概览 –>
|
||||
<div class="col-sm-6" style="height: 45vh; padding: 10px;">
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>{{$t('viewsMain.finishedInboundTask')}}</span>
|
||||
<!-- 图表区域 -->
|
||||
<el-row :gutter="20" class="chart-row">
|
||||
<el-col :span="12">
|
||||
<el-card class="chart-card">
|
||||
<div slot="header" class="card-header">
|
||||
<span>{{ $t('index.taskTypeDistribution') }}</span> <!-- 任务类型分布 -->
|
||||
</div>
|
||||
<el-table
|
||||
:data="table2Data"
|
||||
style="width: 100%"
|
||||
:height="tableHeight"
|
||||
v-loading="loading2">
|
||||
<el-table-column prop="workValue" :label="$t('viewsMain.taskKey')" /><!– 任务键值 –>
|
||||
<el-table-column prop="workName" :label="$t('viewsMain.finishedInboundTaskName')" /><!– 已完成入库任务 –>
|
||||
<el-table-column prop="workNum" :label="$t('viewsMain.totalFinishedCount')" ><!– 全部已完成数量 –>
|
||||
<!– <template slot-scope="scope">–>
|
||||
<!– {{ Number(scope.row.workNum).toFixed(6) }}–>
|
||||
<!– </template>–>
|
||||
</el-table-column>
|
||||
<el-table-column prop="by1" :label="$t('viewsMain.todayFinishedCount')"> <!– 今日已完成数量 –>
|
||||
<!– <template slot-scope="scope">
|
||||
{{ Number(scope.row.by1).toFixed(6) }}–>
|
||||
<!– </template>–>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div id="taskTypeChart" style="height: 300px;"></div>
|
||||
</el-card>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-card class="chart-card">
|
||||
<div slot="header" class="card-header">
|
||||
<span>{{ $t('index.deviceStatusDistribution') }}</span> <!-- 设备状态分布 -->
|
||||
</div>
|
||||
<div id="deviceStatusChart" style="height: 300px;"></div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!– 未完成出库任务概览 –>
|
||||
<div class="col-sm-6" style="height: 45vh; padding: 10px;">
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>{{$t('viewsMain.unfinishedOutboundTask')}}</span>
|
||||
<!-- 实时任务展示 -->
|
||||
<el-row :gutter="20" class="task-row">
|
||||
<el-col :span="12">
|
||||
<el-card class="task-card">
|
||||
<div slot="header" class="card-header">
|
||||
<span>{{ $t('index.currentTaskQueue') }}</span> <!-- 当前任务队列 -->
|
||||
<el-button type="text" @click="refreshTasks">{{ $t('index.refresh') }}</el-button> <!-- 刷新 -->
|
||||
</div>
|
||||
<el-table
|
||||
:data="table3Data"
|
||||
:data="currentTasks"
|
||||
style="width: 100%"
|
||||
:height="tableHeight"
|
||||
v-loading="loading3">
|
||||
<el-table-column prop="workValue" :label="$t('viewsMain.taskKey')" /><!– 任务键值 –>
|
||||
<el-table-column prop="workName" :label="$t('viewsMain.unfinishedOutboundTaskName')" /><!– 未完成出库任务 –>
|
||||
<el-table-column prop="workNum" :label="$t('viewsMain.totalUnfinishedCount')"><!– 全部未完成数量 –>
|
||||
<!– <template slot-scope="scope">–>
|
||||
<!– {{ Number(scope.row.workNum).toFixed(6) }}–>
|
||||
<!– </template>–>
|
||||
height="300"
|
||||
v-loading="loading.tasks">
|
||||
<el-table-column prop="reqCode" :label="$t('index.requestCode')" width="120"/> <!-- 请求编号 -->
|
||||
<el-table-column prop="wmsTaskType" :label="$t('index.taskType')" width="100"> <!-- 任务类型 -->
|
||||
<template slot-scope="scope">
|
||||
<dict-tag :options="dict.type.wms_task_type" :value="scope.row.wmsTaskType"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="by1" :label="$t('viewsMain.todayUnfinishedCount')"> <!– 今日未完成数量 –>
|
||||
<!– <template slot-scope="scope">
|
||||
{{ Number(scope.row.by1).toFixed(6) }}–>
|
||||
<!– </template>–>
|
||||
<el-table-column prop="positionCode1" :label="$t('index.startPoint')" width="80"/> <!-- 起点 -->
|
||||
<el-table-column prop="positionCode2" :label="$t('index.endPoint')" width="80"/> <!-- 终点 -->
|
||||
<el-table-column prop="priority" :label="$t('index.priority')" width="80"/> <!-- 优先级 -->
|
||||
<el-table-column prop="status" :label="$t('index.status')" width="100"> <!-- 状态 -->
|
||||
<template slot-scope="scope">
|
||||
<el-tag :type="getStatusType(scope.row.status)">
|
||||
<dict-tag :options="dict.type.task_status" :value="scope.row.status"/>
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="reqTime" :label="$t('index.requestTime')" show-overflow-tooltip/> <!-- 请求时间 -->
|
||||
</el-table>
|
||||
</el-card>
|
||||
</div>
|
||||
|
||||
<!– 已完成出库任务概览 –>
|
||||
<div class="col-sm-6" style="height: 45vh; padding: 10px;">
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>{{$t('viewsMain.finishedOutboundTask')}}</span>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-card class="task-card">
|
||||
<div slot="header" class="card-header">
|
||||
<span>{{ $t('index.runningDeviceList') }}</span> <!-- 正在运行设备列表 -->
|
||||
<el-button type="text" @click="refreshDevices">{{ $t('index.refresh') }}</el-button> <!-- 刷新 -->
|
||||
</div>
|
||||
<el-table
|
||||
:data="table4Data"
|
||||
:data="deviceList"
|
||||
style="width: 100%"
|
||||
:height="tableHeight"
|
||||
v-loading="loading4">
|
||||
<el-table-column prop="workValue" :label="$t('viewsMain.taskKey')" /><!– 任务键值 –>
|
||||
<el-table-column prop="workName" :label="$t('viewsMain.finishedOutboundTaskName')" /><!– 已完成出库任务 –>
|
||||
<el-table-column prop="workNum" :label="$t('viewsMain.totalFinishedCount')" ><!– 全部已完成数量 –>
|
||||
<!– <template slot-scope="scope">–>
|
||||
<!– {{ Number(scope.row.workNum).toFixed(6) }}–>
|
||||
<!– </template>–>
|
||||
</el-table-column>
|
||||
<el-table-column prop="by1" :label="$t('viewsMain.todayFinishedCount')"> <!– 今日已完成数量 –>
|
||||
<!– <template slot-scope="scope">
|
||||
{{ Number(scope.row.by1).toFixed(6) }}–>
|
||||
<!– </template>–>
|
||||
height="300"
|
||||
v-loading="loading.devices">
|
||||
<el-table-column prop="deviceCode" :label="$t('index.deviceCode')" width="200"/> <!-- 设备编码 -->
|
||||
<el-table-column prop="deviceName" :label="$t('index.deviceName')" width="200"/> <!-- 设备名称 -->
|
||||
<el-table-column prop="deviceType" :label="$t('index.type')" width="150"> <!-- 类型 -->
|
||||
<template slot-scope="scope">
|
||||
<el-tag>{{scope.row.deviceType}}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="taskNo" :label="$t('index.currentTask')" show-overflow-tooltip/> <!-- 当前任务 -->
|
||||
</el-table>
|
||||
</el-card>
|
||||
</div>
|
||||
</div>-->
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listWork1, listWork2, listWork3, listWork4 } from '@/api/work'
|
||||
import * as echarts from 'echarts'
|
||||
import { getDeviceStats, getTaskStats, getCurrentTasks, getDeviceList, getTaskTypeChart, getDeviceStatusChart } from '@/api/index'
|
||||
|
||||
export default {
|
||||
name: 'Index',
|
||||
dicts: ['task_status', 'wms_task_type'],
|
||||
data() {
|
||||
return {
|
||||
// 表格数据
|
||||
table1Data: [],
|
||||
table2Data: [],
|
||||
table3Data: [],
|
||||
table4Data: [],
|
||||
// 统计数据
|
||||
deviceStats: {
|
||||
agvCount: 0,
|
||||
ctuCount: 0,
|
||||
ssjCount: 0
|
||||
},
|
||||
taskStats: {
|
||||
pendingCount: 0,
|
||||
runningCount: 0,
|
||||
finishedCount: 0
|
||||
},
|
||||
// 当前任务列表
|
||||
currentTasks: [],
|
||||
// 设备列表
|
||||
deviceList: [],
|
||||
// 加载状态
|
||||
loading1: false,
|
||||
loading2: false,
|
||||
loading3: false,
|
||||
loading4: false,
|
||||
// 表格高度
|
||||
tableHeight: '35vh',
|
||||
loading: {
|
||||
tasks: false,
|
||||
devices: false
|
||||
},
|
||||
// 图表实例
|
||||
taskTypeChart: null,
|
||||
deviceStatusChart: null,
|
||||
// 定时器
|
||||
timer: null
|
||||
refreshTimer: null
|
||||
}
|
||||
},
|
||||
created() {
|
||||
//this.getList()
|
||||
// 开启定时刷新
|
||||
//this.timer = setInterval(this.getList, 10000)
|
||||
this.initData()
|
||||
// 添加页面可见性监听
|
||||
this.handleVisibilityChange = this.handleVisibilityChange.bind(this)
|
||||
document.addEventListener('visibilitychange', this.handleVisibilityChange)
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
this.initCharts()
|
||||
})
|
||||
// 页面挂载后启动定时器
|
||||
this.startTimer()
|
||||
},
|
||||
activated() {
|
||||
// keep-alive组件激活时启动定时器
|
||||
this.startTimer()
|
||||
},
|
||||
deactivated() {
|
||||
// keep-alive组件失活时停止定时器
|
||||
this.stopTimer()
|
||||
},
|
||||
beforeDestroy() {
|
||||
// 组件销毁前清除定时器
|
||||
if (this.timer) {
|
||||
clearInterval(this.timer)
|
||||
// 清除定时器
|
||||
this.stopTimer()
|
||||
// 移除页面可见性监听
|
||||
document.removeEventListener('visibilitychange', this.handleVisibilityChange)
|
||||
// 销毁图表
|
||||
if (this.taskTypeChart) {
|
||||
this.taskTypeChart.dispose()
|
||||
}
|
||||
if (this.deviceStatusChart) {
|
||||
this.deviceStatusChart.dispose()
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
// 监听路由变化
|
||||
'$route'(to, from) {
|
||||
// 当路由变化时,检查是否为首页
|
||||
if (to.path === '/index' || to.name === 'Index' || to.path === '/') {
|
||||
this.startTimer() // 进入首页时启动定时器
|
||||
} else {
|
||||
this.stopTimer() // 离开首页时停止定时器
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/** 获取数据列表 */
|
||||
getList() {
|
||||
this.loading1 = true
|
||||
this.loading2 = true
|
||||
this.loading3 = true
|
||||
this.loading4 = true
|
||||
// 启动定时器
|
||||
startTimer() {
|
||||
// 如果定时器已存在,先清除
|
||||
this.stopTimer()
|
||||
// 只有在页面可见且为首页时才启动定时器
|
||||
if (this.isPageVisible() && this.isIndexPage()) {
|
||||
this.refreshTimer = setInterval(() => {
|
||||
this.refreshData()
|
||||
}, 8000) // 5秒刷新一次
|
||||
console.log('定时器已启动') // 定时器已启动
|
||||
}
|
||||
},
|
||||
// 停止定时器
|
||||
stopTimer() {
|
||||
if (this.refreshTimer) {
|
||||
clearInterval(this.refreshTimer)
|
||||
this.refreshTimer = null
|
||||
console.log('定时器已停止') // 定时器已停止
|
||||
}
|
||||
},
|
||||
// 检查页面是否可见
|
||||
isPageVisible() {
|
||||
return document.visibilityState === 'visible'
|
||||
},
|
||||
// 检查是否为首页
|
||||
isIndexPage() {
|
||||
return this.$route.path === '/index' || this.$route.name === 'Index' || this.$route.path === '/'
|
||||
},
|
||||
// 处理页面可见性变化
|
||||
handleVisibilityChange() {
|
||||
if (this.isPageVisible() && this.isIndexPage()) {
|
||||
this.startTimer() // 页面变为可见且为首页时启动定时器
|
||||
} else {
|
||||
this.stopTimer() // 页面不可见时停止定时器
|
||||
}
|
||||
},
|
||||
// 初始化数据
|
||||
async initData() {
|
||||
await Promise.all([
|
||||
this.loadDeviceStats(),
|
||||
this.loadTaskStats(),
|
||||
this.loadCurrentTasks(),
|
||||
this.loadDeviceList()
|
||||
])
|
||||
},
|
||||
// 刷新数据
|
||||
async refreshData() {
|
||||
await this.initData()
|
||||
this.updateCharts()
|
||||
},
|
||||
// 加载设备统计
|
||||
async loadDeviceStats() {
|
||||
try {
|
||||
const response = await getDeviceStats()
|
||||
if (response.code === 200) {
|
||||
this.deviceStats = response.data
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载设备统计失败:', error) // 加载设备统计失败
|
||||
this.$message.error(this.$t('index.loadDeviceStatsError')) // 加载设备统计失败
|
||||
}
|
||||
},
|
||||
// 加载任务统计
|
||||
async loadTaskStats() {
|
||||
try {
|
||||
const response = await getTaskStats()
|
||||
if (response.code === 200) {
|
||||
this.taskStats = response.data
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载任务统计失败:', error) // 加载任务统计失败
|
||||
this.$message.error(this.$t('index.loadTaskStatsError')) // 加载任务统计失败
|
||||
}
|
||||
},
|
||||
// 加载当前任务
|
||||
async loadCurrentTasks() {
|
||||
this.loading.tasks = true
|
||||
try {
|
||||
const response = await getCurrentTasks()
|
||||
if (response.code === 200) {
|
||||
this.currentTasks = response.data
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载任务列表失败:', error) // 加载任务列表失败
|
||||
this.$message.error(this.$t('index.loadTaskListError')) // 加载任务列表失败
|
||||
} finally {
|
||||
this.loading.tasks = false
|
||||
}
|
||||
},
|
||||
// 加载设备列表
|
||||
async loadDeviceList() {
|
||||
this.loading.devices = true
|
||||
try {
|
||||
const response = await getDeviceList()
|
||||
if (response.code === 200) {
|
||||
this.deviceList = response.data
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载设备列表失败:', error) // 加载设备列表失败
|
||||
this.$message.error(this.$t('index.loadDeviceListError')) // 加载设备列表失败
|
||||
} finally {
|
||||
this.loading.devices = false
|
||||
}
|
||||
},
|
||||
// 初始化图表
|
||||
initCharts() {
|
||||
this.initTaskTypeChart()
|
||||
this.initDeviceStatusChart()
|
||||
},
|
||||
// 初始化任务类型图表
|
||||
async initTaskTypeChart() {
|
||||
const chartDom = document.getElementById('taskTypeChart')
|
||||
this.taskTypeChart = echarts.init(chartDom)
|
||||
|
||||
// 获取未完成入库任务
|
||||
listWork3().then(response => {
|
||||
this.table1Data = response.rows
|
||||
this.loading1 = false
|
||||
})
|
||||
try {
|
||||
const response = await getTaskTypeChart()
|
||||
let chartData = []
|
||||
if (response.code === 200 && response.data.length > 0) {
|
||||
chartData = response.data.map(item => ({
|
||||
...item,
|
||||
name: this.selectDictLabel(this.dict.type.wms_task_type, item.name)
|
||||
}))
|
||||
} else {
|
||||
// 默认数据
|
||||
chartData = [
|
||||
{ value: 45, name: this.$t('index.inboundTask') }, // 入库任务
|
||||
{ value: 35, name: this.$t('index.outboundTask') }, // 出库任务
|
||||
{ value: 20, name: this.$t('index.transferTask') } // 移库任务
|
||||
]
|
||||
}
|
||||
|
||||
// 获取已完成入库任务
|
||||
listWork1().then(response => {
|
||||
this.table2Data = response.rows
|
||||
this.loading2 = false
|
||||
})
|
||||
const option = {
|
||||
tooltip: {
|
||||
trigger: 'item'
|
||||
},
|
||||
legend: {
|
||||
orient: 'vertical',
|
||||
left: 'left'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: this.$t('index.taskTypeName'), // 任务类型
|
||||
type: 'pie',
|
||||
radius: '50%',
|
||||
data: chartData,
|
||||
emphasis: {
|
||||
itemStyle: {
|
||||
shadowBlur: 10,
|
||||
shadowOffsetX: 0,
|
||||
shadowColor: 'rgba(0, 0, 0, 0.5)'
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
this.taskTypeChart.setOption(option)
|
||||
} catch (error) {
|
||||
console.error('加载任务类型图表数据失败:', error) // 加载任务类型图表数据失败
|
||||
}
|
||||
},
|
||||
// 初始化设备状态图表
|
||||
async initDeviceStatusChart() {
|
||||
const chartDom = document.getElementById('deviceStatusChart')
|
||||
this.deviceStatusChart = echarts.init(chartDom)
|
||||
|
||||
// 获取未完成出库任务
|
||||
listWork4().then(response => {
|
||||
this.table3Data = response.rows
|
||||
this.loading3 = false
|
||||
})
|
||||
try {
|
||||
const response = await getDeviceStatusChart()
|
||||
let runningData = [0, 0, 0]
|
||||
let idleData = [0, 0, 0]
|
||||
|
||||
// 获取已完成出库任务
|
||||
listWork2().then(response => {
|
||||
this.table4Data = response.rows
|
||||
this.loading4 = false
|
||||
})
|
||||
if (response.code === 200) {
|
||||
const statusData = response.data
|
||||
|
||||
// AGV数据
|
||||
if (statusData.AGV) {
|
||||
runningData[0] = statusData.AGV['运行'] || 0 // 运行
|
||||
idleData[0] = statusData.AGV['其他'] || 0 // 其他
|
||||
}
|
||||
// CTU数据
|
||||
if (statusData.CTU) {
|
||||
runningData[1] = statusData.CTU['运行'] || 0 // 运行
|
||||
idleData[1] = statusData.CTU['其他'] || 0 // 其他
|
||||
}
|
||||
// SSJ数据
|
||||
if (statusData.SSJ) {
|
||||
runningData[2] = statusData.SSJ['运行'] || 0 // 运行
|
||||
idleData[2] = statusData.SSJ['其他'] || 0 // 其他
|
||||
}
|
||||
} else {
|
||||
// 默认数据
|
||||
runningData = [8, 4, 2]
|
||||
idleData = [7, 4, 3]
|
||||
}
|
||||
|
||||
const option = {
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'shadow'
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
data: [this.$t('index.running'), this.$t('index.other')] // 运行, 其他
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: ['AGV', 'CTU', 'SSJ']
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: this.$t('index.running'), // 运行
|
||||
type: 'bar',
|
||||
data: runningData,
|
||||
itemStyle: { color: '#67C23A' }
|
||||
},
|
||||
{
|
||||
name: this.$t('index.other'), // 其他
|
||||
type: 'bar',
|
||||
data: idleData,
|
||||
itemStyle: { color: '#909399' }
|
||||
}
|
||||
]
|
||||
}
|
||||
this.deviceStatusChart.setOption(option)
|
||||
} catch (error) {
|
||||
console.error('加载设备状态图表数据失败:', error) // 加载设备状态图表数据失败
|
||||
// 使用默认数据
|
||||
const option = {
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'shadow'
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
data: [this.$t('index.running'), this.$t('index.other')] // 运行, 其他
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: ['AGV', 'CTU', 'SSJ']
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: this.$t('index.running'), // 运行
|
||||
type: 'bar',
|
||||
data: [8, 4, 2],
|
||||
itemStyle: { color: '#67C23A' }
|
||||
},
|
||||
{
|
||||
name: this.$t('index.other'), // 其他
|
||||
type: 'bar',
|
||||
data: [7, 4, 3],
|
||||
itemStyle: { color: '#909399' }
|
||||
}
|
||||
]
|
||||
}
|
||||
this.deviceStatusChart.setOption(option)
|
||||
}
|
||||
},
|
||||
// 更新图表
|
||||
async updateCharts() {
|
||||
if (this.taskTypeChart) {
|
||||
await this.initTaskTypeChart()
|
||||
}
|
||||
if (this.deviceStatusChart) {
|
||||
await this.initDeviceStatusChart()
|
||||
}
|
||||
},
|
||||
// 刷新任务
|
||||
refreshTasks() {
|
||||
this.loadCurrentTasks()
|
||||
},
|
||||
// 刷新设备
|
||||
refreshDevices() {
|
||||
this.loadDeviceList()
|
||||
},
|
||||
// 获取状态类型
|
||||
getStatusType(status) {
|
||||
const statusMap = {
|
||||
'0': 'info',
|
||||
'1': 'warning',
|
||||
'2': 'primary',
|
||||
'3': 'success',
|
||||
'4': 'warning',
|
||||
}
|
||||
return statusMap[status] || 'info'
|
||||
},
|
||||
|
||||
// 获取设备类型文本
|
||||
getDeviceTypeText(type) {
|
||||
const typeMap = {
|
||||
'1': 'AGV',
|
||||
'2': 'CTU',
|
||||
'3': 'SSJ'
|
||||
}
|
||||
return typeMap[type] || this.$t('index.unknown') // 未知
|
||||
},
|
||||
// 获取设备状态类型
|
||||
getDeviceStatusType(status) {
|
||||
const statusMap = {
|
||||
'运行中': 'success',
|
||||
'空闲': 'info',
|
||||
'故障': 'danger',
|
||||
'维护': 'warning'
|
||||
}
|
||||
return statusMap[status] || 'info'
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.row {
|
||||
.app-container {
|
||||
padding: 20px;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.stats-row {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.chart-row {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.task-row {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.stats-card {
|
||||
height: 120px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.stats-card:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.stats-content {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin: 0 -10px;
|
||||
}
|
||||
.col-sm-6 {
|
||||
width: 50%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.box-card {
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.stats-icon {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-right: 20px;
|
||||
font-size: 24px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.agv-icon {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
}
|
||||
|
||||
.ctu-icon {
|
||||
background: linear-gradient(135deg, #36d1dc 0%, #5b86e5 100%);
|
||||
}
|
||||
|
||||
.queue-icon {
|
||||
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
|
||||
}
|
||||
|
||||
.running-icon {
|
||||
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
|
||||
}
|
||||
|
||||
.finish-icon {
|
||||
background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
|
||||
}
|
||||
|
||||
.stats-info {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.stats-number {
|
||||
font-size: 32px;
|
||||
font-weight: bold;
|
||||
color: #303133;
|
||||
line-height: 1;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.stats-label {
|
||||
font-size: 14px;
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
.chart-card,
|
||||
.task-card {
|
||||
height: 400px;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-weight: bold;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.el-table {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.el-table th {
|
||||
background-color: #fafafa;
|
||||
}
|
||||
|
||||
.el-tag {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 768px) {
|
||||
.stats-row .el-col {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.chart-row .el-col,
|
||||
.task-row .el-col {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.stats-content {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.stats-number {
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user