From e43b1580dfb5367478d30bfe3f9de985c6872986 Mon Sep 17 00:00:00 2001
From: CD配唱片 <CD配唱片>
Date: 星期二, 06 五月 2025 15:36:52 +0800
Subject: [PATCH] 提交标准工艺路线,钣金冗余工单,钣金供应缺口

---
 src/views/mainPlan/sheetMetalOrderManage/index.vue      |  521 ++++++++++++++
 src/views/mainPlan/sheetMetalSupplyGap/index.vue        |  495 +++++++++++++
 src/views/basicData/processRouteDataPreparate/index.vue |  618 +++++++++++++++++
 src/views/mainPlan/sheetMetalRedundantReport/index.vue  |  478 +++++++++++++
 4 files changed, 2,112 insertions(+), 0 deletions(-)

diff --git a/src/views/basicData/processRouteDataPreparate/index.vue b/src/views/basicData/processRouteDataPreparate/index.vue
new file mode 100644
index 0000000..ba13333
--- /dev/null
+++ b/src/views/basicData/processRouteDataPreparate/index.vue
@@ -0,0 +1,618 @@
+<template>
+  <div class="app-container">
+    <el-row :gutter="20">
+      <el-form
+        :model="queryParams"
+        ref="queryRef"
+        :rules="rules"
+        :inline="true"
+        v-show="showSearch"
+        label-width="68px"
+      >
+        <el-row :gutter="20">
+          <el-col :span="6">
+            <el-form-item label="鏂欏彿" prop="itemCode">
+              <el-input
+                style="width: 240px"
+                v-model="queryParams.itemCode"
+                placeholder="璇疯緭鍏ユ枡鍙�"
+                clearable
+                @keyup.enter="handleQuery"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="18" style="text-align: right">
+            <el-form-item>
+              <el-button type="primary" icon="Search" @click="handleQuery"
+                >鏌ヨ</el-button
+              >
+              <el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+    </el-row>
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="Refresh"
+          @click="handleRefresh"
+          v-hasPermi="['apsPartRouteStat:edit']"
+          >鏇存柊</el-button
+        >
+      </el-col>
+      <right-toolbar
+        v-model:showSearch="showSearch"
+        @queryTable="getList"
+      ></right-toolbar>
+    </el-row>
+
+    <HxlhTable
+      style="width: 100%"
+      :columns="columns"
+      :data="planList"
+      :loading="loading"
+      :height="height"
+      @on-checkbox="handleCheckboxChange"
+      :page="page"
+      @changePageNo="changePageNo"
+      @changePageSize="changePageSize"
+      :expand-config="expandConfig"
+      :subGridOptions="subGridOptions"
+    >
+    </HxlhTable>
+  </div>
+</template>
+
+<script setup name="ApsPlatePlan">
+import {
+  listPlan,
+  examplePlan,
+  confirmPart,
+} from "@/api/mainPlan/apsPlatePlan.js";
+import { listProcessRoute } from "@/api/basicData/processRoute.js";
+import HxlhTable from "@/components/HxlhTable/index.vue";
+import { ref } from "vue";
+import { getToken } from "@/utils/auth.js";
+import { ElMessage } from "element-plus";
+
+const { proxy } = getCurrentInstance();
+// 鍒嗛〉灞炴��
+const page = ref({
+  total: 0,
+  current: 1,
+  size: 10
+});
+const {
+  aps_is_suspended,
+  aps_document_status,
+  aps_account,
+  aps_business_type,
+} = proxy.useDict(
+  "aps_is_suspended",
+  "aps_document_status",
+  "aps_account",
+  "aps_business_type"
+);
+
+const exampleList = ref([]);
+const planList = ref([]);
+const loading = ref(true);
+const showSearch = ref(true);
+const single = ref(true);
+const total = ref(0);
+const daterangePlanStartDay = ref([]);
+const daterangePlanEndDay = ref([]);
+
+const height = ref(document.documentElement.clientHeight - 270 + "px;");
+const isVisible = ref(false);
+const isError = ref(false);
+const planned = ref(true);
+const batchNumber = ref(null);
+const exampleHeight = ref("500px");
+const uploadRef = ref();
+
+/*** 鐢ㄦ埛瀵煎叆鍙傛暟 */
+const upload = reactive({
+  // 鏄惁鏄剧ず寮瑰嚭灞傦紙鐢ㄦ埛瀵煎叆锛�
+  open: false,
+  // 寮瑰嚭灞傛爣棰橈紙鐢ㄦ埛瀵煎叆锛�
+  title: "",
+  // 鏄惁绂佺敤涓婁紶
+  isUploading: false,
+  // 鏄惁鏇存柊宸茬粡瀛樺湪鐨勭敤鎴锋暟鎹�
+  updateSupport: 0,
+  // 璁剧疆涓婁紶鐨勮姹傚ご閮�
+  headers: { Authorization: "Bearer " + getToken(), local: "zhl" },
+  // 涓婁紶鐨勫湴鍧�
+  url: import.meta.env.VITE_APP_BASE_API + "/aps/apsPlatePlan/importData",
+});
+
+// 琛ㄦ牸閰嶇疆
+const exampleColumns = ref([
+  { type: "seq", title: "搴忓彿", width: 60 },
+  {
+    title: "涓昏鍒掑憳",
+    field: "masterPlanner",
+    width: 100,
+  },
+  {
+    title: "鍛ㄦ棩",
+    field: "weekDay",
+    width: 100,
+    formatter: ({ cellValue, row, column }) => {
+      if (cellValue) {
+        const weekDay = new Date(cellValue);
+        const year = weekDay.getFullYear();
+        const month = String(weekDay.getMonth() + 1).padStart(2, "0");
+        const day = String(weekDay.getDate()).padStart(2, "0");
+        return `${month}-${day}`;
+      }
+      return "";
+    },
+  },
+  {
+    title: "鍛ㄥ害",
+    field: "weekCycle",
+    width: 80,
+  },
+  {
+    title: "涓讳欢鏂欏彿",
+    field: "mainPartNumber",
+    width: 150,
+  },
+  {
+    title: "涓讳欢鍥惧彿",
+    field: "mainPartDrawingNumber",
+    width: 150,
+  },
+  {
+    title: "瀹㈡埛鍚嶇О",
+    field: "customer",
+    width: 200,
+  },
+  {
+    title: "涓氬姟绫诲瀷",
+    field: "businessType",
+    width: 150,
+  },
+  {
+    title: "鍗曟嵁鍙�",
+    field: "documentNumber",
+    width: 150,
+  },
+  {
+    title: "闇�姹傚垎绫�",
+    field: "requirementType",
+    width: 150,
+  },
+  {
+    title: "鍗曟嵁鐘舵��",
+    field: "documentStatus",
+    width: 100,
+  },
+  {
+    title: "鏂欏彿",
+    field: "itemNumber",
+    width: 150,
+  },
+  {
+    title: "鍥惧彿",
+    field: "drawingNo",
+    width: 150,
+  },
+  {
+    title: "鐗堟湰鍙�",
+    field: "versionNumber",
+    width: 100,
+  },
+  {
+    title: "鐢熶骇鏁伴噺",
+    field: "productionQuantity",
+    width: 100,
+  },
+  {
+    title: "鑹搧鏁伴噺",
+    field: "goodProductsQuantity",
+    width: 100,
+  },
+  {
+    title: "宸ュ簭鍙�",
+    field: "processNumber",
+    width: 150,
+  },
+  {
+    title: "宸ヤ綔涓績",
+    field: "workCenter",
+    width: 150,
+  },
+  {
+    title: "鎵�灞為儴闂�",
+    field: "department",
+    width: 100,
+  },
+  {
+    title: "璁″垝寮�宸ユ棩",
+    field: "planStartDay",
+    width: 100,
+  },
+  {
+    title: "璁″垝瀹屽伐鏃�",
+    field: "planEndDay",
+    width: 100,
+  },
+  {
+    title: "澶囨枡鏂欏彿",
+    field: "standbyNumber",
+    width: 100,
+  },
+  {
+    title: "澶囨枡鍚嶇О",
+    field: "standbyName",
+    width: 200,
+  },
+  {
+    title: "澶囨枡搴撳瓨",
+    field: "standbyStock",
+    width: 100,
+  },
+  {
+    title: "涓嬮亾宸ュ簭鎵�灞為儴闂�",
+    field: "nextProcessDeparment",
+    width: 180,
+  },
+  {
+    title: "鏄惁鎸傝捣",
+    field: "isSuspended",
+    width: 100,
+  },
+  {
+    title: "澶栧崗鏍囪瘑",
+    field: "isOutsourcing",
+    width: 100,
+  },
+  {
+    title: "璐﹀",
+    field: "account",
+    width: 100,
+  },
+  // {
+  //   title: '涓婇樁鐗╂枡',
+  //   field: 'advancedMaterials',
+  //   width: 100,
+  // },
+  // {
+  //   title: '涓婇樁鍗曟嵁鍙�',
+  //   field: 'advancedDocumentNumber',
+  //   width: 100,
+  // },
+  // {
+  //   title: '涓婇樁闇�姹傛棩鏈�',
+  //   field: 'advancedRequirementDay',
+  //   width: 150,
+  // },
+  // {
+  //   title: '璁″垝榻愬',
+  //   field: 'isPlanComplete',
+  //   width: 100,
+  // },
+  // {
+  //   title: '搴撳瓨榻愬',
+  //   field: 'isStockComplete',
+  //   width: 100,
+  // },
+  // {
+  //   title: '鏄惁鏈夋姌杩斿伐搴�',
+  //   field: 'hasTurnback',
+  //   width: 150,
+  // },
+  // {
+  //   title: '椋庨櫓鏍囪瘑',
+  //   field: 'hasRisk',
+  //   width: 100,
+  // },
+]);
+
+// 琛ㄦ牸閰嶇疆
+const columns = ref([
+  {
+    field: "expand",
+    type: "expand",
+    width: 60,
+    align: "center",
+    slots: { content: "expandContent" },
+  },
+  { type: "checkbox", width: 60, align: "center" },
+  {
+    title: "宸ヨ壓璺嚎ID",
+    field: "mainPartNumber",
+  },
+  {
+    title: "宸ヨ壓璺嚎鐗堟湰",
+    field: "businessType",
+  },
+  {
+    title: "鏂欏彿",
+    field: "documentNumber",
+  },
+  {
+    title: "鐢熸晥鏃ユ湡",
+    field: "requirementType",
+  },
+  {
+    title: "澶辨晥鏃ユ湡",
+    field: "documentStatus",
+  },
+  {
+    title: "闆嗘垚鏃ユ湡",
+    field: "itemNumber",
+  },
+  {
+    title: "閫傜敤宸ュ巶",
+    field: "drawingNo",
+  },
+]);
+
+const data = reactive({
+  form: {},
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    customer: null,
+    documentNumber: null,
+    itemCode: null,
+  },
+  rules: {
+    itemCode: [{ required: true, message: "璇疯緭鍏ユ枡鍙�", trigger: "blur" }],
+  },
+});
+
+const { queryParams, form, rules } = toRefs(data);
+function changePageNo(currentPage) {
+  queryParams.value.pageNum = currentPage;
+  page.value.current = currentPage;
+  getList();
+}
+function changePageSize(pageSize) {
+  page.value.current = 1;
+  queryParams.value.pageNum = 1;
+  queryParams.value.pageSize = pageSize;
+  getList();
+}
+/** 鏌ヨ閽i噾璁″垝涓存椂绠$悊鍒楄〃 */
+function getExampleList() {
+  loading.value = true;
+  queryParams.value = {};
+  queryParams.value.batchNumber = batchNumber.value;
+  examplePlan(queryParams.value).then((response) => {
+    exampleList.value = response.rows;
+    total.value = response.total;
+    loading.value = false;
+  });
+}
+
+/** 鏌ヨ闆朵欢璁″垝绠$悊鍒楄〃 */
+function getList() {
+  loading.value = true;
+  queryParams.value.params = {};
+  if (null != daterangePlanStartDay && "" !== daterangePlanStartDay) {
+    queryParams.value.params["beginPlanStartDay"] =
+      daterangePlanStartDay.value[0];
+    queryParams.value.params["endPlanStartDay"] =
+      daterangePlanStartDay.value[1];
+  }
+  if (null != daterangePlanEndDay && "" !== daterangePlanEndDay) {
+    queryParams.value.params["beginPlanEndDay"] = daterangePlanEndDay.value[0];
+    queryParams.value.params["endPlanEndDay"] = daterangePlanEndDay.value[1];
+  }
+  listPlan(queryParams.value).then((response) => {
+    planList.value = response.rows;
+    loading.value = false;
+  });
+}
+
+/** 鎼滅储鎸夐挳鎿嶄綔 */
+function handleQuery() {
+  proxy.$refs["queryRef"].validate((valid) => {
+    if (valid) {
+      getList();
+    }
+  });
+}
+
+/** 閲嶇疆鎸夐挳鎿嶄綔 */
+function resetQuery() {
+  daterangePlanStartDay.value = [];
+  daterangePlanEndDay.value = [];
+  proxy.resetForm("queryRef");
+  handleQuery();
+}
+
+// 澶氶�夋閫変腑鏁版嵁
+const handleCheckboxChange = (data) => {
+  console.log(data);
+};
+
+/** 鎵归噺淇敼璁″垝寮�宸ユ棩鎸夐挳鎿嶄綔 */
+function plannedStart() {}
+
+/** 鎵归噺淇敼璁″垝瀹屽伐鏃ユ寜閽搷浣� */
+function plannedEnd() {}
+
+/** 瀵煎叆鎸夐挳鎿嶄綔 */
+function handleImport() {
+  upload.title = "閽i噾璁″垝鏁版嵁涓婁紶";
+  upload.open = true;
+}
+
+/** 瀵煎嚭鎸夐挳鎿嶄綔 */
+function handleExport() {
+  proxy.download(
+    "aps/apsPlatePlan/export",
+    {
+      ...queryParams.value,
+    },
+    `plan_${new Date().getTime()}.xlsx`
+  );
+}
+
+/** 涓嬭浇妯℃澘鎿嶄綔 */
+function importTemplate() {
+  proxy.download(
+    "system/user/importTemplate",
+    {},
+    `user_template_${new Date().getTime()}.xlsx`
+  );
+}
+
+/** buildEexample */
+function buildEexample() {
+  proxy.$refs["uploadRef"].submit();
+}
+
+/**鏂囦欢涓婁紶涓鐞� */
+const handleFileUploadProgress = (event, file, fileList) => {
+  upload.isUploading = true;
+};
+
+/** 鏂囦欢涓婁紶鎴愬姛澶勭悊 */
+const handleFileSuccess = (response, file, fileList) => {
+  if (response.code == "200") {
+    batchNumber.value = response.data;
+    isVisible.value = true;
+    planned.value = false;
+    isError.value = false;
+    getExampleList();
+  } else {
+    isError.value = true;
+    proxy.$alert(
+      "<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" +
+        response.msg +
+        "</div>",
+      "瀵煎叆缁撴灉",
+      { dangerouslyUseHTMLString: true }
+    );
+  }
+  proxy.$refs["uploadRef"].handleRemove(file);
+  upload.isUploading = false;
+};
+
+/** 涓婁紶骞惰В鏋愭寜閽搷浣� */
+function uploadParse() {
+  queryParams.value.params = {};
+  queryParams.value.params["batchNumber"] = batchNumber.value;
+  confirmPart(queryParams.value).then((response) => {
+    exampleList.value = response.rows;
+    loading.value = false;
+    isVisible.value = false;
+    isError.value = false;
+    planned.value = true;
+    upload.open = false;
+    ElMessage({
+      message: "姘斾綋绠¤矾璁″垝鏁版嵁宸叉垚鍔熶笂浼犲拰瑙f瀽",
+      type: "success",
+    });
+    getList();
+  });
+}
+
+/** dialog鍙栨秷 */
+function dialogCancel() {
+  if (uploadRef.value) {
+    uploadRef.value.clearFiles();
+  }
+  isVisible.value = false;
+  isError.value = false;
+  planned.value = true;
+  upload.open = false;
+  upload.isUploading = false;
+}
+/*瀹氫箟涓嬫媺浜岀骇琛�*/
+
+const subGridOptions = reactive({
+  border: true,
+  showOverflow: true,
+  columns: [
+    {
+      title: "宸ヨ壓璺嚎ID",
+      field: "itemNo",
+      width: 150,
+      align: "center",
+    },
+    {
+      title: "宸ュ簭搴忓彿",
+      field: "workOrderNo",
+      width: 150,
+      align: "center",
+    },
+    {
+      title: "宸ュ簭鍚嶇О",
+      field: "processNumber",
+      width: 100,
+      align: "center",
+    },
+    {
+      title: "鐢熸晥鏃ユ湡",
+      field: "processName",
+      width: 150,
+      align: "center",
+    },
+    {
+      title: "澶辨晥鏃ユ湡",
+      field: "processPlanStartDay",
+      width: 200,
+      align: "center",
+    },
+    {
+      title: "闆嗘垚鏃ユ湡",
+      field: "processPlanEndDay",
+      width: 200,
+      align: "center",
+    },
+    {
+      title: "閫傜敤宸ュ巶",
+      field: "standardTime",
+      width: 90,
+      align: "center",
+    },
+    {
+      title: "閫傜敤杞﹂棿",
+      field: "processOrder",
+      width: 90,
+      align: "center",
+    },
+    {
+      title: "浜ц兘妯″瀷",
+      field: "integrationDay",
+      width: 160,
+      align: "center",
+    },
+    {
+      title: "璁捐浜ц兘",
+      field: "integrationDay",
+      width: 160,
+      align: "center",
+    },
+  ],
+});
+const expandConfig = ref({
+  lazy: true,
+  loadMethod({ row }) {
+    // 璋冪敤鎺ュ彛
+    return listProcessRoute({ workOrderNo: row.documentNumber }).then(
+      (data) => {
+        row.subList = data.rows;
+      }
+    );
+  },
+});
+
+getList();
+</script>
+<style lang="css" scoped>
+h4 {
+  font-weight: bold;
+}
+</style>
diff --git a/src/views/mainPlan/sheetMetalOrderManage/index.vue b/src/views/mainPlan/sheetMetalOrderManage/index.vue
new file mode 100644
index 0000000..544f05e
--- /dev/null
+++ b/src/views/mainPlan/sheetMetalOrderManage/index.vue
@@ -0,0 +1,521 @@
+<template>
+  <div class="app-container">
+    <el-form
+      class="responsive-form"
+      :model="queryParams"
+      ref="queryRef"
+      :inline="true"
+      v-show="showSearch"
+      label-width="110px"
+    >
+        <el-form-item label="宸ュ崟鍙�" prop="description">
+            <el-input
+              style="width: 140px"
+              v-model="queryParams.description"
+              placeholder="璇疯緭鍏ラ渶姹傝拷婧疘D"
+              clearable
+              @keyup.enter="handleQuery"
+            />
+          </el-form-item>
+      <!-- <el-row type="flex" justify="left">
+        <el-col :span="5"> -->
+          <el-form-item label="闇�姹傝拷婧疘D" prop="description">
+            <el-input
+              style="width: 140px"
+              v-model="queryParams.description"
+              placeholder="璇疯緭鍏ラ渶姹傝拷婧疘D"
+              clearable
+              @keyup.enter="handleQuery"
+            />
+          </el-form-item>
+        <!-- </el-col>
+        <el-col :span="5"> -->
+          <el-form-item label="鏂欏彿" prop="description">
+            <el-input
+              style="width: 140px"
+              v-model="queryParams.description"
+              placeholder="璇疯緭鍏ユ枡鍙�"
+              clearable
+              @keyup.enter="handleQuery"
+            />
+          </el-form-item>
+          <el-form-item label="寤惰繜椋庨櫓鏍囪瘑" prop="description">
+            <el-input
+              style="width: 140px"
+              v-model="queryParams.description"
+              placeholder="璇疯緭鍏ユ枡鍙�"
+              clearable
+              @keyup.enter="handleQuery"
+            />
+          </el-form-item>
+        <!-- </el-col>
+        <el-col :span="14" style="text-align: right"> -->
+          <el-form-item class="column-with-margin">
+            <el-button type="primary" icon="Search" @click="handleQuery"
+              >鏌ヨ</el-button
+            >
+            <el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
+          </el-form-item>
+        <!-- </el-col>
+      </el-row> -->
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+            type="primary"
+            plain
+            icon="Plus"
+            :disabled="single"
+            @click="handleUpdate"
+            v-hasPermi="['apsPlatePlan:edit']"
+        >鎵归噺鏇存柊宸ュ崟璁″垝鏃ユ湡</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+            type="success"
+            plain
+            icon="Edit"
+            :disabled="single"
+            @click="handleUpdate"
+            v-hasPermi="['apsPlatePlan:edit']"
+        >鐢熸垚閽i噾璁″垝宸ュ崟</el-button>
+      </el-col>
+      <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+    <HxlhTable
+      style="width: 100%"
+      :columns="columns"
+      :data="calendarList"
+      :loading="loading"
+      :height="height"
+      ref="tableRef"
+      :page="page"
+      @changePageNo="changePageNo"
+      @changePageSize="changePageSize"
+      @on-checkbox="handleCheckboxChange"
+      class="auto-height-grid"
+    >
+    </HxlhTable>
+  </div>
+</template>
+
+<script setup name="Calendar">
+import HxlhTable from "@/components/HxlhTable";
+import {
+  listCalendar,
+  getCalendar,
+  delCalendar,
+  addCalendar,
+  updateCalendar,
+} from "@/api/basicData/calendar";
+import axios from "axios";
+import { listAll_plant } from "@/api/basicData/plant";
+import { listAll_shop, listAps_shop } from "@/api/basicData/shop";
+import { selectProcessNameList } from "@/api/basicData/processRoute.js";
+const { proxy } = getCurrentInstance();
+const tableRef = ref();
+const calendarList = ref([]);
+const loading = ref(true);
+const showSearch = ref(true);
+const ids = ref([]);
+const single = ref(true);
+const multiple = ref(true);
+const total = ref(0);
+const title = ref("");
+const data = reactive({
+  form: {
+    type: "1",
+  },
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    description: null,
+    type: null,
+    effectiveDate: null,
+    expiringDate: null,
+    content: null,
+    applicableFactory: null,
+    applicableWorkshop: null,
+    applicableProcess: null,
+  },
+});
+const { queryParams, form, rules } = toRefs(data);
+const typeRadioNumber = ref(1);
+const plantList = ref([]);
+const shopList = ref([]);
+const allShopList = ref([]);
+const processList = ref([]);
+const height = ref(document.documentElement.clientHeight - 220 + "px;");
+// 琛ㄦ牸閰嶇疆-鍒楄〃
+const columns = ref([
+  { type: "checkbox", width: 60, align: "center" },
+  {
+    title: "闇�姹侷D",
+    field: "description",
+    width: 150,
+    align: "center",
+  },
+  {
+    title: "闇�姹傝拷婧疘D",
+    field: "type",
+    width: 200,
+    align: "center",
+  },
+  {
+    title: "宸ュ崟鍙�",
+    field: "effectiveDate",
+    width: 200,
+    align: "center",
+  },
+  {
+    title: "鍖归厤鏁伴噺",
+    field: "expiringDate",
+    width: 200,
+    align: "center",
+  },
+  {
+    title: "宸ュ崟绫诲瀷",
+    field: "expiringDate",
+    width: 200,
+    align: "center",
+  },
+  {
+    title: "鏂欏彿",
+    field: "createTime",
+    width: 200,
+    align: "center",
+  },
+  {
+    title: "涓讳欢鍥惧彿",
+    field: "createTime",
+    width: 200,
+    align: "center",
+  },
+  {
+    title: "涓讳欢瀹㈡埛",
+    field: "createTime",
+    width: 200,
+    align: "center",
+  },
+  {
+    title: "鐢熶骇鏁伴噺",
+    field: "updateTime",
+    width: 100,
+    align: "center",
+  },
+  {
+    title: "闇�姹傛棩鏈�",
+    field: "updateTime",
+    width: 100,
+    align: "center",
+  },
+  {
+    title: "閫傜敤宸ュ巶",
+    field: "applicableFactory",
+    width: 200,
+    align: "center",
+    formatter: ({ cellValue, row, column }) => {
+      if (cellValue) {
+        for (let i = 0; i < plantList.value.length; i++) {
+          if (cellValue === plantList.value[i].plantCode) {
+            return plantList.value[i].plantName;
+          }
+        }
+      }
+    },
+  },
+  {
+    title: "鐢熶骇鍩哄湴",
+    field: "updateTime",
+    width: 100,
+    align: "center",
+  },
+]);
+// 鍒嗛〉灞炴��
+const page = ref({
+  total: 0,
+  current: 1,
+  size: 10,
+});
+
+/** 鏌ヨ鏃ュ巻绠$悊鍒楄〃 */
+function getList() {
+  loading.value = true;
+  listCalendar(queryParams.value).then((response) => {
+    calendarList.value = response.rows;
+    page.value.total = response.total;
+    loading.value = false;
+  });
+  axios
+    .all([
+      /** 鏌ヨ宸ュ巶鍒楄〃 */
+      listAll_plant({}),
+      /** 鏌ヨ杞﹂棿鍒楄〃 */
+      listAll_shop({}),
+    ])
+    .then(
+      axios.spread((response1, response2) => {
+        plantList.value = response1.data;
+        shopList.value = response2.data;
+        loading.value = false;
+      })
+    )
+    .catch((error) => {
+      console.error("璇锋眰鍑洪敊:", error);
+    });
+}
+
+// 鍙栨秷鎸夐挳
+function cancel() {
+  open.value = false;
+  reset();
+}
+
+// 琛ㄥ崟閲嶇疆
+function reset() {
+  form.value = {
+    id: null,
+    description: null,
+    type: "1",
+    effectiveDate: null,
+    expiringDate: null,
+    content: null,
+    applicableFactory: null,
+    applicableWorkshop: null,
+    applicableProcess: null,
+    createBy: null,
+    createTime: null,
+    updateBy: null,
+    updateTime: null,
+  };
+  proxy.resetForm("calendarRef");
+}
+
+/** 鎼滅储鎸夐挳鎿嶄綔 */
+function handleQuery() {
+  queryParams.value.pageNum = 1;
+  getList();
+}
+
+/** 閲嶇疆鎸夐挳鎿嶄綔 */
+function resetQuery() {
+  proxy.resetForm("queryRef");
+  handleQuery();
+}
+
+// 澶氶�夋閫変腑鏁版嵁
+function handleSelectionChange(selection) {
+  ids.value = selection.map((item) => item.id);
+  single.value = selection.length != 1;
+  multiple.value = !selection.length;
+}
+
+/** 鏂板鎸夐挳鎿嶄綔 */
+async function handleAdd() {
+  reset();
+  open.value = true;
+  title.value = "娣诲姞鏃ュ巻绠$悊";
+}
+/** 閫夋嫨宸ュ巶鍚庝簨浠� 鍔犺浇杞﹂棿 鍜� 宸ュ簭 **/
+function changePlant(plant) {
+  listAps_shop({ plantCode: plant }).then((response) => {
+    shopList.value = response.rows;
+  });
+  selectProcessNameList({ orgCode: plant }).then((response) => {
+    processList.value = response.rows;
+  });
+}
+/** 淇敼鎸夐挳鎿嶄綔 */
+function handleUpdate(row) {
+  reset();
+  const _id = row.id || ids.value;
+  getCalendar(_id).then((response) => {
+    form.value = response.data;
+    // form.value.content = JSON.parse(response.data.content.value);
+    if (form.value.type === "1") {
+      weekDaysSettingList.value = JSON.parse(
+        response.data.content.value
+      ).weekdays;
+    } else if (form.value.type === "2") {
+      holidays.value = JSON.parse(response.data.content.value).holidays;
+    }
+
+    open.value = true;
+    title.value = "淇敼鏃ュ巻绠$悊";
+  });
+}
+
+/** 鎻愪氦鎸夐挳 */
+function submitForm() {
+  proxy.$refs["calendarRef"].validate((valid) => {
+    if (valid) {
+      if (form.value.id != null) {
+        if (form.value.type === "1") {
+          updateCalendar({
+            ...form.value,
+            content: {
+              weekdays: weekDaysSettingList.value,
+            },
+            applicableWorkshop: form.value.applicableWorkshop,
+            applicableProcess: form.value.applicableProcess,
+          }).then((response) => {
+            proxy.$modal.msgSuccess("淇敼鎴愬姛");
+            open.value = false;
+            getList();
+          });
+        } else if (form.value.type === "2") {
+          updateCalendar({
+            ...form.value,
+            content: {
+              holidays: holidays.value,
+            },
+            applicableWorkshop: form.value.applicableWorkshop,
+            applicableProcess: form.value.applicableProcess,
+          }).then((response) => {
+            proxy.$modal.msgSuccess("淇敼鎴愬姛");
+            open.value = false;
+            getList();
+          });
+        }
+      } else {
+        if (form.value.type === "1") {
+          addCalendar({
+            ...form.value,
+            content: {
+              weekdays: weekDaysSettingList.value,
+            },
+          }).then((response) => {
+            proxy.$modal.msgSuccess("鏂板鎴愬姛");
+            open.value = false;
+            getList();
+          });
+        } else if (form.value.type === "2") {
+          addCalendar({
+            ...form.value,
+            content: {
+              holidays: holidays.value,
+            },
+          }).then((response) => {
+            proxy.$modal.msgSuccess("鏂板鎴愬姛");
+            open.value = false;
+            getList();
+          });
+        }
+      }
+    }
+  });
+}
+
+/** 鍒犻櫎鎸夐挳鎿嶄綔 */
+function handleDelete(row) {
+  const _ids = row.id || ids.value;
+  proxy.$modal
+    .confirm('鏄惁纭鍒犻櫎鏃ュ巻绠$悊缂栧彿涓�"' + _ids + '"鐨勬暟鎹」锛�')
+    .then(function () {
+      return delCalendar(_ids);
+    })
+    .then(() => {
+      getList();
+      proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+    })
+    .catch(() => {});
+}
+
+/** 瀵煎嚭鎸夐挳鎿嶄綔 */
+function handleExport() {
+  proxy.download(
+    "core/calendar/export",
+    {
+      ...queryParams.value,
+    },
+    `calendar_${new Date().getTime()}.xlsx`
+  );
+}
+function handleSwitchType(e) {
+  typeRadioNumber.value = e;
+  form.value.type = e;
+  form.value.effectiveDate = null;
+  form.value.expiringDate = null;
+  form.value.content = null;
+  form.value.applicableFactory = null;
+  form.value.applicableWorkshop = null;
+  form.value.applicableProcess = null;
+}
+function changePageNo(currentPage) {
+  queryParams.value.pageNum = currentPage;
+  page.value.current = currentPage;
+  getList();
+}
+function changePageSize(pageSize) {
+  page.value.current = 1;
+  queryParams.value.pageNum = 1;
+  queryParams.value.pageSize = pageSize;
+  getList();
+}
+// 澶氶�夋閫変腑鏁版嵁
+const handleCheckboxChange = (data) => {
+  ids.value = data.records.map((item) => item.id);
+  single.value = data.records.length !== 1;
+  multiple.value = !data.records.length;
+};
+onMounted(() => {
+  getList();
+});
+</script>
+<style lang="scss" scoped>
+.column-with-margin {
+  margin-right: 0px;
+}
+.title_bar_line {
+  display: flex;
+  justify-content: flex-start;
+  align-items: center;
+  color: #333;
+  margin-bottom: 10px;
+  .line_short {
+    width: 5%;
+    height: 1px;
+    margin-right: 20px;
+    border-top: 1px solid #ddd;
+  }
+  .line_long {
+    width: 60%;
+    height: 1px;
+    margin-left: 20px;
+    border-top: 1px solid #ddd;
+  }
+}
+.week_flex {
+  display: flex;
+  justify-content: flex-start;
+  align-content: center;
+  color: #606266;
+  font-weight: 700;
+  margin-left: 20px;
+  &.mt20 {
+    margin-top: 20px;
+    margin-left: 0 !important;
+  }
+  .week_flex_item {
+    &:nth-child(1) {
+      margin-top: 5px;
+    }
+    &:nth-child(2) {
+      margin-left: 20px;
+    }
+  }
+}
+.factory_use_item {
+  margin-top: 10px;
+}
+.mart5 {
+  margin-top: 5px;
+}
+.custom-height {
+  height: 200px; /* 鎴栬�呬娇鐢� min-height */
+}
+.auto-height-grid .xe-body .xe-body--row {
+  height: auto; /* 鎴栬�呬娇鐢� min-height */
+}
+</style>
diff --git a/src/views/mainPlan/sheetMetalRedundantReport/index.vue b/src/views/mainPlan/sheetMetalRedundantReport/index.vue
new file mode 100644
index 0000000..858de3e
--- /dev/null
+++ b/src/views/mainPlan/sheetMetalRedundantReport/index.vue
@@ -0,0 +1,478 @@
+<template>
+  <div class="app-container">
+    <el-form
+      class="responsive-form"
+      :model="queryParams"
+      ref="queryRef"
+      :inline="true"
+      v-show="showSearch"
+      label-width="90px"
+    >
+      <el-row type="flex" justify="left">
+        <el-col :span="5">
+          <el-form-item label="闇�姹傝拷婧疘D" prop="description">
+            <el-input
+              style="width: 140px"
+              v-model="queryParams.description"
+              placeholder="璇疯緭鍏ラ渶姹傝拷婧疘D"
+              clearable
+              @keyup.enter="handleQuery"
+            />
+          </el-form-item>
+        </el-col>
+        <el-col :span="5">
+          <el-form-item label="鏂欏彿" prop="description">
+            <el-input
+              style="width: 140px"
+              v-model="queryParams.description"
+              placeholder="璇疯緭鍏ユ枡鍙�"
+              clearable
+              @keyup.enter="handleQuery"
+            />
+          </el-form-item>
+        </el-col>
+        <el-col :span="14" style="text-align: right">
+          <el-form-item class="column-with-margin">
+            <el-button type="primary" icon="Search" @click="handleQuery"
+              >鏌ヨ</el-button
+            >
+            <el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
+          </el-form-item>
+        </el-col>
+      </el-row>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="Download"
+          @click="handleExport"
+          v-hasPermi="['core:calendar:export']"
+          >瀵煎嚭</el-button
+        >
+      </el-col>
+      <right-toolbar
+        v-model:showSearch="showSearch"
+        @queryTable="getList"
+      ></right-toolbar>
+    </el-row>
+    <HxlhTable
+      style="width: 100%"
+      :columns="columns"
+      :data="calendarList"
+      :loading="loading"
+      :height="height"
+      ref="tableRef"
+      :page="page"
+      @changePageNo="changePageNo"
+      @changePageSize="changePageSize"
+      @on-checkbox="handleCheckboxChange"
+      class="auto-height-grid"
+    >
+    </HxlhTable>
+  </div>
+</template>
+
+<script setup name="Calendar">
+import HxlhTable from "@/components/HxlhTable";
+import {
+  listCalendar,
+  getCalendar,
+  delCalendar,
+  addCalendar,
+  updateCalendar,
+} from "@/api/basicData/calendar";
+import axios from "axios";
+import { listAll_plant } from "@/api/basicData/plant";
+import { listAll_shop, listAps_shop } from "@/api/basicData/shop";
+import { selectProcessNameList } from "@/api/basicData/processRoute.js";
+const { proxy } = getCurrentInstance();
+const tableRef = ref();
+const calendarList = ref([]);
+const loading = ref(true);
+const showSearch = ref(true);
+const ids = ref([]);
+const single = ref(true);
+const multiple = ref(true);
+const total = ref(0);
+const title = ref("");
+const data = reactive({
+  form: {
+    type: "1",
+  },
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    description: null,
+    type: null,
+    effectiveDate: null,
+    expiringDate: null,
+    content: null,
+    applicableFactory: null,
+    applicableWorkshop: null,
+    applicableProcess: null,
+  },
+});
+const { queryParams, form, rules } = toRefs(data);
+const typeRadioNumber = ref(1);
+const plantList = ref([]);
+const shopList = ref([]);
+const allShopList = ref([]);
+const processList = ref([]);
+const height = ref(document.documentElement.clientHeight - 220 + "px;");
+// 琛ㄦ牸閰嶇疆-鍒楄〃
+const columns = ref([
+  {
+    title: "宸ュ崟鍙�",
+    field: "description",
+    width: 150,
+    align: "center"
+  },
+  {
+    title: "瀛愪欢鏂欏彿",
+    field: "type",
+    width: 200,
+    align: "center"
+  },
+  {
+    title: "鐢熶骇鏁伴噺",
+    field: "effectiveDate",
+    width: 200,
+    align: "center",
+  },
+  {
+    title: "鏈尮閰嶇敓浜ф暟閲�",
+    field: "expiringDate",
+    width: 200,
+    align: "center"
+  },
+  {
+    title: "閫傜敤宸ュ巶",
+    field: "applicableFactory",
+    width: 200,
+    align: "center",
+    formatter: ({ cellValue, row, column }) => {
+      if (cellValue) {
+        for (let i = 0; i < plantList.value.length; i++) {
+          if (cellValue === plantList.value[i].plantCode) {
+            return plantList.value[i].plantName;
+          }
+        }
+      }
+    },
+  },
+  {
+    title: "鐢熶骇鍩哄湴",
+    field: "expiringDate",
+    width: 200,
+    align: "center"
+  },
+  {
+    title: "璁″垝寮�宸ユ棩",
+    field: "createTime",
+    width: 200,
+    align: "center",
+  },
+  {
+    title: "璁″垝瀹屽伐鏃�",
+    field: "updateTime",
+    width: 100,
+    align: "center",
+  },
+  {
+    title: "宸ュ崟鍒涘缓鏃堕棿",
+    field: "updateTime",
+    width: 100,
+    align: "center",
+  },
+]);
+// 鍒嗛〉灞炴��
+const page = ref({
+  total: 0,
+  current: 1,
+  size: 10,
+});
+
+/** 鏌ヨ鏃ュ巻绠$悊鍒楄〃 */
+function getList() {
+  loading.value = true;
+  listCalendar(queryParams.value).then((response) => {
+    calendarList.value = response.rows;
+    page.value.total = response.total;
+    loading.value = false;
+  });
+  axios
+    .all([
+      /** 鏌ヨ宸ュ巶鍒楄〃 */
+      listAll_plant({}),
+      /** 鏌ヨ杞﹂棿鍒楄〃 */
+      listAll_shop({}),
+    ])
+    .then(
+      axios.spread((response1, response2) => {
+        plantList.value = response1.data;
+        shopList.value = response2.data;
+        loading.value = false;
+      })
+    )
+    .catch((error) => {
+      console.error("璇锋眰鍑洪敊:", error);
+    });
+}
+
+// 鍙栨秷鎸夐挳
+function cancel() {
+  open.value = false;
+  reset();
+}
+
+// 琛ㄥ崟閲嶇疆
+function reset() {
+  form.value = {
+    id: null,
+    description: null,
+    type: "1",
+    effectiveDate: null,
+    expiringDate: null,
+    content: null,
+    applicableFactory: null,
+    applicableWorkshop: null,
+    applicableProcess: null,
+    createBy: null,
+    createTime: null,
+    updateBy: null,
+    updateTime: null,
+  };
+  proxy.resetForm("calendarRef");
+}
+
+/** 鎼滅储鎸夐挳鎿嶄綔 */
+function handleQuery() {
+  queryParams.value.pageNum = 1;
+  getList();
+}
+
+/** 閲嶇疆鎸夐挳鎿嶄綔 */
+function resetQuery() {
+  proxy.resetForm("queryRef");
+  handleQuery();
+}
+
+// 澶氶�夋閫変腑鏁版嵁
+function handleSelectionChange(selection) {
+  ids.value = selection.map((item) => item.id);
+  single.value = selection.length != 1;
+  multiple.value = !selection.length;
+}
+
+/** 鏂板鎸夐挳鎿嶄綔 */
+async function handleAdd() {
+  reset();
+  open.value = true;
+  title.value = "娣诲姞鏃ュ巻绠$悊";
+}
+/** 閫夋嫨宸ュ巶鍚庝簨浠� 鍔犺浇杞﹂棿 鍜� 宸ュ簭 **/
+function changePlant(plant) {
+  listAps_shop({ plantCode: plant }).then((response) => {
+    shopList.value = response.rows;
+  });
+  selectProcessNameList({ orgCode: plant }).then((response) => {
+    processList.value = response.rows;
+  });
+}
+/** 淇敼鎸夐挳鎿嶄綔 */
+function handleUpdate(row) {
+  reset();
+  const _id = row.id || ids.value;
+  getCalendar(_id).then((response) => {
+    form.value = response.data;
+    // form.value.content = JSON.parse(response.data.content.value);
+    if (form.value.type === "1") {
+      weekDaysSettingList.value = JSON.parse(
+        response.data.content.value
+      ).weekdays;
+    } else if (form.value.type === "2") {
+      holidays.value = JSON.parse(response.data.content.value).holidays;
+    }
+
+    open.value = true;
+    title.value = "淇敼鏃ュ巻绠$悊";
+  });
+}
+
+/** 鎻愪氦鎸夐挳 */
+function submitForm() {
+  proxy.$refs["calendarRef"].validate((valid) => {
+    if (valid) {
+      if (form.value.id != null) {
+        if (form.value.type === "1") {
+          updateCalendar({
+            ...form.value,
+            content: {
+              weekdays: weekDaysSettingList.value,
+            },
+            applicableWorkshop: form.value.applicableWorkshop,
+            applicableProcess: form.value.applicableProcess,
+          }).then((response) => {
+            proxy.$modal.msgSuccess("淇敼鎴愬姛");
+            open.value = false;
+            getList();
+          });
+        } else if (form.value.type === "2") {
+          updateCalendar({
+            ...form.value,
+            content: {
+              holidays: holidays.value,
+            },
+            applicableWorkshop: form.value.applicableWorkshop,
+            applicableProcess: form.value.applicableProcess,
+          }).then((response) => {
+            proxy.$modal.msgSuccess("淇敼鎴愬姛");
+            open.value = false;
+            getList();
+          });
+        }
+      } else {
+        if (form.value.type === "1") {
+          addCalendar({
+            ...form.value,
+            content: {
+              weekdays: weekDaysSettingList.value,
+            },
+          }).then((response) => {
+            proxy.$modal.msgSuccess("鏂板鎴愬姛");
+            open.value = false;
+            getList();
+          });
+        } else if (form.value.type === "2") {
+          addCalendar({
+            ...form.value,
+            content: {
+              holidays: holidays.value,
+            },
+          }).then((response) => {
+            proxy.$modal.msgSuccess("鏂板鎴愬姛");
+            open.value = false;
+            getList();
+          });
+        }
+      }
+    }
+  });
+}
+
+/** 鍒犻櫎鎸夐挳鎿嶄綔 */
+function handleDelete(row) {
+  const _ids = row.id || ids.value;
+  proxy.$modal
+    .confirm('鏄惁纭鍒犻櫎鏃ュ巻绠$悊缂栧彿涓�"' + _ids + '"鐨勬暟鎹」锛�')
+    .then(function () {
+      return delCalendar(_ids);
+    })
+    .then(() => {
+      getList();
+      proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+    })
+    .catch(() => {});
+}
+
+/** 瀵煎嚭鎸夐挳鎿嶄綔 */
+function handleExport() {
+  proxy.download(
+    "core/calendar/export",
+    {
+      ...queryParams.value,
+    },
+    `calendar_${new Date().getTime()}.xlsx`
+  );
+}
+function handleSwitchType(e) {
+  typeRadioNumber.value = e;
+  form.value.type = e;
+  form.value.effectiveDate = null;
+  form.value.expiringDate = null;
+  form.value.content = null;
+  form.value.applicableFactory = null;
+  form.value.applicableWorkshop = null;
+  form.value.applicableProcess = null;
+}
+function changePageNo(currentPage) {
+  queryParams.value.pageNum = currentPage;
+  page.value.current = currentPage;
+  getList();
+}
+function changePageSize(pageSize) {
+  page.value.current = 1;
+  queryParams.value.pageNum = 1;
+  queryParams.value.pageSize = pageSize;
+  getList();
+}
+// 澶氶�夋閫変腑鏁版嵁
+const handleCheckboxChange = (data) => {
+  ids.value = data.records.map((item) => item.id);
+  single.value = data.records.length !== 1;
+  multiple.value = !data.records.length;
+};
+onMounted(() => {
+  getList();
+});
+</script>
+<style lang="scss" scoped>
+.column-with-margin {
+  margin-right: 0px;
+}
+.title_bar_line {
+  display: flex;
+  justify-content: flex-start;
+  align-items: center;
+  color: #333;
+  margin-bottom: 10px;
+  .line_short {
+    width: 5%;
+    height: 1px;
+    margin-right: 20px;
+    border-top: 1px solid #ddd;
+  }
+  .line_long {
+    width: 60%;
+    height: 1px;
+    margin-left: 20px;
+    border-top: 1px solid #ddd;
+  }
+}
+.week_flex {
+  display: flex;
+  justify-content: flex-start;
+  align-content: center;
+  color: #606266;
+  font-weight: 700;
+  margin-left: 20px;
+  &.mt20 {
+    margin-top: 20px;
+    margin-left: 0 !important;
+  }
+  .week_flex_item {
+    &:nth-child(1) {
+      margin-top: 5px;
+    }
+    &:nth-child(2) {
+      margin-left: 20px;
+    }
+  }
+}
+.factory_use_item {
+  margin-top: 10px;
+}
+.mart5 {
+  margin-top: 5px;
+}
+.custom-height {
+  height: 200px; /* 鎴栬�呬娇鐢� min-height */
+}
+.auto-height-grid .xe-body .xe-body--row {
+  height: auto; /* 鎴栬�呬娇鐢� min-height */
+}
+</style>
diff --git a/src/views/mainPlan/sheetMetalSupplyGap/index.vue b/src/views/mainPlan/sheetMetalSupplyGap/index.vue
new file mode 100644
index 0000000..d60e9aa
--- /dev/null
+++ b/src/views/mainPlan/sheetMetalSupplyGap/index.vue
@@ -0,0 +1,495 @@
+<template>
+  <div class="app-container">
+    <el-form
+      class="responsive-form"
+      :model="queryParams"
+      ref="queryRef"
+      :inline="true"
+      v-show="showSearch"
+      label-width="90px"
+    >
+      <el-row type="flex" justify="left">
+        <el-col :span="5">
+          <el-form-item label="闇�姹傝拷婧疘D" prop="description">
+            <el-input
+              style="width: 140px"
+              v-model="queryParams.description"
+              placeholder="璇疯緭鍏ラ渶姹傝拷婧疘D"
+              clearable
+              @keyup.enter="handleQuery"
+            />
+          </el-form-item>
+        </el-col>
+        <el-col :span="5">
+          <el-form-item label="鏂欏彿" prop="description">
+            <el-input
+              style="width: 140px"
+              v-model="queryParams.description"
+              placeholder="璇疯緭鍏ユ枡鍙�"
+              clearable
+              @keyup.enter="handleQuery"
+            />
+          </el-form-item>
+        </el-col>
+        <el-col :span="14" style="text-align: right">
+          <el-form-item class="column-with-margin">
+            <el-button type="primary" icon="Search" @click="handleQuery"
+              >鏌ヨ</el-button
+            >
+            <el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
+          </el-form-item>
+        </el-col>
+      </el-row>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="Download"
+          @click="handleExport"
+          v-hasPermi="['core:calendar:export']"
+          >瀵煎嚭</el-button
+        >
+      </el-col>
+      <right-toolbar
+        v-model:showSearch="showSearch"
+        @queryTable="getList"
+      ></right-toolbar>
+    </el-row>
+    <HxlhTable
+      style="width: 100%"
+      :columns="columns"
+      :data="calendarList"
+      :loading="loading"
+      :height="height"
+      ref="tableRef"
+      :page="page"
+      @changePageNo="changePageNo"
+      @changePageSize="changePageSize"
+      @on-checkbox="handleCheckboxChange"
+      class="auto-height-grid"
+    >
+    </HxlhTable>
+  </div>
+</template>
+
+<script setup name="Calendar">
+import HxlhTable from "@/components/HxlhTable";
+import {
+  listCalendar,
+  getCalendar,
+  delCalendar,
+  addCalendar,
+  updateCalendar,
+} from "@/api/basicData/calendar";
+import axios from "axios";
+import { listAll_plant } from "@/api/basicData/plant";
+import { listAll_shop, listAps_shop } from "@/api/basicData/shop";
+import { selectProcessNameList } from "@/api/basicData/processRoute.js";
+const { proxy } = getCurrentInstance();
+const tableRef = ref();
+const calendarList = ref([]);
+const loading = ref(true);
+const showSearch = ref(true);
+const ids = ref([]);
+const single = ref(true);
+const multiple = ref(true);
+const total = ref(0);
+const title = ref("");
+const data = reactive({
+  form: {
+    type: "1",
+  },
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    description: null,
+    type: null,
+    effectiveDate: null,
+    expiringDate: null,
+    content: null,
+    applicableFactory: null,
+    applicableWorkshop: null,
+    applicableProcess: null,
+  },
+});
+const { queryParams, form, rules } = toRefs(data);
+const typeRadioNumber = ref(1);
+const plantList = ref([]);
+const shopList = ref([]);
+const allShopList = ref([]);
+const processList = ref([]);
+const height = ref(document.documentElement.clientHeight - 220 + "px;");
+// 琛ㄦ牸閰嶇疆-鍒楄〃
+const columns = ref([
+  {
+    title: "闇�姹侷D",
+    field: "description",
+    width: 150,
+    align: "center",
+  },
+  {
+    title: "闇�姹傝拷婧疘D",
+    field: "type",
+    width: 200,
+    align: "center",
+  },
+  {
+    title: "鏂欏彿",
+    field: "effectiveDate",
+    width: 200,
+    align: "center",
+  },
+  {
+    title: "BOM浣庨樁鐮�",
+    field: "expiringDate",
+    width: 200,
+    align: "center",
+  },
+  {
+    title: "鍖归厤鐘舵��",
+    field: "expiringDate",
+    width: 200,
+    align: "center",
+  },
+  {
+    title: "鍖归厤妯″紡",
+    field: "createTime",
+    width: 200,
+    align: "center",
+  },
+  {
+    title: "鏈尮閰嶉渶姹傛暟閲�",
+    field: "createTime",
+    width: 200,
+    align: "center",
+  },
+  {
+    title: "璁″垝寮�宸ユ棩",
+    field: "createTime",
+    width: 200,
+    align: "center",
+  },
+  {
+    title: "璁″垝瀹屽伐鏃�",
+    field: "updateTime",
+    width: 100,
+    align: "center",
+  },
+  {
+    title: "闇�姹傛棩鏈�",
+    field: "updateTime",
+    width: 100,
+    align: "center",
+  },
+  {
+    title: "閫傜敤宸ュ巶",
+    field: "applicableFactory",
+    width: 200,
+    align: "center",
+    formatter: ({ cellValue, row, column }) => {
+      if (cellValue) {
+        for (let i = 0; i < plantList.value.length; i++) {
+          if (cellValue === plantList.value[i].plantCode) {
+            return plantList.value[i].plantName;
+          }
+        }
+      }
+    },
+  },
+  {
+    title: "鐢熶骇鍩哄湴",
+    field: "updateTime",
+    width: 100,
+    align: "center",
+  },
+]);
+// 鍒嗛〉灞炴��
+const page = ref({
+  total: 0,
+  current: 1,
+  size: 10,
+});
+
+/** 鏌ヨ鏃ュ巻绠$悊鍒楄〃 */
+function getList() {
+  loading.value = true;
+  listCalendar(queryParams.value).then((response) => {
+    calendarList.value = response.rows;
+    page.value.total = response.total;
+    loading.value = false;
+  });
+  axios
+    .all([
+      /** 鏌ヨ宸ュ巶鍒楄〃 */
+      listAll_plant({}),
+      /** 鏌ヨ杞﹂棿鍒楄〃 */
+      listAll_shop({}),
+    ])
+    .then(
+      axios.spread((response1, response2) => {
+        plantList.value = response1.data;
+        shopList.value = response2.data;
+        loading.value = false;
+      })
+    )
+    .catch((error) => {
+      console.error("璇锋眰鍑洪敊:", error);
+    });
+}
+
+// 鍙栨秷鎸夐挳
+function cancel() {
+  open.value = false;
+  reset();
+}
+
+// 琛ㄥ崟閲嶇疆
+function reset() {
+  form.value = {
+    id: null,
+    description: null,
+    type: "1",
+    effectiveDate: null,
+    expiringDate: null,
+    content: null,
+    applicableFactory: null,
+    applicableWorkshop: null,
+    applicableProcess: null,
+    createBy: null,
+    createTime: null,
+    updateBy: null,
+    updateTime: null,
+  };
+  proxy.resetForm("calendarRef");
+}
+
+/** 鎼滅储鎸夐挳鎿嶄綔 */
+function handleQuery() {
+  queryParams.value.pageNum = 1;
+  getList();
+}
+
+/** 閲嶇疆鎸夐挳鎿嶄綔 */
+function resetQuery() {
+  proxy.resetForm("queryRef");
+  handleQuery();
+}
+
+// 澶氶�夋閫変腑鏁版嵁
+function handleSelectionChange(selection) {
+  ids.value = selection.map((item) => item.id);
+  single.value = selection.length != 1;
+  multiple.value = !selection.length;
+}
+
+/** 鏂板鎸夐挳鎿嶄綔 */
+async function handleAdd() {
+  reset();
+  open.value = true;
+  title.value = "娣诲姞鏃ュ巻绠$悊";
+}
+/** 閫夋嫨宸ュ巶鍚庝簨浠� 鍔犺浇杞﹂棿 鍜� 宸ュ簭 **/
+function changePlant(plant) {
+  listAps_shop({ plantCode: plant }).then((response) => {
+    shopList.value = response.rows;
+  });
+  selectProcessNameList({ orgCode: plant }).then((response) => {
+    processList.value = response.rows;
+  });
+}
+/** 淇敼鎸夐挳鎿嶄綔 */
+function handleUpdate(row) {
+  reset();
+  const _id = row.id || ids.value;
+  getCalendar(_id).then((response) => {
+    form.value = response.data;
+    // form.value.content = JSON.parse(response.data.content.value);
+    if (form.value.type === "1") {
+      weekDaysSettingList.value = JSON.parse(
+        response.data.content.value
+      ).weekdays;
+    } else if (form.value.type === "2") {
+      holidays.value = JSON.parse(response.data.content.value).holidays;
+    }
+
+    open.value = true;
+    title.value = "淇敼鏃ュ巻绠$悊";
+  });
+}
+
+/** 鎻愪氦鎸夐挳 */
+function submitForm() {
+  proxy.$refs["calendarRef"].validate((valid) => {
+    if (valid) {
+      if (form.value.id != null) {
+        if (form.value.type === "1") {
+          updateCalendar({
+            ...form.value,
+            content: {
+              weekdays: weekDaysSettingList.value,
+            },
+            applicableWorkshop: form.value.applicableWorkshop,
+            applicableProcess: form.value.applicableProcess,
+          }).then((response) => {
+            proxy.$modal.msgSuccess("淇敼鎴愬姛");
+            open.value = false;
+            getList();
+          });
+        } else if (form.value.type === "2") {
+          updateCalendar({
+            ...form.value,
+            content: {
+              holidays: holidays.value,
+            },
+            applicableWorkshop: form.value.applicableWorkshop,
+            applicableProcess: form.value.applicableProcess,
+          }).then((response) => {
+            proxy.$modal.msgSuccess("淇敼鎴愬姛");
+            open.value = false;
+            getList();
+          });
+        }
+      } else {
+        if (form.value.type === "1") {
+          addCalendar({
+            ...form.value,
+            content: {
+              weekdays: weekDaysSettingList.value,
+            },
+          }).then((response) => {
+            proxy.$modal.msgSuccess("鏂板鎴愬姛");
+            open.value = false;
+            getList();
+          });
+        } else if (form.value.type === "2") {
+          addCalendar({
+            ...form.value,
+            content: {
+              holidays: holidays.value,
+            },
+          }).then((response) => {
+            proxy.$modal.msgSuccess("鏂板鎴愬姛");
+            open.value = false;
+            getList();
+          });
+        }
+      }
+    }
+  });
+}
+
+/** 鍒犻櫎鎸夐挳鎿嶄綔 */
+function handleDelete(row) {
+  const _ids = row.id || ids.value;
+  proxy.$modal
+    .confirm('鏄惁纭鍒犻櫎鏃ュ巻绠$悊缂栧彿涓�"' + _ids + '"鐨勬暟鎹」锛�')
+    .then(function () {
+      return delCalendar(_ids);
+    })
+    .then(() => {
+      getList();
+      proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+    })
+    .catch(() => {});
+}
+
+/** 瀵煎嚭鎸夐挳鎿嶄綔 */
+function handleExport() {
+  proxy.download(
+    "core/calendar/export",
+    {
+      ...queryParams.value,
+    },
+    `calendar_${new Date().getTime()}.xlsx`
+  );
+}
+function handleSwitchType(e) {
+  typeRadioNumber.value = e;
+  form.value.type = e;
+  form.value.effectiveDate = null;
+  form.value.expiringDate = null;
+  form.value.content = null;
+  form.value.applicableFactory = null;
+  form.value.applicableWorkshop = null;
+  form.value.applicableProcess = null;
+}
+function changePageNo(currentPage) {
+  queryParams.value.pageNum = currentPage;
+  page.value.current = currentPage;
+  getList();
+}
+function changePageSize(pageSize) {
+  page.value.current = 1;
+  queryParams.value.pageNum = 1;
+  queryParams.value.pageSize = pageSize;
+  getList();
+}
+// 澶氶�夋閫変腑鏁版嵁
+const handleCheckboxChange = (data) => {
+  ids.value = data.records.map((item) => item.id);
+  single.value = data.records.length !== 1;
+  multiple.value = !data.records.length;
+};
+onMounted(() => {
+  getList();
+});
+</script>
+<style lang="scss" scoped>
+.column-with-margin {
+  margin-right: 0px;
+}
+.title_bar_line {
+  display: flex;
+  justify-content: flex-start;
+  align-items: center;
+  color: #333;
+  margin-bottom: 10px;
+  .line_short {
+    width: 5%;
+    height: 1px;
+    margin-right: 20px;
+    border-top: 1px solid #ddd;
+  }
+  .line_long {
+    width: 60%;
+    height: 1px;
+    margin-left: 20px;
+    border-top: 1px solid #ddd;
+  }
+}
+.week_flex {
+  display: flex;
+  justify-content: flex-start;
+  align-content: center;
+  color: #606266;
+  font-weight: 700;
+  margin-left: 20px;
+  &.mt20 {
+    margin-top: 20px;
+    margin-left: 0 !important;
+  }
+  .week_flex_item {
+    &:nth-child(1) {
+      margin-top: 5px;
+    }
+    &:nth-child(2) {
+      margin-left: 20px;
+    }
+  }
+}
+.factory_use_item {
+  margin-top: 10px;
+}
+.mart5 {
+  margin-top: 5px;
+}
+.custom-height {
+  height: 200px; /* 鎴栬�呬娇鐢� min-height */
+}
+.auto-height-grid .xe-body .xe-body--row {
+  height: auto; /* 鎴栬�呬娇鐢� min-height */
+}
+</style>

--
Gitblit v1.9.3