src/views/productionManagement/productionOrder/MaterialRequisitionDialog.vue
@@ -9,49 +9,45 @@
    class="material-requisition-dialog"
  >
    <div class="material-requisition-form">
      <!-- 原材料列表 -->
      <el-table :data="materialList" border style="width: 100%" height="65vh">
        <el-table-column type="index" label="序号" width="60" align="center" />
        <el-table-column prop="productName" label="产品名称" min-width="150" />
        <el-table-column prop="model" label="型号" min-width="150" />
        <!-- <el-table-column prop="batchNo" label="批号" min-width="150">
          <template #default="{ row }">
            <el-select
              v-model="row.batchNo"
              placeholder="请选择批号"
              clearable
              style="width: 100%"
            >
              <el-option
                v-for="item in row.batchOptions || []"
                :key="item.batchNo"
                :label="item.batchNo"
                :value="item.batchNo"
              />
            </el-select>
          </template>
        </el-table-column> -->
        <el-table-column prop="unit" label="单位" width="80" align="center" />
        <el-table-column prop="qualitity" label="数量" width="100" align="center">
          <template #default="{ row }">
            {{ row.qualitity || 0 }}
          </template>
        </el-table-column>
        <el-table-column prop="requisitionQty" label="领用数量" width="120" align="center">
          <template #default="{ row }">
            <el-input-number
              v-model="row.requisitionQty"
              :min="0"
              :precision="2"
              :controls="false"
              :disabled="!row.qualitity || hasDrawMaterials"
              style="width: 100%"
            />
          </template>
        </el-table-column>
        <el-table-column prop="remark" label="备注" min-width="150">
        </el-table-column>
      </el-table>
        <!-- 原材料 Tab -->
          <div class="operation-bar">
            <el-button type="primary" @click="handleAdd">新增</el-button>
          </div>
          <el-table :data="materialList" border style="width: 100%" height="50vh">
            <el-table-column type="index" label="序号" width="60" align="center" />
            <el-table-column prop="productName" label="产品名称" min-width="150" />
            <el-table-column prop="model" label="型号" min-width="150" />
            <el-table-column prop="unit" label="单位" width="80" align="center" />
            <!-- <el-table-column prop="qualitity" label="可领用数量" width="100" align="center">
              <template #default="{ row }">
                {{ row.qualitity || 0 }}
              </template>
            </el-table-column> -->
            <el-table-column prop="requisitionQty" label="领用数量" width="120" align="center">
              <template #default="{ row }">
                <el-input-number
                  v-model="row.requisitionQty"
                  :min="0"
                  :max="row.qualitity || 0"
                  :precision="2"
                  :controls="false"
                  :disabled="!row.qualitity"
                  style="width: 100%"
                />
              </template>
            </el-table-column>
            <el-table-column prop="remark" label="备注" min-width="150">
              <template #default="{ row }">
                <el-input v-model="row.remark" placeholder="请输入备注" clearable />
              </template>
            </el-table-column>
            <el-table-column label="操作" width="80" align="center">
              <template #default="{ $index }">
                <el-button type="danger" link @click="handleDelete($index)">删除</el-button>
              </template>
            </el-table-column>
          </el-table>
    </div>
    <template #footer>
@@ -60,13 +56,50 @@
        <el-button @click="handleCancel">取 消</el-button>
      </span>
    </template>
    <!-- 新增原材料弹窗 -->
    <el-dialog
      v-model="addDialogVisible"
      title="选择原材料"
      width="800px"
      top="5vh"
      :close-on-click-modal="false"
      append-to-body
    >
      <el-table
        :data="availableMaterials"
        border
        style="width: 100%"
        height="50vh"
        @selection-change="handleSelectionChange"
      >
        <el-table-column type="selection" width="55" align="center" />
        <el-table-column type="index" label="序号" width="60" align="center" />
        <el-table-column prop="productName" label="产品名称" min-width="150" />
        <el-table-column prop="model" label="型号" min-width="150" />
        <el-table-column prop="unit" label="单位" width="80" align="center" />
        <!-- <el-table-column prop="qualitity" label="可领用数量" width="100" align="center">
          <template #default="{ row }">
            {{ row.qualitity || 0 }}
          </template>
        </el-table-column> -->
      </el-table>
      <template #footer>
        <span class="dialog-footer">
          <el-button type="primary" @click="handleAddConfirm">确 定</el-button>
          <el-button @click="addDialogVisible = false">取 消</el-button>
        </span>
      </template>
    </el-dialog>
  </el-dialog>
