gaoluyang
11 小时以前 ab264123941cd3d345687af92aab2a9e04968960
src/views/inventoryManagement/receiptManagement/Record.vue
@@ -1,49 +1,52 @@
<template>
  <div>
    <div class="search_form" style="margin-bottom: 10px;">
      <el-form
          ref="searchFormRef"
          :model="searchForm"
          class="demo-form-inline"
      >
    <div class="search_form"
         style="margin-bottom: 10px;">
      <el-form ref="searchFormRef"
               :model="searchForm"
               class="demo-form-inline">
        <el-row :gutter="20">
          <el-col :span="4">
            <el-form-item label="入库日期" prop="timeStr">
            <el-form-item label="入库日期"
                          prop="timeStr">
              <el-date-picker v-model="searchForm.timeStr"
                              type="date"
                              placeholder="请选择日期"
                              value-format="YYYY-MM-DD"
                              format="YYYY-MM-DD"
                              clearable/>
                              clearable />
            </el-form-item>
          </el-col>
          <el-col :span="4">
            <el-form-item label="产品大类" prop="productName">
            <el-form-item label="产品大类"
                          prop="productName">
              <el-input v-model="searchForm.productName"
                        style="width: 240px"
                        placeholder="请输入"
                        clearable/>
                        clearable />
            </el-form-item>
          </el-col>
          <el-col :span="4">
            <el-form-item label="产品规格" prop="model">
            <el-form-item label="规格型号"
                          prop="model">
              <el-input v-model="searchForm.model"
                        style="width: 240px"
                        placeholder="请输入"
                        clearable/>
                        clearable />
            </el-form-item>
          </el-col>
          <el-col :span="4">
            <el-form-item label="批号" prop="batchNo">
            <el-form-item label="批号"
                          prop="batchNo">
              <el-input v-model="searchForm.batchNo"
                        style="width: 240px"
                        placeholder="请输入"
                        clearable/>
                        clearable />
            </el-form-item>
          </el-col>
          <el-col :span="4">
            <el-form-item label="来源" prop="recordType">
            <el-form-item label="来源"
                          prop="recordType">
              <el-select v-model="searchForm.recordType"
                         style="width: 240px"
                         placeholder="请选择"
@@ -51,17 +54,17 @@
                <el-option v-for="item in stockRecordTypeOptions"
                           :key="item.value"
                           :label="item.label"
                           :value="item.value"/>
                           :value="item.value" />
              </el-select>
            </el-form-item>
          </el-col>
          <!-- 按钮 -->
          <el-col :span="4">
            <el-form-item>
              <el-button type="primary" @click="getList">
              <el-button type="primary"
                         @click="getList">
                搜索
              </el-button>
              <el-button @click="resetSearch">
                重置
              </el-button>
@@ -71,10 +74,15 @@
      </el-form>
    </div>
    <div class="actions">
      <el-button type="primary" @click="handleBatchApprove">审批</el-button>
      <el-button type="primary"
                 :disabled="!canBatchApprove"
                 @click="handleBatchApprove">审批</el-button>
      <el-button :disabled="!canReverseApprove"
                 @click="handleReverseApprove">反审</el-button>
      <el-button @click="handleOut">导出</el-button>
      <el-button type="danger"
                 plain
                 :disabled="!canDelete"
                 @click="handleDelete">删除
      </el-button>
    </div>
