409 lines
11 KiB
Vue
409 lines
11 KiB
Vue
<template>
|
|
<div class="work-order-page">
|
|
<el-row :gutter="20">
|
|
<el-col :span="5">
|
|
<div class="order-list">
|
|
<h3>今日工单列表</h3>
|
|
<ul>
|
|
<li v-for="(order, index) in orders" style="position: relative;"
|
|
@click="onHandleOrderClick(order)" :key="index" :class="{ active: order.active }">
|
|
<span>{{ order.workOrderCode }}</span>
|
|
<div style="color: #666;font-size: 12px;">
|
|
<span>{{ order.lineName }}</span>
|
|
<span style="margin-left: 20px;">数量:{{ order.totalQty }}</span>
|
|
</div>
|
|
<span style="position: absolute; right: 5%; top:35%"
|
|
:class="getOrderStatusClass(order.orderStatus)">{{
|
|
getOrderStatusText(order.orderStatus) }}</span>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</el-col>
|
|
|
|
<el-col :span="15">
|
|
<div class="main-content">
|
|
<h2>工单号: {{ currentOrder.workOrderCode }}</h2>
|
|
<div class="product-info">
|
|
<div class="info-item">
|
|
<span>产线编号:</span>
|
|
<span>{{ currentOrder.lineCode }}</span>
|
|
</div>
|
|
<div class="info-item">
|
|
<span>产线名称:</span>
|
|
<span>{{ currentOrder.lineName }}</span>
|
|
</div>
|
|
<div class="info-item">
|
|
<span>工艺路线编码:</span>
|
|
<span>{{ currentOrder.processCode }}</span>
|
|
</div>
|
|
<div class="info-item">
|
|
<span>工艺路线名称:</span>
|
|
<span>{{ currentOrder.processName }}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="order-data">
|
|
<div class="data-item">
|
|
<span>工单日期:</span>
|
|
<span>{{ currentOrder.orderDate }}</span>
|
|
</div>
|
|
<div class="data-item">
|
|
<span>零件编码:</span>
|
|
<span>{{ currentOrder.materialCode }}</span>
|
|
</div>
|
|
<div class="data-item">
|
|
<span>工单状态:</span>
|
|
<span :class="getOrderStatusClass(currentOrder.orderStatus)">{{
|
|
getOrderStatusText(currentOrder.orderStatus)
|
|
}}</span>
|
|
</div>
|
|
<div class="data-item">
|
|
<span>零件名称:</span>
|
|
<span>{{ currentOrder.materialName }}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="remark">
|
|
<p>{{ currentOrder.remark }}</p>
|
|
</div>
|
|
|
|
<div class="input-section">
|
|
<div class="input-group">
|
|
<label>合格数</label>
|
|
<input v-model.number="currentOrder.okQty" type="number" />
|
|
</div>
|
|
<div class="input-group">
|
|
<label>不合格数</label>
|
|
<input min="0" v-model.number="currentOrder.ngQty" type="number" />
|
|
</div>
|
|
<div class="input-group">
|
|
<label>不良原因</label>
|
|
<textarea min="0" v-model="currentOrder.defectReason" placeholder="请输入不良原因"></textarea>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="button-group">
|
|
<el-button @click="save">保存</el-button>
|
|
<el-button type="primary" @click="completeOrder">工单完工</el-button>
|
|
</div>
|
|
</div>
|
|
</el-col>
|
|
|
|
<el-col :span="4">
|
|
<div class="scan-area">
|
|
<h3>标签扫描</h3>
|
|
<el-form label-width="70px">
|
|
<el-form-item label="选择产线">
|
|
<el-select filterable clearable @change="handleSelectLineName" v-model="lineName"
|
|
placeholder="请选择产线">
|
|
<el-option v-for="item in productionLine" :key="item.value" :label="item.label"
|
|
:value="item.value" />
|
|
</el-select>
|
|
</el-form-item>
|
|
<el-form-item label="扫码结果">
|
|
<el-input @keyup.enter="handleQuery" placeholder="请扫描或输入"
|
|
v-model="tagNumber"></el-input>
|
|
</el-form-item>
|
|
</el-form>
|
|
</div>
|
|
</el-col>
|
|
</el-row>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, onMounted } from 'vue';
|
|
import { getProcessInfoTree, updateProcessInfo, updateProcessInfoList, checkFirstInspection, getLineName } from '@/api/humanComputerInteraction/index.js';
|
|
import { ElMessage } from 'element-plus';
|
|
const productionLine = ref([])
|
|
const tagNumber = ref('');
|
|
import { dayjs } from 'element-plus';
|
|
const orders = ref([
|
|
]);
|
|
const lineName = ref('');
|
|
// 当前选中的工单
|
|
const currentOrder = ref({
|
|
workOrderCode: '',//工单编号
|
|
lineCode: '',//产线编号
|
|
lineName: '',//产线名称
|
|
processCode: '',//工艺路线编码
|
|
processName: '',//工艺路线名称
|
|
orderDate: '',//工单日期
|
|
materialCode: '',//零件编码
|
|
materialName: '',//零件名称
|
|
okQty: '',//合格数
|
|
ngQty: '',//不合格数
|
|
defectReason: '',//不良原因描述
|
|
totalQty: '',//总数
|
|
orderStatus: '',//工单状态
|
|
UpdateBy: '',
|
|
UpdateName: '',
|
|
});
|
|
|
|
const getLeftTreeList = () => {
|
|
getProcessInfoTree().then(res => {
|
|
if (res.code == 200) {
|
|
orders.value = res.data
|
|
}
|
|
})
|
|
}
|
|
getLeftTreeList()
|
|
const getLineNameData = () => {
|
|
getLineName().then(res => {
|
|
if (res.code == 200) {
|
|
productionLine.value = res.data.map(item => {
|
|
return {
|
|
label: item.label,
|
|
value: item.value
|
|
}
|
|
})
|
|
}
|
|
})
|
|
}
|
|
getLineNameData()
|
|
const getOrderStatusClass = (status) => {
|
|
const statusClassMap = {
|
|
'0': 'pending',
|
|
'1': 'processing',
|
|
'2': 'completed'
|
|
};
|
|
return statusClassMap[status] || '';
|
|
};
|
|
const getOrderStatusText = (status) => {
|
|
const statusMap = {
|
|
'0': '待执行',
|
|
'1': '执行中',
|
|
'2': '已完成'
|
|
};
|
|
return statusMap[status] || '';
|
|
};
|
|
const isWhiteText = ref(false)
|
|
const onHandleOrderClick = (val) => {
|
|
isWhiteText.value = true
|
|
orders.value.forEach(order => {
|
|
order.active = false;
|
|
});
|
|
val.active = true;
|
|
currentOrder.value = {
|
|
...val
|
|
}
|
|
}
|
|
|
|
const handleQuery = () => {
|
|
if (!lineName.value) {
|
|
ElMessage.error('请选择产线名称');
|
|
return;
|
|
}
|
|
let params={
|
|
lineCode:lineName.value,
|
|
checkDate:dayjs(new Date()).format('YYYY-MM-DD'),
|
|
}
|
|
checkFirstInspection(params).then(res => {
|
|
if (res.code == 400) {
|
|
ElMessage.error(res.msg);
|
|
return
|
|
}
|
|
if(res && res.code == 200){
|
|
ElMessage.success('请求成功!');
|
|
}
|
|
})
|
|
}
|
|
// 保存按钮点击事件
|
|
const save = () => {
|
|
updateProcessInfo(currentOrder.value).then(res => {
|
|
if (res.code == 200) {
|
|
ElMessage.success('保存成功')
|
|
}
|
|
})
|
|
};
|
|
|
|
const completeOrder = () => {
|
|
if (currentOrder.value.orderStatus == '2') {
|
|
ElMessage.warning('工单已完工,请勿重复操作')
|
|
return;
|
|
}
|
|
let data = {
|
|
...currentOrder.value,
|
|
orderStatus: currentOrder.value.orderStatus = '2'
|
|
}
|
|
updateProcessInfoList(data).then(res => {
|
|
if (res.code == 200) {
|
|
ElMessage.success('状态修改完成')
|
|
}
|
|
})
|
|
};
|
|
</script>
|
|
|
|
<style scoped>
|
|
.work-order-page {
|
|
padding: 20px;
|
|
height: 100%;
|
|
background-color: #f5f5f5;
|
|
}
|
|
|
|
.top-bar {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 20px;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.time {
|
|
color: #666;
|
|
}
|
|
|
|
.pending {
|
|
color: #999999;
|
|
}
|
|
|
|
.processing {
|
|
color: #409EFF;
|
|
}
|
|
|
|
.completed {
|
|
color: #4caf50;
|
|
}
|
|
|
|
.order-list {
|
|
background: white;
|
|
border-radius: 8px;
|
|
padding: 16px;
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
.order-list h3 {
|
|
margin-top: 0;
|
|
color: white;
|
|
background-color: #409EFF;
|
|
padding: 8px;
|
|
border-radius: 4px;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.order-list ul {
|
|
list-style: none;
|
|
padding: 0;
|
|
margin: 10px 0;
|
|
}
|
|
|
|
.order-list li {
|
|
padding: 8px;
|
|
border-bottom: 1px solid #eee;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.order-list li:hover {
|
|
background-color: #f0f0f0;
|
|
}
|
|
|
|
.order-list li.active {
|
|
background-color: #f0f0f0;
|
|
color: #000 !important;
|
|
}
|
|
|
|
.order-list .status {
|
|
float: right;
|
|
padding: 2px 8px;
|
|
border-radius: 4px;
|
|
font-size: 12px;
|
|
}
|
|
|
|
.white-text {
|
|
color: white;
|
|
}
|
|
|
|
.main-content {
|
|
background: white;
|
|
border-radius: 8px;
|
|
padding: 20px;
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
.main-content h2 {
|
|
margin-top: 0;
|
|
color: #333;
|
|
font-size: 18px;
|
|
}
|
|
|
|
.info-item,
|
|
.data-item {
|
|
display: flex;
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
.info-item span:first-child,
|
|
.data-item span:first-child {
|
|
width: 100px;
|
|
font-weight: bold;
|
|
color: #666;
|
|
}
|
|
|
|
.info-item span:last-child,
|
|
.data-item span:last-child {
|
|
flex: 1;
|
|
}
|
|
|
|
.normal {
|
|
color: #4caf50;
|
|
}
|
|
|
|
.remark {
|
|
margin: 20px 0;
|
|
padding: 10px;
|
|
background-color: #f9f9f9;
|
|
border-radius: 4px;
|
|
font-size: 12px;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.input-section {
|
|
margin: 20px 0;
|
|
}
|
|
|
|
.input-group {
|
|
margin-bottom: 16px;
|
|
}
|
|
|
|
.input-group label {
|
|
display: block;
|
|
margin-bottom: 8px;
|
|
font-weight: bold;
|
|
color: #333;
|
|
}
|
|
|
|
.input-group input,
|
|
.input-group textarea {
|
|
width: 100%;
|
|
padding: 8px;
|
|
border: 1px solid #ddd;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.button-group {
|
|
display: flex;
|
|
gap: 16px;
|
|
margin-top: 20px;
|
|
}
|
|
|
|
.scan-area {
|
|
background: white;
|
|
border-radius: 8px;
|
|
padding: 20px;
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
text-align: center;
|
|
}
|
|
|
|
.scan-area h3 {
|
|
margin-top: 0;
|
|
color: #333;
|
|
}
|
|
|
|
.scan-box {
|
|
width: 100%;
|
|
height: 100px;
|
|
background-color: #409EFF;
|
|
margin-top: 16px;
|
|
border-radius: 4px;
|
|
}
|
|
</style> |