</template>
<script setup>
import { ref, reactive, computed, watch } from 'vue';
import { ref, computed, watch } from 'vue';
import { ElMessage } from 'element-plus';
import { getByBomId, drawMaterials } from '@/api/productionManagement/productionOrder.js';
import { drawMaterials } from '@/api/productionManagement/productionOrder.js';
import { getMaterials } from '@/api/inventoryManagement/stockInventory.js';
const props = defineProps({
  modelValue: {
@@ -88,8 +121,13 @@
const loading = ref(false);
const saving = ref(false);
const activeTab = ref('material');
const materialList = ref([]);
const hasDrawMaterials = ref(false);
// 新增弹窗相关
const addDialogVisible = ref(false);
const availableMaterials = ref([]);
const selectedMaterials = ref([]);
// 监听弹框打开,加载数据
watch(() => props.modelValue, (val) => {
@@ -101,26 +139,46 @@
const loadMaterialList = async () => {
  const order = props.orderData;
  const drawMaterialsData = order.drawMaterials;
  const bomId = order?.bomId;
  // 如果已有领料数据,直接使用
  // 先获取getMaterials的最新数据
  let materialsFromApi = [];
  if (bomId) {
    try {
      const res = await getMaterials({ bomId });
      materialsFromApi = res.data || [];
    } catch (error) {
      console.error('查询原材料列表失败:', error);
    }
  }
  // 加载已保存的领料数据
  if (drawMaterialsData) {
    hasDrawMaterials.value = true;
    try {
      const list = typeof drawMaterialsData === 'string'
        ? JSON.parse(drawMaterialsData)
        : drawMaterialsData;
      materialList.value = list.map(item => ({
        ...item,
        requisitionQty: item.requisitionQty || 0
      }));
      return;
      // 合并数据:使用API的qualitity,使用保存的requisitionQty和remark
      materialList.value = list.map(savedItem => {
        const apiItem = materialsFromApi.find(m => m.id === savedItem.id || m.productModelId === savedItem.productModelId);
        return {
          ...savedItem,
          qualitity: apiItem?.qualitity ?? savedItem.qualitity ?? 0,
          requisitionQty: savedItem.requisitionQty || 0
        };
      });
    } catch (e) {
      console.error('解析领料数据失败:', e);
      materialList.value = [];
    }
  } else {
    materialList.value = [];
  }
};
  // 没有领料数据,调用接口查询
  hasDrawMaterials.value = false;
// 打开新增弹窗
const handleAdd = async () => {
  const order = props.orderData;
  const bomId = order?.bomId;
  if (!bomId) {
    ElMessage.warning('当前订单缺少BOM信息');
@@ -129,30 +187,63 @@
  loading.value = true;
  try {
    const res = await getByBomId({ bomId });
    const data = res.data || [];
    // 处理数据,添加领用数量字段和批号选项
    materialList.value = data.map(item => ({
      ...item,
      requisitionQty: item.qualitity ? 0 : 0,
      batchNo: item.batchNo || '',
      remark: item.remark || '',
      // 批号选项,从库存原材料信息中获取
      batchOptions: item.inventoryList || []
    }));
    const res = await getMaterials({ bomId });
    console.log('getMaterials返回数据:', res.data);
    // 直接展示所有数据,不过滤
    availableMaterials.value = res.data || [];
    selectedMaterials.value = [];
    addDialogVisible.value = true;
  } catch (error) {
    console.error('查询原材料列表失败:', error);
    ElMessage.error('查询原材料列表失败');
    materialList.value = [];
  } finally {
    loading.value = false;
  }
};
// 选择变化
const handleSelectionChange = (selection) => {
  selectedMaterials.value = selection;
};
// 确认添加
const handleAddConfirm = () => {
  if (selectedMaterials.value.length === 0) {
    ElMessage.warning('请选择至少一条记录');
    return;
  }
  // 过滤掉已存在的(通过id和productModelId判断)
  const existingIds = materialList.value.map(item => item.id);
  const existingProductModelIds = materialList.value.map(item => item.productModelId);
  const newItems = selectedMaterials.value
    .filter(item => !existingIds.includes(item.id) && !existingProductModelIds.includes(item.productModelId))
    .map(item => ({
      ...item,
      requisitionQty: 0,
      remark: ''
    }));
  if (newItems.length === 0) {
    ElMessage.warning('所选数据已存在,无需重复添加');
    return;
  }
  materialList.value = [...materialList.value, ...newItems];
  addDialogVisible.value = false;
  ElMessage.success(`成功添加 ${newItems.length} 条记录`);
};
// 删除
const handleDelete = (index) => {
  materialList.value.splice(index, 1);
};
const handleCancel = () => {
  visible.value = false;
  materialList.value = [];
  hasDrawMaterials.value = false;
  activeTab.value = 'material';
};
const handleConfirm = async () => {
@@ -178,7 +269,7 @@
    ElMessage.success('领料保存成功');
    visible.value = false;
    materialList.value = [];
    hasDrawMaterials.value = false;
    activeTab.value = 'material';
  } catch (error) {
    console.error('保存领料失败:', error);
    ElMessage.error('保存领料失败');
@@ -190,6 +281,14 @@
<style scoped lang="scss">
.material-requisition-form {
  .operation-bar {
    margin-bottom: 15px;
  }
  .el-tabs {
    height: 100%;
  }
  .el-table {
    margin-top: 10px;
  }
@@ -223,4 +322,12 @@
  padding: 15px 20px;
  border-top: 1px solid #e4e7ed;
}
:deep(.el-tabs__content) {
  height: calc(100% - 55px);
}
:deep(.el-tab-pane) {
  height: 100%;
}
</style>