feat: 增加AGV任务管理并完善磨合管理
This commit is contained in:
@@ -1,18 +0,0 @@
|
||||
模块介绍
|
||||
用于 处理各工位生产过程中 出现的异常情况(如 进站失败重试 出站失败重试) 开放功能重试按钮、查看工位产品信息、加工状态、可以看工位当前产品 过站情况 等
|
||||
|
||||
功能需求
|
||||
1.首先进入页面仍然需要刷卡弹窗进行登陆 登陆后 首先拉出工位当前在位产品信息 然后是 显示三个重试按钮
|
||||
2.三个重试按钮 分别是 (进站重试、出站重试、申请条码) 分别对应后端三个接口 (接口地址 仍然是 window.g.API_MES_Controller_URL + /url)
|
||||
4.显示一块区域 或者 点按钮显示一个弹窗(看情况和UI自由发挥) 就可以拉出 该产品 各工位接口执行情况Moby数据 用户可以查看前面各工位接口执行情况
|
||||
5.存储过程相关你需要先调用 SqlServerMCP 去查看存储过程定义以及参数 还有返回结果后再进行开发
|
||||
6.界面要适配 竖屏PAD 因为会在竖屏Pad上进行使用 要界面友好
|
||||
7.我发现 刷卡登陆弹窗在竖屏Pad上会出现 弹窗宽度不宽 但是 输入框超出了弹窗范围
|
||||
|
||||
|
||||
资源位置
|
||||
1.这个页面文件是 (D:\项目文件\52.智柔PDC线\前端\MES_ApiFailRetry\src\views\OpStatus.vue)
|
||||
2.重试接口程序位置 可查看重试接口参数 (D:\项目文件\52.智柔PDC线\程序\MesProject_2025.09.161105\MisDataFun\MisDataFun\webApi\WebSendServer.cs 的 ApiFailRetry 方法)
|
||||
3.刷卡登陆功能参考 和 工位列表获取参考 (D:\项目文件\52.智柔PDC线\前端\MES_ApiFailRetry\src\views\index.vue)
|
||||
4.工位状态存储过程 PAD_工位状态_查询 切换选择工位时调用 进入页面默认选择第一个工位 其中 状态 1 已进站 2 已完成 其他都是未进站
|
||||
5.工位产品 接口调用情况查询存储过程 PAD_工位状态_产品接口Moby_查询 其中请求内容列是个多行文本 这个如果要看可以是单独弹窗或者单独区域显示(你看怎么合适怎么来)
|
||||
1808
src/components/AgvTaskManagement.vue
Normal file
1808
src/components/AgvTaskManagement.vue
Normal file
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,7 @@ import {ElMessage} from 'element-plus' // 引入Element Plus的消息提示组
|
||||
const name_config = `OP8888`
|
||||
// import.meta.env.VITE_BASE_URL
|
||||
console.log(window.g)
|
||||
const request_config = window.g.API_WEB_URL + `/submit/MESCommonBase.ashx`
|
||||
const request_config = window.g.API_WEB_URL
|
||||
export const name = name_config
|
||||
const service = axios.create({
|
||||
baseURL: request_config,
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
<template>
|
||||
<div class="management-page">
|
||||
<el-tabs v-model="activeTab" class="management-tabs">
|
||||
<el-tab-pane label="AGV任务" name="agv">
|
||||
<AgvTaskManagement v-if="activeTab === 'agv'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="库位监控" name="slots">
|
||||
<div class="running-in-page">
|
||||
<!-- 顶部标题栏 -->
|
||||
<div class="page-header">
|
||||
@@ -151,6 +157,22 @@
|
||||
>
|
||||
AGV离开
|
||||
</el-button>
|
||||
<el-button
|
||||
type="info"
|
||||
size="large"
|
||||
:loading="toggleCallLoading"
|
||||
@click="handleToggleCall"
|
||||
>
|
||||
{{ selectedSlot?.是否呼叫 ? '取消呼叫' : '设为呼叫' }}
|
||||
</el-button>
|
||||
<el-button
|
||||
type="danger"
|
||||
size="large"
|
||||
:loading="clearSlotLoading"
|
||||
@click="handleClearSlot"
|
||||
>
|
||||
清空库位数据
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
@@ -222,15 +244,20 @@
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, onMounted, onUnmounted, getCurrentInstance, inject } from 'vue'
|
||||
import { ref, computed, onMounted, onUnmounted, getCurrentInstance, inject, watch } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { Refresh, Right } from '@element-plus/icons-vue'
|
||||
import AgvTaskManagement from '@/components/AgvTaskManagement.vue'
|
||||
|
||||
const { proxy } = getCurrentInstance()
|
||||
const ExecHttpRequest = inject('ExecHttpRequest')
|
||||
const activeTab = ref('agv')
|
||||
|
||||
// 数据
|
||||
const loading = ref(false)
|
||||
@@ -249,6 +276,11 @@ const confirmTransferLoading = ref(false)
|
||||
const agvArriveLoading = ref(false)
|
||||
const agvLeaveLoading = ref(false)
|
||||
|
||||
// 库位运维操作
|
||||
const toggleCallLoading = ref(false)
|
||||
const clearSlotLoading = ref(false)
|
||||
const OPERATOR = '磨合系统'
|
||||
|
||||
// PLC相关
|
||||
const plcConfigList = window.g.showPosList || []
|
||||
const plcValues = ref({}) // 存储点位值 Key=TagCode, Value=0/1
|
||||
@@ -326,7 +358,6 @@ const handleSlotClick = (slot) => {
|
||||
}
|
||||
|
||||
// 监听弹窗打开关闭,控制PLC轮询
|
||||
import { watch } from 'vue'
|
||||
watch(dialogVisible, (val) => {
|
||||
if (val) {
|
||||
fetchPLCValues()
|
||||
@@ -621,9 +652,100 @@ const handleAGVLeave = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
// 切换是否呼叫
|
||||
const handleToggleCall = async () => {
|
||||
if (!selectedSlot.value) return
|
||||
|
||||
const targetText = selectedSlot.value.是否呼叫 ? '取消呼叫' : '设为呼叫'
|
||||
try {
|
||||
await ElMessageBox.confirm(
|
||||
`确认将库位 ${selectedSlot.value.库位号} ${targetText}?此操作会写入系统日志。`,
|
||||
'确认',
|
||||
{ confirmButtonText: '确认', cancelButtonText: '取消', type: 'warning' }
|
||||
)
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
|
||||
toggleCallLoading.value = true
|
||||
try {
|
||||
const param = [
|
||||
['库位号', selectedSlot.value.库位号],
|
||||
['操作人', OPERATOR]
|
||||
]
|
||||
const data = proxy.CreateData('11', 'XD_磨合_状态_是否呼叫_切换', param)
|
||||
const res = await proxy.ExecDatabase(data)
|
||||
const row = res.data && res.data[0] ? res.data[0] : {}
|
||||
|
||||
if (row.result === 1) {
|
||||
ElMessage.success(`${targetText}成功`)
|
||||
selectedSlot.value.是否呼叫 = Number(row.是否呼叫) || 0
|
||||
loadData(false)
|
||||
} else {
|
||||
ElMessage.error(row.msg || `${targetText}失败`)
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('切换呼叫状态失败:', err)
|
||||
ElMessage.error('切换呼叫状态异常')
|
||||
} finally {
|
||||
toggleCallLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 清空库位数据
|
||||
const handleClearSlot = async () => {
|
||||
if (!selectedSlot.value) return
|
||||
|
||||
try {
|
||||
await ElMessageBox.confirm(
|
||||
`确认清空库位 ${selectedSlot.value.库位号} 的产品/工序/状态数据?此操作会写入系统日志,且不可撤销。`,
|
||||
'危险操作',
|
||||
{ confirmButtonText: '确认清空', cancelButtonText: '取消', type: 'error' }
|
||||
)
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
|
||||
clearSlotLoading.value = true
|
||||
try {
|
||||
const param = [
|
||||
['库位号', selectedSlot.value.库位号],
|
||||
['操作人', OPERATOR]
|
||||
]
|
||||
const data = proxy.CreateData('11', 'XD_磨合_状态_清空', param)
|
||||
const res = await proxy.ExecDatabase(data)
|
||||
const row = res.data && res.data[0] ? res.data[0] : {}
|
||||
|
||||
if (row.result === 1) {
|
||||
ElMessage.success('库位数据已清空')
|
||||
dialogVisible.value = false
|
||||
loadData()
|
||||
} else {
|
||||
ElMessage.error(row.msg || '清空库位数据失败')
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('清空库位数据失败:', err)
|
||||
ElMessage.error('清空库位数据异常')
|
||||
} finally {
|
||||
clearSlotLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (activeTab.value === 'slots') {
|
||||
loadData()
|
||||
startAutoRefresh()
|
||||
}
|
||||
})
|
||||
|
||||
watch(activeTab, value => {
|
||||
if (value === 'slots') {
|
||||
loadData()
|
||||
startAutoRefresh()
|
||||
} else {
|
||||
dialogVisible.value = false
|
||||
stopAutoRefresh()
|
||||
}
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
@@ -632,9 +754,33 @@ onUnmounted(() => {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.running-in-page {
|
||||
.management-page {
|
||||
min-height: 100vh;
|
||||
background: #e8eaed;
|
||||
}
|
||||
|
||||
.management-tabs {
|
||||
:deep(.el-tabs__header) {
|
||||
padding: 0 18px;
|
||||
margin: 0;
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #dcdfe6;
|
||||
}
|
||||
|
||||
:deep(.el-tabs__item) {
|
||||
height: 52px;
|
||||
font-size: 15px;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
:deep(.el-tabs__content) {
|
||||
overflow: visible;
|
||||
}
|
||||
}
|
||||
|
||||
.running-in-page {
|
||||
min-height: calc(100vh - 52px);
|
||||
background: #e8eaed;
|
||||
color: #1a1a1a;
|
||||
padding: 16px;
|
||||
box-sizing: border-box;
|
||||
|
||||
Reference in New Issue
Block a user