张诺
2 天以前 7619d415522ab3dc3299d6a2a9f5c9964a692d3f
src/views/production/components/ProductionDetailsTable.vue
@@ -2,11 +2,21 @@
  <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">
@@ -29,7 +39,7 @@
          @input="handleInput('laborCost', $index, $event)"
        >
          <template #suffix>
            <i style="font-style:normal;">元</i>
            <i style="font-style: normal">元</i>
          </template>
        </el-input>
      </template>
@@ -44,7 +54,7 @@
          @input="handleInput('energyConsumptionCost', $index, $event)"
        >
          <template #suffix>
            <i style="font-style:normal;">元</i>
            <i style="font-style: normal">元</i>
          </template>
        </el-input>
      </template>
@@ -59,7 +69,7 @@
          @input="handleInput('equipmentDepreciation', $index, $event)"
        >
          <template #suffix>
            <i style="font-style:normal;">元</i>
            <i style="font-style: normal">元</i>
          </template>
        </el-input>
      </template>
@@ -74,7 +84,7 @@
          @input="handleInput('purchasePrice', $index, $event)"
        >
          <template #suffix>
            <i style="font-style:normal;">元</i>
            <i style="font-style: normal">元</i>
          </template>
        </el-input>
      </template>
@@ -83,6 +93,7 @@
    <el-table-column label="总成本" min-width="120">
      <template #default="{ row, $index }">
        <el-input 
          disabled
          v-model="row.totalCost" 
          placeholder="总成本"
          type="number"
@@ -90,21 +101,36 @@
          @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" 
@@ -120,93 +146,251 @@
</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>