@@ -89,37 +97,37 @@
                height="calc(100vh - 18.5em)">
        <el-table-column align="center"
                         type="selection"
                         :selectable="isRowSelectableForApprove"
                         width="55"/>
                         :selectable="isRowSelectable"
                         width="55" />
        <el-table-column align="center"
                         label="序号"
                         type="index"
                         width="60"/>
                         width="60" />
        <el-table-column label="入库批次"
                         prop="inboundBatches"
                         width="280"
                         show-overflow-tooltip/>
                         width="200"
                         show-overflow-tooltip />
        <el-table-column label="入库时间"
                         prop="createTime"
                         show-overflow-tooltip/>
                         show-overflow-tooltip />
        <el-table-column label="产品大类"
                         prop="productName"
                         show-overflow-tooltip/>
                         show-overflow-tooltip />
        <el-table-column label="规格型号"
                         prop="model"
                         show-overflow-tooltip/>
                         show-overflow-tooltip />
        <el-table-column label="批号"
                         prop="batchNo"
                         show-overflow-tooltip/>
                         show-overflow-tooltip />
        <el-table-column label="单位"
                         prop="unit"
                         show-overflow-tooltip/>
                         show-overflow-tooltip />
        <el-table-column label="入库数量"
                         prop="stockInNum"
                         show-overflow-tooltip/>
                         show-overflow-tooltip />
        <el-table-column label="入库人"
                         prop="createBy"
                         show-overflow-tooltip/>
                         show-overflow-tooltip />
        <el-table-column label="来源"
                         prop="recordType"
                         show-overflow-tooltip>
@@ -127,11 +135,21 @@
            {{ getRecordType(scope.row.recordType) }}
          </template>
        </el-table-column>
        <el-table-column v-if="showSourceOrderNoColumn"
                         label="源单号"
                         width="150"
                         prop="sourceOrderNo"
                         show-overflow-tooltip>
          <template #default="scope">
            {{ formatSourceOrderNo(scope.row?.sourceOrderNo) }}
          </template>
        </el-table-column>
        <el-table-column label="审批状态"
                         prop="approvalStatus"
                         show-overflow-tooltip>
          <template #default="scope">
            <el-tag :type="getApprovalStatusTagType(scope.row.approvalStatus)" size="small">
            <el-tag :type="getApprovalStatusTagType(scope.row.approvalStatus)"
                    size="small">
              {{ getApprovalStatusLabel(scope.row.approvalStatus) }}
            </el-tag>
          </template>
@@ -142,252 +160,355 @@
                  layout="total, sizes, prev, pager, next, jumper"
                  :page="page.current"
                  :limit="page.size"
                  @pagination="pageProductChange"/>
                  @pagination="pageProductChange" />
    </div>
  </div>
</template>
<script setup>
import pagination from "@/components/PIMTable/Pagination.vue";
import {
  ref,
  reactive,
  toRefs,
  onMounted,
  getCurrentInstance,
} from "vue";
import {ElMessageBox} from "element-plus";
import {
  getStockInRecordListPage,
  batchDeletePendingStockInRecords,
  batchApproveStockInRecords,
} from "@/api/inventoryManagement/stockInRecord.js";
import {
  findAllQualifiedStockInRecordTypeOptions,
  // findAllUnQualifiedStockInRecordTypeOptions,
} from "@/api/basicData/enum.js";
  import pagination from "@/components/PIMTable/Pagination.vue";
  import {
    ref,
    reactive,
    toRefs,
    computed,
    onMounted,
    getCurrentInstance,
  } from "vue";
  import { ElMessageBox } from "element-plus";
  import {
    getStockInRecordListPage,
    batchDeletePendingStockInRecords,
    batchApproveStockInRecords,
    batchUnapproveStockInRecords,
  } from "@/api/inventoryManagement/stockInRecord.js";
  import {
    findAllQualifiedStockInRecordTypeOptions,
    // findAllUnQualifiedStockInRecordTypeOptions,
  } from "@/api/basicData/enum.js";
const {proxy} = getCurrentInstance();
  const { proxy } = getCurrentInstance();
const props = defineProps({
  type: {
    type: String,
    required: true,
    default: '0'
  },
  topParentProductId: {
    type: [String, Number],
    default: undefined
  }
})
  const props = defineProps({
    type: {
      type: String,
      required: true,
      default: "0",
    },
    topParentProductId: {
      type: [String, Number],
      default: undefined,
    },
  });
const tableData = ref([]);
const selectedRows = ref([]);
const tableLoading = ref(false);
// 来源类型选项
const stockRecordTypeOptions = ref([]);
const page = reactive({
  current: 1,
  size: 10,
});
const total = ref(0);
  const tableData = ref([]);
  const selectedRows = ref([]);
  const tableLoading = ref(false);
  // 来源类型选项
  const stockRecordTypeOptions = ref([]);
  const page = reactive({
    current: 1,
    size: 10,
  });
  const total = ref(0);
