From 7ffee77a904f9d314d917db6c0a9424c6305dcdd Mon Sep 17 00:00:00 2001
From: yyb <995253665@qq.com>
Date: 星期二, 24 三月 2026 09:56:03 +0800
Subject: [PATCH] 生产成本核算增加用量字段

---
 src/views/costAccounting/productionCostAccounting/index.vue |  246 +++++++++++++++++++++++++++++++++++--------------
 1 files changed, 175 insertions(+), 71 deletions(-)

diff --git a/src/views/costAccounting/productionCostAccounting/index.vue b/src/views/costAccounting/productionCostAccounting/index.vue
index 78ca6c5..372a490 100644
--- a/src/views/costAccounting/productionCostAccounting/index.vue
+++ b/src/views/costAccounting/productionCostAccounting/index.vue
@@ -100,13 +100,9 @@
           <div class="kpi-label">鎬荤敓浜ф垚鏈�</div>
           <div class="kpi-value">楼{{ formatMoney(overview.totalCost) }}</div>
         </div>
-        <div class="kpi-item kpi-raw">
-          <div class="kpi-label">鍘熸枡鎴愭湰</div>
-          <div class="kpi-value">楼{{ formatMoney(overview.rawCost) }}</div>
-        </div>
-        <div class="kpi-item kpi-aux">
-          <div class="kpi-label">杈呮枡鎴愭湰</div>
-          <div class="kpi-value">楼{{ formatMoney(overview.auxCost) }}</div>
+        <div class="kpi-item kpi-avg">
+          <div class="kpi-label">姣忚鍗曞钩鍧囨垚鏈�</div>
+          <div class="kpi-value">楼{{ formatMoney(overview.avgCostPerOrder) }}</div>
         </div>
         <div class="kpi-item kpi-order">
           <div class="kpi-label">璁㈠崟鏁伴噺</div>
@@ -125,17 +121,15 @@
           </template>
           <el-table :data="categorySummary" stripe class="lux-table" height="260">
             <el-table-column prop="category" label="浜у搧绫诲埆" min-width="140" />
-            <el-table-column prop="rawCost" label="鍘熸枡鎴愭湰(鍏�)" align="right">
+            <el-table-column prop="totalQuantity" label="鐢ㄩ噺" align="right" min-width="120">
               <template #default="scope">
-                <span class="price-value">{{ formatMoney(scope.row.rawCost) }}</span>
+                <span class="quantity-cell">
+                  <span class="quantity-value">{{ formatNumber(scope.row.totalQuantity, 2) }}</span>
+                  <span class="quantity-unit">{{ scope.row.unit || "-" }}</span>
+                </span>
               </template>
             </el-table-column>
-            <el-table-column prop="auxCost" label="杈呮枡鎴愭湰(鍏�)" align="right">
-              <template #default="scope">
-                <span class="price-value">{{ formatMoney(scope.row.auxCost) }}</span>
-              </template>
-            </el-table-column>
-            <el-table-column prop="totalCost" label="鎬绘垚鏈�(鍏�)" align="right">
+            <el-table-column prop="totalCost" label="鎴愭湰(鍏�)" align="right">
               <template #default="scope">
                 <span class="cost-value">楼{{ formatMoney(scope.row.totalCost) }}</span>
               </template>
@@ -153,6 +147,14 @@
           <el-table :data="orderSummary" stripe class="lux-table" height="260">
             <el-table-column prop="orderNo" label="鐢熶骇璁㈠崟" min-width="150" />
             <el-table-column prop="category" label="浜у搧绫诲埆" min-width="120" />
+            <el-table-column prop="totalQuantity" label="鐢ㄩ噺" align="right" min-width="120">
+              <template #default="scope">
+                <span class="quantity-cell">
+                  <span class="quantity-value">{{ formatNumber(scope.row.totalQuantity, 2) }}</span>
+                  <span class="quantity-unit">{{ scope.row.unit || "-" }}</span>
+                </span>
+              </template>
+            </el-table-column>
             <el-table-column prop="totalCost" label="鎬绘垚鏈�(鍏�)" align="right">
               <template #default="scope">
                 <span class="cost-value">楼{{ formatMoney(scope.row.totalCost) }}</span>
