实现一键生成配方

This commit is contained in:
2025-11-26 22:06:12 +08:00
parent 17ae47fa68
commit 5fb1808943
3 changed files with 192 additions and 4 deletions

View File

@@ -0,0 +1,164 @@
<template>
<el-dialog
title="一键生成配方"
v-model="dialogVisible"
width="500px"
:before-close="handleCancel"
>
<el-form :model="form" ref="generateRecipeForm" label-width="100px">
<el-form-item label="生成对象" prop="selectedPigType" :rules="[{ required: true, message: '请选择生成对象', trigger: 'change' }]">
<el-select v-model="form.selectedPigType" placeholder="请选择猪品种-猪年龄阶段" style="width: 100%;">
<el-option
v-for="item in pigTypesOptions"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="生成方式" prop="selectedGenerationMethod" :rules="[{ required: true, message: '请选择生成方式', trigger: 'change' }]">
<el-select v-model="form.selectedGenerationMethod" placeholder="请选择生成方式" style="width: 100%;">
<el-option label="使用系统中所有可用的原料" value="all_raw_materials"></el-option>
</el-select>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="handleCancel">取消</el-button>
<el-button type="primary" @click="handleGenerate" :loading="loading">生成</el-button>
</span>
</template>
</el-dialog>
</template>
<script>
import { ref, reactive, watch, onMounted, computed } from 'vue';
import { ElMessage } from 'element-plus';
import { FeedApi } from '../../api/feed'; // 假设 FeedApi 包含生成配方接口
export default {
name: 'GenerateRecipeDialog',
props: {
visible: {
type: Boolean,
default: false,
},
},
emits: ['update:visible', 'success', 'cancel'],
setup(props, { emit }) {
const generateRecipeForm = ref(null);
const loading = ref(false);
const pigTypesOptions = ref([]);
const form = reactive({
selectedPigType: '',
selectedGenerationMethod: 'all_raw_materials', // 默认选中
});
// 计算属性,用于控制 dialog 的显示
const dialogVisible = computed({
get: () => props.visible,
set: (val) => emit('update:visible', val),
});
/**
* 获取猪种类数据并格式化为下拉选项
*/
const fetchPigTypes = async () => {
try {
const response = await FeedApi.getPigTypes({ page: 1, page_size: 999 }); // 调用 FeedApi 中的 getPigTypes 方法获取猪类型列表
if (response.data && response.data.list) {
pigTypesOptions.value = response.data.list.map(pigType => ({
label: `${pigType.breed_name}-${pigType.age_stage_name}`,
value: `${pigType.id}`, // 下拉框的值直接是 pigType 的 ID
}));
}
} catch (error) {
console.error('获取猪种类失败:', error);
ElMessage.error('获取猪种类失败');
}
};
/**
* 处理生成配方逻辑
*/
const handleGenerate = async () => {
if (!generateRecipeForm.value) return;
generateRecipeForm.value.validate(async (valid) => {
if (valid) {
loading.value = true;
try {
const pigTypeId = parseInt(form.selectedPigType); // 获取选中的 pigType ID
// 调用一键生成配方的接口
const response = await FeedApi.generateRecipeFromAllMaterials(pigTypeId);
if (response.data) {
ElMessage.success('配方生成成功!');
emit('success', response.data.name, response.data.description); // 传递配方名称和简介
dialogVisible.value = false; // 关闭弹窗
} else {
ElMessage.error('配方生成失败:未知错误');
}
} catch (error) {
console.error('一键生成配方失败:', error);
ElMessage.error('一键生成配方失败: ' + (error.response?.data?.message || error.message || '未知错误'));
} finally {
loading.value = false;
}
} else {
ElMessage.warning('请检查表单填写');
return false;
}
});
};
/**
* 处理取消操作
*/
const handleCancel = () => {
dialogVisible.value = false;
emit('cancel');
// 重置表单字段
if (generateRecipeForm.value) {
generateRecipeForm.value.resetFields();
}
form.selectedPigType = ''; // 手动清空,因为 resetFields 不会清空未绑定 prop 的字段
};
// 监听 visible 变化,当弹窗打开时加载数据
watch(() => props.visible, (newVal) => {
if (newVal) {
fetchPigTypes();
// 每次打开时重置表单
if (generateRecipeForm.value) {
generateRecipeForm.value.resetFields();
}
form.selectedPigType = '';
form.selectedGenerationMethod = 'all_raw_materials';
}
});
onMounted(() => {
// 首次加载时也获取一次,以防万一
// fetchPigTypes(); // 移到 watch 中,确保每次打开弹窗都刷新数据
});
return {
generateRecipeForm,
dialogVisible,
form,
pigTypesOptions,
loading,
handleGenerate,
handleCancel,
};
},
};
</script>
<style scoped>
</style>

