zhangwencui
3 天以前 ed36047f6ce0b91dad25efc10c8a0e83dd533a68
src/views/productionManagement/productionOrder/index.vue
@@ -3,16 +3,8 @@
    <div class="search_form">
      <el-form :model="searchForm"
               :inline="true">
        <el-form-item label="客户名称:">
          <el-input v-model="searchForm.customerName"
                    placeholder="请输入"
                    clearable
                    prefix-icon="Search"
                    style="width: 160px;"
                    @change="handleQuery" />
        </el-form-item>
        <el-form-item label="合同号:">
          <el-input v-model="searchForm.salesContractNo"
        <el-form-item label="订单号:">
          <el-input v-model="searchForm.npsNo"
                    placeholder="请输入"
                    clearable
                    prefix-icon="Search"
@@ -20,30 +12,67 @@
                    @change="handleQuery" />
        </el-form-item>
        <el-form-item label="产品名称:">
          <el-input v-model="searchForm.productCategory"
          <el-input v-model="searchForm.productName"
                    placeholder="请输入"
                    clearable
                    prefix-icon="Search"
                    style="width: 160px;"
                    @change="handleQuery" />
        </el-form-item>
        <el-form-item label="产品类型:">
          <el-select v-model="searchForm.strength"
                     style="width: 200px;"
                     placeholder="请选择产品类型"
                     clearable
                     @change="handleQuery">
            <el-option v-for="option in productTypeOptions2"
                       :key="option.dictLabel"
                       :label="option.dictLabel"
                       :value="option.dictLabel" />
          </el-select>
        </el-form-item>
        <el-form-item label="创建时间:">
          <el-date-picker v-model="createTime"
                          type="daterange"
                          range-separator="至"
                          start-placeholder="开始日期"
                          value-format="YYYY-MM-DD"
                          format="YYYY-MM-DD"
                          end-placeholder="结束日期"
                          style="width: 300px;"
                          @change="handleQuery" />
        </el-form-item>
        <el-form-item label="规格:">
          <el-input v-model="searchForm.specificationModel"
          <el-input v-model="searchForm.model"
                    placeholder="请输入"
                    clearable
                    prefix-icon="Search"
                    style="width: 160px;"
                    @change="handleQuery" />
        </el-form-item>
        <el-form-item label="状态:">
          <el-select v-model="searchForm.status"
                     placeholder="请选择"
                     style="width: 160px;"
                     @change="handleQuery">
            <el-option v-for="item in statusOptions"
                       :key="item.value"
                       :label="item.label"
                       :value="item.value" />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary"
                     @click="handleQuery">搜索</el-button>
          <el-button type="primary"
                     @click="handleReset">重置</el-button>
          <el-button type="danger"
                     @click="handleDelete">退回</el-button>
          <el-button @click="handleOut">导出</el-button>
        </el-form-item>
      </el-form>
      <div>
        <el-button type="primary" @click="isShowNewModal = true">新增</el-button>
        <el-button @click="handleOut">导出</el-button>
      </div>
      <!-- <div style="width:350px;text-align:right;">
      </div> -->
    </div>
    <div class="table_list">
      <PIMTable rowKey="id"
@@ -52,13 +81,20 @@
                :page="page"
                :tableLoading="tableLoading"
                :row-class-name="tableRowClassName"
                :isSelection="true"
                :selectable="row => row.status != 4"
                @selection-change="handleSelectionChange"
                @pagination="pagination">
        <template #completionStatus="{ row }">
          <el-progress
            :percentage="toProgressPercentage(row?.completionStatus)"
            :color="progressColor(toProgressPercentage(row?.completionStatus))"
            :status="toProgressPercentage(row?.completionStatus) >= 100 ? 'success' : ''"
          />
          <el-progress :percentage="toProgressPercentage(row?.completionStatus)"
                       :color="progressColor(toProgressPercentage(row?.completionStatus))"
                       :status="toProgressPercentage(row?.completionStatus) >= 100 ? 'success' : ''" />
        </template>
        <template #quantity="{ row }">
          {{ row.quantity || '-' }}<span style="color:rgb(63, 95, 211)"> 块</span>
        </template>
        <template #completeQuantity="{ row }">
          {{ row.completeQuantity || '-' }}<span style="color:rgb(42, 169, 146)"> 方</span>
        </template>
      </PIMTable>
    </div>
