| | |
| | | <el-table :data="tableData" :border="border" style="width: 100%"> |
| | | <el-table-column label="煤种" min-width="120" > |
| | | <template #default="{ row, $index }" > |
| | | <el-input |
| | | v-model="row.coal" |
| | | placeholder="请输入煤种" |
| | | @input="handleInput('coal', $index, $event)" |
| | | <el-select |
| | | clearable |
| | | :model-value="getCoalNameById(row.coal) || row.coal" |
| | | placeholder="请选择煤种" |
| | | @change="(value) => handleCoalSelectChange(row, value)" |
| | | filterable |
| | | :key="`coal-select-${$index}-${weekList.length}`" |
| | | > |
| | | <el-option |
| | | v-for="(item, index) of weekList" |
| | | :key="`option-${index}-${item.key}`" |
| | | :label="item.value" |
| | | :value="item.value" |
| | | /> |
| | | </el-select> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="生产数量" min-width="120"> |
| | |
| | | @input="handleInput('laborCost', $index, $event)" |
| | | > |
| | | <template #suffix> |
| | | <i style="font-style:normal;">元</i> |
| | | <i style="font-style: normal">元</i> |
| | | </template> |
| | | </el-input> |
| | | </template> |
| | |
| | | @input="handleInput('energyConsumptionCost', $index, $event)" |
| | | > |
| | | <template #suffix> |
| | | <i style="font-style:normal;">元</i> |
| | | <i style="font-style: normal">元</i> |
| | | </template> |
| | | </el-input> |
| | | </template> |
| | |
| | | @input="handleInput('equipmentDepreciation', $index, $event)" |
| | | > |
| | | <template #suffix> |
| | | <i style="font-style:normal;">元</i> |
| | | <i style="font-style: normal">元</i> |
| | | </template> |
| | | </el-input> |
| | | </template> |
| | |
| | | @input="handleInput('purchasePrice', $index, $event)" |
| | | > |
| | | <template #suffix> |
| | | <i style="font-style:normal;">元</i> |
| | | <i style="font-style: normal">元</i> |
| | | </template> |
| | | </el-input> |
| | | </template> |
| | |
| | | <el-table-column label="总成本" min-width="120"> |
| | | <template #default="{ row, $index }"> |
| | | <el-input |
| | | disabled |
| | | v-model="row.totalCost" |
| | | placeholder="总成本" |
| | | type="number" |
| | |
| | | @input="handleInput('totalCost', $index, $event)" |
| | | > |
| | | <template #suffix> |
| | | <i style="font-style:normal;">元</i> |
| | | <i style="font-style: normal">元</i> |
| | | </template> |
| | | </el-input> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="生产人" min-width="120"> |
| | | <template #default="{ row, $index }"> |
| | | <el-input |
| | | v-model="row.producer" |
| | | placeholder="生产人" |
| | | @input="handleInput('producer', $index, $event)" |
| | | <el-select |
| | | clearable |
| | | :model-value="getUserNameById(row.producer) || row.producer" |
| | | placeholder="请选择生产人" |
| | | @change="(value) => handleUserSelectChange(row, value)" |
| | | filterable |
| | | :key="`producer-select-${$index}-${userList.length}`" |
| | | > |
| | | <el-option |
| | | v-for="(item, index) of userList" |
| | | :key="`option-${index}-${item.key}`" |
| | | :label="item.value" |
| | | :value="item.value" |
| | | /> |
| | | </el-select> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column v-if="showOperations" label="操作" width="120" fixed="right"> |
| | | <el-table-column |
| | | v-if="showOperations" |
| | | label="操作" |
| | | width="120" |
| | | fixed="right" |
| | | > |
| | | <template #default="{ $index }"> |
| | | <el-button |
| | | type="danger" |
| | |
| | | </template> |
| | | |
| | | <script setup name="ProductionDetailsTable"> |
| | | import { ref, computed, watch } from 'vue' |
| | | import { Delete } from '@element-plus/icons-vue' |
| | | |
| | | import { ref, computed, watch, onMounted, nextTick } from "vue"; |
| | | import { Delete } from "@element-plus/icons-vue"; |
| | | import { getCoalFieldList } from "@/api/basicInformation/coalQualityMaintenance"; |
| | | import { userListAll } from "@/api/publicApi"; |
| | | const props = defineProps({ |
| | | modelValue: { |
| | | type: Array, |
| | | default: () => [] |
| | | default: () => [], |
| | | }, |
| | | border: { |
| | | type: Boolean, |
| | | default: false |
| | | default: false, |
| | | }, |
| | | showOperations: { |
| | | type: Boolean, |
| | | default: true |
| | | default: true, |
| | | }, |
| | | autoCalculate: { |
| | | type: Boolean, |
| | | default: true |
| | | } |
| | | }) |
| | | default: true, |
| | | }, |
| | | }); |
| | | |
| | | const emit = defineEmits(['update:modelValue', 'input-change', 'delete-row']) |
| | | const emit = defineEmits(["update:modelValue", "input-change", "delete-row"]); |
| | | |
| | | // 使用 v-model 进行双向绑定 |
| | | const tableData = computed({ |
| | | get() { |
| | | return props.modelValue |
| | | return props.modelValue; |
| | | }, |
| | | set(value) { |
| | | emit('update:modelValue', value) |
| | | } |
| | | }) |
| | | emit("update:modelValue", value); |
| | | }, |
| | | }); |
| | | |
| | | // 处理输入变化 |
| | | const handleInput = (field, index, value) => { |
| | | const newData = [...tableData.value] |
| | | newData[index][field] = value |
| | | const newData = [...tableData.value]; |
| | | newData[index][field] = value; |
| | | |
| | | // 如果开启自动计算总成本 |
| | | if (props.autoCalculate && ['laborCost', 'energyCost', 'equipmentDepreciation', 'purchasePrice'].includes(field)) { |
| | | calculateTotalCost(newData[index]) |
| | | if ( |
| | | props.autoCalculate && |
| | | [ |
| | | "laborCost", |
| | | "energyCost", |
| | | "equipmentDepreciation", |
| | | "purchasePrice", |
| | | ].includes(field) |
| | | ) { |
| | | calculateTotalCost(newData[index]); |
| | | } |
| | | |
| | | tableData.value = newData |
| | | emit('input-change', { field, index, value, row: newData[index] }) |
| | | } |
| | | tableData.value = newData; |
| | | emit("input-change", { field, index, value, row: newData[index] }); |
| | | }; |
| | | |
| | | // 计算总成本 |
| | | const calculateTotalCost = (row) => { |
| | | const laborCost = parseFloat(row.laborCost) || 0 |
| | | const energyCost = parseFloat(row.energyCost) || 0 |
| | | const equipmentDepreciation = parseFloat(row.equipmentDepreciation) || 0 |
| | | const purchasePrice = parseFloat(row.purchasePrice) || 0 |
| | | const laborCost = parseFloat(row.laborCost) || 0; |
| | | const energyCost = parseFloat(row.energyCost) || 0; |
| | | const equipmentDepreciation = parseFloat(row.equipmentDepreciation) || 0; |
| | | const purchasePrice = parseFloat(row.purchasePrice) || 0; |
| | | |
| | | row.totalCost = (laborCost + energyCost + equipmentDepreciation + purchasePrice).toFixed(2) |
| | | } |
| | | row.totalCost = ( |
| | | laborCost + |
| | | energyCost + |
| | | equipmentDepreciation + |
| | | purchasePrice |
| | | ).toFixed(2); |
| | | }; |
| | | |
| | | // 删除行 |
| | | const handleDelete = (index) => { |
| | | const newData = [...tableData.value] |
| | | newData.splice(index, 1) |
| | | tableData.value = newData |
| | | emit('delete-row', index) |
| | | } |
| | | const newData = [...tableData.value]; |
| | | newData.splice(index, 1); |
| | | tableData.value = newData; |
| | | emit("delete-row", index); |
| | | }; |
| | | |
| | | // 处理煤种选择变化 |
| | | |
| | | // 处理煤种选择变化(新方法:名称选择转ID) |
| | | const handleCoalSelectChange = (row, selectedName) => { |
| | | // 根据选择的名称找到对应的ID |
| | | const coalItem = weekList.value.find(item => item.value === selectedName); |
| | | if (coalItem) { |
| | | row.coal = coalItem.key; // 设置为ID |
| | | } else { |
| | | row.coal = ''; // 如果没找到,清空 |
| | | } |
| | | }; |
| | | |
| | | // 根据ID获取煤种名称(用于显示) |
| | | const getCoalNameById = (id) => { |
| | | const coal = weekList.value.find(item => item.key == id); |
| | | return coal ? coal.value : id; |
| | | }; |
| | | |
| | | const weekList = ref([]); |
| | | |
| | | |
| | | // 监听表格数据变化,确保显示正确 |
| | | watch(() => props.modelValue, (newValue) => { |
| | | if (newValue && weekList.value.length > 0) { |
| | | // 当数据加载完成且weekList已获取时,确保显示正确 |
| | | } |
| | | }, { deep: true }); |
| | | |
| | | // 监听weekList变化,当下拉数据加载完成后处理显示 |
| | | watch(weekList, (newList) => { |
| | | if (newList.length > 0 && tableData.value.length > 0) { |
| | | // 强制触发表格重新渲染以确保el-select正确显示 |
| | | nextTick(() => { |
| | | // 触发一个微小的数据变化来强制重新渲染 |
| | | const tempData = [...tableData.value]; |
| | | tableData.value = tempData; |
| | | }); |
| | | } |
| | | }, { deep: true }); |
| | | |
| | | onMounted(async()=>{ |
| | | let res = await getCoalFieldList() |
| | | res.data.forEach(item => { |
| | | let obj = {}; |
| | | obj.value = item.fieldName; |
| | | obj.key = item.id; |
| | | weekList.value.push(obj); |
| | | }); |
| | | let ress = await userListAll(); |
| | | ress.data.forEach(item => { |
| | | let obj = {}; |
| | | obj.value = item.nickName; |
| | | obj.key = item.userId; |
| | | userList.value.push(obj); |
| | | }); |
| | | // 通知父组件weekList已加载完成 |
| | | nextTick(() => { |
| | | }); |
| | | }) |
| | | const dropdownList = ref([]); |
| | | // 获取下拉数据 |
| | | const getDropdownData = async () => { |
| | | let res = await getCoalFieldList(); |
| | | if (res.code === 200) { |
| | | dropdownList.value = res.data.map((item) => ({ |
| | | value: item.fieldName, |
| | | key: item.id, |
| | | })); |
| | | } else { |
| | | ElMessage.error("获取下拉数据失败"); |
| | | } |
| | | }; |
| | | const userList = ref([]); |
| | | const getUserList = (async()=>{ |
| | | let res = await userListAll(); |
| | | if (res.code === 200) { |
| | | userList.value = res.data.map((item) => ({ |
| | | value: item.nickName, |
| | | key: item.userId, |
| | | })); |
| | | } else { |
| | | ElMessage.error("获取用户列表失败"); |
| | | } |
| | | }) |
| | | // 监听表格数据变化,确保显示正确 |
| | | watch(() => props.modelValue, (newValue) => { |
| | | if (newValue && userList.value.length > 0) { |
| | | // 当数据加载完成且weekList已获取时,确保显示正确 |
| | | } |
| | | }, { deep: true }); |
| | | |
| | | // 监听userList变化,当下拉数据加载完成后处理显示 |
| | | watch(userList, (newList) => { |
| | | if (newList.length > 0 && tableData.value.length > 0) { |
| | | // 强制触发表格重新渲染以确保el-select正确显示 |
| | | nextTick(() => { |
| | | // 触发一个微小的数据变化来强制重新渲染 |
| | | const tempData = [...tableData.value]; |
| | | tableData.value = tempData; |
| | | }); |
| | | } |
| | | }, { deep: true }); |
| | | |
| | | const getUserNameById = (id) => { |
| | | const producer = userList.value.find(item => item.key == id); |
| | | return producer ? producer.value : id; |
| | | }; |
| | | // 处理用户选择变化(新方法:名称选择转ID) |
| | | const handleUserSelectChange = (row, selectedName) => { |
| | | // 根据选择的名称找到对应的ID |
| | | const userItem = userList.value.find(item => item.value === selectedName); |
| | | if (userItem) { |
| | | row.producer = userItem.key; // 设置为ID |
| | | } else { |
| | | row.producer = ''; // 如果没找到,清空 |
| | | } |
| | | }; |
| | | // 暴露方法给父组件使用 |
| | | defineExpose({ |
| | | calculateTotalCost, |
| | | getDropdownData, |
| | | getCoalNameById, // 暴露获取煤种名称的方法 |
| | | weekList, // 暴露weekList让父组件可以访问 |
| | | addRow: (rowData = {}) => { |
| | | const defaultRow = { |
| | | coal: '', |
| | | calorificValue: '', |
| | | productionQuantity: '', |
| | | laborCost: '', |
| | | energyCost: '', |
| | | equipmentDepreciation: '', |
| | | purchasePrice: '', |
| | | totalCost: '', |
| | | ...rowData |
| | | } |
| | | tableData.value = [...tableData.value, defaultRow] |
| | | coal: "", |
| | | calorificValue: "", |
| | | productionQuantity: "", |
| | | laborCost: "", |
| | | energyCost: "", |
| | | equipmentDepreciation: "", |
| | | purchasePrice: "", |
| | | totalCost: "", |
| | | producer: "", |
| | | ...rowData, |
| | | }; |
| | | tableData.value = [...tableData.value, defaultRow]; |
| | | }, |
| | | clearData: () => { |
| | | tableData.value = [] |
| | | tableData.value = []; |
| | | }, |
| | | // 添加一个方法来等待weekList加载完成 |
| | | waitForWeekList: () => { |
| | | return new Promise((resolve) => { |
| | | if (weekList.value.length > 0) { |
| | | resolve(); |
| | | } else { |
| | | const unwatch = watch(weekList, (newList) => { |
| | | if (newList.length > 0) { |
| | | unwatch(); |
| | | resolve(); |
| | | } |
| | | }) |
| | | }); |
| | | } |
| | | }); |
| | | }, |
| | | // 强制刷新表格显示 |
| | | forceRefresh: () => { |
| | | nextTick(() => { |
| | | const tempData = [...tableData.value]; |
| | | tableData.value = tempData; |
| | | }); |
| | | } |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped> |