View File

@@ -25,7 +25,7 @@
<el-table-column prop="name" label="原料名称" />
<el-table-column prop="percentage" label="占比">
<template #default="scope">
{{ (scope.row.percentage * 100).toFixed(2) }}%
{{ (scope.row.percentage * 100).toFixed(4) }}%
</template>
</el-table-column>
</el-table>
@@ -35,7 +35,7 @@
<el-table-column prop="name" label="原料名称" />
<el-table-column label="占比">
<template #default="scope">
<el-input-number v-model="scope.row.percentage" :min="0" :max="1" :step="0.01" :precision="2" @change="updateNutrientSummary"></el-input-number>
<el-input-number v-model="scope.row.percentage" :min="0" :max="1" :step="0.0001" :precision="4" @change="updateNutrientSummary"></el-input-number>
</template>
</el-table-column>
<el-table-column label="操作">

View File

@@ -9,7 +9,10 @@
<el-icon :size="20"><Refresh /></el-icon>
</el-button>
</div>
<div>
<el-button type="primary" @click="addRecipe">新增配方</el-button>
<el-button type="success" @click="openGenerateRecipeDialog">一键生成配方</el-button>
</div>
</div>
</template>
@@ -55,6 +58,13 @@
v-model:visible="detailDialogVisible"
:recipe="selectedRecipe"
/>
<!-- 一键生成配方对话框 -->
<GenerateRecipeDialog
v-model:visible="generateRecipeDialogVisible"
@success="onGenerateRecipeSuccess"
@cancel="generateRecipeDialogVisible = false"
/>
</div>
</template>
@@ -65,6 +75,7 @@ import RecipeTable from '../../components/feed/RecipeTable.vue';
import RecipeForm from '../../components/feed/RecipeForm.vue';
import RecipeDetailDialog from '../../components/feed/RecipeDetailDialog.vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import GenerateRecipeDialog from '../../components/feed/GenerateRecipeDialog.vue'; // 引入新的组件
export default {
name: 'RecipeList',
@@ -72,7 +83,8 @@ export default {
RecipeTable,
RecipeForm,
RecipeDetailDialog,
Refresh
Refresh,
GenerateRecipeDialog, // 注册新的组件
},
data() {
return {
@@ -84,6 +96,7 @@ export default {
isEdit: false,
detailDialogVisible: false,
selectedRecipe: null,
generateRecipeDialogVisible: false, // 控制一键生成配方弹窗的显示
};
},
async mounted() {
@@ -141,6 +154,17 @@ export default {
handleShowDetails(recipe) {
this.selectedRecipe = recipe;
this.detailDialogVisible = true;
},
/**
* 打开一键生成配方对话框
*/
openGenerateRecipeDialog() {
this.generateRecipeDialogVisible = true;
},
onGenerateRecipeSuccess(recipeName, recipeDescription) {
ElMessage.success(`配方 "${recipeName}" 生成成功: ${recipeDescription}`);
this.generateRecipeDialogVisible = false;
this.loadRecipes(); // 刷新配方列表
}
}
};