zouyu
2026-01-16 30dc46174a37613366081bd1abab8eb71c171f7f
src/views/productionManagement/productionOrder/index.vue
@@ -1,197 +1,382 @@
<template>
   <div class="app-container">
      <div class="search_form">
         <div>
            <span class="search_title">客户名称:</span>
            <el-input
               v-model="searchForm.customerName"
               style="width: 240px"
               placeholder="请输入"
               @change="handleQuery"
               clearable
               prefix-icon="Search"
            />
            <span class="search_title ml10">项目名称:</span>
            <el-input
               v-model="searchForm.projectName"
               style="width: 240px"
               placeholder="请输入"
               @change="handleQuery"
               clearable
               prefix-icon="Search"
            />
            <span class="search_title ml10">录入日期:</span>
            <el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
                                    placeholder="请选择" clearable @change="changeDaterange" />
            <el-button type="primary" @click="handleQuery" style="margin-left: 10px"
            >搜索</el-button
            >
         </div>
         <div>
            <el-button @click="handleOut">导出</el-button>
         </div>
      </div>
      <div class="table_list">
         <PIMTable
            rowKey="id"
            :column="tableColumn"
            :tableData="tableData"
            :page="page"
            :tableLoading="tableLoading"
            @pagination="pagination"
         ></PIMTable>
      </div>
   </div>
  <div class="app-container">
    <div class="search_form">
      <div>
        <span class="search_title">产品大类:</span>
<!--        <el-tree-select-->
<!--            v-model="searchForm.productCategory"-->
<!--            :data="productOptions"-->
<!--            placeholder="请选择"-->
<!--            clearable-->
<!--            check-strictly-->
<!--            :render-after-expand="false"-->
<!--            style="width: 240px"-->
<!--            @change="handleQuery"-->
<!--        />-->
        <el-input
            v-model="searchForm.productCategory"
            style="width: 240px"
            placeholder="请输入"
            @change="handleQuery"
            clearable
            prefix-icon="Search"
        />
        <span class="search_title ml10">录入日期:</span>
        <el-date-picker v-model="searchForm.registerDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
                        placeholder="请选择" clearable @change="changeDaterange" />
        <el-button type="primary" @click="handleQuery" style="margin-left: 10px"
        >搜索</el-button
        >
      </div>
      <div>
        <el-button type="primary" @click="openDialog('create')">新增订单</el-button>
        <el-button @click="handleOut">导出</el-button>
      </div>
    </div>
    <div class="table_list">
      <PIMTable
          rowKey="id"
          :column="tableColumn"
          :tableData="tableData"
          :page="page"
          :tableLoading="tableLoading"
          @pagination="pagination"
      >
        <template #action="{ row }">
          <el-button type="primary" link @click="handleEdit(row)">编辑</el-button>
          <el-button type="danger" link @click="handleDelete(row)">删除</el-button>
        </template>
      </PIMTable>
    </div>
    <el-dialog v-model="dialogVisible" :title="dialogTitle" width="40%" @close="closeDialog">
      <el-form ref="formRef" :model="form" :rules="formRules" label-width="100px">
        <el-form-item label="录入日期" prop="registerDate">
          <el-date-picker v-model="form.registerDate" type="date" value-format="YYYY-MM-DD" format="YYYY-MM-DD" placeholder="请选择录入日期" style="width: 100%"/>
        </el-form-item>
        <el-form-item label="产品大类" prop="productCategory">
          <el-input
              v-model="form.productCategory"
              placeholder="请输入产品大类"
              clearable
          />
        </el-form-item>
        <el-form-item label="规格型号" prop="specificationModel">
          <el-input
              v-model="form.specificationModel"
              placeholder="请输入规格型号"
              clearable
          />
        </el-form-item>
        <el-form-item label="单位" prop="unit">
          <el-input
              v-model="form.unit"
              placeholder="请输入单位"
              clearable
          />
        </el-form-item>
        <el-form-item label="数量" prop="quantity">
          <el-input-number v-model="form.quantity" :min="0" :step="0.1" style="width: 100%"/>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitForm">确认</el-button>
          <el-button @click="closeDialog">取消</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>