const data = reactive({
  searchForm: {
    productName: "",
    batchNo: "",
    model: "",
    timeStr: "",
    recordType: "",
  },
});
const {searchForm} = toRefs(data);
const searchFormRef = ref(null);
  const data = reactive({
    searchForm: {
      productName: "",
      batchNo: "",
      model: "",
      timeStr: "",
      recordType: "",
    },
  });
  const { searchForm } = toRefs(data);
  const searchFormRef = ref(null);
const resetSearch = () => {
  searchFormRef.value?.resetFields();
  page.current = 1;
  getList();
}
  const resetSearch = () => {
    searchFormRef.value?.resetFields();
    page.current = 1;
    getList();
  };
const getRecordType = (recordType) => {
  return stockRecordTypeOptions.value.find(item => item.value === recordType)?.label || ''
}
  const getRecordType = recordType => {
    return (
      stockRecordTypeOptions.value.find(item => item.value === recordType)
        ?.label || ""
    );
  };
const approvalStatusLabelMap = {
  0: "待审批",
  1: "通过",
  2: "驳回",
  pending: "待审批",
  approved: "通过",
  rejected: "驳回",
  PENDING: "待审批",
  APPROVED: "通过",
  REJECTED: "驳回",
};
approvalStatusLabelMap[3] = "待确认";
  const approvalStatusLabelMap = {
    0: "待审批",
    1: "通过",
    2: "驳回",
    pending: "待审批",
    approved: "通过",
    rejected: "驳回",
    PENDING: "待审批",
    APPROVED: "通过",
    REJECTED: "驳回",
  };
  approvalStatusLabelMap[3] = "待确认";
const getApprovalStatusLabel = (status) => {
  if (status === null || status === undefined || status === "") {
    return "待审批";
  }
  return approvalStatusLabelMap[status] || "待审批";
};
  const getApprovalStatusLabel = status => {
    if (status === null || status === undefined || status === "") {
      return "待审批";
    }
    return approvalStatusLabelMap[status] || "待审批";
  };
// 通过/驳回固定色;其余(含待审批、空值、未映射但文案为待审批)统一用 warning 预警色
const getApprovalStatusTagType = (status) => {
  if (status === 1 || status === "1" || status === "approved" || status === "APPROVED") return "success";
  if (status === 2 || status === "2" || status === "rejected" || status === "REJECTED") return "danger";
  return "warning";
};
  // 通过/驳回固定色;其余(含待审批、空值、未映射但文案为待审批)统一用 warning 预警色
  const getApprovalStatusTagType = status => {
    if (
      status === 1 ||
      status === "1" ||
      status === "approved" ||
      status === "APPROVED"
    )
      return "success";
    if (
      status === 2 ||
      status === "2" ||
      status === "rejected" ||
      status === "REJECTED"
    )
      return "danger";
    return "warning";
  };
const isPendingApproval = status => {
  return status === 0 || status === "0" || status === "pending" || status === "PENDING" || status === null || status === undefined || status === "";
};
  const isPendingApproval = status => {
    return (
      status === 0 ||
      status === "0" ||
      status === "pending" ||
      status === "PENDING" ||
      status === null ||
      status === undefined ||
      status === ""
    );
  };
const isRowSelectableForApprove = row => {
  return isPendingApproval(row?.approvalStatus);
};
  const isRejectedApproval = status => {
    return (
      status === 2 ||
      status === "2" ||
      status === "rejected" ||
      status === "REJECTED"
    );
  };
const pageProductChange = obj => {
  page.current = obj.page;
  page.size = obj.limit;
  getList();
};
  const isRowSelectable = row => {
    return (
      isPendingApproval(row?.approvalStatus) ||
      isRejectedApproval(row?.approvalStatus)
    );
  };
