1、提交配煤计算器 解除煤种限制
2、增加销售出库的导出功能
3、库存管理正式库的导出功能
4、文档管理优化
5、优化设备管理模块
已修改8个文件
1265 ■■■■ 文件已修改
src/views/archiveManagement/index.vue 393 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/calculator/index.vue 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipment/management/index.vue 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipment/management/mould/equipmentRequisitionDialog.vue 79 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipment/management/mould/managementDialog.vue 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/salesOutbound/components/formDia.vue 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/salesOutbound/index.vue 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/warehouseManagement/index.vue 723 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/archiveManagement/index.vue
@@ -34,13 +34,21 @@
            :expand-on-click-node="false"
            :filter-node-method="filterNode"
            :props="props"
            :lazy="false"
            :load="undefined"
            :render-after-expand="true"
            :auto-expand-parent="true"
            :indent="20"
            class="custom-tree"
            node-key="id"
            @node-click="handleNodeClick"
            @node-expand="handleNodeExpand"
          >
            <template #default="{ node, data }">
              <div
                class="tree-node-content"
                :data-temp-id="data._tempId"
                :data-node-id="data.id"
                @dblclick="headerDbClick(node, data)"
              >
                <div class="node-icon">
@@ -61,7 +69,7 @@
                  }}</span>
                  <el-input
                    v-else
                    :ref="(el) => setInputRef(el, data)"
                    :ref="(el) => setInputRef(data.id || data._tempId, el)"
                    v-model="newName"
                    autofocus
                    class="tree-input"
@@ -69,6 +77,7 @@
                    size="small"
                    @blur="(event) => handleInputBlur(event, data, node)"
                    @keyup.enter="(event) => handleInputBlur(event, data, node)"
                    @keyup.esc="() => cancelEdit(data, node)"
                  />
                </div>
                <div v-show="!data.isEdit" class="node-actions">
@@ -76,7 +85,8 @@
                    icon="Plus"
                    link
                    size="small"
                    title="新增子节点"
                    :title="getNodeDepth(data) >= 7 ? '已达到最大嵌套层级(7层)' : '新增子节点'"
                    :disabled="getNodeDepth(data) >= 7"
                    @click.stop="append(data)"
                  ></el-button>
                  <el-button
@@ -165,7 +175,7 @@
  </el-card>
