467 lines
17 KiB
Vue
467 lines
17 KiB
Vue
<template>
|
||
<div class="graph-container-box">
|
||
<el-row>
|
||
<el-col :span="16">
|
||
<knova-stage @rectClick="selectCard" :matMapList="matMapList" :rects="rects" :lines="lines"></knova-stage>
|
||
</el-col>
|
||
<el-col :span="8">
|
||
<div style="border: 1px solid #000; padding: 10px; border-radius: 10px; margin-bottom: 10px;">
|
||
<!-- 调整工具,选择两个位置,两个下拉选,分别双向绑定 -->
|
||
<el-form :model="adjustForm" ref="adjustForm" label-width="80px">
|
||
<el-form-item label="当前位置" prop="current">
|
||
<el-select v-model="adjustForm.current" placeholder="请选择当前位置">
|
||
<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-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>
|
||
</div>
|
||
|
||
<div style="border: 1px solid #000; padding: 10px; border-radius: 10px; margin-bottom: 10px;">
|
||
<el-row v-if="selectedCard">
|
||
<el-col :span="12">
|
||
<div class="detail-item">
|
||
<span class="detail-label">位置名称:</span>
|
||
<span class="detail-value">{{ selectedCard.positionNameCn || '-' }}</span>
|
||
</div>
|
||
<div class="detail-item">
|
||
<span class="detail-label">位置代号:</span>
|
||
<span class="detail-value">{{ selectedCard.positionNameEn || '-' }}</span>
|
||
</div>
|
||
<div class="detail-item">
|
||
<span class="detail-label">钢卷号:</span>
|
||
<span class="detail-value">{{ selectedCard.matId || '-' }}</span>
|
||
</div>
|
||
<div class="detail-item">
|
||
<span class="detail-label">计划ID:</span>
|
||
<span class="detail-value">{{ selectedCard.planId || '-' }}</span>
|
||
</div>
|
||
<div class="detail-item">
|
||
<span class="detail-label">计划号:</span>
|
||
<span class="detail-value">{{ selectedCard.planNo || '-' }}</span>
|
||
</div>
|
||
<div class="detail-item">
|
||
<span class="detail-label">开卷机编号:</span>
|
||
<span class="detail-value">{{ selectedCard.porIdx || '-' }}</span>
|
||
</div>
|
||
<div class="detail-item">
|
||
<span class="detail-label">卷取机编号:</span>
|
||
<span class="detail-value">{{ selectedCard.trIdx || '-' }}</span>
|
||
</div>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<!-- 加载状态 -->
|
||
<div class="empty-tip" v-if="isLoadingReturn">加载回退信息中...</div>
|
||
|
||
<!-- 错误状态 -->
|
||
<div class="empty-tip" v-else-if="returnError" style="color: #f56c6c;">
|
||
{{ returnError }}
|
||
</div>
|
||
|
||
<!-- 回退信息内容 -->
|
||
<div class="detail-list" v-else-if="Object.keys(returnInfo).length > 0">
|
||
<div class="detail-item">
|
||
<span class="detail-label">回退钢卷号:</span>
|
||
<span class="detail-value">{{ returnInfo.entryMatId || '-' }}</span>
|
||
</div>
|
||
<div class="detail-item">
|
||
<span class="detail-label">回退计划ID:</span>
|
||
<span class="detail-value">{{ returnInfo.planId || '-' }}</span>
|
||
</div>
|
||
<div class="detail-item">
|
||
<span class="detail-label">回退计划号:</span>
|
||
<span class="detail-value">{{ returnInfo.planNo || '-' }}</span>
|
||
</div>
|
||
<div class="detail-item">
|
||
<span class="detail-label">回退类型:</span>
|
||
<span class="detail-value">{{ returnInfo.returnType || '-' }}</span>
|
||
</div>
|
||
<div class="detail-item">
|
||
<span class="detail-label">回退重量:</span>
|
||
<span class="detail-value">
|
||
{{ returnInfo.returnWeight || '-' }}
|
||
{{ returnInfo.returnWeight ? 'kg' : '' }}
|
||
</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 无回退信息 -->
|
||
<div class="empty-tip" v-else>无回退信息</div>
|
||
</el-col>
|
||
</el-row>
|
||
<el-row v-else>
|
||
<div class="empty-tip">请选择钢卷卡片查看详情</div>
|
||
</el-row>
|
||
</div>
|
||
|
||
<div style="border: 1px solid #000; padding: 10px; border-radius: 10px; margin-bottom: 10px;">
|
||
<el-row v-if="selectedCard">
|
||
<div class="operation-panel">
|
||
<div class="panel-content">
|
||
<!-- 非调整模式:显示操作按钮 -->
|
||
<div class="operation-buttons">
|
||
<div class="button-group">
|
||
<el-button size="mini" type="primary" @click="handleOperate(selectedCard, 'ONLINE')"
|
||
class="btn-block">
|
||
钢卷上线
|
||
</el-button>
|
||
<el-button size="mini" type="warning" @click="handleOperate(selectedCard, 'UNLOAD')"
|
||
class="btn-block mt-2">
|
||
手动卸卷
|
||
</el-button>
|
||
<el-button size="mini" type="danger" @click="handleOperate(selectedCard, 'ALL_RETURN')"
|
||
class="btn-block mt-2">
|
||
整卷回退
|
||
</el-button>
|
||
<el-button size="mini" type="danger" @click="handleOperate(selectedCard, 'HALF_RETURN')"
|
||
class="btn-block mt-2">
|
||
半卷回退
|
||
</el-button>
|
||
<el-button size="mini" type="info" @click="handleOperate(selectedCard, 'BLOCK')"
|
||
class="btn-block mt-2">
|
||
卸卷并封闭
|
||
</el-button>
|
||
<!-- <el-button size="mini" type="info" @click="handleOperate(selectedCard, 'THROW_TAIL')" class="btn-block mt-2">
|
||
甩尾
|
||
</el-button> -->
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</el-row>
|
||
|
||
<el-row v-else>
|
||
<div class="empty-tip">请选择钢卷卡片进行操作</div>
|
||
</el-row>
|
||
</div>
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<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-input v-model="operateMatForm.porIdx"></el-input>
|
||
</el-form-item>
|
||
<el-form-item label="卷取机编号" 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>
|
||
<el-form-item label="钢卷号" prop="entryMatId">
|
||
<el-input v-model="operateMatForm.entryMatId" placeholder="请输入钢卷号"></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-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="甩尾" 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>
|
||
<el-form-item label="回退重量" prop="returnWeight">
|
||
<el-input v-model="operateMatForm.returnWeight" placeholder="请输入回退重量"></el-input>
|
||
</el-form-item>
|
||
<el-form-item label="回退备注" 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>
|
||
</template>
|
||
</el-form>
|
||
<div slot="footer" class="dialog-footer">
|
||
<el-button @click="operateMatStatus = false">取消</el-button>
|
||
<el-button type="primary" @click="submitOperateForm">确定</el-button>
|
||
</div>
|
||
</el-dialog>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import createFetch from '@/api/l2/track'
|
||
import { getConfigKey } from '@/api/system/config'
|
||
import KnovaStage from './components/knovaStage.vue'
|
||
import { rects, lines } from './panels/track/rects'
|
||
|
||
export default {
|
||
components: {
|
||
KnovaStage
|
||
},
|
||
data() {
|
||
return {
|
||
fetchApi: undefined,
|
||
rects,
|
||
lines,
|
||
matMapList: [],
|
||
selectedCard: null, // 非调整模式选中的单个卡片
|
||
adjustForm: {
|
||
current: null,
|
||
target: null
|
||
}, // 调整模式选中的位置:[当前, 目标],双向绑定
|
||
adjustMode: false, // 是否为调整模式
|
||
deviceMap: {},
|
||
operateMatForm: {
|
||
porIdx: null,
|
||
trIdx: null,
|
||
planId: '',
|
||
entryMatId: '',
|
||
// planNo: '',
|
||
operation: '',
|
||
returnMatId: '',
|
||
returnWeight: null,
|
||
returnRemark: '',
|
||
coilLength: null
|
||
},
|
||
operateRules: {
|
||
planId: [{ required: true, message: '请输入计划id', trigger: 'blur' }],
|
||
entryMatId: [{ required: true, message: '请输入钢卷号', trigger: 'blur' }],
|
||
operation: [{ required: true, message: '请选择操作类型', trigger: 'change' }],
|
||
returnMatId: [
|
||
{
|
||
required: true,
|
||
message: '请输入回退卷号',
|
||
trigger: 'blur',
|
||
validator: (rule, val, cb) => {
|
||
if (['ALL_RETURN', 'HALF_RETURN'].includes(this.operateMatForm.operation) && !val) {
|
||
cb(new Error('请输入回退卷号'))
|
||
} else cb()
|
||
}
|
||
}
|
||
],
|
||
returnWeight: [
|
||
{
|
||
required: true,
|
||
message: '请输入回退重量',
|
||
trigger: 'blur',
|
||
validator: (rule, val, cb) => {
|
||
if (['ALL_RETURN', 'HALF_RETURN'].includes(this.operateMatForm.operation) && (val === null || val === '')) {
|
||
cb(new Error('请输入回退重量'))
|
||
} else cb()
|
||
}
|
||
}
|
||
]
|
||
},
|
||
operateMatStatus: false, // 操作对话框显示状态
|
||
returnInfo: {}, // 存储回退接口返回的数据
|
||
isLoadingReturn: false, // 回退信息加载状态
|
||
returnError: '' // 回退信息获取失败的提示
|
||
}
|
||
},
|
||
computed: {
|
||
// 操作对话框标题
|
||
getOperateTitle() {
|
||
const titleMap = {
|
||
'ONLINE': '钢卷上线',
|
||
'UNLOAD': '手动卸卷',
|
||
'ALL_RETURN': '整卷回退',
|
||
'HALF_RETURN': '半卷回退',
|
||
'BLOCK': '卸卷并封闭',
|
||
'THROW_TAIL': '甩尾'
|
||
}
|
||
return titleMap[this.operateMatForm.operation] || '钢卷操作'
|
||
}
|
||
},
|
||
|
||
methods: {
|
||
// 获取钢卷数据
|
||
fetchData() {
|
||
this.fetchApi.getTrackMatPosition().then(res => {
|
||
this.matMapList = res.data.matMapList || []
|
||
// this.deviceMap = res.data.matMapList || {}
|
||
}).catch(err => {
|
||
console.error('获取钢卷数据失败:', err)
|
||
this.$message.error('获取数据失败,请重试')
|
||
})
|
||
},
|
||
|
||
/**
|
||
* 获取回退信息
|
||
* @param {Number} posIdx - 位置索引(接口必填query参数)
|
||
*/
|
||
fetchReturnData(posIdx) {
|
||
// 1. 校验posIdx
|
||
if (!posIdx && posIdx !== 0) {
|
||
this.returnInfo = {};
|
||
this.returnError = '缺少位置索引(posIdx),无法获取回退信息';
|
||
return;
|
||
}
|
||
|
||
// 2. 加载状态初始化
|
||
this.isLoadingReturn = true;
|
||
this.returnError = '';
|
||
|
||
// 3. 调用回退接口(posIdx作为query参数传递)
|
||
this.fetchApi.getBackData({ posIdx })
|
||
.then(res => {
|
||
this.isLoadingReturn = false;
|
||
// 接口成功且有数据
|
||
if (res.code === 200 && res.data) {
|
||
this.returnInfo = res.data;
|
||
} else {
|
||
this.returnInfo = {};
|
||
this.returnError = res.msg || '获取回退信息失败';
|
||
}
|
||
})
|
||
.catch(err => {
|
||
this.isLoadingReturn = false;
|
||
this.returnInfo = {};
|
||
this.returnError = '获取回退信息出错,请重试';
|
||
console.error('回退信息接口异常:', err);
|
||
});
|
||
},
|
||
|
||
// 选择卡片(区分调整/非调整模式)
|
||
selectCard(item) {
|
||
this.selectedCard = this.selectedCard === item ? null : item
|
||
// 选中卡片时查询回退信息,取消选中时清空
|
||
if (this.selectedCard) {
|
||
this.fetchReturnData(this.selectedCard.posIdx);
|
||
this.adjustForm.current = this.selectedCard.positionNameEn
|
||
} else {
|
||
this.returnInfo = {};
|
||
this.returnError = '';
|
||
this.adjustForm.current = null
|
||
}
|
||
},
|
||
|
||
// 确认调整位置
|
||
handleConfirmAdjust() {
|
||
const { current, target } = this.adjustForm
|
||
|
||
if (!current || !target) {
|
||
this.$message.warning('请选择当前位置和目标位置')
|
||
return
|
||
}
|
||
|
||
const params = {
|
||
currentPos: current,
|
||
targetPos: target,
|
||
}
|
||
|
||
this.$confirm(`确定将 ${current} 的钢卷调整到 ${target}?`, '确认调整', {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning'
|
||
}).then(() => {
|
||
this.fetchApi.adjustPosition(params).then(() => {
|
||
this.$message.success('调整成功')
|
||
this.exitAdjustMode()
|
||
this.fetchData()
|
||
}).catch(err => {
|
||
console.error('调整失败:', err)
|
||
this.$message.error('调整失败,请重试')
|
||
})
|
||
}).catch(() => {
|
||
this.$message.info('已取消调整')
|
||
})
|
||
},
|
||
|
||
// 打开操作对话框
|
||
handleOperate(row, operation) {
|
||
this.$refs.operateForm?.resetFields()
|
||
this.operateMatForm = {
|
||
porIdx: row.posIdx || null,
|
||
trIdx: row.posIdx || null,
|
||
planId: row.planId || '',
|
||
entryMatId: row.matId || '',
|
||
planNo: row.planNo || '',
|
||
operation: operation,
|
||
returnMatId: '',
|
||
returnWeight: null,
|
||
returnRemark: '',
|
||
coilLength: null
|
||
}
|
||
this.operateMatStatus = true
|
||
},
|
||
|
||
// 提交操作表单
|
||
submitOperateForm() {
|
||
this.$refs.operateForm.validate(valid => {
|
||
if (valid) {
|
||
this.fetchApi.operateMat(this.operateMatForm).then(() => {
|
||
this.$message.success('操作成功')
|
||
this.operateMatStatus = false
|
||
this.fetchData()
|
||
}).catch(err => {
|
||
console.error('操作失败:', err)
|
||
this.$message.error('操作失败,请重试')
|
||
})
|
||
} else {
|
||
this.$message.warning('请完善表单信息')
|
||
}
|
||
})
|
||
}
|
||
},
|
||
|
||
mounted() {
|
||
getConfigKey('line.zine.baseURL').then(res => {
|
||
this.fetchApi = createFetch(res.msg)
|
||
this.fetchData()
|
||
})
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
.graph-container-box {
|
||
width: 100%;
|
||
box-sizing: border-box;
|
||
height: calc(100vh - 86px);
|
||
padding: 20px;
|
||
// background-color: #c0c0c0;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.graph-container {
|
||
width: 100%;
|
||
height: 100%;
|
||
position: relative;
|
||
|
||
img {
|
||
width: 1881px;
|
||
height: 608px;
|
||
}
|
||
|
||
// 图形元素基础样式
|
||
.graph-list>div {
|
||
position: absolute;
|
||
}
|
||
|
||
// 文字容器样式
|
||
.text-wrapper {
|
||
position: relative;
|
||
height: 100%;
|
||
}
|
||
|
||
// 文字基础样式(可被配置项覆盖)
|
||
.text-wrapper span {
|
||
position: absolute;
|
||
color: #333;
|
||
/* 默认文字颜色 */
|
||
font-size: 14px;
|
||
/* 默认文字大小 */
|
||
}
|
||
}
|
||
</style>
|