首页与国际化

This commit is contained in:
猫猫guowen
2025-08-05 15:39:36 +08:00
parent 4547502ca6
commit 4e5ba7fd59
6 changed files with 791 additions and 149 deletions

View File

@@ -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 */

View File

@@ -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'
}
}

View File

@@ -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'
}
}

View File

@@ -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: '未知' // 未知
}
}

View File

@@ -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 }
}
]
},

View File

@@ -1,198 +1,679 @@
<template>
<div class="app-container">
<!--div class="row">
&lt;!&ndash; 未完成入库任务概览 &ndash;&gt;
<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')" /> &lt;!&ndash; 任务键值 &ndash;&gt;
<el-table-column prop="workName" :label="$t('viewsMain.unfinishedInboundTaskName')" />&lt;!&ndash; 未完成入库任务 &ndash;&gt;
<el-table-column prop="workNum" :label="$t('viewsMain.totalUnfinishedCount')" >&lt;!&ndash; 全部未完成数量 &ndash;&gt;
&lt;!&ndash; <template slot-scope="scope">&ndash;&gt;
&lt;!&ndash; {{ Number(scope.row.workNum).toFixed(6) }}&ndash;&gt;
&lt;!&ndash; </template>&ndash;&gt;
</el-table-column>
<el-table-column prop="by1" :label="$t('viewsMain.todayUnfinishedCount')"> &lt;!&ndash; 今日未完成数量 &ndash;&gt;
&lt;!&ndash; <template slot-scope="scope">
{{ Number(scope.row.by1).toFixed(6) }}
</template>&ndash;&gt;
</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>
&lt;!&ndash; 已完成入库任务概览 &ndash;&gt;
<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')" />&lt;!&ndash; 任务键值 &ndash;&gt;
<el-table-column prop="workName" :label="$t('viewsMain.finishedInboundTaskName')" />&lt;!&ndash; 已完成入库任务 &ndash;&gt;
<el-table-column prop="workNum" :label="$t('viewsMain.totalFinishedCount')" >&lt;!&ndash; 全部已完成数量 &ndash;&gt;
&lt;!&ndash; <template slot-scope="scope">&ndash;&gt;
&lt;!&ndash; {{ Number(scope.row.workNum).toFixed(6) }}&ndash;&gt;
&lt;!&ndash; </template>&ndash;&gt;
</el-table-column>
<el-table-column prop="by1" :label="$t('viewsMain.todayFinishedCount')"> &lt;!&ndash; 今日已完成数量 &ndash;&gt;
&lt;!&ndash; <template slot-scope="scope">
{{ Number(scope.row.by1).toFixed(6) }}&ndash;&gt;
&lt;!&ndash; </template>&ndash;&gt;
</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>
&lt;!&ndash; 未完成出库任务概览 &ndash;&gt;
<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')" />&lt;!&ndash; 任务键值 &ndash;&gt;
<el-table-column prop="workName" :label="$t('viewsMain.unfinishedOutboundTaskName')" />&lt;!&ndash; 未完成出库任务 &ndash;&gt;
<el-table-column prop="workNum" :label="$t('viewsMain.totalUnfinishedCount')">&lt;!&ndash; 全部未完成数量 &ndash;&gt;
&lt;!&ndash; <template slot-scope="scope">&ndash;&gt;
&lt;!&ndash; {{ Number(scope.row.workNum).toFixed(6) }}&ndash;&gt;
&lt;!&ndash; </template>&ndash;&gt;
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')"> &lt;!&ndash; 今日未完成数量 &ndash;&gt;
&lt;!&ndash; <template slot-scope="scope">
{{ Number(scope.row.by1).toFixed(6) }}&ndash;&gt;
&lt;!&ndash; </template>&ndash;&gt;
<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>
&lt;!&ndash; 已完成出库任务概览 &ndash;&gt;
<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')" />&lt;!&ndash; 任务键值 &ndash;&gt;
<el-table-column prop="workName" :label="$t('viewsMain.finishedOutboundTaskName')" />&lt;!&ndash; 已完成出库任务 &ndash;&gt;
<el-table-column prop="workNum" :label="$t('viewsMain.totalFinishedCount')" >&lt;!&ndash; 全部已完成数量 &ndash;&gt;
&lt;!&ndash; <template slot-scope="scope">&ndash;&gt;
&lt;!&ndash; {{ Number(scope.row.workNum).toFixed(6) }}&ndash;&gt;
&lt;!&ndash; </template>&ndash;&gt;
</el-table-column>
<el-table-column prop="by1" :label="$t('viewsMain.todayFinishedCount')"> &lt;!&ndash; 今日已完成数量 &ndash;&gt;
&lt;!&ndash; <template slot-scope="scope">
{{ Number(scope.row.by1).toFixed(6) }}&ndash;&gt;
&lt;!&ndash; </template>&ndash;&gt;
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>