@@ -87,10 +123,130 @@
        </span>
      </template>
    </el-dialog>
    <new-product-order v-if="isShowNewModal"
                         v-model:visible="isShowNewModal"
                         @completed="handleQuery" />
                       v-model:visible="isShowNewModal"
                       @completed="handleQuery" />
    <!-- 来源数据弹窗 -->
    <el-dialog v-model="sourceDataDialogVisible"
               title="来源数据"
               width="1000px">
      <div class="applyno-summary1">
        <div class="summary-item">
          <span class="summary-label">产品名称:</span>
          <span class="summary-value">
            <el-tag type="primary">{{ sourceRowData.productName || '-' }}</el-tag>
          </span>
        </div>
        <div class="summary-item">
          <span class="summary-label">产品规格:</span>
          <span class="summary-value">{{ sourceRowData.model || '-' }}</span>
        </div>
        <div class="summary-item">
          <span class="summary-label">物料编码:</span>
          <span class="summary-value">{{ sourceRowData.materialCode || '-' }}</span>
        </div>
        <div class="summary-item">
          <span class="summary-label">强度:</span>
          <span class="summary-value">{{ sourceRowData.strength || '-' }}</span>
        </div>
      </div>
      <div class="source-data-container">
        <!-- 左侧applyNo列表 -->
        <div class="applyno-list">
          <div class="list-header">申请单列表</div>
          <div class="list-body">
            <div v-for="(item, index) in sourceTableData"
                 :key="item.applyNo || index"
                 class="applyno-item"
                 :class="{ active: selectedApplyNo === item.applyNo }"
                 @click="selectApplyNo(item)">
              <div class="applyno-text">{{ item.applyNo }}</div>
              <div class="applyno-info">{{ item.customerName }}</div>
            </div>
          </div>
        </div>
        <!-- 右侧详细信息 -->
        <div class="detail-info">
          <div v-if="selectedSourceData && selectedSourceData.items && selectedSourceData.items.length > 0">
            <div v-for="item in selectedSourceData.items"
                 :key="item.id"
                 class="source-data-card">
              <!-- <div class="card-header">
                <div class="data-source-tag">
                </div>
                <div class="card-title">产品明细</div>
              </div> -->
              <div class="card-body">
                <div class="info-grid">
                  <div class="info-item">
                    <div class="info-label">数据来源</div>
                    <div class="info-value">
                      <el-tag :type="item.dataSourceType == 1 ? 'primary' : 'warning'">
                        {{ item.dataSourceType == 1 ? '钉钉同步' : '手动新增' }}
                      </el-tag>
                    </div>
                  </div>
                  <div class="info-item">
                    <div class="info-label">块数</div>
                    <div class="info-value">{{ item.quantity || '-' }}<span style="color:rgb(63, 95, 211)"> 块</span></div>
                  </div>
                  <div class="info-item">
                    <div class="info-label">方数</div>
                    <div class="info-value">{{ item.volume || '-' }}<span style="color:rgba(27, 104, 90, 0.76)"> 方</span></div>
                  </div>
                  <div class="info-item">
                    <div class="info-label">下发状态</div>
                    <div class="info-value">
                      <el-tag :type="{
                        0: 'warning',
                        1: 'primary',
                        2: 'info'
                      }[item.status] || 'info'">
                        {{ item.status == 0 ? '待下发' : item.status == 1 ? '部分下发' : '已下发' }}
                      </el-tag>
                    </div>
                  </div>
                  <div class="info-item">
                    <div class="info-label">已下发方数</div>
                    <div class="info-value">{{ item.assignedQuantity ? `${item.assignedQuantity}` : 0 }}<span style="color:rgba(214, 134, 22, 0.76)"> 方</span></div>
                  </div>
                  <div class="info-item">
                    <div class="info-label">尺寸</div>
                    <div class="info-value">{{ item.length || '-' }}mm × {{ item.width || '-' }}mm × {{ item.height || '-' }}mm</div>
                  </div>
                  <div class="info-item">
                    <div class="info-label">计划开始日期</div>
                    <div class="info-value">{{ item.startDate ? dayjs(item.startDate).format('YYYY-MM-DD') : '' }}</div>
                  </div>
                  <div class="info-item">
                    <div class="info-label">计划结束日期</div>
                    <div class="info-value">{{ item.endDate ? dayjs(item.endDate).format('YYYY-MM-DD') : '' }}</div>
                  </div>
                  <!-- <div class="info-item">
                    <div class="info-label">强度</div>
                    <div class="info-value">{{ item.strength || '' }}</div>
                  </div> -->
                </div>
                <div class="remarks-section">
                  <div class="info-item full-width">
                    <div class="info-label">备注 1</div>
                    <div class="info-value">{{ item.remarkOne || '-' }}</div>
                  </div>
                  <div class="info-item full-width">
                    <div class="info-label">备注 2</div>
                    <div class="info-value">{{ item.remarkTwo || '-' }}</div>
                  </div>
                </div>
              </div>
            </div>
          </div>
          <div v-else
               class="empty-state">
            <el-empty :description="selectedSourceData ? '该申请单暂无数据' : '请选择一个申请单'" />
          </div>
        </div>
      </div>
    </el-dialog>
  </div>