@@ -175,17 +177,15 @@
         <el-table-column prop="timeLabel" :label="timeColumnLabel" min-width="110" />
         <el-table-column prop="category" label="浜у搧绫诲埆" min-width="120" />
         <el-table-column prop="orderNo" label="鐢熶骇璁㈠崟" min-width="150" />
-        <el-table-column prop="rawCost" label="鍘熸枡鎴愭湰(鍏�)" align="right">
+        <el-table-column prop="totalQuantity" label="鐢ㄩ噺" align="right" min-width="130">
           <template #default="scope">
-            <span class="price-value">{{ formatMoney(scope.row.rawCost) }}</span>
+            <span class="quantity-cell">
+              <span class="quantity-value">{{ formatNumber(scope.row.totalQuantity, 2) }}</span>
+              <span class="quantity-unit">{{ scope.row.unit || "-" }}</span>
+            </span>
           </template>
         </el-table-column>
-        <el-table-column prop="auxCost" label="杈呮枡鎴愭湰(鍏�)" align="right">
-          <template #default="scope">
-            <span class="price-value">{{ formatMoney(scope.row.auxCost) }}</span>
-          </template>
-        </el-table-column>
-        <el-table-column prop="totalCost" label="鎬绘垚鏈�(鍏�)" align="right">
+        <el-table-column prop="totalCost" label="鎴愭湰(鍏�)" align="right">
           <template #default="scope">
             <span class="cost-value">楼{{ formatMoney(scope.row.totalCost) }}</span>
           </template>
@@ -211,21 +211,35 @@
 
     <el-drawer
       v-model="detailVisible"
-      title="鐢熶骇鎴愭湰鎷嗗垎鏄庣粏"
-      size="560px"
+      :with-header="false"
+      class="detail-drawer"
+      size="760px"
+      :close-on-click-modal="true"
+      :close-on-press-escape="true"
       destroy-on-close
     >
       <div v-if="detailRow" class="drawer-head">
-        <div><b>{{ timeColumnLabel }}锛�</b>{{ detailRow.timeLabel }}</div>
-        <div><b>浜у搧绫诲埆锛�</b>{{ detailRow.category }}</div>
-        <div><b>鐢熶骇璁㈠崟锛�</b>{{ detailRow.orderNo }}</div>
+        <div class="meta-item">
+          <span class="meta-label">{{ timeColumnLabel }}</span>
+          <span class="meta-value">{{ detailRow.timeLabel }}</span>
+        </div>
+        <div class="meta-item">
+          <span class="meta-label">浜у搧绫诲埆</span>
+          <span class="meta-value">{{ detailRow.category }}</span>
+        </div>
+        <div class="meta-item">
+          <span class="meta-label">鐢熶骇璁㈠崟</span>
+          <span class="meta-value">{{ detailRow.orderNo }}</span>
+        </div>
       </div>
       <el-table :data="detailMaterials" class="lux-table" stripe>
         <el-table-column prop="materialName" label="鐗╂枡鍚嶇О" min-width="120" />
-        <el-table-column prop="materialType" label="绫诲瀷" width="80" />
-        <el-table-column prop="quantity" label="鎶曞叆閲�" align="right">
+        <el-table-column prop="quantity" label="鎶曞叆閲�" align="right" min-width="140">
           <template #default="scope">
-            {{ formatNumber(scope.row.quantity, 2) }} {{ scope.row.unit }}
+            <span class="quantity-cell">
+              <span class="quantity-value">{{ formatNumber(scope.row.quantity, 2) }}</span>
+              <span class="quantity-unit">{{ scope.row.unit }}</span>
+            </span>
           </template>
         </el-table-column>
         <el-table-column prop="unitPrice" label="鍗曚环(鍏�)" align="right">
@@ -233,16 +247,17 @@
             {{ formatNumber(scope.row.unitPrice, 2) }}
           </template>
         </el-table-column>
-        <el-table-column prop="cost" label="鎴愭湰(鍏�)" align="right">
+        <el-table-column prop="cost" label="鎴愭湰(鍏�)" align="right" min-width="132">
           <template #default="scope">
