指定变更类型

This commit is contained in:
2025-11-27 18:22:28 +08:00
parent 19d4dd64d4
commit 24344e380a

View File

@@ -16,15 +16,32 @@
<el-radio label="out">取出</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="变更类型" prop="source_type">
<el-select v-model="form.source_type" placeholder="请选择变更类型" style="width: 100%;">
<el-option
v-for="item in availableSourceTypes"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="变动数量" prop="change_amount">
<el-input-group class="stock-adjustment-input-group">
<el-input-number
v-model="form.change_amount"
:min="1"
:precision="0"
:step="1000"
v-model="displayAmount"
:min="computedMin"
:precision="computedPrecision"
:step="computedStep"
controls-position="right"
style="width: 100%;"
></el-input-number>
<template #append>
<el-select v-model="unit" placeholder="单位" style="width: 80px;">
<el-option label="g" value="g"></el-option>
<el-option label="kg" value="kg"></el-option>
</el-select>
</template>
</el-input-group>
</el-form-item>
<el-form-item label="备注" prop="remarks">
<el-input v-model="form.remarks" type="textarea" :rows="2"></el-input>
@@ -40,9 +57,10 @@
</template>
<script>
import {ref, reactive, computed, watch} from 'vue';
import {ElMessage} from 'element-plus';
import {InventoryApi} from '../../api/inventory';
import { ref, reactive, computed, watch } from 'vue';
import { ElMessage } from 'element-plus';
import { InventoryApi } from '../../api/inventory';
import { StockLogSourceType } from '../../enums'; // 导入 StockLogSourceType
export default {
name: 'StockAdjustmentDialog',
@@ -55,22 +73,20 @@ export default {
type: Object,
default: () => ({}),
},
operationType: {
type: String,
default: 'in', // 'in' or 'out'
},
},
emits: ['update:visible', 'success'],
setup(props, {emit}) {
setup(props, { emit }) {
const formRef = ref(null);
const dialogVisible = computed({
get: () => props.visible,
set: (val) => emit('update:visible', val),
});
const unit = ref('g'); // 默认单位为克
const form = reactive({
operationType: props.operationType,
change_amount: 1000,
operationType: 'in', // 默认存入
source_type: StockLogSourceType.MANUAL, // 默认变更类型
change_amount: 1000, // 内部始终以克为单位
remarks: '',
});
@@ -78,25 +94,94 @@ export default {
return form.operationType === 'in' ? '存入库存' : '取出库存';
});
watch(() => props.operationType, (newType) => {
form.operationType = newType;
// 定义存入和取出对应的变更类型
const inSourceTypes = [
{ value: StockLogSourceType.PURCHASE, label: '采购入库' },
{ value: StockLogSourceType.FERMENT_END, label: '发酵入库' },
{ value: StockLogSourceType.MANUAL, label: '手动盘点' },
];
const outSourceTypes = [
{ value: StockLogSourceType.FEEDING, label: '饲喂出库' },
{ value: StockLogSourceType.DETERIORATE, label: '变质出库' },
{ value: StockLogSourceType.SALE, label: '售卖出库' },
{ value: StockLogSourceType.MISCELLANEOUS, label: '杂用领取' },
{ value: StockLogSourceType.FERMENT_START, label: '发酵出库' },
{ value: StockLogSourceType.MANUAL, label: '手动盘点' },
];
// 根据操作类型动态计算可用的变更类型
const availableSourceTypes = computed(() => {
const types = form.operationType === 'in' ? inSourceTypes : outSourceTypes;
// 如果当前选中的 source_type 不在新的可用列表中,则重置为第一个可用类型或 MANUAL
if (!types.some(item => item.value === form.source_type)) {
form.source_type = types.length > 0 ? types[0].value : StockLogSourceType.MANUAL;
}
return types;
});
// 计算属性:用于 el-input-number 的显示值和输入值转换
const displayAmount = computed({
get() {
if (unit.value === 'kg') {
return form.change_amount / 1000;
}
return form.change_amount;
},
set(val) {
if (unit.value === 'kg') {
form.change_amount = val * 1000;
} else {
form.change_amount = val;
}
},
});
// 计算属性el-input-number 的步长
const computedStep = computed(() => {
return unit.value === 'kg' ? 0.1 : 100;
});
// 计算属性el-input-number 的精度
const computedPrecision = computed(() => {
return unit.value === 'kg' ? 2 : 0;
});
// 计算属性el-input-number 的最小值
const computedMin = computed(() => {
return unit.value === 'kg' ? 0.001 : 1;
});
watch(() => props.visible, (newVal) => {
if (newVal) {
// 弹窗打开时重置表单
form.change_amount = 1000;
// 弹窗打开时重置表单和单位
form.change_amount = 1000; // 默认1000克
form.remarks = '';
form.operationType = props.operationType;
form.operationType = 'in'; // 默认存入
form.source_type = StockLogSourceType.MANUAL; // 默认变更类型
unit.value = 'g'; // 默认单位为克
formRef.value?.clearValidate();
}
});
const rules = {
source_type: [
{ required: true, message: '请选择变更类型', trigger: 'change' },
],
change_amount: [
{required: true, message: '请输入变动数量', trigger: 'blur'},
{type: 'number', message: '数量必须为数字', trigger: 'blur'},
{min: 1, message: '数量必须大于0', trigger: 'blur'},
{
required: true,
message: '请输入变动数量',
trigger: 'blur',
// 验证器直接作用于内部的 form.change_amount (克)
validator: (rule, value, callback) => {
if (form.change_amount === null || form.change_amount === undefined || form.change_amount <= 0) {
callback(new Error('数量必须大于0'));
} else {
callback();
}
},
},
],
};
@@ -104,10 +189,10 @@ export default {
try {
await formRef.value.validate();
let finalChangeAmount = form.change_amount;
let finalChangeAmount = form.change_amount; // form.change_amount 已经是克
if (form.operationType === 'out') {
finalChangeAmount = -finalChangeAmount;
// 检查是否超出库存
// 检查是否超出库存 (props.rawMaterial.stock 也是克)
if (props.rawMaterial.stock + finalChangeAmount < 0) {
ElMessage.error('取出数量不能大于当前库存!');
return;
@@ -117,6 +202,7 @@ export default {
const data = {
raw_material_id: props.rawMaterial.raw_material_id,
change_amount: finalChangeAmount,
source_type: form.source_type, // 添加 source_type
remarks: form.remarks,
};
@@ -144,11 +230,39 @@ export default {
rules,
handleSubmit,
handleClose,
unit,
displayAmount,
computedStep,
computedPrecision,
computedMin,
availableSourceTypes, // 暴露给模板
};
},
};
</script>
<style scoped>
/* 可以添加一些样式 */
/* 确保 el-input-group 的 append 部分正确显示 */
.stock-adjustment-input-group {
display: flex;
width: 100%; /* 确保 input-group 占据可用宽度 */
}
/* 针对 el-input-number 内部的输入框 */
.stock-adjustment-input-group :deep(.el-input-number) {
flex: 1; /* 让 el-input-number 占据剩余空间 */
}
/* 针对 el-input-group__append 内部的 el-select */
.stock-adjustment-input-group :deep(.el-input-group__append) {
background-color: var(--el-fill-color-blank);
padding: 0;
/* 确保 select 宽度固定 */
width: 80px;
}
.stock-adjustment-input-group :deep(.el-input-group__append .el-select) {
margin: 0;
width: 100%; /* 让 select 填充 append 区域 */
}
</style>