</template>
@@ -99,58 +255,108 @@
  import { ElMessageBox } from "element-plus";
  import dayjs from "dayjs";
  import { useRouter } from "vue-router";
  import { getDicts } from "@/api/system/dict/data";
  import {
    productOrderListPage,
    listProcessRoute,
    bindingRoute,
    listProcessBom,
    delProductOrder,
    revokeProductOrder,
    getProductOrderSource,
  } from "@/api/productionManagement/productionOrder.js";
  import { listPage } from "@/api/productionManagement/processRoute.js";
  import { listMain as getOrderProcessRouteMain } from "@/api/productionManagement/productProcessRoute.js";
  const NewProductOrder = defineAsyncComponent(() => import("@/views/productionManagement/productionOrder/New.vue"));
  import { fileDel } from "@/api/financialManagement/revenueManagement.js";
  import PIMTable from "@/components/PIMTable/PIMTable.vue";
  const NewProductOrder = defineAsyncComponent(() =>
    import("@/views/productionManagement/productionOrder/New.vue")
  );
  const { proxy } = getCurrentInstance();
  const router = useRouter();
  const isShowNewModal = ref(false);
  const sourceDataDialogVisible = ref(false);
  const sourceTableData = ref([]);
  const selectedApplyNo = ref("");
  const selectedSourceData = ref(null);
  const sourceRowData = ref(null);
  const tableColumn = ref([
    {
      label: "状态",
      prop: "status",
      dataType: "tag",
      formatData: val => {
        const statusMap = {
          1: "待开始",
          2: "进行中",
          3: "已完成",
          4: "已取消",
        };
        return statusMap[val] || "";
      },
      formatType: val => {
        const statusMap = {
          1: "error",
          2: "warning",
          3: "success",
          4: "info",
        };
        return statusMap[val] || "info";
      },
      width: 100,
    },
    {
      label: "生产订单号",
      prop: "npsNo",
      width: '120px',
    },
    {
      label: "销售合同号",
      prop: "salesContractNo",
      width: '150px',
    },
    {
      label: "客户名称",
      prop: "customerName",
      width: '200px',
      width: "120px",
    },
    {
      label: "产品名称",
      prop: "productCategory",
      width: '120px',
      prop: "productName",
      width: "120px",
      dataType: "tag",
    },
    {
      label: "规格",
      prop: "specificationModel",
      width: '120px',
      prop: "model",
      width: "120px",
    },
    {
      label: "强度",
      prop: "strength",
      width: "120px",
      dataType: "tag",
    },
    {
      label: "物料编码",
      prop: "materialCode",
      width: "120px",
    },
    {
      label: "工艺路线编号",
      prop: "processRouteCode",
      width: '200px',
      width: "200px",
      className: "status-cell",
    },
    {
      label: "需求数量",
      prop: "quantity",
      dataType: "slot",
      align: "right",
      slot: "quantity",
      width: 120,
    },
    {
      label: "完成数量",
      prop: "completeQuantity",
      dataType: "slot",
      align: "right",
      slot: "completeQuantity",
      width: 120,
    },
    {
      dataType: "slot",
@@ -173,17 +379,31 @@
    },
    {
      label: "交付日期",
      prop: "deliveryDate",
      prop: "planCompleteTime",
      formatData: val => (val ? dayjs(val).format("YYYY-MM-DD") : ""),
      width: 120,
    },
    {
      label: "创建时间",
      prop: "createTime",
      formatData: val => (val ? dayjs(val).format("YYYY-MM-DD HH:mm:ss") : ""),
      width: 120,
    },
    {
      dataType: "action",
      label: "操作",
      align: "center",
      fixed: "right",
      width: 200,
      width: 300,
      operation: [
        {
          name: "来源",
          type: "text",
          clickFun: row => {
            showSourceData(row);
          },
        },
        {
          name: "工艺路线",
          type: "text",
@@ -194,18 +414,26 @@
        {
          name: "绑定工艺路线",
          type: "text",
          showHide: row => !row.processRouteCode,
          showHide: row => !row.routeId,
          clickFun: row => {
            openBindRouteDialog(row);
          },
        },
        {
          name: "产品结构",
          name: "删除",
          type: "text",
          showHide: row => row.status == 4,
          clickFun: row => {
            showProductStructure(row);
            handleDeleteSolo(row);
          },
        },
        // {
        //   name: "产品结构",
        //   type: "text",
        //   clickFun: row => {
        //     showProductStructure(row);
        //   },
        // },
      ],
    },
  ]);
@@ -216,14 +444,170 @@
    size: 100,
    total: 0,
  });
  const selectedRows = ref([]);
  // 来源数据弹窗相关
  const sourceTableColumn = ref([
    {
      label: "数据来源",
      width: "100px",
      prop: "dataSourceType",
      dataType: "tag",
      formatType: params => {
        const typeMap = {
          2: "warning",
          1: "primary",
        };
        return typeMap[params] || "info";
      },
      formatData: cell => (cell == 1 ? "钉钉同步" : "手动新增"),
    },
    {
      label: "申请单编号",
      prop: "applyNo",
      width: "150px",
    },
    {
      label: "客户名称",
      prop: "customerName",
      width: "150px",
    },
    {
      label: "产品名称",
      prop: "productName",
      width: "200px",
      dataType: "tag",
      formatType: params => {
        return "primary";
      },
    },
    {
      label: "产品规格",
      prop: "model",
      width: "150px",
      className: "spec-cell",
    },
    {
      label: "物料编码",
      prop: "materialCode",
      width: "150px",
    },
    {
      label: "块数",
      prop: "quantity",
      align: "right",
      dataType: "slot",
      slot: "quantity",
    },
    {
      label: "方数",
      prop: "volume",
      width: "150px",
      align: "right",
      dataType: "slot",
      slot: "volume",
      className: "volume-cell",
    },
    {
      label: "下发状态",
      prop: "status",
      width: "150px",
      className: "status-cell",
      dataType: "tag",
      formatType: params => {
        const typeMap = {
          0: "warning",
          1: "primary",
          2: "info",
        };
        return typeMap[params] || "info";
      },
      formatData: cell => {
        const statusMap = {
          0: "待下发",
          1: "部分下发",
          2: "已下发",
        };
        return statusMap[cell] || "";
      },
    },
    {
      label: "已下发方数",
      prop: "assignedQuantity",
      width: "150px",
      className: "spec-cell",
      formatData: cell => (cell ? `${cell}方` : 0),
    },
    {
      label: "长",
      prop: "length",
      className: "dimension-cell",
      formatData: cell => (cell ? `${cell}mm` : ""),
    },
    {
      label: "宽",
      prop: "width",
      className: "dimension-cell",
      formatData: cell => (cell ? `${cell}mm` : ""),
    },
    {
      label: "高",
      prop: "height",
      className: "dimension-cell",
      formatData: cell => (cell ? `${cell}mm` : ""),
    },
    {
      label: "计划开始日期",
      prop: "startDate",
      width: "150px",
      className: "date-cell",
      formatData: cell => (cell ? dayjs(cell).format("YYYY-MM-DD") : ""),
    },
    {
      label: "计划结束日期",
      prop: "endDate",
      width: "150px",
      className: "date-cell",
      formatData: cell => (cell ? dayjs(cell).format("YYYY-MM-DD") : ""),
    },
    {
      label: "强度",
      prop: "strength",
      formatData: cell => {
        if (!cell) return "";
        return cell;
      },
    },
    {
      label: "备注 1",
      width: "150px",
      prop: "remarkOne",
    },
    {
      label: "备注 2",
      width: "150px",
      prop: "remarkTwo",
    },
  ]);
  const sourceTableLoading = ref(false);
  const sourcePage = reactive({
    current: 1,
    size: 100,
    total: 0,
  });
  const data = reactive({
    searchForm: {
      customerName: "",
      salesContractNo: "",
      projectName: "",
      productCategory: "",
      specificationModel: "",
      productName: "",
      model: "",
      dictCode: null,
      startTime: null,
      endTime: null,
      strength: null,
      status: "",
    },
  });
  const { searchForm } = toRefs(data);