-            <span class="cost-value">楼{{ formatMoney(scope.row.cost) }}</span>
+            <span class="cost-value no-wrap-money">楼{{ formatMoney(scope.row.cost) }}</span>
           </template>
         </el-table-column>
       </el-table>
       <div class="drawer-foot">
-        <span>鍘熸枡锛毬{ formatMoney(detailRawCost) }}</span>
-        <span>杈呮枡锛毬{ formatMoney(detailAuxCost) }}</span>
-        <span class="strong">鍚堣锛毬{ formatMoney(detailTotalCost) }}</span>
+        <div class="foot-item total">
+          <span class="foot-label">鎴愭湰鍚堣</span>
+          <span class="foot-value no-wrap-money">楼{{ formatMoney(detailTotalCost) }}</span>
+        </div>
       </div>
     </el-drawer>
   </div>
@@ -369,16 +384,14 @@
     const key = keyFn(item);
     if (!map.has(key)) {
       map.set(key, {
-        rawCost: 0,
-        auxCost: 0,
         totalCost: 0,
+        totalQuantity: 0,
         materials: [],
       });
     }
     const bucket = map.get(key);
-    if (item.materialType === "鍘熸枡") bucket.rawCost += item.cost;
-    if (item.materialType === "杈呮枡") bucket.auxCost += item.cost;
     bucket.totalCost += item.cost;
+    bucket.totalQuantity += Number(item.quantity) || 0;
     bucket.materials.push(item);
   }
   return map;
@@ -400,8 +413,8 @@
       timeLabel,
       category,
       orderNo,
-      rawCost: val.rawCost,
-      auxCost: val.auxCost,
+      totalQuantity: val.totalQuantity,
+      unit: val.materials[0]?.unit || "",
       totalCost: val.totalCost,
       materials: val.materials,
     });
@@ -425,8 +438,8 @@
   for (const [category, val] of map) {
     rows.push({
       category,
-      rawCost: val.rawCost,
-      auxCost: val.auxCost,
+      totalQuantity: val.totalQuantity,
+      unit: val.materials[0]?.unit || "",
       totalCost: val.totalCost,
     });
   }
@@ -440,6 +453,8 @@
     rows.push({
       orderNo,
       category: val.materials[0]?.category || "-",
+      totalQuantity: val.totalQuantity,
+      unit: val.materials[0]?.unit || "",
       totalCost: val.totalCost,
     });
   }
@@ -447,18 +462,12 @@
 });
 
 const overview = computed(() => {
-  const rawCost = filteredRecords.value
-    .filter((item) => item.materialType === "鍘熸枡")
-    .reduce((sum, item) => sum + item.cost, 0);
-  const auxCost = filteredRecords.value
-    .filter((item) => item.materialType === "杈呮枡")
-    .reduce((sum, item) => sum + item.cost, 0);
   const orderCount = new Set(filteredRecords.value.map((item) => item.orderNo)).size;
+  const totalCost = filteredRecords.value.reduce((sum, item) => sum + item.cost, 0);
   return {
-    rawCost,
-    auxCost,
-    totalCost: rawCost + auxCost,
+    totalCost,
     orderCount,
+    avgCostPerOrder: orderCount === 0 ? 0 : totalCost / orderCount,
   };
 });
 
@@ -467,16 +476,6 @@
 
 const detailMaterials = computed(() => detailRow.value?.materials || []);
 
-const detailRawCost = computed(() =>
-  detailMaterials.value
-    .filter((item) => item.materialType === "鍘熸枡")
-    .reduce((sum, item) => sum + item.cost, 0)
-);
-const detailAuxCost = computed(() =>
-  detailMaterials.value
-    .filter((item) => item.materialType === "杈呮枡")
-    .reduce((sum, item) => sum + item.cost, 0)
-);
 const detailTotalCost = computed(() =>
   detailMaterials.value.reduce((sum, item) => sum + item.cost, 0)
 );
