| | |
| | | <el-form-item :label="'煤种' + (index + 1)"> |
| | | <div class="input-wrapper"> |
| | | <el-input |
| | | v-model="item.name" |
| | | v-model="item.coalId" |
| | | v-show="item.type !== '已有煤'" |
| | | placeholder="请输入" |
| | | style="width: 100%" |
| | | /> |
| | | |
| | | |
| | | <el-select |
| | | v-model="item.name" |
| | | v-model="item.coalId" |
| | | v-show="item.type === '已有煤'" |
| | | placeholder="请选择" |
| | | style="width: 100%" |
| | | @change="handleCoalSelectChange(index, item.coalId)" |
| | | > |
| | | <el-option |
| | | v-for="ele in coalInfoList" |
| | | v-for="ele in infoCoals" |
| | | :key="ele.key" |
| | | :label="ele.value" |
| | | :value="ele.key" |
| | | >{{ ele.value }} |
| | | </el-option> |
| | | >{{ ele.value }} |
| | | </el-option> |
| | | </el-select> |
| | | </div> |
| | | </el-form-item> |
| | |
| | | <el-col :span="6"> |
| | | <el-form-item label="发热量"> |
| | | <el-input |
| | | v-if="item.type !== '未知煤'" |
| | | :value=" |
| | | infoCoals.find((coal) => coal.key === item.coalId) |
| | | ?.item.coalValues.find((value) => value.fieldName === '发热量')?.coalValue || '0' |
| | | " |
| | | type="number" |
| | | style="width: 100%" |
| | | :disabled="true" |
| | | > |
| | | <template v-slot:suffix> |
| | | <i style="font-style: normal">kcal</i> |
| | | </template> |
| | | </el-input> |
| | | <el-input |
| | | v-else |
| | | v-model="item.cv" |
| | | type="number" |
| | | placeholder="请输入发热量" |
| | | style="width: 100%" |
| | | > |
| | | <template v-slot:suffix> |
| | | <i style="font-style: normal">kcal/kg</i> |
| | | <i style="font-style: normal">kcal</i> |
| | | </template> |
| | | </el-input> |
| | | </el-form-item> |
| | |
| | | <el-col :span="6"> |
| | | <el-form-item label="价格"> |
| | | <el-input |
| | | v-if="item.type !== '未知煤'" |
| | | |
| | | :value=" |
| | | infoCoals.find((coal) => coal.key === item.coalId) |
| | | ?.item.priceExcludingTax || 0 |
| | | " |
| | | type="number" |
| | | style="width: 100%" |
| | | :disabled="item.type === '已有煤'" |
| | | > |
| | | <template v-slot:suffix> |
| | | <i style="font-style: normal">元/吨</i> |
| | | </template> |
| | | </el-input> |
| | | <el-input |
| | | v-else |
| | | v-model="item.price" |
| | | placeholder="请输入价格" |
| | | type="number" |
| | | style="width: 100%" |
| | | > |
| | |
| | | <el-col :span="6"> |
| | | <el-form-item label="硫分"> |
| | | <el-input |
| | | v-if="item.type !== '未知煤'" |
| | | :disabled="item.type === '已有煤'" |
| | | v-model="item.sulfur" |
| | | :value=" |
| | | infoCoals.find((coal) => coal.key === item.coalId) |
| | | ?.item.coalValues.find((value) => value.fieldName === '硫分')?.coalValue || '0' |
| | | " |
| | | type="number" |
| | | placeholder="可选" |
| | | style="width: 100%" |
| | | > |
| | | <template v-slot:suffix> |
| | | <i style="font-style: normal">%</i> |
| | | </template> |
| | | </el-input> |
| | | <el-input |
| | | v-else |
| | | v-model="item.sulfur" |
| | | type="number" |
| | | placeholder="可选" |
| | |
| | | <el-col :span="6"> |
| | | <el-form-item label="灰分"> |
| | | <el-input |
| | | v-if="item.type !== '未知煤'" |
| | | :disabled="item.type === '已有煤'" |
| | | v-model="item.ash" |
| | | :value=" |
| | | infoCoals.find((coal) => coal.key === item.coalId) |
| | | ?.item.coalValues.find((value) => value.fieldName === '灰分')?.coalValue || '0' |
| | | " |
| | | type="number" |
| | | placeholder="可选" |
| | | style="width: 100%" |
| | | > |
| | | <template v-slot:suffix> |
| | | <i style="font-style: normal">%</i> |
| | | </template> |
| | | </el-input> |
| | | <el-input |
| | | v-else |
| | | v-model="item.ash" |
| | | type="number" |
| | | placeholder="可选" |
| | |
| | | <el-col :span="6"> |
| | | <el-form-item label="水分"> |
| | | <el-input |
| | | v-if="item.type !== '未知煤'" |
| | | :disabled="item.type === '已有煤'" |
| | | v-model="item.moisture" |
| | | :value=" |
| | | infoCoals.find((coal) => coal.key === item.coalId) |
| | | ?.item.coalValues.find((value) => value.fieldName === '水分')?.coalValue || '0' |
| | | " |
| | | type="number" |
| | | placeholder="可选" |
| | | style="width: 100%" |
| | | > |
| | | <template v-slot:suffix> |
| | | <i style="font-style: normal">%</i> |
| | | </template> |
| | | </el-input> |
| | | <el-input |
| | | v-else |
| | | v-model="item.moisture" |
| | | type="number" |
| | | placeholder="可选" |
| | |
| | | style="width: 100%" |
| | | > |
| | | <template v-slot:suffix> |
| | | <i style="font-style: normal">kcal/kg</i> |
| | | <i style="font-style: normal">kcal</i> |
| | | </template> |
| | | </el-input> |
| | | </el-form-item> |
| | |
| | | </div> |
| | | <div class="footer"> |
| | | <el-button @click="cancel">重置</el-button> |
| | | <el-button type="primary" @click="submitForm" plain> |
| | | 查看计算结果 |
| | | <el-button type="primary" @click="addWarehoused" plain> |
| | | 添加至待入库 |
| | | </el-button> |
| | | <el-button type="primary" @click="submitForm">计算最优配比</el-button> |
| | | </div> |
| | |
| | | class="result-table" |
| | | style="width: 100%" |
| | | > |
| | | <el-table-column prop="name" label="煤种" min-width="80" /> |
| | | <el-table-column prop="coalId" label="煤种" min-width="80"> |
| | | <template #default="scope"> |
| | | {{ |
| | | infoCoals.find((coal) => coal.key === scope.row.coalId) |
| | | ?.value || |
| | | "" || |
| | | matchCoalName(scope.row.coalId) |
| | | }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="ratio" label="配比" min-width="80"> |
| | | <template #default="scope"> {{ scope.row.ratio }}% </template> |
| | | </el-table-column> |
| | | <el-table-column prop="tonnage" label="吨数" min-width="80"> |
| | | <el-table-column prop="quantity" label="吨数" min-width="80"> |
| | | <template #default="scope"> |
| | | {{ scope.row.tonnage }}吨 |
| | | {{ scope.row.quantity }}吨 |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="scoops" label="铲数" min-width="80"> |
| | |
| | | <div class="prop-item"> |
| | | <span class="prop-label">发热量:</span> |
| | | <span class="prop-value" |
| | | >{{ result.optimal.props.cv.toFixed(2) }} kcal/kg</span |
| | | >{{ result.optimal.props.cv.toFixed(2) }} kcal</span |
| | | > |
| | | </div> |
| | | <div class="prop-item"> |
| | |
| | | >{{ result.optimal.props.cost.toFixed(2) }} 元/吨</span |
| | | > |
| | | </div> |
| | | <div class="prop-item"> |
| | | <span class="prop-label">生成:</span> |
| | | <el-autocomplete |
| | | v-model="result.optimal.props.createCoal" |
| | | :fetch-suggestions="querySearch" |
| | | clearable |
| | | size="small" |
| | | class="inline-input red-border" |
| | | style="width: 180px; min-height: 24px !important" |
| | | placeholder="请输入生成煤种" |
| | | @blur="handleSelect($event)" |
| | | @select="handleSelect($event)" |
| | | /> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | |
| | | class="alt-table" |
| | | style="width: 100%" |
| | | > |
| | | <el-table-column prop="name" label="煤种" min-width="80" /> |
| | | <el-table-column prop="coalId" label="煤种" min-width="80"> |
| | | <template #default="scope"> |
| | | {{ |
| | | infoCoals.find((coal) => coal.key === scope.row.coalId) |
| | | ?.value || |
| | | "" || |
| | | matchCoalName(scope.row.coalId) |
| | | }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="ratio" label="配比" min-width="80"> |
| | | <template #default="scope"> |
| | | {{ scope.row.ratio }}% |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="tonnage" label="吨数" min-width="80"> |
| | | <el-table-column prop="quantity" label="吨数" min-width="80"> |
| | | <template #default="scope"> |
| | | {{ scope.row.tonnage }}吨 |
| | | {{ scope.row.quantity }}吨 |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="scoops" label="铲数" min-width="80"> |
| | |
| | | </div> |
| | | |
| | | <div class="alt-props"> |
| | | <span>发热量: {{ alt.props.cv.toFixed(2) }} kcal/kg,</span> |
| | | <span>发热量: {{ alt.props.cv.toFixed(2) }} kcal,</span> |
| | | <span>硫分: {{ alt.props.sulfur.toFixed(2) }}%,</span> |
| | | <span>灰分: {{ alt.props.ash.toFixed(2) }}%,</span> |
| | | <span>水分: {{ alt.props.moisture.toFixed(2) }}%,</span> |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { reactive, toRefs, nextTick, onMounted } from "vue"; |
| | | import { reactive, toRefs, nextTick, onMounted, ref } from "vue"; |
| | | import { ElMessage, ElMessageBox } from "element-plus"; |
| | | import { getCoalInfoList } from "@/api/procureMent"; // 假设有一个API获取煤种信息 |
| | | import { getCoalBlendingList,addPendingInventory } from "@/api/calculator/index.js"; |
| | | |
| | | const data = reactive({ |
| | | formInline: { |
| | |
| | | coalForms: [ |
| | | { |
| | | type: "未知煤", |
| | | name: "煤A", |
| | | coalId: "煤A", |
| | | cv: 6200, // 发热量 |
| | | price: 450, // 价格 |
| | | sulfur: 0.6, // 硫分 |
| | |
| | | }, |
| | | { |
| | | type: "未知煤", |
| | | name: "煤B", |
| | | coalId: "煤B", |
| | | cv: 5800, |
| | | price: 380, |
| | | sulfur: 1.0, |
| | |
| | | }, |
| | | { |
| | | type: "未知煤", |
| | | name: "煤C", |
| | | coalId: "煤C", |
| | | cv: 5400, |
| | | price: 320, |
| | | sulfur: 1.4, |
| | |
| | | optimal: null, |
| | | alternatives: [], |
| | | error: null, |
| | | createCoal: null, |
| | | }, |
| | | }); |
| | | const handleCoalSelectChange = (index, coalId) => { |
| | | const selectedCoal = infoCoals.value.find(item => item.key === coalId); |
| | | |
| | | if (!selectedCoal?.item?.coalValues) { |
| | | console.warn('未找到选中的煤种数据或数据格式不正确'); |
| | | return; |
| | | } |
| | | |
| | | // 获取煤质参数的通用函数 |
| | | const getCoalValue = (fieldName) => { |
| | | return selectedCoal.item.coalValues.find( |
| | | value => value.fieldName === fieldName |
| | | )?.coalValue || 0; |
| | | }; |
| | | |
| | | // 批量更新表单数据 |
| | | Object.assign(data.coalForms[index], { |
| | | price: selectedCoal.item.priceExcludingTax || 0, |
| | | cv: getCoalValue("发热量"), |
| | | sulfur: getCoalValue("硫分"), |
| | | ash: getCoalValue("灰分"), |
| | | moisture: getCoalValue("水分") |
| | | }); |
| | | }; |
| | | const coalInfoList = ref([]); |
| | | // onMounted |
| | | onMounted(async () => { |
| | | let result = await getCoalInfoList(); |
| | | if (result.code === 200) { |
| | | result.data.forEach((item) => { |
| | | let obj = { |
| | | // 获取煤种信息 |
| | | const getCoalInfo = async () => { |
| | | try { |
| | | const result = await getCoalInfoList(); |
| | | if (result.code === 200) { |
| | | coalInfoList.value = result.data.map(item => ({ |
| | | value: item.coal, |
| | | key: item.id, |
| | | }; |
| | | coalInfoList.value.push(obj); |
| | | }); |
| | | } else { |
| | | })); |
| | | } else { |
| | | ElMessage.error("获取煤种信息失败,请稍后重试"); |
| | | } |
| | | } catch (error) { |
| | | ElMessage.error("获取煤种信息失败,请稍后重试"); |
| | | } |
| | | }; |
| | | // 表格展示用:匹配煤种名称 |
| | | const matchCoalName = (name) => { |
| | | if (!name || !coalInfoList.value?.length) return name; |
| | | |
| | | // 优先按 key 匹配,再按 value 匹配 |
| | | const foundCoal = coalInfoList.value.find(item => |
| | | String(item.key) === String(name) || item.value === name |
| | | ); |
| | | |
| | | return foundCoal?.value || name; |
| | | }; |
| | | // 自动补全搜索 |
| | | const querySearch = (q, cb) => { |
| | | const results = q |
| | | ? coalInfoList.value.filter(c => c.value.includes(q)) |
| | | : coalInfoList.value; |
| | | cb(results); |
| | | }; |
| | | |
| | | // 选择/失焦处理 |
| | | const handleSelect = (item) => { |
| | | const val = item.value || item.target?.value || ""; |
| | | const found = coalInfoList.value.find(c => c.value === val || c.key === val); |
| | | |
| | | result.value.optimal.props.createCoal = found ? found.key : val; |
| | | result.value.optimal.props.coalId = found?.key || null; |
| | | |
| | | // 更新显示名称 |
| | | const matchedName = matchCoalName(result.value.optimal.props.createCoal); |
| | | if (matchedName !== result.value.optimal.props.createCoal) { |
| | | result.value.optimal.props.createCoal = matchedName; |
| | | } |
| | | }; |
| | | onMounted(async () => { |
| | | getCoalInfo(); |
| | | geInfoCoals(); |
| | | }); |
| | | const infoCoals = ref([]); |
| | | // 初始化煤种字段 |
| | | const geInfoCoals = async () => { |
| | | try { |
| | | const res = await getCoalBlendingList(); |
| | | if (res.code === 200) { |
| | | console.log("获取煤种信息成功", res.data); |
| | | infoCoals.value = res.data.map(item => ({ |
| | | value: item.supplierCoal, |
| | | key: item.coalId, |
| | | item, |
| | | })); |
| | | } else { |
| | | ElMessage.error("获取煤种信息失败,请稍后重试"); |
| | | } |
| | | } catch (error) { |
| | | ElMessage.error("获取煤种信息失败,请稍后重试"); |
| | | } |
| | | }; |
| | | // 线性规划求解函数 |
| | | const solveBlend = (coals, constraints) => { |
| | | // 数据验证 |
| | | if (constraints.maxSulfur) { |
| | | let missingSulfur = coals.some((coal) => !coal.sulfur && coal.sulfur !== 0); |
| | | if (missingSulfur) { |
| | | throw new Error( |
| | | "如果设置了最大硫分约束,则所有参与配比的煤种都必须提供硫分数据。" |
| | | ); |
| | | const validateConstraint = (constraintValue, fieldName, coalField) => { |
| | | if (constraintValue && coals.some(coal => !coal[coalField] && coal[coalField] !== 0)) { |
| | | throw new Error(`如果设置了${fieldName}约束,则所有煤种都必须提供${fieldName}数据。`); |
| | | } |
| | | } |
| | | if (constraints.maxAsh) { |
| | | let missingAsh = coals.some((coal) => !coal.ash && coal.ash !== 0); |
| | | if (missingAsh) { |
| | | throw new Error("如果设置了最大灰分约束,则所有煤种都必须提供灰分数据。"); |
| | | } |
| | | } |
| | | if (constraints.maxMoisture) { |
| | | let missingMoisture = coals.some( |
| | | (coal) => !coal.moisture && coal.moisture !== 0 |
| | | ); |
| | | if (missingMoisture) { |
| | | throw new Error("如果设置了最大水分约束,则所有煤种都必须提供水分数据。"); |
| | | } |
| | | } |
| | | }; |
| | | |
| | | // 简单的线性规划求解(最小化成本) |
| | | // 这里使用简化的算法,实际项目中可以集成更专业的求解器 |
| | | validateConstraint(constraints.maxSulfur, '最大硫分', 'sulfur'); |
| | | validateConstraint(constraints.maxAsh, '最大灰分', 'ash'); |
| | | validateConstraint(constraints.maxMoisture, '最大水分', 'moisture'); |
| | | |
| | | try { |
| | | // 模拟求解过程 |
| | | let totalCoals = coals.length; |
| | | let ratios = new Array(totalCoals).fill(0); |
| | | |
| | | // 简单的等权重分配作为初始解 |
| | | let avgRatio = 1 / totalCoals; |
| | | ratios = ratios.map(() => avgRatio); |
| | | let ratios = new Array(coals.length).fill(1 / coals.length); |
| | | |
| | | // 验证约束条件 |
| | | // 验证约束条件并调整配比 |
| | | let blendProps = calcBlendProps(coals, ratios); |
| | | |
| | | if (constraints.minCalorific && blendProps.cv < constraints.minCalorific) { |
| | | // 调整配比以满足最低发热量 |
| | | let highCvCoals = coals |
| | | // 优先使用高发热量煤种 |
| | | const sortedCoals = coals |
| | | .map((coal, i) => ({ index: i, cv: coal.cv })) |
| | | .sort((a, b) => b.cv - a.cv); |
| | | |
| | | ratios = new Array(totalCoals).fill(0); |
| | | ratios[highCvCoals[0].index] = 0.6; |
| | | ratios[highCvCoals[1] ? highCvCoals[1].index : 0] = 0.4; |
| | | ratios = new Array(coals.length).fill(0); |
| | | ratios[sortedCoals[0].index] = 0.6; |
| | | if (sortedCoals[1]) ratios[sortedCoals[1].index] = 0.4; |
| | | } |
| | | |
| | | return ratios; |
| | |
| | | return coals |
| | | .map((coal, i) => { |
| | | if (ratios[i] < 1e-6) return null; |
| | | let tonnage = ratios[i] * total; |
| | | let scoops = tonnage / scoop; |
| | | let quantity = ratios[i] * total; |
| | | let scoops = quantity / scoop; |
| | | return { |
| | | name: coal.name, |
| | | coalId: coal.coalId, |
| | | ratio: (ratios[i] * 100).toFixed(2), |
| | | tonnage: tonnage.toFixed(1), |
| | | quantity: quantity.toFixed(1), |
| | | scoops: scoops.toFixed(1), |
| | | }; |
| | | }) |
| | |
| | | data.coalForms = [ |
| | | { |
| | | type: "未知煤", |
| | | name: "煤A", |
| | | coalId: "煤A", |
| | | cv: 6200, |
| | | price: 450, |
| | | sulfur: 0.6, |
| | |
| | | }, |
| | | { |
| | | type: "未知煤", |
| | | name: "煤B", |
| | | coalId: "煤B", |
| | | cv: 5800, |
| | | price: 380, |
| | | sulfur: 1.0, |
| | |
| | | }, |
| | | { |
| | | type: "未知煤", |
| | | name: "煤C", |
| | | coalId: "煤C", |
| | | cv: 5400, |
| | | price: 320, |
| | | sulfur: 1.4, |
| | |
| | | }; |
| | | ElMessage.success("表单已重置"); |
| | | }; |
| | | const addWarehoused = () => { |
| | | // 验证前置条件 |
| | | const validationChecks = [ |
| | | { condition: !result.value, message: "请先计算最优配比后再添加至待入库" }, |
| | | { condition: !result.value.optimal, message: "请先计算最优配比" }, |
| | | { condition: !result.value.optimal.props.createCoal, message: "请先选择生成煤种" } |
| | | ]; |
| | | |
| | | for (const check of validationChecks) { |
| | | if (check.condition) { |
| | | ElMessage.error(check.message); |
| | | return; |
| | | } |
| | | } |
| | | |
| | | // 验证配比中的煤种 |
| | | const coals = result.value.optimal.instructions.map(item => item.coalId); |
| | | const allCoalsFound = coals.every(coalId => |
| | | coalInfoList.value.some(item => item.key === coalId) |
| | | ); |
| | | |
| | | if (!allCoalsFound) { |
| | | ElMessage.error("配比中包含未知煤种,请先添加至煤种列表"); |
| | | return; |
| | | } |
| | | |
| | | // 验证生成煤种 |
| | | const createCoalExists = coalInfoList.value.some( |
| | | item => item.key === result.value.optimal.props.coalId |
| | | ); |
| | | |
| | | if (!createCoalExists) { |
| | | ElMessage.warning("生成煤种是未知煤种,无法添加至待入库"); |
| | | return; |
| | | } |
| | | |
| | | // 准备数据 |
| | | const optimalData = result.value.optimal; |
| | | optimalData.props.totalTonnage = formInline.value.totalTonnage; |
| | | optimalData.props.cost = parseFloat(optimalData.props.cost.toFixed(2)); |
| | | |
| | | // 添加官方ID |
| | | optimalData.instructions.forEach(item => { |
| | | item.officialId = item.coalId; |
| | | }); |
| | | |
| | | const params = { |
| | | fieldsResultList: optimalData.props, |
| | | coalResultList: optimalData.instructions, |
| | | }; |
| | | |
| | | addPendingInventory(params).then(res => { |
| | | if (res.code === 200 && res.data === true) { |
| | | ElMessage.success("添加至待入库成功"); |
| | | } |
| | | }); |
| | | }; |
| | | const submitForm = () => { |
| | | console.log(coalForms.value) |
| | | // 数据验证 |
| | | let validCoals = coalForms.value.filter( |
| | | (coal) => coal.name && coal.cv && coal.price |
| | | const validCoals = coalForms.value.filter( |
| | | coal => coal.coalId && coal.cv && coal.price |
| | | ); |
| | | |
| | | if (validCoals.length < 2) { |
| | |
| | | |
| | | try { |
| | | // 求解最优配比 |
| | | let ratios = solveBlend(validCoals, constraints.value); |
| | | const ratios = solveBlend(validCoals, constraints.value); |
| | | if (!ratios) { |
| | | data.result.error = "无可行解,请检查约束条件或煤种数据"; |
| | | data.result.show = true; |
| | |
| | | } |
| | | |
| | | // 计算结果 |
| | | let props = calcBlendProps(validCoals, ratios); |
| | | let instructions = genInstructions( |
| | | const props = calcBlendProps(validCoals, ratios); |
| | | const instructions = genInstructions( |
| | | validCoals, |
| | | ratios, |
| | | formInline.value.totalTonnage, |
| | |
| | | |
| | | data.result = { |
| | | show: true, |
| | | optimal: { |
| | | ratios, |
| | | props, |
| | | instructions, |
| | | }, |
| | | optimal: { ratios, props, instructions }, |
| | | alternatives: [], |
| | | error: null, |
| | | }; |
| | |
| | | |
| | | const generateAlternatives = (coals) => { |
| | | const altList = [ |
| | | { |
| | | desc: "发热量降1%", |
| | | mod: { minCalorific: constraints.value.minCalorific * 0.99 }, |
| | | }, |
| | | { |
| | | desc: "发热量降2%", |
| | | mod: { minCalorific: constraints.value.minCalorific * 0.98 }, |
| | | }, |
| | | { |
| | | desc: "硫分升1%", |
| | | mod: { maxSulfur: constraints.value.maxSulfur * 1.01 }, |
| | | }, |
| | | { |
| | | desc: "硫分升2%", |
| | | mod: { maxSulfur: constraints.value.maxSulfur * 1.02 }, |
| | | }, |
| | | { |
| | | desc: "发热量降0.5%且硫分升0.5%", |
| | | { desc: "发热量降1%", mod: { minCalorific: constraints.value.minCalorific * 0.99 } }, |
| | | { desc: "发热量降2%", mod: { minCalorific: constraints.value.minCalorific * 0.98 } }, |
| | | { desc: "硫分升1%", mod: { maxSulfur: constraints.value.maxSulfur * 1.01 } }, |
| | | { desc: "硫分升2%", mod: { maxSulfur: constraints.value.maxSulfur * 1.02 } }, |
| | | { |
| | | desc: "发热量降0.5%且硫分升0.5%", |
| | | mod: { |
| | | minCalorific: constraints.value.minCalorific * 0.995, |
| | | maxSulfur: constraints.value.maxSulfur * 1.005, |
| | | }, |
| | | } |
| | | }, |
| | | ]; |
| | | |
| | | data.result.alternatives = []; |
| | | |
| | | for (let alt of altList) { |
| | | data.result.alternatives = altList.reduce((alternatives, alt) => { |
| | | try { |
| | | let altConstraints = Object.assign({}, constraints.value, alt.mod); |
| | | let altRatios = solveBlend(coals, altConstraints); |
| | | if (!altRatios) continue; |
| | | const altConstraints = { ...constraints.value, ...alt.mod }; |
| | | const altRatios = solveBlend(coals, altConstraints); |
| | | |
| | | if (altRatios) { |
| | | const altProps = calcBlendProps(coals, altRatios); |
| | | const altInstructions = genInstructions( |
| | | coals, altRatios, formInline.value.totalTonnage, formInline.value.scoopWeight |
| | | ); |
| | | |
| | | let altProps = calcBlendProps(coals, altRatios); |
| | | let altInstructions = genInstructions( |
| | | coals, |
| | | altRatios, |
| | | formInline.value.totalTonnage, |
| | | formInline.value.scoopWeight |
| | | ); |
| | | |
| | | data.result.alternatives.push({ |
| | | desc: alt.desc, |
| | | ratios: altRatios, |
| | | props: altProps, |
| | | instructions: altInstructions, |
| | | }); |
| | | alternatives.push({ |
| | | desc: alt.desc, |
| | | ratios: altRatios, |
| | | props: altProps, |
| | | instructions: altInstructions, |
| | | }); |
| | | } |
| | | } catch (error) { |
| | | console.warn(`备选方案 ${alt.desc} 计算失败:`, error); |
| | | } |
| | | } |
| | | return alternatives; |
| | | }, []); |
| | | }; |
| | | |
| | | const { formInline, constraints, coalForms, result } = toRefs(data); |
| | |
| | | return; |
| | | } |
| | | |
| | | // 如果当前数组长度大于所需数量,截断 |
| | | // 截断多余的或填充不足的煤种 |
| | | if (coalForms.value.length > num) { |
| | | coalForms.value = coalForms.value.slice(0, num); |
| | | return; |
| | | } |
| | | |
| | | // 否则,填充新的空对象 |
| | | while (coalForms.value.length < num) { |
| | | coalForms.value.push({ |
| | | type: "未知煤", |
| | | name: `煤${String.fromCharCode(65 + coalForms.value.length)}`, |
| | | cv: 0, |
| | | price: 0, |
| | | sulfur: "", |
| | | ash: "", |
| | | moisture: "", |
| | | }); |
| | | } else { |
| | | while (coalForms.value.length < num) { |
| | | coalForms.value.push({ |
| | | type: "未知煤", |
| | | coalId: `煤${String.fromCharCode(65 + coalForms.value.length)}`, |
| | | cv: 0, |
| | | price: 0, |
| | | sulfur: "", |
| | | ash: "", |
| | | moisture: "", |
| | | }); |
| | | } |
| | | } |
| | | }; |
| | | |
| | | // 处理煤种类型变化 |
| | | const handleCoalTypeChange = (index) => { |
| | | // 当煤种类型改变时,清空煤种名称,避免数据混乱 |
| | | coalForms.value[index].name = ""; |
| | | coalForms.value[index].coalId = ""; |
| | | }; |
| | | </script> |
| | | |
| | | <style scoped> |
| | | <style scoped lang="scss"> |
| | | .view { |
| | | display: flex; |
| | | gap: 10px; |
| | |
| | | background: #f5f7fa; |
| | | border-radius: 4px; |
| | | font-size: 13px; |
| | | align-items: center; |
| | | } |
| | | |
| | | .prop-label { |
| | |
| | | padding: 4px 8px; |
| | | } |
| | | } |
| | | :deep(.el-input__wrapper) { |
| | | min-height: 24px !important; |
| | | } |
| | | :deep(.el-input__inner) { |
| | | min-height: 24px !important; |
| | | } |
| | | </style> |