const getList = () => {
  tableLoading.value = true;
  getStockInRecordListPage(Object.assign({}, {...searchForm.value, ...page,  topParentProductId: props.topParentProductId}))
  const canBatchApprove = computed(() => {
    return (
      selectedRows.value.length > 0 &&
      selectedRows.value.every(row => isPendingApproval(row.approvalStatus))
    );
  });
  const canReverseApprove = computed(() => {
    return (
      selectedRows.value.length > 0 &&
      selectedRows.value.every(row => isRejectedApproval(row.approvalStatus))
    );
  });
  const canDelete = computed(() => canBatchApprove.value);
  const showSourceOrderNoColumn = computed(() => {
    const topParentProductId = Number(props.topParentProductId);
    return topParentProductId === 276 || topParentProductId === 278;
  });
  const formatSourceOrderNo = value => {
    const text = String(value ?? "").trim();
    return text || "--";
  };
  const pageProductChange = obj => {
    page.current = obj.page;
    page.size = obj.limit;
    getList();
  };
  const getList = () => {
    tableLoading.value = true;
    getStockInRecordListPage(
      Object.assign(
        {},
        {
          ...searchForm.value,
          ...page,
          topParentProductId: props.topParentProductId,
        }
      )
    )
      .then(res => {
        tableData.value = res.data.records;
        total.value = res.data.total || 0;
      }).finally(() => {
    tableLoading.value = false;
  })
};
      })
      .finally(() => {
        tableLoading.value = false;
      });
  };
// 获取来源类型选项
const fetchStockRecordTypeOptions = () => {
  if (props.type === '0') {
    findAllQualifiedStockInRecordTypeOptions()
        .then(res => {
          stockRecordTypeOptions.value = res.data;
        })
    return
  }
  // findAllUnQualifiedStockInRecordTypeOptions()
  //     .then(res => {
  //       stockRecordTypeOptions.value = res.data;
  //     })
}
  // 获取来源类型选项
  const fetchStockRecordTypeOptions = () => {
    if (props.type === "0") {
      findAllQualifiedStockInRecordTypeOptions().then(res => {
        stockRecordTypeOptions.value = res.data;
      });
      return;
    }
    // findAllUnQualifiedStockInRecordTypeOptions()
    //     .then(res => {
    //       stockRecordTypeOptions.value = res.data;
    //     })
  };
// 表格选择数据
const handleSelectionChange = selection => {
  selectedRows.value = selection.filter(item => item.id && isPendingApproval(item.approvalStatus));
};
  // 表格选择数据
  const handleSelectionChange = selection => {
    selectedRows.value = selection.filter(
      item => item.id && isRowSelectable(item)
    );
  };
const expandedRowKeys = ref([]);
  const expandedRowKeys = ref([]);