@@ -247,18 +631,18 @@
  // 添加表行类名方法
  const tableRowClassName = ({ row }) => {
    if (row.isFh) return '';
    const diff = row.deliveryDaysDiff;
    if (diff === 15) {
      return 'yellow';
    } else if (diff === 10) {
      return 'pink';
    } else if (diff === 2) {
      return 'purple';
    } else if (diff < 2) {
      return 'red';
    }
    // if (!row.planCompleteTime) return "";
    // if (row.isFh) return "";
    // const diff = row.deliveryDaysDiff;
    // if (diff === 15) {
    //   return "yellow";
    // } else if (diff === 10) {
    //   return "pink";
    // } else if (diff === 2) {
    //   return "purple";
    // } else if (diff < 2) {
    //   return "red";
    // }
  };
  // 绑定工艺路线弹框
@@ -266,6 +650,7 @@
  const bindRouteLoading = ref(false);
  const bindRouteSaving = ref(false);
  const routeOptions = ref([]);
  const productTypeOptions = ref([]);
  const bindForm = reactive({
    orderId: null,
    routeId: null,
@@ -276,15 +661,32 @@
    bindForm.routeId = null;
    bindRouteDialogVisible.value = true;
    routeOptions.value = [];
    if (!row.productModelId) {
    if (!row.model) {
      proxy.$modal.msgWarning("当前订单缺少产品型号,无法查询工艺路线");
      bindRouteDialogVisible.value = false;
      return;
    }
    bindRouteLoading.value = true;
    const distName =
      row.productName == "板材"
        ? row.productName
        : row.productName + "-" + row.strength;
    try {
      const res = await listProcessRoute({ productModelId: row.productModelId });
      routeOptions.value = res.data || [];
      // 获取产品类型字典
      const dictRes = await getDicts("product_type");
      if (dictRes.code === 200) {
        productTypeOptions.value = dictRes.data;
        // 用distName匹配dictLabel,获取dictCode
        const matchedType = productTypeOptions.value.find(
          item => item.dictLabel === distName
        );
        const dictCode = matchedType ? matchedType.dictCode : row.productType;
        // 使用dictCode查询工艺路线列表
        const res = await listPage({ dictCode, status: true });
        routeOptions.value = res.data.records || [];
      }
    } catch (e) {
      console.error("获取工艺路线列表失败:", e);
      proxy.$modal.msgError("获取工艺路线列表失败");
@@ -314,7 +716,27 @@
      bindRouteSaving.value = false;
    }
  };
  const statusOptions = ref([
    { value: 1, label: "待开始" },
    { value: 2, label: "进行中" },
    { value: 3, label: "已完成" },
    { value: 4, label: "已取消" },
  ]);
  const handleReset = () => {
    searchForm.value = {
      customerName: "",
      salesContractNo: "",
      projectName: "",
      productName: "",
      model: "",
      status: "",
      strength: null,
      startTime: null,
      endTime: null,
    };
    createTime.value = [];
    handleQuery();
  };
  // 查询列表
  /** 搜索按钮操作 */
  const handleQuery = () => {
@@ -336,11 +758,25 @@
    }
    handleQuery();
  };
  const createTime = ref([]);
  const getList = () => {
    tableLoading.value = true;
    // 构造一个新的对象,不包含entryDate字段
    const params = { ...searchForm.value, ...page };
    params.entryDate = undefined;
    params.startTime =
      createTime.value.length > 0
        ? dayjs(createTime.value[0]).format("YYYY-MM-DD HH:mm:ss")
        : undefined;
    params.endTime =
      createTime.value.length > 0
        ? dayjs(createTime.value[1])
            .hour(23)
            .minute(59)
            .second(59)
            .format("YYYY-MM-DD HH:mm:ss")
        : undefined;
    productOrderListPage(params)
      .then(res => {
        tableLoading.value = false;
@@ -355,23 +791,23 @@
  const showRouteItemModal = async row => {
    const orderId = row.id;
    try {
      const res = await getOrderProcessRouteMain(orderId);
      const data = res.data || {};
      if (!data || !data.id) {
        proxy.$modal.msgWarning("未找到关联的工艺路线");
        return;
      }
      router.push({
        path: "/productionManagement/processRouteItem",
        query: {
          id: data.id,
          processRouteCode: data.processRouteCode || "",
          productName: data.productName || "",
          model: data.model || "",
          bomNo: data.bomNo || "",
          description: data.description || "",
          orderId,
          id: row.routeId,
          processRouteCode: row.processRouteCode || "",
          productName: row.productName || "",
          model: row.model || "",
          bomNo: row.bomNo || "",
          bomId: row.bomId || "",
          description: row.description || "",
          dictLabel:
            row.productName == "板材"
              ? row.productName
              : row.productName + "-" + row.strength,
          orderId: row.id,
          type: "order",
          editable: true,
        },
      });
    } catch (e) {
@@ -381,17 +817,128 @@
  };
  const showProductStructure = row => {
    if (!row.processRouteCode) {
      proxy.$modal.msgWarning("请先绑定工艺路线");
      return;
    }
    router.push({
      path: "/productionManagement/productStructureDetail",
      query: {
        id: row.id,
        bomNo: row.bomNo || "",
        productName: row.productCategory || "",
        productModelName: row.specificationModel || "",
        productName: row.productName || "",
        productModelName: row.model || "",
        orderId: row.id,
        type: "order",
      },
    });
  };
  // 选择申请单
  const selectApplyNo = item => {
    selectedApplyNo.value = item.applyNo;
    selectedSourceData.value = item;
  };
  // 查看来源生产计划数据
  const showSourceData = row => {
    // 存储点击来源按钮时传递的row参数
    sourceRowData.value = row;
    // 调用API获取来源数据
    getProductOrderSource(row.id)
      .then(res => {
        if (res.code === 200) {
          // 处理接口返回的数据,调整为我们需要的格式
          sourceTableData.value = res.data.map(item => {
            return {
              applyNo: item.applyNo,
              customerName: item.productPlans[0]?.customerName || "",
              items: item.productPlans.map(plan => {
                return {
                  id: plan.id,
                  dataSourceType: plan.dataSourceType,
                  productName: plan.productName,
                  model: plan.model,
                  materialCode: plan.materialCode,
                  quantity: plan.quantity,
                  volume: plan.volume,
                  status: plan.status,
                  assignedQuantity: plan.assignedQuantity,
                  length: plan.length,
                  width: plan.width,
                  height: plan.height,
                  startDate: plan.startDate,
                  endDate: plan.endDate,
                  strength: plan.strength,
                  remarkOne: plan.remarkOne,
                  remarkTwo: plan.remarkTwo,
                };
              }),
            };
          });
          sourcePage.total = sourceTableData.value.length;
          // 默认选择第一个申请单
          if (sourceTableData.value.length > 0) {
            selectApplyNo(sourceTableData.value[0]);
          } else {
            selectedApplyNo.value = "";
            selectedSourceData.value = null;
          }
          // 打开弹窗
          sourceDataDialogVisible.value = true;
        } else {
          proxy.$modal.msgError(res.msg || "获取来源数据失败");
        }
      })
      .catch(err => {
        proxy.$modal.msgError("获取来源数据失败");
        console.error(err);
      });
  };
  // 表格选择数据
  const handleSelectionChange = selection => {
    selectedRows.value = selection;
  };
  const handleDeleteSolo = row => {
    ElMessageBox.confirm("选中的内容将被删除,是否确认删除?", "导出", {
      confirmButtonText: "确认",
      cancelButtonText: "取消",
      type: "warning",
    })
      .then(() => {
        delProductOrder(row.id).then(res => {
          proxy.$modal.msgSuccess("删除成功");
          getList();
        });
      })
      .catch(() => {
        proxy.$modal.msg("已取消");
      });
  };
  const handleDelete = () => {
    let ids = [];
    if (selectedRows.value.length > 0) {
      ids = selectedRows.value.map(item => item.id);
    } else {
      proxy.$modal.msgWarning("请选择数据");
      return;
    }
    ElMessageBox.confirm("选中的内容将被退回,是否确认退回?", "导出", {
      confirmButtonText: "确认",
      cancelButtonText: "取消",
      type: "warning",
    })
      .then(() => {
        revokeProductOrder(ids).then(res => {
          proxy.$modal.msgSuccess("退回成功");
          getList();
        });
      })
      .catch(() => {
        proxy.$modal.msg("已取消");
      });
  };
  // 导出
@@ -402,7 +949,11 @@
      type: "warning",
    })
      .then(() => {
        proxy.download("/productOrder/export", {...searchForm.value}, "生产订单.xlsx");
        proxy.download(
          "/productOrder/export",
          { ...searchForm.value },
          "生产订单.xlsx"
        );
      })
      .catch(() => {
        proxy.$modal.msg("已取消");
@@ -410,30 +961,274 @@
  };
  const handleConfirmRoute = () => {};
  const productTypeOptions2 = ref([]);
  // 获取产品类型字典
  const getProductTypeOptions = () => {
    getDicts("block_strength")
      .then(res => {
        if (res.code === 200) {
          productTypeOptions2.value = res.data;
        }
      })
      .catch(err => {
        console.error("获取产品类型字典失败:", err);
      });
  };
  onMounted(() => {
    getProductTypeOptions();
    getList();
  });
</script>
<style scoped lang="scss">
.search_form{
  align-items: start;
}
  .search_form {
    align-items: start;
  }
::v-deep .yellow {
  background-color: #FAF0DE;
}
  ::v-deep .yellow {
    background-color: #faf0de;
  }
::v-deep .pink {
  background-color: #FAE1DE;
}
  ::v-deep .pink {
    background-color: #fae1de;
  }
::v-deep .red {
  background-color: #f80202;
}
  ::v-deep .red {
    background-color: #f80202;
  }
::v-deep .purple{
  background-color: #F4DEFA;
}
  ::v-deep .purple {
    background-color: #f4defa;
  }
</style>
<style lang="scss">
  .status-cell {
    font-weight: 600;
    color: #409eff;
    font-family: "Courier New", monospace;
    text-shadow: 0 1px 2px rgba(64, 158, 255, 0.2);
  }
  .source-data-container {
    display: flex;
    gap: 20px;
    height: 500px;
    .applyno-list {
      width: 250px;
      background: #fff;
      border-radius: 8px;
      box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
      overflow: hidden;
      .list-header {
        padding: 12px 16px;
        background: #f5f7fa;
        border-bottom: 1px solid #e4e7ed;
        font-weight: 600;
        color: #303133;
      }
      .list-body {
        height: calc(100% - 48px);
        overflow-y: auto;
        .applyno-item {
          padding: 12px 16px;
          border-bottom: 1px solid #f0f2f5;
          cursor: pointer;
          transition: all 0.3s;
          &:hover {
            background: #f5f7fa;
          }
          &.active {
            background: #ecf5ff;
            border-left: 4px solid #409eff;
          }
          .applyno-text {
            font-weight: 600;
            color: #303133;
            font-family: "Courier New", monospace;
            margin-bottom: 4px;
          }
          .applyno-info {
            font-size: 12px;
            color: #909399;
          }
        }
      }
    }
    .detail-info {
      flex: 1;
      background: #fff;
      border-radius: 8px;
      // box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
      overflow: auto;
      display: flex;
      flex-direction: column;
      .applyno-summary {
        padding: 16px 20px;
        background: #f5f7fa;
        border-bottom: 1px solid #e4e7ed;
        display: flex;
        flex-wrap: wrap;
        gap: 16px;
        .summary-item {
          display: flex;
          align-items: center;
          .summary-label {
            font-size: 13px;
            color: #909399;
            margin-right: 8px;
            font-weight: 500;
          }
          .summary-value {
            font-size: 14px;
            color: #303133;
            font-weight: 500;
          }
        }
      }
      .empty-state {
        flex: 1;
        display: flex;
        align-items: center;
        justify-content: center;
      }
      .source-data-card {
        flex: 1;
        display: flex;
        flex-direction: column;
        overflow: hidden;
        margin-top: 20px;
        margin-right: 20px;
        box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
        .card-header {
          display: flex;
          justify-content: space-between;
          align-items: center;
          padding: 16px 20px;
          background: #f5f7fa;
          border-bottom: 1px solid #e4e7ed;
          .data-source-tag {
            flex-shrink: 0;
          }
          .card-title {
            font-weight: 600;
            color: #303133;
            font-size: 14px;
          }
        }
        .card-body {
          flex: 1;
          padding: 20px;
          overflow-y: auto;
          background-color: #f5f7fa;
          .info-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
            gap: 16px;
            margin-bottom: 20px;
            .info-item {
              display: flex;
              flex-direction: column;
              .info-label {
                font-size: 12px;
                color: #909399;
                margin-bottom: 4px;
                font-weight: 500;
              }
              .info-value {
                font-size: 14px;
                color: #303133;
                font-weight: 500;
              }
            }
            .info-item.full-width {
              grid-column: 1 / -1;
            }
          }
          .remarks-section {
            display: flex;
            // flex-direction: column;
            gap: 12px;
            border-top: 1px solid #e4e7ed;
            padding-top: 16px;
            .info-item {
              display: flex;
              width: 50%;
              flex-direction: column;
              .info-label {
                font-size: 12px;
                color: #909399;
                margin-bottom: 4px;
                font-weight: 500;
              }
              .info-value {
                font-size: 14px;
                color: #303133;
                line-height: 1.5;
                padding: 8px;
                background: #f9fafc;
                border-radius: 4px;
                border: 1px solid #ecf5ff;
              }
            }
          }
        }
      }
    }
  }
  .applyno-summary1 {
    padding: 16px 20px;
    background: #f5f7fa;
    border-bottom: 1px solid #e4e7ed;
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    .summary-item {
      display: flex;
      align-items: center;
      margin-right: 20px;
      .summary-label {
        font-size: 13px;
        color: #909399;
        margin-right: 8px;
        font-weight: 500;
      }
      .summary-value {
        font-size: 14px;
        color: #303133;
        font-weight: 500;
      }
    }
  }
</style>