<template>
|
<el-dialog
|
v-model="visible"
|
title="清场记录"
|
width="900px"
|
:close-on-click-modal="false"
|
destroy-on-close
|
>
|
<div class="clearance-record-form">
|
<!-- 基本信息区域 -->
|
<div class="basic-info">
|
<table class="info-table">
|
<tr>
|
<td class="label">产品名称</td>
|
<td class="value" colspan="3">{{ formData.productName }}</td>
|
<td class="label">生产日期</td>
|
<td class="value">{{ formData.productionDate }}</td>
|
</tr>
|
<tr>
|
<td class="label">规格</td>
|
<td class="value">{{ formData.spec }}</td>
|
<td class="label">批号</td>
|
<td class="value">{{ formData.batchNo }}</td>
|
<td class="label">生产车间</td>
|
<td class="value">{{ formData.workshop }}</td>
|
</tr>
|
</table>
|
</div>
|
|
<!-- 清场检查项目表格 -->
|
<div class="check-items-section">
|
<table class="check-table">
|
<thead>
|
<tr>
|
<th class="item-no">序号</th>
|
<th class="content">清场内容及要求</th>
|
<th class="result" colspan="2">检查结果</th>
|
</tr>
|
</thead>
|
<tbody>
|
<tr v-for="(item, index) in formData.checkItems" :key="index">
|
<td class="item-no">{{ item.itemNo }}</td>
|
<td class="content">{{ item.content }}</td>
|
<td class="result-option">
|
<el-radio-group v-model="item.result">
|
<el-radio label="符合规定">符合规定</el-radio>
|
</el-radio-group>
|
</td>
|
<td class="result-option">
|
<el-radio-group v-model="item.result">
|
<el-radio label="不符合规定">不符合规定</el-radio>
|
</el-radio-group>
|
</td>
|
</tr>
|
</tbody>
|
</table>
|
</div>
|
|
<!-- 签名区域 -->
|
<div class="signature-section">
|
<table class="signature-table">
|
<tr>
|
<td class="label">清场人</td>
|
<td class="value">
|
<el-input v-model="formData.cleaner" placeholder="请输入清场人" clearable />
|
</td>
|
<td class="label">日期</td>
|
<td class="value">
|
<el-date-picker
|
v-model="formData.cleanDate"
|
type="datetime"
|
placeholder="选择日期时间"
|
format="YYYY-MM-DD HH:mm:ss"
|
value-format="YYYY-MM-DD HH:mm:ss"
|
style="width: 100%"
|
/>
|
</td>
|
<td class="label">检查人</td>
|
<td class="value">
|
<el-input v-model="formData.inspector" placeholder="请输入检查人" clearable />
|
</td>
|
<td class="label">日期</td>
|
<td class="value">
|
<el-date-picker
|
v-model="formData.inspectDate"
|
type="datetime"
|
placeholder="选择日期时间"
|
format="YYYY-MM-DD HH:mm:ss"
|
value-format="YYYY-MM-DD HH:mm:ss"
|
style="width: 100%"
|
/>
|
</td>
|
</tr>
|
</table>
|
</div>
|
</div>
|
|
<template #footer>
|
<span class="dialog-footer">
|
<el-button @click="handleCancel">取 消</el-button>
|
<el-button type="primary" :loading="saving" @click="handleSave">保 存</el-button>
|
</span>
|
</template>
|
</el-dialog>
|
</template>
|
|
<script setup>
|
import { ref, reactive, watch, computed } from 'vue';
|
import dayjs from 'dayjs';
|
|
const props = defineProps({
|
modelValue: {
|
type: Boolean,
|
default: false
|
},
|
orderData: {
|
type: Object,
|
default: () => ({})
|
}
|
});
|
|
const emit = defineEmits(['update:modelValue', 'save']);
|
|
const visible = computed({
|
get: () => props.modelValue,
|
set: (val) => emit('update:modelValue', val)
|
});
|
|
const saving = ref(false);
|
|
// 默认检查项目
|
const defaultCheckItems = [
|
{ itemNo: 1, content: '车间内无前批遗留物、废弃物。', result: '符合规定', remark: '' },
|
{ itemNo: 2, content: '车间内无无关指令、规程、记录等。', result: '符合规定', remark: '' },
|
{ itemNo: 3, content: '桌面、工作台应清洁,无尘、无垢。', result: '符合规定', remark: '' },
|
{ itemNo: 4, content: '地面清洁,无积尘、杂物。', result: '符合规定', remark: '' },
|
{ itemNo: 5, content: '设备及部件内、外应清洁,无异物。', result: '符合规定', remark: '' },
|
{ itemNo: 6, content: '容器具应清洁无异物,并置指定位置', result: '符合规定', remark: '' },
|
{ itemNo: 7, content: '卫生洁具清洁,并置指定位置', result: '符合规定', remark: '' },
|
{ itemNo: 8, content: '其它', result: '符合规定', remark: '' }
|
];
|
|
const formData = reactive({
|
orderId: '',
|
productName: '',
|
productionDate: '',
|
spec: '',
|
batchNo: '',
|
workshop: '',
|
checkItems: JSON.parse(JSON.stringify(defaultCheckItems)),
|
cleaner: '',
|
cleanDate: '',
|
inspector: '',
|
inspectDate: ''
|
});
|
|
// 监听弹框打开,初始化数据
|
watch(() => props.modelValue, (val) => {
|
if (val && props.orderData) {
|
initFormData();
|
}
|
});
|
|
const initFormData = () => {
|
const order = props.orderData;
|
|
const cleanRecord = order.cleanRecord || order.clearanceRecord;
|
if (cleanRecord) {
|
try {
|
const record = typeof cleanRecord === 'string'
|
? JSON.parse(cleanRecord)
|
: cleanRecord;
|
|
// 加载基本字段
|
formData.orderId = record.orderId || order.npsNo || '';
|
formData.productName = record.productName || order.productCategory || '';
|
formData.productionDate = record.productionDate || (order.startTime ? dayjs(order.startTime).format('YYYY-MM-DD') : dayjs().format('YYYY-MM-DD'));
|
formData.spec = record.spec || order.specificationModel || '';
|
formData.batchNo = record.batchNo || order.batchNo || order.uidNo || '';
|
formData.workshop = record.workshop || order.workshop || order.manufacturingTeam || '';
|
|
// 加载检查项目,保持默认结构但更新结果
|
if (record.checkItems && Array.isArray(record.checkItems)) {
|
formData.checkItems = defaultCheckItems.map((defaultItem, index) => {
|
const savedItem = record.checkItems.find(item => item.itemNo === defaultItem.itemNo);
|
return {
|
...defaultItem,
|
result: savedItem?.result || '符合规定',
|
remark: savedItem?.remark || ''
|
};
|
});
|
} else {
|
formData.checkItems = JSON.parse(JSON.stringify(defaultCheckItems));
|
}
|
|
// 加载签名信息
|
formData.cleaner = record.cleaner || '';
|
formData.cleanDate = record.cleanDate || dayjs().format('YYYY-MM-DD HH:mm:ss');
|
formData.inspector = record.inspector || '';
|
formData.inspectDate = record.inspectDate || dayjs().format('YYYY-MM-DD HH:mm:ss');
|
} catch (e) {
|
console.error('解析清场记录数据失败:', e);
|
resetFormData(order);
|
}
|
} else {
|
resetFormData(order);
|
}
|
};
|
|
const resetFormData = (order) => {
|
// 重置检查项目
|
formData.checkItems = JSON.parse(JSON.stringify(defaultCheckItems));
|
|
// 自动带入订单数据
|
formData.orderId = order.npsNo || '';
|
formData.productName = order.productCategory || '';
|
formData.productionDate = order.startTime ? dayjs(order.startTime).format('YYYY-MM-DD') : dayjs().format('YYYY-MM-DD');
|
formData.spec = order.specificationModel || '';
|
formData.batchNo = order.batchNo || order.uidNo || '';
|
formData.workshop = order.workshop || order.manufacturingTeam || '';
|
|
// 清场人和检查人默认为空,日期默认为当前时间
|
formData.cleaner = '';
|
formData.cleanDate = dayjs().format('YYYY-MM-DD HH:mm:ss');
|
formData.inspector = '';
|
formData.inspectDate = dayjs().format('YYYY-MM-DD HH:mm:ss');
|
};
|
|
const handleCancel = () => {
|
visible.value = false;
|
};
|
|
const handleSave = () => {
|
// 验证必填项
|
if (!formData.cleaner) {
|
ElMessage.warning('请输入清场人');
|
return;
|
}
|
if (!formData.cleanDate) {
|
ElMessage.warning('请选择清场日期');
|
return;
|
}
|
if (!formData.inspector) {
|
ElMessage.warning('请输入检查人');
|
return;
|
}
|
if (!formData.inspectDate) {
|
ElMessage.warning('请选择检查日期');
|
return;
|
}
|
|
// 构造保存的JSON数据
|
const saveData = {
|
orderId: formData.orderId,
|
productName: formData.productName,
|
productionDate: formData.productionDate,
|
spec: formData.spec,
|
batchNo: formData.batchNo,
|
workshop: formData.workshop,
|
checkItems: formData.checkItems.map(item => ({
|
itemNo: item.itemNo,
|
content: item.content,
|
result: item.result,
|
remark: item.remark || undefined
|
})),
|
cleaner: formData.cleaner,
|
cleanDate: formData.cleanDate,
|
inspector: formData.inspector,
|
inspectDate: formData.inspectDate
|
};
|
|
// 移除undefined字段
|
saveData.checkItems = saveData.checkItems.map(item => {
|
if (!item.remark) delete item.remark;
|
return item;
|
});
|
|
saving.value = true;
|
emit('save', saveData, () => {
|
saving.value = false;
|
visible.value = false;
|
});
|
};
|
</script>
|
|
<style scoped lang="scss">
|
.clearance-record-form {
|
.basic-info {
|
margin-bottom: 20px;
|
}
|
|
.info-table {
|
width: 100%;
|
border-collapse: collapse;
|
border: 1px solid #dcdfe6;
|
|
td {
|
border: 1px solid #dcdfe6;
|
padding: 10px;
|
font-size: 14px;
|
}
|
|
.label {
|
background-color: #f5f7fa;
|
width: 100px;
|
text-align: center;
|
font-weight: 500;
|
}
|
|
.value {
|
background-color: #fff;
|
min-width: 150px;
|
}
|
}
|
|
.check-items-section {
|
margin-bottom: 10px;
|
|
.check-table {
|
width: 100%;
|
border-collapse: collapse;
|
border: 1px solid #dcdfe6;
|
|
th, td {
|
border: 1px solid #dcdfe6;
|
padding: 12px 10px;
|
font-size: 14px;
|
}
|
|
th {
|
background-color: #f5f7fa;
|
font-weight: 500;
|
text-align: center;
|
}
|
|
.item-no {
|
width: 60px;
|
text-align: center;
|
}
|
|
.content {
|
text-align: left;
|
padding-left: 15px;
|
}
|
|
.result {
|
width: 200px;
|
text-align: center;
|
}
|
|
.result-option {
|
width: 150px;
|
text-align: center;
|
|
:deep(.el-radio-group) {
|
display: flex;
|
justify-content: center;
|
}
|
}
|
}
|
}
|
|
.remark-section {
|
margin-bottom: 20px;
|
padding: 0 10px;
|
}
|
|
.signature-section {
|
.signature-table {
|
width: 100%;
|
border-collapse: collapse;
|
border: 1px solid #dcdfe6;
|
|
td {
|
border: 1px solid #dcdfe6;
|
padding: 10px;
|
font-size: 14px;
|
}
|
|
.label {
|
background-color: #f5f7fa;
|
width: 80px;
|
text-align: center;
|
font-weight: 500;
|
}
|
|
.value {
|
background-color: #fff;
|
min-width: 150px;
|
}
|
}
|
}
|
}
|
|
.dialog-footer {
|
display: flex;
|
justify-content: flex-end;
|
gap: 10px;
|
}
|
</style>
|