@@ -515,14 +514,14 @@
 };
 
 const handleExport = () => {
-  const headers = [timeColumnLabel.value, "浜у搧绫诲埆", "鐢熶骇璁㈠崟", "鍘熸枡鎴愭湰", "杈呮枡鎴愭湰", "鎬绘垚鏈�"];
+  const headers = [timeColumnLabel.value, "浜у搧绫诲埆", "鐢熶骇璁㈠崟", "鐢ㄩ噺", "鍗曚綅", "鎴愭湰(鍏�)"];
   const lines = tableData.value.map((row) =>
     [
       row.timeLabel,
       row.category,
       row.orderNo,
-      row.rawCost.toFixed(2),
-      row.auxCost.toFixed(2),
+      row.totalQuantity.toFixed(2),
+      row.unit || "",
       row.totalCost.toFixed(2),
     ].join(",")
   );
@@ -661,7 +660,7 @@
 
 .kpi-strip {
   display: grid;
-  grid-template-columns: repeat(4, minmax(0, 1fr));
+  grid-template-columns: repeat(3, minmax(0, 1fr));
   gap: 12px;
 }
 
@@ -679,8 +678,8 @@
   background: linear-gradient(135deg, rgba(22, 163, 74, 0.1), rgba(255, 255, 255, 0.86));
 }
 
-.kpi-aux {
-  background: linear-gradient(135deg, rgba(245, 158, 11, 0.1), rgba(255, 255, 255, 0.86));
+.kpi-avg {
+  background: linear-gradient(135deg, rgba(99, 102, 241, 0.14), rgba(255, 255, 255, 0.86));
 }
 
 .kpi-order {
@@ -709,19 +708,115 @@
   color: var(--lux-danger);
 }
 
+.no-wrap-money {
+  display: inline-block;
+  white-space: nowrap;
+}
+
 .drawer-head {
   display: grid;
-  gap: 8px;
+  grid-template-columns: repeat(3, minmax(0, 1fr));
+  gap: 10px;
   margin-bottom: 12px;
+}
+
+.meta-item {
+  padding: 10px 12px;
+  border-radius: 10px;
+  border: 1px solid var(--lux-border);
+  background: rgba(15, 23, 42, 0.03);
+  display: grid;
+  gap: 4px;
+}
+
+.meta-label {
+  font-size: 12px;
+  color: var(--lux-subtle);
+}
+
+.meta-value {
   color: var(--lux-text);
+  font-size: 16px;
+  font-weight: 700;
+}
+
+.material-type-tag {
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  min-width: 46px;
+  height: 24px;
+  padding: 0 8px;
+  border-radius: 999px;
+  font-size: 12px;
+  font-weight: 700;
+}
+
+.material-type-tag.is-raw {
+  color: #15803d;
+  background: rgba(22, 163, 74, 0.12);
+}
+
+.material-type-tag.is-aux {
+  color: #b45309;
+  background: rgba(245, 158, 11, 0.16);
+}
+
+.quantity-value {
+  font-weight: 700;
+  color: var(--lux-text);
+  margin-right: 6px;
+}
+
+.quantity-cell {
+  display: inline-flex;
+  align-items: baseline;
+  white-space: nowrap;
+}
+
+.quantity-unit {
+  color: var(--lux-subtle);
 }
 
 .drawer-foot {
   display: flex;
   justify-content: flex-end;
-  gap: 18px;
+  gap: 12px;
   margin-top: 12px;
+  padding-top: 12px;
+  border-top: 1px dashed var(--lux-border);
+}
+
+.foot-item {
+  display: inline-flex;
+  align-items: center;
+  gap: 8px;
+  padding: 7px 16px;
+  border-radius: 999px;
+  border: 1px solid var(--lux-border);
+  background: #fff;
+}
+
+.foot-label {
+  color: var(--lux-subtle);
+  font-size: 14px;
+}
+
+.foot-value {
   color: var(--lux-text);
+  font-weight: 700;
+  font-size: 16px;
+}
+
+.foot-item.total {
+  border-color: rgba(47, 111, 237, 0.26);
+  background: rgba(47, 111, 237, 0.08);
+}
+
+.foot-item.total .foot-value {
+  color: #1e3a8a;
+  font-size: 18px;
+  font-weight: 800;
 }
 
 .pagination-container {
@@ -763,5 +858,14 @@
   .filter-layout {
     flex-direction: column;
   }
+
+  .drawer-head {
+    grid-template-columns: 1fr;
+  }
+
+  .drawer-foot {
+    justify-content: flex-start;
+    flex-wrap: wrap;
+  }
 }
 </style>

--
Gitblit v1.9.3