<script setup>
import {onMounted, ref} from "vue";
import {onMounted, ref, reactive, toRefs, getCurrentInstance} from "vue";
import { ElMessageBox } from "element-plus";
import dayjs from "dayjs";
import {schedulingListPage} from "@/api/productionManagement/productionOrder.js";
import {schedulingListPage, addProductionOrder, updateProductionOrder, deleteProductionOrder} from "@/api/productionManagement/productionOrder.js";
import {productTreeList} from "@/api/basicData/product.js";
const { proxy } = getCurrentInstance();
const tableColumn = ref([
   {
      label: "录入日期",
      prop: "entryDate",
      width: 120,
   },
   {
      label: "合同号",
      prop: "salesContractNo",
      width: 220,
   },
   {
      label: "客户合同号",
      prop: "customerContractNo",
      width: 250,
   },
   {
      label: "客户名称",
      prop: "customerName",
      width: 250,
   },
   {
      label: "项目名称",
      prop: "projectName",
      width:300
   },
   {
      label: "付款状态",
      prop: "status",
      dataType: "tag",
      formatType: (params) => {
         if (params == '未完成') {
            return "danger";
         } else if (params == '已完成') {
            return "success";
         } else {
            return null;
         }
      },
   },
   {
      label: "产品大类",
      prop: "productCategory",
      width: 160,
   },
   {
      label: "规格型号",
      prop: "specificationModel",
      width: 220,
   },
   {
      label: "单位",
      prop: "unit",
      width:90
   },
   {
      label: "数量",
      prop: "quantity",
   },
   {
      label: "排产数量",
      prop: "schedulingNum",
      width: 100,
   },
   {
      label: "完工数量",
      prop: "successNum",
      width: 100,
   },
  {
    label: "录入日期",
    prop: "registerDate",
    width: 120,
  },
  {
    label: "生产订单号",
    prop: "orderNo",
  },
  {
    label: "产品大类",
    prop: "productCategory",
  },
  {
    label: "规格型号",
    prop: "specificationModel",
  },
  {
    label: "单位",
    prop: "unit",
  },
  {
    label: "数量",
    prop: "quantity",
  },
  // {
  //     label: "排产数量",
  //     prop: "schedulingNum",
  //     width: 100,
  // },
  // {
  //     label: "完工数量",
  //     prop: "successNum",
  //     width: 100,
  // },
  {
    label: "操作",
    prop: "action",
    width: 120,
    fixed: "right",
    dataType: "slot",
    align: "center",
    slot: "action"
  }
]);
const tableData = ref([]);
const tableLoading = ref(false);
const page = reactive({
   current: 1,
   size: 100,
   total: 0,
const page = ref({
  current: 1,
  size: 100,
  total: 0,
});
const dialogVisible = ref(false);
const dialogTitle = ref("");
const dialogMode = ref(""); // 'create' 或 'edit'
const formRef = ref();
const productOptions = ref([]);
const form = reactive({
  id: null,
  registerDate: dayjs().format("YYYY-MM-DD"),
  productCategory: "",
  specificationModel: "",
  unit: "",
  quantity: null,
});
const formRules = {
  registerDate: [{ required: true, message: "请选择录入日期", trigger: "change" }],
  productCategory: [{ required: true, message: "请输入产品大类", trigger: "blur" }],
  specificationModel: [{ required: true, message: "请输入规格型号", trigger: "blur" }],
  unit: [{ required: true, message: "请输入单位", trigger: "blur" }],
  quantity: [{ required: true, message: "请输入数量", trigger: "blur" }],
};
const data = reactive({
   searchForm: {
      customerName: "",
      projectName: "",
      entryDate: null, // 录入日期
      entryDateStart: undefined,
      entryDateEnd: undefined,
   },
  searchForm: {
    productCategory: "",
    registerDate: null, // 录入日期
    entryDateStart: undefined,
    entryDateEnd: undefined,
  },
});
const { searchForm } = toRefs(data);
const openDialog = (mode, row = null) => {
  dialogMode.value = mode;
  if (mode === 'create') {
    dialogTitle.value = "新增生产订单";
    resetForm();
  } else if (mode === 'edit') {
    dialogTitle.value = "编辑生产订单";
    resetForm();
    console.log('编辑数据:', row);
    // 填充编辑数据
    form.id = row.id;
    form.registerDate = row.registerDate;
    form.productCategory = row.productCategory;
    form.specificationModel = row.specificationModel;
    form.unit = row.unit;
    form.quantity = row.quantity;
  }
  dialogVisible.value = true;
};
const closeDialog = () => {
  dialogVisible.value = false;
};
const resetForm = () => {
  form.id = null;
  form.registerDate = dayjs().format("YYYY-MM-DD");
  form.productCategory = "";
  form.specificationModel = "";
  form.unit = "";
  form.quantity = null;
};
const submitForm = () => {
  formRef.value?.validate(async (valid) => {
    if (!valid) return;
    try {
      const payload = {
        registerDate: form.registerDate,
        productCategory: form.productCategory,
        specificationModel: form.specificationModel,
        unit: form.unit,
        quantity: form.quantity,
      };
      if (dialogMode.value === 'create') {
        await addProductionOrder(payload);
        proxy.$modal.msgSuccess("新增成功");
      } else if (dialogMode.value === 'edit') {
        payload.id = form.id;
        await updateProductionOrder(payload);
        proxy.$modal.msgSuccess("编辑成功");
      }
      closeDialog();
      getList();
    } catch (err) {
      console.error(`${dialogMode.value === 'create' ? '新增' : '编辑'}失败`, err);
      proxy.$modal.msgError(`${dialogMode.value === 'create' ? '新增' : '编辑'}失败,请重试`);
    }
  });
};
// 编辑方法
const handleEdit = (row) => {
  openDialog('edit', row);
};
// 删除方法
const handleDelete = (row) => {
  proxy.$modal.confirm(`确定要删除生产订单"${row.orderNo}"吗?`, "删除确认", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  }).then(async () => {
    try {
      await deleteProductionOrder([row.id]);
      proxy.$modal.msgSuccess("删除成功");
      getList(); // 刷新列表
    } catch (err) {
      console.error("删除失败", err);
      proxy.$modal.msgError("删除失败,请重试");
    }
  }).catch(() => {
    proxy.$modal.msg("已取消删除");
  });
};
const getProductOptions = () => {
  return productTreeList().then((res) => {
    productOptions.value = convertIdToValue(res || []);
  });
};
const convertIdToValue = (data) => {
  return data.map((item) => {
    const { id, children, ...rest } = item;
    const newItem = {
      ...rest,
      value: id,
    };
    if (children && children.length > 0) {
      newItem.children = convertIdToValue(children);
    }
    return newItem;
  });
};
const findNodeById = (nodes, value) => {
  for (let i = 0; i < nodes.length; i++) {
    if (nodes[i].value === value) {
      return nodes[i].label;
    }
    if (nodes[i].children && nodes[i].children.length > 0) {
      const label = findNodeById(nodes[i].children, value);
      if (label) return label;
    }
  }
  return null;
};
// 查询列表
/** 搜索按钮操作 */
const handleQuery = () => {
   page.current = 1;
   getList();
  page.value.current = 1;
  getList();
};
const pagination = (obj) => {
   page.current = obj.page;
   page.size = obj.limit;
   getList();
  page.value.current = obj.page;
  page.value.size = obj.limit;
  getList();
};
const changeDaterange = (value) => {
   if (value) {
      searchForm.value.entryDateStart = value[0];
      searchForm.value.entryDateEnd = value[1];
   } else {
      searchForm.value.entryDateStart = undefined;
      searchForm.value.entryDateEnd = undefined;
   }
   handleQuery();
  if (value) {
    searchForm.value.entryDateStart = value[0];
    searchForm.value.entryDateEnd = value[1];
  } else {
    searchForm.value.entryDateStart = undefined;
    searchForm.value.entryDateEnd = undefined;
  }
  handleQuery();
};
const getList = () => {
   tableLoading.value = true;
   // 构造一个新的对象,不包含entryDate字段
   const params = { ...searchForm.value, ...page };
   params.entryDate = undefined
   schedulingListPage(params).then((res) => {
      tableLoading.value = false;
      tableData.value = res.data.records;
      page.total = res.data.total;
   }).catch(() => {
      tableLoading.value = false;
   })
  tableLoading.value = true;
  // 构造一个新的对象,不包含entryDate字段和 total 字段
  const { total, ...pageParams } = page.value;
  const params = { ...searchForm.value, ...pageParams };
  params.registerDate = undefined;
  if (params.productCategory) {
    // 如果是对象类型,获取其label(名称)而不是value(ID)
    if (typeof params.productCategory === "object") {
      params.productCategory = findNodeById(productOptions.value, params.productCategory) || params.productCategory;
    }
    // 如果是ID,转换为名称
    else if (typeof params.productCategory === "string" || typeof params.productCategory === "number") {
      const categoryName = findNodeById(productOptions.value, params.productCategory);
      if (categoryName) {
        params.productCategory = categoryName;
      }
    }
  }
  schedulingListPage(params).then((res) => {
    tableLoading.value = false;
    tableData.value = res.data.records;
    page.value.total = res.data.total;
  }).catch(() => {
    tableLoading.value = false;
  })
};
// 导出
const handleOut = () => {
   ElMessageBox.confirm("选中的内容将被导出,是否确认导出?", "导出", {
      confirmButtonText: "确认",
      cancelButtonText: "取消",
      type: "warning",
   })
      .then(() => {
         proxy.download("/salesLedger/scheduling/export", {}, "生产订单.xlsx");
      })
      .catch(() => {
         proxy.$modal.msg("已取消");
      });
  ElMessageBox.confirm("选中的内容将被导出,是否确认导出?", "导出", {
    confirmButtonText: "确认",
    cancelButtonText: "取消",
    type: "warning",
  })
      .then(() => {
        // proxy.download("/salesLedger/scheduling/export", {}, "生产订单.xlsx");
        proxy.download("/productionOrder/export", {}, "生产订单.xlsx");
      })
      .catch(() => {
        proxy.$modal.msg("已取消");
      });
};
onMounted(() => {
   getList();
  getProductOptions();
  // 不设置默认日期,全部条件为空加载
  searchForm.value.registerDate = null;
  searchForm.value.entryDateStart = undefined;
  searchForm.value.entryDateEnd = undefined;
  getList();
});
</script>