</template>
<script setup>
import { nextTick, onMounted, reactive, ref } from "vue";
import { computed, nextTick, onMounted, reactive, ref } from "vue";
import ETable from "@/components/Table/ETable.vue";
import {
  ElButton,
@@ -226,6 +236,41 @@
  label: "name",
  children: "children",
  isLeaf: "leaf",
};
// ===== 计算属性 =====
// 计算总节点数
const totalNodeCount = computed(() => {
  const countNodes = (nodes) => {
    let count = 0;
    for (const node of nodes || []) {
      count += 1;
      if (node.children) {
        count += countNodes(node.children);
      }
    }
    return count;
  };
  return countNodes(treeData.value);
});
// 检查是否为大量节点(超过1000个节点时提示性能优化)
const isLargeTree = computed(() => totalNodeCount.value > 1000);
// 获取节点深度的函数
const getNodeDepth = (nodeData) => {
  if (!nodeData || !nodeData.id) return 0;
  let depth = 1;
  const node = treeRef.value?.getNode(nodeData.id);
  let parentNode = node?.parent;
  while (parentNode && parentNode.data && parentNode.data.id) {
    depth++;
    parentNode = parentNode.parent;
  }
  return depth;
};
// ===== 工具函数 =====
@@ -337,6 +382,20 @@
  getArchiveListData();
};
// 节点展开事件处理
const handleNodeExpand = (data, node, instance) => {
  // 展开后稍微延迟,确保子节点渲染完成
  setTimeout(() => {
    // 如果有新添加的编辑状态节点,聚焦到它
    if (data.children && data.children.length > 0) {
      const editingChild = data.children.find(child => child.isEdit && child._tempId);
      if (editingChild) {
        focusInput(editingChild._tempId, 200);
      }
    }
  }, 100);
};
const handlePageChange = (pagination) => {
  try {
    const { page, limit } = pagination;
@@ -427,22 +486,62 @@
  }
};
// ===== 树节点编辑函数 =====
const setInputRef = (el, data) => {
  if (el) {
    inputRefs.value.set(data.id || data, el);
const setInputRef = (key, el) => {
  if (el && key) {
    inputRefs.value.set(key, el);
  }
};
const headerDbClick = (node, data) => {
  data.isEdit = true;
  newName.value = data.name;
  nextTick(() => {
    const inputEl = inputRefs.value.get(data.id || data);
    if (inputEl) {
      inputEl.focus();
      inputEl.select();
  try {
    data.isEdit = true;
    newName.value = data.name;
    nextTick(() => {
      const key = data._tempId || data.id;
      if (key) {
        focusInput(key, 50);
      }
    });
  } catch (error) {
    console.error('进入编辑模式失败:', error);
    ElMessage.error('进入编辑模式失败');
  }
};
// 取消编辑功能
const cancelEdit = (data, node) => {
  try {
    data.isEdit = false;
    // 如果是新创建的临时节点,删除它
    if (data._tempId && !data.id) {
      if (node.parent) {
        const parent = node.parent.data;
        const index = parent.children?.indexOf(data);
        if (index > -1) {
          parent.children.splice(index, 1);
        }
      } else {
        // 根节点
        const index = treeData.value.indexOf(data);
        if (index > -1) {
          treeData.value.splice(index, 1);
        }
      }
      // 清理输入框引用
      const key = data._tempId;
      if (inputRefs.value.has(key)) {
        inputRefs.value.delete(key);
      }
    }
  });
    // 重置名称
    newName.value = "";
  } catch (error) {
    console.error('取消编辑失败:', error);
  }
};
const expandParentNodes = (node) => {
@@ -460,11 +559,21 @@
    comeTreeData.isEdit = false;
    const newValue = newName.value.trim();
    if (comeTreeData.name === newValue) return;
    // 如果名称为空,处理空名称情况
    if (!newValue) {
      newName.value = comeTreeData.name || "新节点";
      // 如果是新创建的临时节点,删除它
      if (comeTreeData._tempId && !comeTreeData.id) {
        cancelEdit(comeTreeData, node);
      } else {
        // 已存在的节点,恢复原名称
        newName.value = comeTreeData.name || "新节点";
      }
      ElMessage.warning("节点名称不能为空");
      return;
    }
    // 如果名称没有改变,直接返回
    if (comeTreeData.name === newValue) {
      return;
    }
@@ -480,6 +589,20 @@
      comeTreeData.name = newValue;
      if (!comeTreeData.id && result.data) {
        comeTreeData.id = result.data.id || result.data;
        // 清理临时ID
        if (comeTreeData._tempId) {
          const tempKey = comeTreeData._tempId;
          delete comeTreeData._tempId;
          // 更新引用映射
          if (inputRefs.value.has(tempKey)) {
            const inputEl = inputRefs.value.get(tempKey);
            inputRefs.value.delete(tempKey);
            if (comeTreeData.id && inputEl) {
              inputRefs.value.set(comeTreeData.id, inputEl);
            }
          }
        }
      }
      showSuccess("保存成功");
@@ -490,18 +613,42 @@
        if (currentNodeId && treeRef.value) {
          const targetNode = treeRef.value.getNode(currentNodeId);
          if (targetNode) {
            // 展开当前节点
            targetNode.expanded = true;
            // 展开所有父节点
            expandParentNodes(targetNode);
            // 滚动到节点位置
            setTimeout(() => {
              const nodeElement = document.querySelector(`[data-node-id="${currentNodeId}"]`);
              if (nodeElement) {
                nodeElement.scrollIntoView({
                  behavior: 'smooth',
                  block: 'center'
                });
              }
            }, 300);
          }
        }
      });
    } else {
      comeTreeData.name = comeTreeData.name || "新节点";
      // 保存失败,恢复原名称或删除临时节点
      if (comeTreeData._tempId && !comeTreeData.id) {
        cancelEdit(comeTreeData, node);
      } else {
        comeTreeData.name = comeTreeData.name || "新节点";
      }
      ElMessage.error("保存失败: " + (result.msg || "未知错误"));
    }
  } catch (error) {
    handleError(error, "保存节点失败");
    comeTreeData.name = comeTreeData.name || "新节点";
    // 出错时处理临时节点
    if (comeTreeData._tempId && !comeTreeData.id) {
      cancelEdit(comeTreeData, node);
    } else {
      comeTreeData.name = comeTreeData.name || "新节点";
    }
  }
};
@@ -509,51 +656,167 @@
const createNewNode = (name, isEdit = true) => ({
  name,
  isEdit,
  _tempId: Date.now() + Math.random(), // 添加临时ID
});
const focusInput = (nodeData, delay = 50) => {
const focusInput = (nodeKey, delay = 100) => {
  setTimeout(() => {
    const inputEl = inputRefs.value.get(nodeData.id || nodeData);
    const inputEl = inputRefs.value.get(nodeKey);
    if (inputEl) {
      inputEl.focus();
      inputEl.select();
      inputEl.$el?.scrollIntoView?.({
        behavior: "smooth",
        block: "nearest",
      });
      try {
        // 先滚动到可视区域
        inputEl.$el?.scrollIntoView?.({
          behavior: "smooth",
          block: "center",
        });
        // 聚焦并选中所有文本,确保可以直接编辑
        setTimeout(() => {
          inputEl.focus();
          inputEl.select();
          // 确保光标在输入框末尾(如果select失败的话)
          const inputElement = inputEl.ref || inputEl.input || inputEl.$el?.querySelector('input');
          if (inputElement) {
            inputElement.setSelectionRange(0, inputElement.value.length);
            // 确保输入框在视口中央
            setTimeout(() => {
              inputElement.scrollIntoView({
                behavior: 'smooth',
                block: 'center'
              });
            }, 100);
          }
        }, 100);
      } catch (error) {
        console.warn('聚焦输入框失败:', error);
        // 备用方案:直接聚焦
        try {
          inputEl.focus();
          // 尝试选中文本
          setTimeout(() => {
            const inputElement = inputEl.ref || inputEl.input || inputEl.$el?.querySelector('input');
            if (inputElement) {
              inputElement.select();
            }
          }, 200);
        } catch (e) {
          console.warn('备用聚焦方案也失败:', e);
        }
      }
    } else {
      console.warn('未找到输入框元素,key:', nodeKey);
    }
  }, delay);
};
const append = async (data) => {
  if (data === "") {
    // 新增根节点
    const newNode = createNewNode("新节点");
    treeData.value.push(newNode);
    newName.value = "新节点";
  try {
    // 检查嵌套层级限制
    const getNodeDepth = (nodeData, currentDepth = 1) => {
      if (!nodeData || data === "") return 0; // 根节点不算层级
      let depth = currentDepth;
      let current = nodeData;
      // 通过树组件获取父节点来计算深度
      if (current.id) {
        const node = treeRef.value?.getNode(current.id);
        let parentNode = node?.parent;
        while (parentNode && parentNode.data && parentNode.data.id) {
          depth++;
          parentNode = parentNode.parent;
        }
      }
      return depth;
    };
    nextTick(() => focusInput(newNode));
  } else {
    const hasChildren = data.children;
    const nodeKey = data.id || data;
    const node = treeRef.value?.getNode(nodeKey);
    const isExpanded = node?.expanded;
    // 如果有子级且未展开,先展开节点
    if (hasChildren && !isExpanded && treeRef.value?.store?.nodesMap[nodeKey]) {
      treeRef.value.store.nodesMap[nodeKey].expanded = true;
    const currentDepth = getNodeDepth(data);
    // 限制最多7层嵌套
    if (currentDepth >= 7) {
      ElMessage.warning('最多只能嵌套7层节点,当前已达到最大层级限制');
      return;
    }
    const newNode = createNewNode("新子节点");
    if (!data.children) {
      data.children = [];
    // 在大量节点时提示性能注意事项
    if (isLargeTree.value && totalNodeCount.value > 2000) {
      const confirmed = await ElMessageBox.confirm(
        `当前树结构包含 ${totalNodeCount.value} 个节点,节点较多可能影响性能。建议考虑分层管理。是否继续添加?`,
        '性能提示',
        {
          confirmButtonText: '继续添加',
          cancelButtonText: '取消',
          type: 'warning',
        }
      ).catch(() => false);
      if (!confirmed) return;
    }
    data.children.push(newNode);
    newName.value = "新子节点";
    const delay = hasChildren && !isExpanded ? 200 : 50;
    nextTick(() => focusInput(newNode, delay));
    if (data === "") {
      // 新增根节点
      const newNode = createNewNode("新节点");
      treeData.value.push(newNode);
      newName.value = "新节点";
      await nextTick();
      focusInput(newNode._tempId, 200);
    } else {
      const hasChildren = data.children && data.children.length > 0;
      const nodeKey = data.id || data;
      const node = treeRef.value?.getNode(nodeKey);
      // 创建新子节点
      const newNode = createNewNode("新子节点");
      if (!data.children) {
        data.children = [];
      }
      data.children.push(newNode);
      newName.value = "新子节点";
      // 强制更新树结构
      await nextTick();
      // 确保父节点展开以显示新节点
      if (node) {
        node.expanded = true;
        // 如果是第一次添加子节点,等待展开动画并确保可见
        if (!hasChildren) {
          await new Promise(resolve => setTimeout(resolve, 300));
          // 展开后滚动到新节点位置
          setTimeout(() => {
            const newNodeElement = document.querySelector(`[data-temp-id="${newNode._tempId}"]`);
            if (newNodeElement) {
              newNodeElement.scrollIntoView({
                behavior: 'smooth',
                block: 'center'
              });
            }
          }, 100);
        }
        // 展开所有父节点确保完全可见
        let parentNode = node.parent;
        while (parentNode && parentNode.data && parentNode.data.id) {
          parentNode.expanded = true;
          parentNode = parentNode.parent;
        }
      }
      // 聚焦到新创建的输入框
      const delay = hasChildren ? 150 : 500; // 如果之前没有子节点,延迟更长时间等展开
      focusInput(newNode._tempId, delay);
    }
  } catch (error) {
    console.error('新增节点失败:', error);
    ElMessage.error('新增节点失败,请重试');
  }
};
@@ -618,18 +881,27 @@
  border-radius: 8px;
  background: #fff;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
  max-height: calc(100vh - 240px); // 限制最大高度,启用滚动
  .custom-tree {
    padding: 8px;
    background: transparent;
    // 使用GPU加速提升滚动性能
    transform: translateZ(0);
    will-change: scroll-position;
    :deep(.el-tree-node) {
      // 减少不必要的重绘
      contain: layout style;
      .el-tree-node__content {
        height: 36px;
        padding: 0 8px;
        border-radius: 6px;
        margin: 2px 0;
        transition: all 0.2s ease;
        // 优化渲染性能
        will-change: background-color;
        &:hover {
          background-color: #f0f9ff;
@@ -709,13 +981,19 @@
      color: #909399;
      min-height: auto;
      &:hover {
      &:hover:not(:disabled) {
        color: #1890ff;
        background-color: #f0f9ff;
      }
      &.el-button--text:hover {
      &.el-button--text:hover:not(:disabled) {
        background-color: #f0f9ff;
      }
      &:disabled {
        color: #c0c4cc;
        cursor: not-allowed;
        background-color: transparent;
      }
    }
  }
@@ -731,11 +1009,13 @@
  :deep(.el-input__wrapper) {
    border-radius: 4px;
    border: 1px solid #d9d9d9;
    border: 1px solid #40a9ff;
    transition: all 0.2s ease;
    box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.1);
    &:hover {
      border-color: #40a9ff;
      border-color: #1890ff;
      box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.15);
    }
    &.is-focus {
@@ -748,10 +1028,15 @@
    padding: 4px 8px;
    font-size: 14px;
    color: #303133;
    background-color: #fff;
    &::placeholder {
      color: #bfbfbf;
    }
    &:focus {
      background-color: #f8fcff;
    }
  }
}
src/views/calculator/index.vue
@@ -826,12 +826,6 @@
  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;
src/views/equipment/management/index.vue
@@ -184,6 +184,8 @@
    columns: [
      { prop: "equipmentNo", label: "设备编号", minWidth: 100 },
      { prop: "equipmentName", label: "设备名称", minWidth: 100 },
      { prop: "consumables", label: "耗材",
        formatter: (row) => (row.consumables ? "是" : "否"), minWidth: 100 },
      { prop: "quantity", label: "总数量", minWidth: 100 },
      { prop: "usedNo", label: "已使用数量", minWidth: 100 },
      { prop: "specification", label: "规格型号", minWidth: 100 },
@@ -206,7 +208,7 @@
        prop: "equipmentStatus",
        label: "使用状态",
        minWidth: 100,
        formatter: (row) => (row.equipmentStatus == "0" ? "使用中" : "已归还"),
        formatter: (row) => (row.equipmentStatus == 1 ? "使用中" : "已归还"),
      },
      { prop: "usageStartTime", label: "使用开始时间", minWidth: 100 },
      { prop: "usageEndTime", label: "使用结束时间", minWidth: 100 },
@@ -267,7 +269,9 @@
};
const resetState = () => {
  form.value = {};
  form.value = {
    consumables: false,
  };
  addOrEdit.value = "add";
  loading.value = true;
  tableData.value = [];
@@ -290,7 +294,9 @@
const handleAdd = () => {
  addOrEdit.value = "add";
  form.value = {};
  form.value = {
    consumables: false,
  };
  title.value = `新增${currentTabConfig.value.label}`;
  // 通用的
  copyForm.value = {};
@@ -366,7 +372,7 @@
// 设备领用弹窗提交处理
const onEquipmentRequisitionSubmit = (formData) => {
  console.log("设备领用提交数据:", formData);
  if (formData.equipmentStatus == "1") {
  if (formData.equipmentStatus == 1) {
    ElMessage.success("设备归还成功");
  } else {
    ElMessage.success("设备领用成功");
src/views/equipment/management/mould/equipmentRequisitionDialog.vue
@@ -7,7 +7,12 @@
  >
    <el-form :model="form" :rules="rules" ref="formRef" label-width="150px">
      <el-form-item label="领用人" prop="userId">
        <el-select v-model="form.userId" placeholder="请选择" :disabled="isViewMode">
        <el-select
          v-model="form.userId"
          placeholder="请选择"
          :disabled="isViewMode"
          @change="getEquipment"
        >
          <el-option
            v-for="item in userList"
            :key="item.userId"
@@ -17,7 +22,11 @@
        </el-select>
      </el-form-item>
      <el-form-item label="设备名称" prop="equipmentId">
        <el-select v-model="form.equipmentId" placeholder="请选择" :disabled="isViewMode">
        <el-select
          v-model="form.equipmentId"
          placeholder="请选择"
          :disabled="isViewMode"
        >
          <el-option
            v-for="item in equipmentList"
            :key="item.id"
@@ -52,9 +61,14 @@
      </el-form-item>
      <el-form-item label="使用状态" prop="equipmentStatus">
        <!-- 编辑的时候自动匹配 -->
        <el-select v-model="form.equipmentStatus" placeholder="请选择" :disabled="isViewMode">
          <el-option label="使用中" value="0" />
          <el-option label="已归还" value="1" />
        <el-select
          v-model="form.equipmentStatus"
          placeholder="请选择"
          :disabled="isViewMode"
          default-first-option
        >
          <el-option label="使用中" :value="1" />
          <el-option label="已归还" :value="2" :disabled="props.id" />
        </el-select>
      </el-form-item>
      <el-form-item label="使用开始时间" prop="usageStartTime">
@@ -87,7 +101,9 @@
    </el-form>
    <template #footer>
      <el-button @click="handleClose">取消</el-button>
      <el-button type="primary" @click="handleSubmit" v-if="!isViewMode">确定</el-button>
      <el-button type="primary" @click="handleSubmit" v-if="!isViewMode"
        >确定</el-button
      >
    </template>
  </el-dialog>
</template>
@@ -100,7 +116,6 @@
import useUserStore from "@/store/modules/user";
onMounted(() => {});
const userStore = useUserStore();
let userList = ref([]);
userStore.getUserList().then((res) => {
@@ -108,9 +123,17 @@
});
// 获取设备列表
const equipmentList = ref([]);
getEquipmentList().then((res) => {
  equipmentList.value = res.data;
});
// 获取最新数据
const getEquipment = async () => {
  try {
    await getEquipmentList().then((res) => {
      equipmentList.value = res.data;
    });
  } catch (error) {
    ElMessage.error("获取设备列表失败");
  }
};
const props = defineProps({
  modelValue: Boolean,
  formData: {
@@ -129,10 +152,10 @@
    type: String,
    default: "",
  },
  equipmentStatus:{
    type: String,
    default: "0"
  }
  equipmentStatus: {
    type: [Number, String], // 允许数字或字符串
    default: 1,
  },
});
const maxQuantity = computed(() => {
  if (!form.value.equipmentId) return 0;
@@ -148,7 +171,12 @@
  get: () => props.modelValue,
  set: (v) => emit("update:modelValue", v),
});
const isViewMode = computed(() => props.addOrEdit === "view" || props.addOrEdit === "viewRow" || props.equipmentStatus ==="1");
const isViewMode = computed(
  () =>
    props.addOrEdit === "view" ||
    props.addOrEdit === "viewRow" ||
    Number(props.equipmentStatus) === 2
);
const isEdit = computed(() => !!props.formData?.id);
const formRef = ref();
@@ -158,19 +186,32 @@
  userId: "",
  equipmentId: "",
  usageQuantity: 1,
  equipmentStatus: 1,
  equipmentStatus: 1, // 默认使用中
  usageStartTime: "",
  remarks: ""
  remarks: "",
};
const form = ref({ ...defaultForm });
// 确保初始化时使用状态有默认值
onMounted(() => {
  if (
    form.value.equipmentStatus === undefined ||
    form.value.equipmentStatus === null
  ) {
    console.log(form.value.equipmentStatus);
    form.value.equipmentStatus = 1;
  }
  getEquipment();
});
watch(
  () => props.formData,
  (val) => {
    if (val && Object.keys(val).length > 0) {
      form.value = { ...defaultForm, ...val };
      // 编辑模式,直接赋值,不使用默认值合并
      form.value = { ...val };
    } else {
      // 新建时重置为初始值,防止脏数据
      // 新增模式,使用默认值
      form.value = { ...defaultForm };
    }
  },
src/views/equipment/management/mould/managementDialog.vue
@@ -36,6 +36,14 @@
            </el-form-item>
          </el-col>
          <el-col :span="11">
            <el-form-item label="是否为耗材" prop="consumables">
              <el-select v-model="formData.consumables" placeholder="请选择是否为耗材类型" :disabled="isViewMode">
                <el-option label="是" :value="true" />
                <el-option label="否" :value="false" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="11">
            <el-form-item label="数量" prop="quantity">
              <el-input
                v-model="formData.quantity"
@@ -225,6 +233,9 @@
  equipmentName: [
    { required: true, message: "请输入供货商名称", trigger: "blur" },
  ],
  consumables: [
    { required: true, message: "请选择是否为耗材", trigger: "change" },
  ],
});
</script>
<style lang="scss" scoped>
src/views/salesOutbound/components/formDia.vue
@@ -110,6 +110,16 @@
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="添加至待补库" prop="isPendingRestock">
              <el-select v-model="form.isPendingRestock" placeholder="">
                <el-option label="是" :value="true" />
                <el-option label="否" :value="false" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
@@ -149,6 +159,7 @@
    netProfit: '',
    inventoryQuantity: '',
    priceIncludingTax: '',
    isPendingRestock: false
  },
  rules: {
    saleDate: [{ required: true, message: "请选择日期", trigger: "change" },],
@@ -165,6 +176,7 @@
        netProfit: [{ required: true, message: "请输入", trigger: "blur" },],
        inventoryQuantity: [{ required: true, message: "请输入", trigger: "blur" },],
        priceIncludingTax: [{ required: true, message: "请输入", trigger: "blur" },],
    isPendingRestock: [{ required: true, message: "请选择是否添加至待补库", trigger: "change" },],
  }
})
src/views/salesOutbound/index.vue
@@ -39,7 +39,7 @@
      <el-space>
        <el-button type="primary" :icon="Plus" @click="openDia(undefined, 'add')">新建</el-button>
        <el-button type="danger" :icon="Delete" @click="handleDelete">删除</el-button>
        <!-- <el-button type="info" plain :icon="Download" @click="handleExport">导出</el-button> -->
        <el-button type="info" plain :icon="Download" @click="handleExport">导出</el-button>
      </el-space>
      <!-- 表格组件 -->
      <div>
@@ -169,7 +169,30 @@
};
// 导出出库
const handleExport = () => {
  const config = { api: "/salesRecord/export", name: "销售出库" };
  proxy.$modal
    .confirm(
      "是否要导出" +
        (selectedRows.value.length > 0
          ? `选中的${selectedRows.value.length}条`
          : "全部") +
        "数据?"
    )
    .then((res) => {
      if (res) {
        ElMessage.success("正在导出数据,请稍候...");
        exportData(config.api, config.name);
      }
    })
    .catch(() => {});
};
const exportData = (api, name) => {
  proxy.download(
    api,
    { exportIds: selectedRows.value.map((row) => row.id) },
    `${new Date().getTime()}${name}${new Date().toLocaleDateString("en-CA")}.xlsx`
  );
  ElMessage.success("导出数据:" + name);
};
// 选择行
const handleSelectionChange = (selection) => {
src/views/warehouseManagement/index.vue
@@ -1,25 +1,25 @@
<template>
  <div class="app-container">
    <el-form :inline="true" :model="queryParams" class="search-form">
            <el-form-item label="登记日期">
                <el-date-picker
                    v-model="queryParams.registrationDate"
                    type="date"
                    value-format="YYYY-MM-DD"
                    format="YYYY-MM-DD"
                    clearable
                    style="width: 100%"
                    placeholder="请选择日期"
                />
            </el-form-item>
            <el-form-item label="煤种">
                <el-input
                    v-model="queryParams.coal"
                    placeholder="请输入煤种"
                    clearable
                    :style="{ width: '100%' }"
                />
            </el-form-item>
      <el-form-item label="登记日期">
        <el-date-picker
          v-model="queryParams.registrationDate"
          type="date"
          value-format="YYYY-MM-DD"
          format="YYYY-MM-DD"
          clearable
          style="width: 100%"
          placeholder="请选择日期"
        />
      </el-form-item>
      <el-form-item label="煤种">
        <el-input
          v-model="queryParams.coal"
          placeholder="请输入煤种"
          clearable
          :style="{ width: '100%' }"
        />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="handleQuery">查询</el-button>
        <el-button @click="resetQuery">重置</el-button>
@@ -28,56 +28,158 @@
    <el-card>
      <!-- 标签页 -->
      <el-tabs
          v-model="activeTab"
          class="info-tabs"
          @tab-click="handleTabClick"
        v-model="activeTab"
        class="info-tabs"
        @tab-click="handleTabClick"
      >
        <el-tab-pane
            v-for="tab in tabs"
            :key="tab.name"
            :label="tab.label"
            :name="tab.name"
          v-for="tab in tabs"
          :key="tab.name"
          :label="tab.label"
          :name="tab.name"
        />
      </el-tabs>
      <!-- 操作按钮区 -->
      <el-space>
<!--        <el-button type="danger" :icon="Delete">删除</el-button>-->
        <!--        <el-button type="danger" :icon="Delete">删除</el-button>-->
        <!-- <el-button type="info" plain :icon="Download">导出</el-button>  -->
        <el-button type="success" plain :icon="Refresh" v-if="activeTab=== 'officialInventory'" @click="mergeRows('merge')">合并</el-button>
        <el-button
          type="success"
          plain
          :icon="Refresh"
          v-if="activeTab === 'officialInventory'"
          @click="mergeRows('merge')"
          >合并</el-button
        >
        <el-button
          type="info"
          plain
          :icon="Download"
          v-if="activeTab === 'officialInventory'"
          @click="handleExport"
          >导出</el-button
        >
      </el-space>
      <div>
        <el-table :data="tableData" border @selection-change="selectionChange" style="width: 100%;height: calc(100vh - 30em)" show-summary :summary-method="summarizeChildrenTable">
        <el-table
          :data="tableData"
          border
          @selection-change="selectionChange"
          style="width: 100%; height: calc(100vh - 30em)"
          show-summary
          :summary-method="summarizeChildrenTable"
        >
          <el-table-column type="selection" width="55" align="center" />
          <el-table-column label="序号" type="index" width="60" align="center" />
          <el-table-column prop="supplierName" label="供货商名称" width="180" sortable/>
          <el-table-column prop="coal" label="煤种" sortable/>
          <el-table-column prop="unit" label="单位" width="70"/>
          <el-table-column prop="inventoryQuantity" label="库存数量" sortable min-width="110"/>
          <el-table-column prop="priceIncludingTax" label="单价(含税)" sortable width="130"/>
          <el-table-column prop="totalPriceIncludingTax" label="总价(含税)" width="130" />
          <el-table-column prop="priceExcludingTax" label="单价(不含税)" width="130" />
          <el-table-column prop="totalPriceExcludingTax" label="总价(不含税)" width="130" />
          <el-table-column prop="pendingReplenishment" label="待补库" width="130" v-if="activeTab=== 'officialInventory'"/>
          <el-table-column label="煤质" align="center" v-if="activeTab=== 'officialInventory'" width="600">
            <el-table-column v-for="col in columnTitle" :key="col.prop" :prop="col.prop" :label="col.label" align="center" sortable min-width="200"/>
          <el-table-column
            label="序号"
            type="index"
            width="60"
            align="center"
          />
          <el-table-column
            prop="supplierName"
            label="供货商名称"
            width="180"
            sortable
          />
          <el-table-column prop="coal" label="煤种" sortable />
          <el-table-column prop="unit" label="单位" width="70" />
          <el-table-column
            prop="inventoryQuantity"
            label="库存数量"
            sortable
            min-width="110"
          />
          <el-table-column
            prop="priceIncludingTax"
            label="单价(含税)"
            sortable
            width="130"
          />
          <el-table-column
            prop="totalPriceIncludingTax"
            label="总价(含税)"
            width="130"
          />
          <el-table-column
            prop="priceExcludingTax"
            label="单价(不含税)"
            width="130"
          />
          <el-table-column
            prop="totalPriceExcludingTax"
            label="总价(不含税)"
            width="130"
          />
          <el-table-column
            prop="pendingReplenishment"
            label="待补库"
            width="130"
            v-if="activeTab === 'officialInventory'"
          />
          <el-table-column
            label="煤质"
            align="center"
            v-if="activeTab === 'officialInventory'"
            width="600"
          >
            <el-table-column
              v-for="col in columnTitle"
              :key="col.prop"
              :prop="col.prop"
              :label="col.label"
              align="center"
              sortable
              min-width="200"
            />
          </el-table-column>
          <el-table-column prop="registrant" label="登记人" width="180"/>
          <el-table-column prop="registrationDate" label="登记日期" width="180"/>
          <el-table-column fixed="right" label="操作" min-width="100" align="center">
          <el-table-column prop="registrant" label="登记人" width="180" />
          <el-table-column
            prop="registrationDate"
            label="登记日期"
            width="180"
          />
          <el-table-column
            fixed="right"
            label="操作"
            min-width="100"
            align="center"
          >
            <template #default="scope">
              <el-button link type="primary" size="small" @click="reviewDia(scope.row)" v-if="activeTab !== 'officialInventory'">审核</el-button>
              <el-button link type="primary" size="small" @click="mergeRows('edit', scope.row)" v-if="activeTab === 'officialInventory'">编辑</el-button>
              <el-button link type="primary" size="small" @click="mergeRows('view', scope.row)" v-if="activeTab === 'officialInventory'">详情</el-button>
              <el-button
                link
                type="primary"
                size="small"
                @click="reviewDia(scope.row)"
                v-if="activeTab !== 'officialInventory'"
                >审核</el-button
              >
              <el-button
                link
                type="primary"
                size="small"
                @click="mergeRows('edit', scope.row)"
                v-if="activeTab === 'officialInventory'"
                >编辑</el-button
              >
              <el-button
                link
                type="primary"
                size="small"
                @click="mergeRows('view', scope.row)"
                v-if="activeTab === 'officialInventory'"
                >详情</el-button
              >
            </template>
          </el-table-column>
        </el-table>
        <pagination
            v-if="total>0"
            :page="pageNum"
            :limit="pageSize"
            :total="total"
            @pagination="handlePagination"
            :layout="'total, prev, pager, next, jumper'"
          v-if="total > 0"
          :page="pageNum"
          :limit="pageSize"
          :total="total"
          @pagination="handlePagination"
          :layout="'total, prev, pager, next, jumper'"
        />
      </div>
    </el-card>
@@ -88,14 +190,24 @@
          <el-col :span="12">
            <el-form-item label="供应商名称" prop="supplierId">
              <el-select v-model="form.supplierId" placeholder="请选择供应商">
                <el-option :label="item.label" v-for="item in supplyList" :key="item.value" :value="item.value"/>
                <el-option
                  :label="item.label"
                  v-for="item in supplyList"
                  :key="item.value"
                  :value="item.value"
                />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="煤种" prop="coalId">
              <el-select v-model="form.coalId" placeholder="请选择煤种">
                <el-option :label="item.label" v-for="item in coalList" :key="item.value" :value="item.value"/>
                <el-option
                  :label="item.label"
                  v-for="item in coalList"
                  :key="item.value"
                  :value="item.value"
                />
              </el-select>
            </el-form-item>
          </el-col>
@@ -103,48 +215,78 @@
        <el-row>
          <el-col :span="12">
            <el-form-item label="单位" prop="unit">
              <el-input v-model="form.unit" placeholder="请输入单位" maxlength="30" />
              <el-input
                v-model="form.unit"
                placeholder="请输入单位"
                maxlength="30"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="库存数量" prop="inventoryQuantity">
              <el-input v-model="form.inventoryQuantity" placeholder="请输入库存数量" :max="inventoryQuantity" type="number"/>
              <el-input
                v-model="form.inventoryQuantity"
                placeholder="请输入库存数量"
                :max="inventoryQuantity"
                type="number"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="单价(含税)" prop="priceIncludingTax">
              <el-input v-model="form.priceIncludingTax" placeholder="请输入单价(含税)" maxlength="30" />
              <el-input
                v-model="form.priceIncludingTax"
                placeholder="请输入单价(含税)"
                maxlength="30"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="总价(含税)" prop="totalPriceIncludingTax">
              <el-input v-model="form.totalPriceIncludingTax" placeholder="请输入总价(含税)" maxlength="30" />
              <el-input
                v-model="form.totalPriceIncludingTax"
                placeholder="请输入总价(含税)"
                maxlength="30"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="单价(不含税)" prop="priceExcludingTax">
              <el-input v-model="form.priceExcludingTax" placeholder="请输入成本单价" maxlength="30" />
              <el-input
                v-model="form.priceExcludingTax"
                placeholder="请输入成本单价"
                maxlength="30"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="总价(不含税)" prop="totalPriceExcludingTax">
              <el-input v-model="form.totalPriceExcludingTax" placeholder="请输入成本单价" maxlength="30" />
              <el-input
                v-model="form.totalPriceExcludingTax"
                placeholder="请输入成本单价"
                maxlength="30"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="煤质方案" prop="coalPlanId">
              <el-select v-model="form.coalPlanId" placeholder="请选择" @change="coalPlanByIdList" clearable>
              <el-select
                v-model="form.coalPlanId"
                placeholder="请选择"
                @change="coalPlanByIdList"
                clearable
              >
                <el-option
                    v-for="dict in qualityPlanOption"
                    :key="dict.id"
                    :label="dict.plan"
                    :value="dict.id"
                  v-for="dict in qualityPlanOption"
                  :key="dict.id"
                  :label="dict.plan"
                  :value="dict.id"
                ></el-option>
              </el-select>
            </el-form-item>
@@ -167,20 +309,47 @@
      </template>
    </el-dialog>
    <!-- 合并数据弹框 -->
    <el-dialog :title="operationType.value === 'edit' ? '编辑库存' : '合并库存'" v-model="mergeVisible" width="800px">
      <el-form :model="mergeForm" :rules="mergeRules" ref="mergeRef" label-width="100px">
    <el-dialog
      :title="operationType.value === 'edit' ? '编辑库存' : '合并库存'"
      v-model="mergeVisible"
      width="800px"
    >
      <el-form
        :model="mergeForm"
        :rules="mergeRules"
        ref="mergeRef"
        label-width="100px"
      >
        <el-row>
          <el-col :span="12">
            <el-form-item label="供应商名称" prop="supplierId">
              <el-select v-model="mergeForm.supplierId" placeholder="请选择供应商" :disabled="operationType === 'view'">
                <el-option :label="item.label" v-for="item in supplyList" :key="item.value" :value="item.value"/>
              <el-select
                v-model="mergeForm.supplierId"
                placeholder="请选择供应商"
                :disabled="operationType === 'view'"
              >
                <el-option
                  :label="item.label"
                  v-for="item in supplyList"
                  :key="item.value"
                  :value="item.value"
                />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="煤种" prop="coalId">
              <el-select v-model="mergeForm.coalId" placeholder="请选择煤种" :disabled="operationType === 'view'">
                <el-option :label="item.label" v-for="item in coalList" :key="item.value" :value="item.value"/>
              <el-select
                v-model="mergeForm.coalId"
                placeholder="请选择煤种"
                :disabled="operationType === 'view'"
              >
                <el-option
                  :label="item.label"
                  v-for="item in coalList"
                  :key="item.value"
                  :value="item.value"
                />
              </el-select>
            </el-form-item>
          </el-col>
@@ -188,48 +357,85 @@
        <el-row>
          <el-col :span="12">
            <el-form-item label="单位" prop="unit">
              <el-input v-model="mergeForm.unit" placeholder="请输入单位" maxlength="30" :disabled="operationType === 'view'"/>
              <el-input
                v-model="mergeForm.unit"
                placeholder="请输入单位"
                maxlength="30"
                :disabled="operationType === 'view'"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="库存数量" prop="inventoryQuantity">
              <el-input v-model="mergeForm.inventoryQuantity" placeholder="请输入库存数量" :max="inventoryQuantity" type="number" :disabled="operationType === 'view'"/>
              <el-input
                v-model="mergeForm.inventoryQuantity"
                placeholder="请输入库存数量"
                :max="inventoryQuantity"
                type="number"
                :disabled="operationType === 'view'"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="单价(含税)" prop="priceIncludingTax">
              <el-input v-model="mergeForm.priceIncludingTax" placeholder="请输入单价(含税)" maxlength="30" :disabled="operationType === 'view'" />
              <el-input
                v-model="mergeForm.priceIncludingTax"
                placeholder="请输入单价(含税)"
                maxlength="30"
                :disabled="operationType === 'view'"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="总价(含税)" prop="totalPriceIncludingTax">
              <el-input v-model="mergeForm.totalPriceIncludingTax" placeholder="请输入总价(含税)" maxlength="30" :disabled="operationType === 'view'" />
              <el-input
                v-model="mergeForm.totalPriceIncludingTax"
                placeholder="请输入总价(含税)"
                maxlength="30"
                :disabled="operationType === 'view'"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="单价(不含税)" prop="priceExcludingTax">
              <el-input v-model="mergeForm.priceExcludingTax" placeholder="请输入单价(不含税)" maxlength="30" :disabled="operationType === 'view'" />
              <el-input
                v-model="mergeForm.priceExcludingTax"
                placeholder="请输入单价(不含税)"
                maxlength="30"
                :disabled="operationType === 'view'"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="总价(不含税)" prop="totalPriceExcludingTax">
              <el-input v-model="mergeForm.totalPriceExcludingTax" placeholder="请输入总价(不含税)" maxlength="30" :disabled="operationType === 'view'" />
              <el-input
                v-model="mergeForm.totalPriceExcludingTax"
                placeholder="请输入总价(不含税)"
                maxlength="30"
                :disabled="operationType === 'view'"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="煤质方案" prop="coalPlanId">
              <el-select v-model="mergeForm.coalPlanId" placeholder="请选择" @change="coalPlanByIdList" clearable :disabled="operationType === 'view'">
              <el-select
                v-model="mergeForm.coalPlanId"
                placeholder="请选择"
                @change="coalPlanByIdList"
                clearable
                :disabled="operationType === 'view'"
              >
                <el-option
                    v-for="dict in qualityPlanOption"
                    :key="dict.id"
                    :label="dict.plan"
                    :value="dict.id"
                  v-for="dict in qualityPlanOption"
                  :key="dict.id"
                  :label="dict.plan"
                  :value="dict.id"
                ></el-option>
              </el-select>
            </el-form-item>
@@ -239,7 +445,10 @@
        <el-row>
          <el-col :span="12" v-for="item in filteredList" :key="item.id">
            <el-form-item :label="item.fieldName">
              <el-input v-model="mergeForm[item.fields]" :disabled="operationType === 'view'" />
              <el-input
                v-model="mergeForm[item.fields]"
                :disabled="operationType === 'view'"
              />
            </el-form-item>
          </el-col>
        </el-row>
@@ -255,25 +464,28 @@
</template>
<script setup>
import {onMounted, ref} from "vue";
import {Delete, Download, Refresh} from "@element-plus/icons-vue";
import { onMounted, ref } from "vue";
import { Delete, Download, Refresh } from "@element-plus/icons-vue";
import Pagination from "@/components/Pagination/index.vue";
import {
  addOrEditCoalValue,
  coalFieldList, coalPlanById,
  coalPlanList, officialInventoryList,
  pendingInventoryList
  coalFieldList,
  coalPlanById,
  coalPlanList,
  officialInventoryList,
  pendingInventoryList,
} from "@/api/warehouseManagement/index.js";
import {editOfficial, merge} from "../../api/warehouseManagement/index.js";
import {getSupplyList} from "@/api/procureMent/index.js";
import {getCoalInfoList} from "@/api/production/index.js";
import { editOfficial, merge } from "../../api/warehouseManagement/index.js";
import { getSupplyList } from "@/api/procureMent/index.js";
import { getCoalInfoList } from "@/api/production/index.js";
import { ElMessage } from "element-plus";
const { proxy } = getCurrentInstance()
const { proxy } = getCurrentInstance();
const tableData = ref([])
const selectedRows = ref([])
const qualityPlanOption = ref([])
const filteredList = ref([])
const tableData = ref([]);
const selectedRows = ref([]);
const qualityPlanOption = ref([]);
const filteredList = ref([]);
const tableLoading = ref(false);
const total = ref(0);
const pageNum = ref(1);
@@ -285,50 +497,58 @@
// 审核弹框
const reviewVisible = ref(false);
// 合并弹框
const mergeVisible = ref(false)
const operationType = ref('')
const mergeVisible = ref(false);
const operationType = ref("");
const data = reactive({
  form: {
    supplierName: '',
    coal: '',
    unit: '',
    inventoryQuantity: '',
    priceIncludingTax: '',
    totalPriceIncludingTax: '',
    priceExcludingTax: '',
    totalPriceExcludingTax: '',
    coalPlanId: '',
    pId: '',
    supplierName: "",
    coal: "",
    unit: "",
    inventoryQuantity: "",
    priceIncludingTax: "",
    totalPriceIncludingTax: "",
    priceExcludingTax: "",
    totalPriceExcludingTax: "",
    coalPlanId: "",
    pId: "",
  },
  mergeForm: {
    supplierId: '',
    coalId: '',
    unit: '',
    inventoryQuantity: '',
    priceIncludingTax: '',
    totalPriceIncludingTax: '',
    priceExcludingTax: '',
    totalPriceExcludingTax: '',
    coalPlanId: '',
    pId: '',
    supplierId: "",
    coalId: "",
    unit: "",
    inventoryQuantity: "",
    priceIncludingTax: "",
    totalPriceIncludingTax: "",
    priceExcludingTax: "",
    totalPriceExcludingTax: "",
    coalPlanId: "",
    pId: "",
  },
  rules: {
    supplierName: [{ required: true, message: "请输入供应商名称", trigger: "blur" }],
    supplierName: [
      { required: true, message: "请输入供应商名称", trigger: "blur" },
    ],
    coal: [{ required: true, message: "请输入煤种", trigger: "blur" }],
    unit: [{ required: true, message: "请输入单位", trigger: "blur" }],
    coalPlanId: [{ required: true, message: "请选择", trigger: "change" }],
    supplierId: [{ required: true, message: "请选择供应商", trigger: "change" }],
    supplierId: [
      { required: true, message: "请选择供应商", trigger: "change" },
    ],
  },
  mergeRules: {
    supplierName: [{ required: true, message: "请输入供应商名称", trigger: "blur" }],
    supplierName: [
      { required: true, message: "请输入供应商名称", trigger: "blur" },
    ],
    coal: [{ required: true, message: "请输入煤种", trigger: "blur" }],
    unit: [{ required: true, message: "请输入单位", trigger: "blur" }],
    coalPlanId: [{ required: true, message: "请选择", trigger: "change" }],
    supplierId: [{ required: true, message: "请选择供应商", trigger: "change" }],
  }
})
    supplierId: [
      { required: true, message: "请选择供应商", trigger: "change" },
    ],
  },
});
const { form, rules, mergeForm, mergeRules } = toRefs(data)
const { form, rules, mergeForm, mergeRules } = toRefs(data);
// 当前标签
const activeTab = ref("pendingInbound");
const tabName = ref("pendingInbound");
@@ -339,10 +559,10 @@
]);
// 查询参数
const queryParams = reactive({
    registrationDate: "",
    coal: "",
})
const columnTitle = ref([])
  registrationDate: "",
  coal: "",
});
const columnTitle = ref([]);
const supplyList = ref([]);
const coalList = ref([]);
@@ -380,52 +600,66 @@
  getList();
};
const summarizeChildrenTable = (param) => {
  return proxy.summarizeTable(param, ['inventoryQuantity', 'priceIncludingTax', 'totalPriceIncludingTax','priceExcludingTax','totalPriceExcludingTax']);
}
  return proxy.summarizeTable(param, [
    "inventoryQuantity",
    "priceIncludingTax",
    "totalPriceIncludingTax",
    "priceExcludingTax",
    "totalPriceExcludingTax",
  ]);
};
// 点击查询
const handleQuery = () => {
  pageNum.value = 1
  pageSize.value = 10
  getList()
}
  pageNum.value = 1;
  pageSize.value = 10;
  getList();
};
// 分页处理
const handlePagination = (val) => {
    pageNum.value = val.page;
    pageSize.value = val.limit;
    getList();
  pageNum.value = val.page;
  pageSize.value = val.limit;
  getList();
};
const getList = () => {
  tableLoading.value = true;
  // 赋值煤质表头展示字段
  if (tabName.value === "pendingInbound") {
    pendingInventoryList({ ...queryParams, current: pageNum.value, size: pageSize.value }).then(res => {
    pendingInventoryList({
      ...queryParams,
      current: pageNum.value,
      size: pageSize.value,
    }).then((res) => {
      tableLoading.value = false;
      tableData.value = res.data.records;
      total.value = res.data.total;
    })
    });
  } else {
    officialInventoryList({ ...queryParams, current: pageNum.value, size: pageSize.value }).then(res => {
    officialInventoryList({
      ...queryParams,
      current: pageNum.value,
      size: pageSize.value,
    }).then((res) => {
      tableLoading.value = false;
      const result = flattenFields(res.data.records);
      tableData.value = result;
      total.value = res.data.total;
      coalFieldListOption()
    })
      coalFieldListOption();
    });
  }
};
// 扁平化处理函数
const flattenFields = (data) => {
  return data.map(item => {
  return data.map((item) => {
    const mergedFields = item.fields.reduce((acc, obj) => {
      const key = Object.keys(obj)[0];
      acc[key] = obj[key];
      return acc;
    }, {});
    // 合并主对象与提取出的 fields 字段
    return {
      ...item,
      ...mergedFields
      ...mergedFields,
    };
  });
};
@@ -440,66 +674,91 @@
};
// 表格选择数据
const selectionChange = (rows) => {
  selectedRows.value = rows
}
  selectedRows.value = rows;
};
// 打开审核弹框
const reviewDia = (row) => {
  reviewVisible.value = true
  filteredList.value = []
  form.value = {...row}
  form.value.pId = row.id
  inventoryQuantity.value = row.inventoryQuantity
  getDropdownData()
  coalPlanListOptions()
}
  reviewVisible.value = true;
  filteredList.value = [];
  form.value = { ...row };
  form.value.pId = row.id;
  inventoryQuantity.value = row.inventoryQuantity;
  getDropdownData();
  coalPlanListOptions();
};
// 查询煤质方案下拉框
const coalPlanListOptions = () => {
  coalPlanList().then(res => {
    qualityPlanOption.value = res.data
  })
}
  coalPlanList().then((res) => {
    qualityPlanOption.value = res.data;
  });
};
// 查询煤质方案字段
const coalPlanByIdList = (id) => {
  coalPlanById({id: id}).then(res => {
    filteredList.value = res.data
    if(!id) {
      filteredList.value = []
  coalPlanById({ id: id }).then((res) => {
    filteredList.value = res.data;
    if (!id) {
      filteredList.value = [];
    }
  })
}
  });
};
// 查询煤质字段
const coalFieldListOption = () => {
  coalFieldList().then(res => {
    filteredList.value = res.data
    columnTitle.value = res.data.map(item => {
  coalFieldList().then((res) => {
    filteredList.value = res.data;
    columnTitle.value = res.data.map((item) => {
      return {
        prop: item.fields,
        label: item.fieldName // 使用 fieldName 作为 label
        label: item.fieldName, // 使用 fieldName 作为 label
      };
    });
  })
}
  });
};
const handleExport = () => {
  const config = { api: "/officialInventory/export", name: "正式库" };
  proxy.$modal
    .confirm(
      "是否要导出" +
        (selectedRows.value.length > 0
          ? `选中的${selectedRows.value.length}条`
          : "全部") +
        "数据?"
    )
    .then((res) => {
      if (res) {
        ElMessage.success("正在导出数据,请稍候...");
        exportData(config.api, config.name);
      }
    })
    .catch(() => {});
};
const exportData = (api, name) => {
  proxy.download(
    api,
    { exportIds: selectedRows.value.map((row) => row.id) },
    `${new Date().getTime()}${name}${new Date().toLocaleDateString("en-CA")}.xlsx`
  );
};
// 合并库存数据方法
const mergeRows = (type,row) => {
  getDropdownData()
  coalPlanListOptions()
  if (type === 'edit') {
const mergeRows = (type, row) => {
  getDropdownData();
  coalPlanListOptions();
  if (type === "edit") {
    mergeVisible.value = true;
  }
  operationType.value = type;
  if (type !== 'merge') {
    mergeForm.value = {...row}
  if (type !== "merge") {
    mergeForm.value = { ...row };
  } else {
    if (selectedRows.value.length < 2) {
      proxy.$modal.msgWarning('请至少选择两条数据')
      return
      proxy.$modal.msgWarning("请至少选择两条数据");
      return;
    }
    mergeVisible.value = true;
    filteredList.value.forEach(item => {
      mergeForm.value[item.fields] = ''
    })
    const data = selectedRows.value
    const selectedIds = selectedRows.value.map(row => row.id);
    filteredList.value.forEach((item) => {
      mergeForm.value[item.fields] = "";
    });
    const data = selectedRows.value;
    const selectedIds = selectedRows.value.map((row) => row.id);
    // 初始化合计和均值变量
    let totalInventory = 0;
    let totalPriceIncludingTax = 0;
@@ -507,7 +766,7 @@
    let priceIncludingTaxSum = 0;
    let priceExcludingTaxSum = 0;
    // 遍历所有选中数据,累加计算
    data.forEach(row => {
    data.forEach((row) => {
      totalInventory += parseFloat(row.inventoryQuantity) || 0;
      priceIncludingTaxSum += parseFloat(row.priceIncludingTax) || 0;
      totalPriceIncludingTax += parseFloat(row.totalPriceIncludingTax) || 0;
@@ -515,10 +774,18 @@
      totalPriceExcludingTax += parseFloat(row.totalPriceExcludingTax) || 0;
    });
    // 计算平均值并保留两位小数
    const avgPriceIncludingTax = Number((priceIncludingTaxSum / data.length).toFixed(2));
    const avgTotalPriceIncludingTax = Number((totalPriceIncludingTax / data.length).toFixed(2));
    const avgPriceExcludingTax = Number((priceExcludingTaxSum / data.length).toFixed(2));
    const avgTotalPriceExcludingTax = Number((totalPriceExcludingTax / data.length).toFixed(2));
    const avgPriceIncludingTax = Number(
      (priceIncludingTaxSum / data.length).toFixed(2)
    );
    const avgTotalPriceIncludingTax = Number(
      (totalPriceIncludingTax / data.length).toFixed(2)
    );
    const avgPriceExcludingTax = Number(
      (priceExcludingTaxSum / data.length).toFixed(2)
    );
    const avgTotalPriceExcludingTax = Number(
      (totalPriceExcludingTax / data.length).toFixed(2)
    );
    // 设置表单显示
    mergeForm.value.inventoryQuantity = totalInventory;
    mergeForm.value.priceIncludingTax = avgPriceIncludingTax;
@@ -527,81 +794,81 @@
    mergeForm.value.totalPriceExcludingTax = avgTotalPriceExcludingTax;
    mergeForm.value.ids = selectedIds;
  }
}
};
// 提交合并表单
const submitForm = () => {
  proxy.$refs.mergeRef.validate(valid => {
  proxy.$refs.mergeRef.validate((valid) => {
    if (valid) {
      delete mergeForm.value.createTime
      delete mergeForm.value.updateTime
      if (operationType.value === 'edit') {
      delete mergeForm.value.createTime;
      delete mergeForm.value.updateTime;
      if (operationType.value === "edit") {
        mergeForm.value.fields = filteredList.value.reduce((acc, item) => {
          const key = item.fields;
          const value = mergeForm.value[key];
          // 判断是否有值(你可以根据需要修改判断条件)
          if (value !== null && value !== undefined && value !== '') {
          if (value !== null && value !== undefined && value !== "") {
            acc.push({ [key]: value });
          }
          return acc;
        }, []);
        editOfficial(mergeForm.value).then(() => {
          cancel()
          proxy.$modal.msgSuccess('修改成功')
          handleQuery()
        })
          cancel();
          proxy.$modal.msgSuccess("修改成功");
          handleQuery();
        });
      } else {
        mergeForm.value.fields = filteredList.value.reduce((acc, item) => {
          const key = item.fields;
          const value = mergeForm.value[key];
          // 判断是否有值(你可以根据需要修改判断条件)
          if (value !== null && value !== undefined && value !== '') {
          if (value !== null && value !== undefined && value !== "") {
            acc.push({ [key]: value });
          }
          return acc;
        }, []);
        mergeForm.value.type = 2
        mergeForm.value.type = 2;
        merge(mergeForm.value).then(() => {
          cancel()
          proxy.$modal.msgSuccess('合并成功')
          handleQuery()
        })
          cancel();
          proxy.$modal.msgSuccess("合并成功");
          handleQuery();
        });
      }
    }
  })
}
  });
};
// 关闭合并表单
const cancel = () => {
  proxy.$refs.mergeRef.resetFields();
  mergeVisible.value = false
}
  mergeVisible.value = false;
};
// 提交审核表单
const submitReviewForm = () => {
  proxy.$refs.formRef.validate((valid) => {
    if (valid) {
      delete form.value.registrationTime
      delete form.value.createTime
      delete form.value.updateTime
      form.value.type = 1
      form.value.fieldValue = filteredList.value.map(item => ({
        [item.fields]: form.value[item.fields]
      }))
      delete form.value.registrationTime;
      delete form.value.createTime;
      delete form.value.updateTime;
      form.value.type = 1;
      form.value.fieldValue = filteredList.value.map((item) => ({
        [item.fields]: form.value[item.fields],
      }));
      addOrEditCoalValue(form.value).then(() => {
        cancelReview()
        proxy.$modal.msgSuccess('提交成功')
        handleQuery()
      })
        cancelReview();
        proxy.$modal.msgSuccess("提交成功");
        handleQuery();
      });
    }
  })
}
  });
};
// 关闭审核弹框
const cancelReview = () => {
  proxy.$refs.formRef.resetFields()
  reviewVisible.value = false
}
  proxy.$refs.formRef.resetFields();
  reviewVisible.value = false;
};
</script>
<style scoped>
:deep(.el-table) {
  margin: 20px 0;
}
</style>
</style>