const handleBatchApprove = () => {
  if (selectedRows.value.length === 0) {
    proxy.$modal.msgWarning("请选择数据");
    return;
  }
  const ids = selectedRows.value.map(item => item.id);
  ElMessageBox.confirm("请选择审批结果", "审批", {
    confirmButtonText: "通过",
    cancelButtonText: "驳回",
    type: "warning",
    distinguishCancelAndClose: true,
  })
  const handleReverseApprove = () => {
    if (!canReverseApprove.value) {
      proxy.$modal.msgWarning("请选择已驳回的数据");
      return;
    }
    const ids = selectedRows.value.map(item => item.id);
    ElMessageBox.confirm("反审后记录将恢复为待审批状态,是否确认反审?", "反审", {
      confirmButtonText: "确认",
      cancelButtonText: "取消",
      type: "warning",
    })
      .then(() => {
        batchApproveStockInRecords({ids, approvalStatus: 1})
        batchUnapproveStockInRecords({ ids })
          .then(() => {
            proxy.$modal.msgSuccess("反审成功");
            getList();
          })
          .catch(() => {
            proxy.$modal.msgError("反审失败");
          });
      })
      .catch(() => {
        proxy.$modal.msg("已取消");
      });
  };
  const handleBatchApprove = () => {
    if (!canBatchApprove.value) {
      proxy.$modal.msgWarning("请选择待审批的数据");
      return;
    }
    const ids = selectedRows.value.map(item => item.id);
    ElMessageBox.confirm("请选择审批结果", "审批", {
      confirmButtonText: "通过",
      cancelButtonText: "驳回",
      type: "warning",
      distinguishCancelAndClose: true,
    })
      .then(() => {
        batchApproveStockInRecords({ ids, approvalStatus: 1 })
          .then(() => {
            proxy.$modal.msgSuccess("审批通过成功");
            getList();
          })
          .catch(() => {
            proxy.$modal.msgError("审批通过失败");
          });
      })
      .catch(action => {
        if (action === "cancel") {
          batchApproveStockInRecords({ ids, approvalStatus: 2 })
            .then(() => {
              proxy.$modal.msgSuccess("审批通过成功");
              proxy.$modal.msgSuccess("审批驳回成功");
              getList();
            })
            .catch(() => {
              proxy.$modal.msgError("审批通过失败");
              proxy.$modal.msgError("审批驳回失败");
            });
      })
      .catch((action) => {
        if (action === "cancel") {
          batchApproveStockInRecords({ids, approvalStatus: 2})
              .then(() => {
                proxy.$modal.msgSuccess("审批驳回成功");
                getList();
              })
              .catch(() => {
                proxy.$modal.msgError("审批驳回失败");
              });
          return;
        }
        proxy.$modal.msg("已取消");
      });
};
  };
// 导出
const handleOut = () => {
  ElMessageBox.confirm("是否确认导出?", "导出", {
    confirmButtonText: "确认",
    cancelButtonText: "取消",
    type: "warning",
  })
  // 导出
  const handleOut = () => {
    ElMessageBox.confirm("是否确认导出?", "导出", {
      confirmButtonText: "确认",
      cancelButtonText: "取消",
      type: "warning",
    })
      .then(() => {
        // 根据不同的 tab 类型调用不同的导出接口
        proxy.download("/stockInRecord/exportStockInRecord", {type: props.type}, props.type === '0' ? "合格入库.xlsx" : "不合格入库.xlsx");
        proxy.download(
          "/stockInRecord/exportStockInRecord",
          { type: props.type },
          props.type === "0" ? "合格入库.xlsx" : "不合格入库.xlsx"
        );
      })
      .catch(() => {
        proxy.$modal.msg("已取消");
      });
};
  };
// 删除
const handleDelete = () => {
  if (selectedRows.value.length === 0) {
    proxy.$modal.msgWarning("请选择数据");
    return;
  }
  const ids = selectedRows.value.map(item => item.id);
  // 删除
  const handleDelete = () => {
    if (!canDelete.value) {
      proxy.$modal.msgWarning("请选择待审批的数据");
      return;
    }
    const ids = selectedRows.value.map(item => item.id);
  ElMessageBox.confirm("选中的内容将被删除,是否确认删除?", "删除", {
    confirmButtonText: "确认",
    cancelButtonText: "取消",
    type: "warning",
  })
    ElMessageBox.confirm("选中的内容将被删除,是否确认删除?", "删除", {
      confirmButtonText: "确认",
      cancelButtonText: "取消",
      type: "warning",
    })
      .then(() => {
        batchDeletePendingStockInRecords(ids)
            .then(() => {
              proxy.$modal.msgSuccess("删除成功");
              getList();
            })
            .catch(() => {
              proxy.$modal.msgError("删除失败");
            });
          .then(() => {
            proxy.$modal.msgSuccess("删除成功");
            getList();
          })
          .catch(() => {
            proxy.$modal.msgError("删除失败");
          });
      })
      .catch(() => {
        proxy.$modal.msg("已取消");
      });
};
  };
onMounted(() => {
  getList();
  fetchStockRecordTypeOptions();
});
watch(
  () => props.topParentProductId,
  () => {
    page.current = 1;
  onMounted(() => {
    getList();
  }
);
    fetchStockRecordTypeOptions();
  });
  watch(
    () => props.topParentProductId,
    () => {
      page.current = 1;
      getList();
    }
  );
</script>
<style scoped lang="scss">
.actions {
  display: flex;
  justify-content: flex-end;
  margin-bottom: 10px;
}
</style>
  .actions {
    display: flex;
    justify-content: flex-end;
    margin-bottom: 10px;
  }
</style>