|
|
|
|
@ -12,23 +12,33 @@
|
|
|
|
|
<el-form-item label="计划编号" prop="planCode">
|
|
|
|
|
<el-input v-model="traceQuery.planCode" clearable />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="明细编号" prop="planDetailCode">
|
|
|
|
|
<!-- <el-form-item label="明细编号" prop="planDetailCode">
|
|
|
|
|
<el-input v-model="traceQuery.planDetailCode" clearable />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-form-item> -->
|
|
|
|
|
<el-form-item label="生产条码" prop="productionBarcode">
|
|
|
|
|
<el-input v-model="traceQuery.productionBarcode" clearable />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="机台" prop="machineName">
|
|
|
|
|
<el-input v-model="traceQuery.machineName" clearable />
|
|
|
|
|
<el-select v-model="traceQuery.machineName" clearable filterable placeholder="请选择机台" style="width: 180px">
|
|
|
|
|
<el-option v-for="item in machineOptions" :key="item.machineId" :label="item.machineName" :value="item.machineName" />
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="物料" prop="materialName">
|
|
|
|
|
<el-input v-model="traceQuery.materialName" clearable />
|
|
|
|
|
<el-input v-model="traceQuery.materialName" clearable readonly placeholder="点击选择物料" style="width: 180px" @click="openMaterialSelect">
|
|
|
|
|
<template #append>
|
|
|
|
|
<el-button icon="Search" @click="openMaterialSelect" />
|
|
|
|
|
</template>
|
|
|
|
|
</el-input>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="班次" prop="shiftName">
|
|
|
|
|
<el-input v-model="traceQuery.shiftName" clearable />
|
|
|
|
|
<el-select v-model="traceQuery.shiftName" clearable filterable placeholder="请选择班次" style="width: 150px">
|
|
|
|
|
<el-option v-for="item in shiftOptions" :key="item.shiftId" :label="item.shiftName" :value="item.shiftName" />
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="班组" prop="classTeamName">
|
|
|
|
|
<el-input v-model="traceQuery.classTeamName" clearable />
|
|
|
|
|
<el-select v-model="traceQuery.classTeamName" clearable filterable placeholder="请选择班组" style="width: 150px">
|
|
|
|
|
<el-option v-for="item in classTeamOptions" :key="item.classTeamId" :label="item.teamName" :value="item.teamName" />
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="创建日期" style="width: 380px">
|
|
|
|
|
<el-date-picker
|
|
|
|
|
@ -321,6 +331,15 @@
|
|
|
|
|
</el-tabs>
|
|
|
|
|
|
|
|
|
|
<!-- Drawer 已移除,详情内容已迁移至底部 Tab(每车基本信息/每车明细信息) -->
|
|
|
|
|
|
|
|
|
|
<!-- 物料选择对话框 -->
|
|
|
|
|
<el-dialog v-model="materialDialogVisible" title="选择物料" width="800px" append-to-body>
|
|
|
|
|
<MaterialSelect ref="materialSelectRef" />
|
|
|
|
|
<template #footer>
|
|
|
|
|
<el-button @click="materialDialogVisible = false">取消</el-button>
|
|
|
|
|
<el-button type="primary" @click="handleMaterialConfirm">确定</el-button>
|
|
|
|
|
</template>
|
|
|
|
|
</el-dialog>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
@ -329,6 +348,13 @@ import { computed, getCurrentInstance, nextTick, onBeforeUnmount, onMounted, rea
|
|
|
|
|
import type { ComponentInternalInstance } from 'vue';
|
|
|
|
|
import * as echarts from 'echarts';
|
|
|
|
|
import { getMixTraceDetail, getSpcCapability, getSpcRunChart, getSpcXbarR, listMixTrace, listSpcSamples } from '@/api/mes/mixTrace';
|
|
|
|
|
import { getProdBaseMachineInfoList } from '@/api/mes/prodBaseMachineInfo';
|
|
|
|
|
import { getBaseShiftInfoList } from '@/api/mes/baseShiftInfo';
|
|
|
|
|
import { getBaseClassTeamInfoList } from '@/api/mes/baseClassTeamInfo';
|
|
|
|
|
import type { ProdBaseMachineInfoVO } from '@/api/mes/prodBaseMachineInfo/types';
|
|
|
|
|
import type { BaseShiftInfoVO } from '@/api/mes/baseShiftInfo/types';
|
|
|
|
|
import type { BaseClassTeamInfoVO } from '@/api/mes/baseClassTeamInfo/types';
|
|
|
|
|
import MaterialSelect from '@/views/mes/recipeInfo/components/MaterialSelect.vue';
|
|
|
|
|
import type {
|
|
|
|
|
MixTraceDetailQuery,
|
|
|
|
|
MixTraceDetailVO,
|
|
|
|
|
@ -357,6 +383,13 @@ const traceTableRef = ref();
|
|
|
|
|
const treeFilterText = ref('');
|
|
|
|
|
const trayBarcode = ref('');
|
|
|
|
|
|
|
|
|
|
/** 下拉框数据 */
|
|
|
|
|
const machineOptions = ref<ProdBaseMachineInfoVO[]>([]);
|
|
|
|
|
const shiftOptions = ref<BaseShiftInfoVO[]>([]);
|
|
|
|
|
const classTeamOptions = ref<BaseClassTeamInfoVO[]>([]);
|
|
|
|
|
const materialSelectRef = ref();
|
|
|
|
|
const materialDialogVisible = ref(false);
|
|
|
|
|
|
|
|
|
|
const traceLoading = ref(false);
|
|
|
|
|
const traceList = ref<any[]>([]);
|
|
|
|
|
const traceTotal = ref(0);
|
|
|
|
|
@ -538,6 +571,60 @@ const handleTrayTrace = () => {
|
|
|
|
|
handleTraceQuery();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** 加载机台下拉选项 */
|
|
|
|
|
const loadMachineOptions = async () => {
|
|
|
|
|
try {
|
|
|
|
|
const res = await getProdBaseMachineInfoList({});
|
|
|
|
|
machineOptions.value = (res as any).data || [];
|
|
|
|
|
} catch {
|
|
|
|
|
machineOptions.value = [];
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** 加载班次下拉选项 */
|
|
|
|
|
const loadShiftOptions = async () => {
|
|
|
|
|
try {
|
|
|
|
|
const res = await getBaseShiftInfoList({});
|
|
|
|
|
shiftOptions.value = (res as any).data || [];
|
|
|
|
|
} catch {
|
|
|
|
|
shiftOptions.value = [];
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** 加载班组下拉选项 */
|
|
|
|
|
const loadClassTeamOptions = async () => {
|
|
|
|
|
try {
|
|
|
|
|
const res = await getBaseClassTeamInfoList({});
|
|
|
|
|
classTeamOptions.value = (res as any).data || [];
|
|
|
|
|
} catch {
|
|
|
|
|
classTeamOptions.value = [];
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** 打开物料选择对话框 */
|
|
|
|
|
const openMaterialSelect = () => {
|
|
|
|
|
materialDialogVisible.value = true;
|
|
|
|
|
nextTick(() => {
|
|
|
|
|
materialSelectRef.value?.getList();
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** 确认物料选择 */
|
|
|
|
|
const handleMaterialConfirm = () => {
|
|
|
|
|
const selected = materialSelectRef.value?.getSelected();
|
|
|
|
|
if (selected) {
|
|
|
|
|
traceQuery.materialName = selected.materialName;
|
|
|
|
|
materialDialogVisible.value = false;
|
|
|
|
|
} else {
|
|
|
|
|
proxy?.$modal?.msgWarning?.('请选择物料');
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** 清除物料选择 */
|
|
|
|
|
const clearMaterialSelect = () => {
|
|
|
|
|
traceQuery.materialName = undefined;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** 从列表数据构建配方树(父=配方编码+物料名,子=该配方下的记录) */
|
|
|
|
|
const buildRecipeTree = (list: any[]) => {
|
|
|
|
|
const grouped = new Map<string, { label: string; recipeId: any; children: any[] }>();
|
|
|
|
|
@ -892,6 +979,10 @@ watch(
|
|
|
|
|
|
|
|
|
|
/** 列表数据变化时构建配方树 */
|
|
|
|
|
watch(traceList, (list) => {
|
|
|
|
|
// 点击配方树后会按 recipeId 过滤列表,此时不重建树,避免只剩当前配方
|
|
|
|
|
if (traceQuery.recipeId && recipeTreeData.value.length > 0) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
buildRecipeTree(list);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
@ -911,6 +1002,10 @@ watch(detailTab, async (tab) => {
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
getTraceList();
|
|
|
|
|
window.addEventListener('resize', handleResize);
|
|
|
|
|
// 加载下拉框数据
|
|
|
|
|
loadMachineOptions();
|
|
|
|
|
loadShiftOptions();
|
|
|
|
|
loadClassTeamOptions();
|
|
|
|
|
// 重置查询时清除选中状态
|
|
|
|
|
watch(() => traceQuery.pageNum, () => {
|
|
|
|
|
selectedRow.value = null;
|
|
|
|
|
|