From 7179a06d3a8c824ee711a701e99114205fce9bcb Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期三, 06 五月 2026 13:31:24 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev_NEW_pro' into dev_NEW_pro

---
 src/views/productionManagement/processStatistics/index.vue |  268 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 268 insertions(+), 0 deletions(-)

diff --git a/src/views/productionManagement/processStatistics/index.vue b/src/views/productionManagement/processStatistics/index.vue
new file mode 100644
index 0000000..25fa531
--- /dev/null
+++ b/src/views/productionManagement/processStatistics/index.vue
@@ -0,0 +1,268 @@
+<template>
+  <div class="app-container">
+    <div class="search-bar">
+      <el-form :model="searchForm"
+               inline>
+        <el-form-item label="鏃ユ湡鍖洪棿:">
+          <el-date-picker v-model="searchForm.dateRange"
+                          type="daterange"
+                          range-separator="鑷�"
+                          start-placeholder="寮�濮嬫棩鏈�"
+                          end-placeholder="缁撴潫鏃ユ湡"
+                          value-format="YYYY-MM-DD"
+                          style="width: 240px" />
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary"
+                     icon="Search"
+                     @click="handleQuery">鎼滅储</el-button>
+        </el-form-item>
+      </el-form>
+    </div>
+    <div class="stats-grid"
+         v-loading="loading">
+      <el-row :gutter="16"
+              v-if="statsData.length > 0">
+        <el-col v-for="(item, index) in statsData"
+                :key="index"
+                :xs="24"
+                :sm="12"
+                :md="8"
+                :lg="4.8"
+                :xl="4.8"
+                class="mb-16">
+          <div class="stats-card">
+            <div class="card-header">
+              <span class="process-name">{{ item.name }}</span>
+              <div class="header-stats">
+                <div class="stat-row">
+                  <span class="label">璁″垝鏁�</span>
+                  <span class="value">{{ item.planned }}</span>
+                </div>
+                <div class="stat-row">
+                  <span class="label">鑹搧鏁�</span>
+                  <span class="value">{{ item.good }}</span>
+                </div>
+                <div class="stat-row">
+                  <span class="label">涓嶈壇鍝佹暟</span>
+                  <span class="value">{{ item.bad }}</span>
+                </div>
+              </div>
+            </div>
+            <div class="card-body">
+              <div class="main-stat">
+                <div class="big-number">{{ item.total }}</div>
+                <div class="sub-label">鐢熶骇浠诲姟鏁�</div>
+              </div>
+            </div>
+            <div class="card-footer">
+              <div class="progress-info">
+                <span class="progress-label">杩涘害:</span>
+                <el-progress :percentage="Math.min(item.percentage, 100)"
+                             :color="getProgressColor(item.percentage)"
+                             :stroke-width="10"
+                             :show-text="false"
+                             class="flex-1" />
+                <span class="percentage-text">{{ item.percentage }}%</span>
+              </div>
+            </div>
+          </div>
+        </el-col>
+      </el-row>
+      <el-empty v-else
+                description="鏆傛棤鏁版嵁" />
+    </div>
+  </div>
+</template>
+
+<script setup>
+  import { reactive, ref, onMounted } from "vue";
+  import dayjs from "dayjs";
+  import { getOperationStatistics } from "@/api/productionManagement/workOrder.js";
+
+  const loading = ref(false);
+  const searchForm = reactive({
+    dateRange: [],
+  });
+
+  const statsData = ref([]);
+
+  const getProgressColor = percentage => {
+    if (percentage >= 100) return "#67c23a";
+    if (percentage >= 50) return "#409eff";
+    if (percentage >= 25) return "#e6a23c";
+    return "red";
+  };
+
+  const getList = () => {
+    loading.value = true;
+    const params = {
+      startDate: searchForm.dateRange?.[0] || "",
+      endDate: searchForm.dateRange?.[1] || "",
+    };
+    getOperationStatistics(params)
+      .then(res => {
+        // 鏍规嵁瀹為檯鎺ュ彛杩斿洖鐨勫瓧娈佃繘琛屾槧灏�
+        statsData.value = (res.data || []).map(item => ({
+          name: item.operationName || "-",
+          total: item.productionTaskCount || 0,
+          planned: item.planQuantity || 0,
+          good: item.goodQuantity || 0,
+          bad: item.scrapQty || 0,
+          percentage: Number(item.completionStatus || 0),
+        }));
+      })
+      .finally(() => {
+        loading.value = false;
+      });
+  };
+
+  const handleQuery = () => {
+    getList();
+  };
+
+  onMounted(() => {
+    getList();
+  });
+</script>
+
+<style scoped lang="scss">
+  .app-container {
+    padding: 20px;
+    background-color: #f0f2f5;
+    min-height: calc(100vh - 84px);
+  }
+
+  .search-bar {
+    background: #fff;
+    padding: 15px 20px 0;
+    border-radius: 4px;
+    margin-bottom: 20px;
+    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
+  }
+
+  .mb-16 {
+    margin-bottom: 16px;
+  }
+
+  // 妯℃嫙 lg="4.8" 鍥犱负 element 涓嶆敮鎸� 24/5
+  @media only screen and (min-width: 1200px) {
+    .el-col-lg-4-8 {
+      width: 20%;
+      max-width: 20%;
+      flex: 0 0 20%;
+    }
+  }
+
+  .stats-card {
+    background: #fff;
+    border-radius: 8px;
+    padding: 16px;
+    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
+    transition: transform 0.3s;
+
+    &:hover {
+      transform: translateY(-2px);
+    }
+
+    .card-header {
+      display: flex;
+      justify-content: space-between;
+      align-items: flex-start;
+      margin-bottom: 12px;
+
+      .process-name {
+        background-color: #e6f7ff;
+        color: #1890ff;
+        padding: 2px 8px;
+        border-radius: 4px;
+        font-size: 14px;
+        font-weight: 500;
+      }
+
+      .header-stats {
+        text-align: right;
+
+        .stat-row {
+          display: flex;
+          justify-content: flex-end;
+          align-items: center;
+          gap: 8px;
+          margin-bottom: 2px;
+
+          .label {
+            font-size: 12px;
+            color: #909399;
+          }
+
+          .value {
+            font-size: 13px;
+            color: #303133;
+            font-weight: bold;
+            min-width: 24px;
+          }
+        }
+      }
+    }
+
+    .card-body {
+      padding: 10px 0;
+
+      .main-stat {
+        .big-number {
+          font-size: 28px;
+          font-weight: bold;
+          color: #303133;
+          line-height: 1;
+        }
+
+        .sub-label {
+          font-size: 14px;
+          color: #606266;
+          margin-top: 8px;
+          font-weight: 500;
+        }
+      }
+    }
+
+    .card-footer {
+      margin-top: 16px;
+
+      .progress-info {
+        display: flex;
+        align-items: center;
+        gap: 8px;
+
+        .progress-label {
+          font-size: 12px;
+          color: #909399;
+          white-space: nowrap;
+        }
+
+        .flex-1 {
+          flex: 1;
+        }
+
+        .percentage-text {
+          font-size: 12px;
+          color: #606266;
+          min-width: 45px;
+          text-align: right;
+        }
+      }
+    }
+  }
+
+  // 淇 el-col 甯冨眬閫傞厤 5 鍒�
+  :deep(.el-row) {
+    display: flex;
+    flex-wrap: wrap;
+  }
+
+  @media only screen and (min-width: 1200px) {
+    .el-col-lg-4\.8 {
+      flex: 0 0 20%;
+      max-width: 20%;
+    }
+  }
+</style>

--
Gitblit v1.9.3