<template>
|
<n-modal
|
:show="visible"
|
@update:show="(value) => emit('update:visible', value)"
|
title="🔧 一键批量校准"
|
preset="card"
|
size="large"
|
:style="bodyStyle"
|
>
|
<n-grid :cols="2" :x-gap="12" :y-gap="12">
|
<n-form-item-gi label="校准日期" required>
|
<n-date-picker v-model:value="form.calibDate" type="date" />
|
</n-form-item-gi>
|
<n-form-item-gi label="统一备注">
|
<n-input v-model:value="form.note" placeholder="批量校准备注(可选)" />
|
</n-form-item-gi>
|
</n-grid>
|
<div>
|
<div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px;">
|
<label class="form-label">选择的盒子</label>
|
<n-checkbox v-model:checked="form.useStandardWeight">
|
全部填入标准重量
|
</n-checkbox>
|
</div>
|
<div class="batch-cali-list">
|
<div v-for="box in selectedRows" :key="box.id" class="batch-cali-item">
|
<div class="box-info">
|
<div class="box-name">{{ box.location }} · {{ box.name }} · {{ box.code }}</div>
|
</div>
|
<div style="display: flex; align-items: center;">
|
<n-input
|
v-model:value="box.actualWeight"
|
type="number"
|
placeholder="输入实际重量"
|
style="width: 120px;"
|
/>
|
<span style="margin-left: 8px; color: #666;">{{ box.unit || 'g' }}</span>
|
</div>
|
</div>
|
</div>
|
<div class="batch-cali-summary">
|
<span>共 <strong>{{ selectedRows.length }}</strong> 个盒子</span>
|
</div>
|
</div>
|
<template #footer>
|
<div class="modal-footer">
|
<span class="modal-hint">校准后自动更新下次校准日期</span>
|
<div class="modal-footer-right">
|
<n-button @click="handleCancel">取消</n-button>
|
<n-button type="success" @click="handleSubmit">✅ 确认全部校准</n-button>
|
</div>
|
</div>
|
</template>
|
</n-modal>
|
</template>
|
|
<script setup lang="ts">
|
import { ref, reactive, watch } from 'vue';
|
import { weighingBoxApi } from '@/service/api/md/weighing-box';
|
import { useMessage } from 'naive-ui';
|
|
const props = defineProps({
|
visible: {
|
type: Boolean,
|
default: false
|
},
|
selectedRows: {
|
type: Array,
|
default: () => []
|
}
|
});
|
|
const emit = defineEmits(['update:visible', 'submitted']);
|
|
const message = useMessage();
|
|
const form = reactive({
|
calibDate: null,
|
note: '',
|
useStandardWeight: false
|
});
|
|
const bodyStyle = {
|
width: '700px'
|
};
|
|
watch(() => props.visible, (newValue) => {
|
if (newValue) {
|
form.calibDate = new Date();
|
form.note = '';
|
form.useStandardWeight = false;
|
// 为每个选中的盒子添加 actualWeight 属性
|
props.selectedRows.forEach(box => {
|
box.actualWeight = '';
|
});
|
}
|
});
|
|
// 监听 useStandardWeight 变化
|
watch(() => form.useStandardWeight, (value) => {
|
if (value) {
|
props.selectedRows.forEach(box => {
|
box.actualWeight = box.weight;
|
});
|
}
|
});
|
|
const handleCancel = () => {
|
emit('update:visible', false);
|
};
|
|
const handleSubmit = async () => {
|
try {
|
const items = props.selectedRows.map(row => ({
|
boxId: row.id,
|
actualWeight: row.actualWeight
|
}));
|
|
const response = await weighingBoxApi.batchCalibrate({
|
boxIds: props.selectedRows.map(row => row.id),
|
calibDate: form.calibDate,
|
note: form.note,
|
items: items
|
});
|
const res = response.response.data;
|
|
if (res.code === 200) {
|
message.success('批量校准成功');
|
emit('update:visible', false);
|
emit('submitted');
|
} else {
|
message.error(res.msg || '批量校准失败');
|
}
|
} catch (error) {
|
message.error('批量校准失败');
|
}
|
};
|
</script>
|
|
<style scoped>
|
/* 表单样式 */
|
.form-label {
|
font-size: 14px;
|
font-weight: 500;
|
color: #333;
|
margin-bottom: 8px;
|
}
|
|
/* 批量校准列表 */
|
.batch-cali-list {
|
max-height: 300px;
|
overflow-y: auto;
|
border: 1px solid #e5e7eb;
|
border-radius: 8px;
|
margin: 12px 0;
|
}
|
|
.batch-cali-item {
|
display: flex;
|
align-items: center;
|
padding: 12px 16px;
|
border-bottom: 1px solid #f0f0f0;
|
font-size: 14px;
|
}
|
|
.batch-cali-item:last-child {
|
border-bottom: none;
|
}
|
|
.batch-cali-item .box-info {
|
flex: 1;
|
}
|
|
.batch-cali-item .box-name {
|
color: #333;
|
margin-bottom: 4px;
|
}
|
|
.batch-cali-item .box-meta {
|
font-size: 12px;
|
color: #666;
|
}
|
|
.batch-cali-summary {
|
background: #f8f9fa;
|
border-radius: 8px;
|
padding: 12px 16px;
|
margin-top: 12px;
|
font-size: 14px;
|
color: #666;
|
}
|
|
/* 模态框底部 */
|
.modal-footer {
|
width: 100%;
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
}
|
|
.modal-hint {
|
font-size: 12px;
|
color: #999;
|
}
|
|
.modal-footer-right {
|
display: flex;
|
gap: 10px;
|
}
|
</style>
|