Bläddra i källkod

新增一次性合格率页面

luoxiao 3 veckor sedan
förälder
incheckning
ab460ec07e

+ 106 - 0
src/api/statistic/firstPassYieldMockData.ts

@@ -0,0 +1,106 @@
+export const getMockData = async () => {
+  const records = [
+    {
+      productLineName: "微电子车间",
+      productName: "产品A",
+      productType: "类型1",
+      goodRate: "95%",
+      badRate: "5%",
+      timeStr: "2025-03-22",
+    },
+    {
+      productLineName: "微电子车间",
+      productName: "产品B",
+      productType: "类型2",
+      goodRate: "90%",
+      badRate: "10%",
+      timeStr: "2025-03-22",
+    },
+    {
+      productLineName: "微电子车间",
+      productName: "产品A",
+      productType: "类型1",
+      goodRate: "95%",
+      badRate: "5%",
+      timeStr: "2025-03-22",
+    },
+    {
+      productLineName: "微电子车间",
+      productName: "产品B",
+      productType: "类型2",
+      goodRate: "90%",
+      badRate: "10%",
+      timeStr: "2025-03-22",
+    },
+    {
+      productLineName: "微电子车间",
+      productName: "产品A",
+      productType: "类型1",
+      goodRate: "95%",
+      badRate: "5%",
+      timeStr: "2025-03-22",
+    },
+    {
+      productLineName: "微电子车间",
+      productName: "产品B",
+      productType: "类型2",
+      goodRate: "90%",
+      badRate: "10%",
+      timeStr: "2025-03-22",
+    },
+    {
+      productLineName: "微电子车间",
+      productName: "产品A",
+      productType: "类型1",
+      goodRate: "95%",
+      badRate: "5%",
+      timeStr: "2025-03-22",
+    },
+    {
+      productLineName: "微电子车间",
+      productName: "产品B",
+      productType: "类型2",
+      goodRate: "90%",
+      badRate: "10%",
+      timeStr: "2025-03-22",
+    },
+    {
+      productLineName: "微电子车间",
+      productName: "产品A",
+      productType: "类型1",
+      goodRate: "95%",
+      badRate: "5%",
+      timeStr: "2025-03-22",
+    },
+    {
+      productLineName: "微电子车间",
+      productName: "产品B",
+      productType: "类型2",
+      goodRate: "90%",
+      badRate: "10%",
+      timeStr: "2025-03-22",
+    },
+    {
+      productLineName: "微电子车间",
+      productName: "产品A",
+      productType: "类型1",
+      goodRate: "95%",
+      badRate: "5%",
+      timeStr: "2025-03-22",
+    },
+    {
+      productLineName: "微电子车间",
+      productName: "产品B",
+      productType: "类型2",
+      goodRate: "90%",
+      badRate: "10%",
+      timeStr: "2025-03-22",
+    },
+  ];
+  return {
+    data: {
+      records: records,
+      totalCount: records.length,
+    },
+  };
+};

+ 9 - 0
src/router/modules/statistic.ts

@@ -20,6 +20,15 @@ export default {
       },
     },
     {
+      path: "first-pass-yield",
+      component: () => import("@/views/statistic/firstPassYield/index.vue"),
+      name: "FirstPassYield",
+      meta: {
+        title: "一次性合格率",
+        icon: "CreditCard",
+      },
+    },
+    {
       path: "report",
       component: () => import("@/views/statistic/report/index.vue"),
       name: "StatisticReport",

+ 313 - 0
src/views/statistic/firstPassYield/index.vue

@@ -0,0 +1,313 @@
+<template>
+  <div class="container1">
+    <div class="infobox">
+      <el-scrollbar>
+        <div class="header">
+          <div class="text">选择统计时间段:</div>
+          <div style="display: flex">
+            <el-date-picker
+              v-model="value1"
+              type="daterange"
+              range-separator="-"
+              start-placeholder="起始时间"
+              end-placeholder="截止时间"
+              format="YYYY-MM-DD"
+              value-format="YYYY-MM-DD"
+              size="small"
+            />
+          </div>
+        </div>
+        <div class="header">
+          <div class="text">选择统计维度:</div>
+          <div>
+            <el-radio-group v-model="radio" style="display: flex">
+              <el-radio size="small" :value="1">天</el-radio>
+              <el-radio size="small" :value="2">周</el-radio>
+              <el-radio size="small" :value="3">月</el-radio>
+              <el-radio size="small" :value="4">年</el-radio>
+            </el-radio-group>
+          </div>
+        </div>
+        <div class="header">
+          <div class="text">选择统计车间:</div>
+          <el-tree
+            ref="treeRef1"
+            :data="statProductionLineData"
+            show-checkbox
+            default-expand-all
+            :default-checked-keys="['line']"
+            node-key="key"
+          />
+        </div>
+        <div class="header" style="border-bottom: 0px">
+          <div class="text">选择统计产品:</div>
+          <el-input size="small" placeholder="请输入产品名称" />
+          <!-- <el-tree
+            ref="treeRef2"
+            :data="data1"
+            show-checkbox
+            default-expand-all
+            :default-checked-keys="['合格率']"
+            node-key="key"
+            highlight-current
+          /> -->
+          <!-- <el-tree
+            v-if="prodt.prodtName"
+            ref="treeRef2"
+            :data="statProductTypeData"
+            show-checkbox
+            default-expand-all
+            :default-checked-keys="['productType1']"
+            node-key="key"
+            style="margin-top: 20px"
+          /> -->
+        </div>
+      </el-scrollbar>
+    </div>
+    <div class="databox">
+      <div class="box">
+        <div class="boxheader">
+          <div>
+            <el-button type="primary" class="btn" @click="getTableData"
+              >统计查询</el-button
+            >
+            <el-button class="btn" @click="reset">重置</el-button>
+          </div>
+          <el-button class="btn" @click="exportFnc">导出</el-button>
+        </div>
+        <div class="info">
+          <el-table
+            :data="tableData"
+            border
+            :style="{ height: maxHeight + 'px' }"
+            style="width: calc(100% - 50)"
+          >
+            <!-- <el-table-column
+              v-if="queryIndexs.includes('productLine')"
+              prop="productLineName"
+              label="产线名称"
+            />
+            <el-table-column
+              v-if="queryIndexs.includes('prodict')"
+              prop="materialName"
+              label="产品名称"
+            />
+            <el-table-column
+              v-if="queryIndexs.includes('operation')"
+              prop="operationName"
+              label="工序名称"
+            /> -->
+            <el-table-column prop="productLineName" label="车间名称" />
+            <el-table-column prop="productName" label="产品名称" />
+            <el-table-column prop="productType" label="批次号" />
+            <el-table-column prop="goodRate" label="良率" />
+            <el-table-column prop="badRate" label="不良率" />
+            <el-table-column prop="timeStr" label="日期" />
+          </el-table>
+        </div>
+        <div class="footer">
+          <Pagination
+            :total="currentOption.total"
+            :page="currentOption.page"
+            :limit="currentOption.limit"
+            :pageSizes="currentOption.pageSizes"
+            v-model:page="currentOption.page"
+            v-model:limit="currentOption.limit"
+            @pagination="getTableData"
+          />
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { getData, getStatLevel, getExport } from "@/api/statistic";
+import { getMockData } from "@/api/statistic/firstPassYieldMockData";
+import Pagination from "@/components/Pagination/index.vue";
+import { downFile } from "@/utils/common";
+
+defineOptions({
+  name: "Dashboard",
+  inheritAttrs: false,
+});
+const exportFnc = async () => {
+  await getExport({
+    endTime: value1.value ? value1.value[1] : "",
+    startTime: value1.value ? value1.value[0] : "",
+    queryTypes: getValue(treeRef1.value.getCheckedNodes()),
+    queryIndex: getValue(treeRef2.value.getCheckedNodes()),
+    timeType: radio.value,
+  }).then((res) => downFile(res));
+};
+const treeRef1 = ref(null);
+const treeRef2 = ref(null);
+const currentOption = ref({
+  total: 0,
+  page: 1,
+  limit: 10,
+  pageSizes: [10, 20, 30, 40, 50, 100],
+});
+
+const maxHeight = ref(null);
+const maxWidth = ref(null);
+
+const value1 = ref(null);
+const radio = ref(1);
+const tableData = ref([]);
+
+const setHeight = () => {
+  maxHeight.value = document.querySelector(".info").clientHeight - 30;
+  maxWidth.value = document.querySelector(".info").clientWidth - 120;
+};
+const getCurrentMonthStartAndEndDates = () => {
+  // 获取当前日期
+  let now = new Date();
+
+  // 获取当前月份的第一天4r
+  let startDate = new Date(now.getFullYear(), now.getMonth(), 1);
+
+  // 获取当前月份的最后一天
+  let endDate = new Date(now.getFullYear(), now.getMonth() + 1, 0);
+
+  // 格式化日期为'YYYY-MM-DD'格式
+  function formatDate(date) {
+    let year = date.getFullYear();
+    let month = String(date.getMonth() + 1).padStart(2, "0");
+    let day = String(date.getDate()).padStart(2, "0");
+    return `${year}-${month}-${day}`;
+  }
+
+  // 返回包含开始和结束日期的数组
+  return [formatDate(startDate), formatDate(endDate)];
+};
+const getValue = (array) => {
+  let resarray = [];
+  for (let i = 0; i < array.length; i++) {
+    resarray.push(array[i].value);
+  }
+  return resarray;
+};
+const queryIndexs = ref([]);
+// const getTableData = async () => {
+//   queryIndexs.value = getValue(treeRef1.value.getCheckedNodes());
+//   const { data } = await getData({
+//     endTime: value1.value ? value1.value[1] : "",
+//     startTime: value1.value ? value1.value[0] : "",
+//     pageNo: currentOption.value.page,
+//     pageSize: currentOption.value.limit,
+//     queryTypes: getValue(treeRef1.value.getCheckedNodes()),
+//     queryIndex: getValue(treeRef2.value.getCheckedNodes()),
+//     timeType: radio.value,
+//   });
+//   tableData.value = data.records;
+//   currentOption.value.total = data.totalCount;
+// };
+
+// mock数据
+const getTableData = async () => {
+  queryIndexs.value = getValue(treeRef1.value.getCheckedNodes());
+  const { data } = await getMockData(); // 使用假数据函数
+  tableData.value = data.records;
+  currentOption.value.total = data.totalCount;
+};
+// -------
+
+const reset = () => {
+  value1.value = getCurrentMonthStartAndEndDates();
+  treeRef1.value.setCheckedKeys([statProductionLineData[0].key], true, true);
+  treeRef2.value.setCheckedKeys([statProductTypeData[0].key], true, true);
+  radio.value = 1;
+  currentOption.value.page = 1;
+  getTableData();
+};
+
+// mock数据
+const statProductionLineData = ref([
+  {
+    key: "line",
+    label: "微电子车间",
+    children: [],
+  },
+]);
+
+// const statProductTypeData = ref([
+//   {
+//     key: "productType",
+//     label: "产品类型",
+//     children: [
+//       {
+//         key: "productType1",
+//         label: "类型1",
+//       },
+//       {
+//         key: "productType2",
+//         label: "类型2",
+//       },
+//     ],
+//   },
+// ]);
+
+//-------------------
+
+const checkedKeys = computed(() => {
+  let array = [];
+  for (let i = 0; i < statProductionLineData.value.length; i++) {
+    array.push(statProductionLineData.value[i].key);
+  }
+  return array;
+});
+
+onMounted(async () => {
+  window.addEventListener("resize", setHeight);
+  value1.value = getCurrentMonthStartAndEndDates();
+  setHeight();
+  // await getStatLevelData();
+  getTableData();
+});
+</script>
+
+<style lang="scss" scoped>
+.btn {
+  margin-left: 10px;
+  height: 25px;
+}
+.container1 {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  background-color: white;
+  .infobox {
+    width: 260px;
+    .header {
+      border-bottom: 2px solid #00000010;
+      padding: 20px;
+    }
+    .body {
+      padding: 20px;
+    }
+  }
+  .databox {
+    width: calc(100% - 260px);
+    border-left: 2px solid #00000010;
+    .box {
+      height: 100%;
+      padding: 5px 20px;
+      display: flex;
+      flex-direction: column;
+      .boxheader {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        margin: 10px 0px 10px -10px;
+      }
+      .info {
+        flex: 1;
+      }
+    }
+  }
+}
+.el-radio {
+  margin-right: 8px;
+}
+</style>