From 34181c0a1eb1aaf37d8942e36d11ab539d9f306c Mon Sep 17 00:00:00 2001
From: yyb <995253665@qq.com>
Date: 星期三, 25 三月 2026 14:30:22 +0800
Subject: [PATCH] 原料生产统计单耗表

---
 src/views/costAccounting/monthlySUCRawMaterial/index.vue |  283 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 283 insertions(+), 0 deletions(-)

diff --git a/src/views/costAccounting/monthlySUCRawMaterial/index.vue b/src/views/costAccounting/monthlySUCRawMaterial/index.vue
new file mode 100644
index 0000000..bfbcd88
--- /dev/null
+++ b/src/views/costAccounting/monthlySUCRawMaterial/index.vue
@@ -0,0 +1,283 @@
+// 鍘熸枡鐢熶骇缁熻鍗曡��
+<template>
+  <div class="monthly-suc-page">
+    <el-card shadow="never" class="query-card">
+      <el-form :inline="true" :model="queryForm">
+        <el-form-item label="鏌ヨ鏈堜唤">
+          <el-date-picker
+            v-model="queryForm.month"
+            type="month"
+            value-format="YYYY-MM"
+            placeholder="閫夋嫨鏈堜唤"
+          />
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" @click="handleQuery">鏌ヨ</el-button>
+          <el-button @click="handleReset">閲嶇疆</el-button>
+        </el-form-item>
+        <el-form-item class="toolbar-right">
+          <el-button type="success" @click="handleImport">瀵煎叆</el-button>
+          <el-button type="warning" @click="handleExport">瀵煎嚭</el-button>
+        </el-form-item>
+      </el-form>
+    </el-card>
+
+    <el-card shadow="never" class="table-card">
+      <el-table
+        :data="tableRows"
+        border
+        class="suc-table single-table"
+        row-key="itemName"
+        :row-class-name="getRowClassName"
+        max-height="520"
+      >
+        <el-table-column prop="itemName" label="椤圭洰" min-width="120" align="center" fixed="left" />
+
+        <el-table-column prop="a35" label="3.5" min-width="110" align="center">
+          <template #default="{ row }">
+            <el-input-number
+              v-if="!row.isYield"
+              v-model="row.a35"
+              :controls="false"
+              :precision="2"
+              :min="0"
+              size="small"
+              class="yellow-input"
+              @change="recalculateRow(row)"
+            />
+            <span v-else class="yield-cell">{{ formatNumber(row.a35, 0) }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="unitA35" label="鍗曡��" min-width="110" align="center">
+          <template #default="{ row }">
+            <span v-if="row.isYield">-</span>
+            <span v-else>{{ formatNumber(row.unitA35, 4) }}</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column prop="a50" label="5.0" min-width="110" align="center">
+          <template #default="{ row }">
+            <el-input-number
+              v-if="!row.isYield"
+              v-model="row.a50"
+              :controls="false"
+              :precision="2"
+              :min="0"
+              size="small"
+              class="yellow-input"
+              @change="recalculateRow(row)"
+            />
+            <span v-else class="yield-cell">{{ formatNumber(row.a50, 0) }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="unitA50" label="鍗曡��" min-width="110" align="center">
+          <template #default="{ row }">
+            <span v-if="row.isYield">-</span>
+            <span v-else>{{ formatNumber(row.unitA50, 4) }}</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column prop="board" label="鏉挎潗" min-width="110" align="center">
+          <template #default="{ row }">
+            <el-input-number
+              v-if="!row.isYield"
+              v-model="row.board"
+              :controls="false"
+              :precision="2"
+              :min="0"
+              size="small"
+              class="yellow-input"
+              @change="recalculateRow(row)"
+            />
+            <span v-else class="yield-cell">{{ formatNumber(row.board, 0) }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="unitBoard" label="鍗曡��" min-width="110" align="center">
+          <template #default="{ row }">
+            <span v-if="row.isYield">-</span>
+            <span v-else>{{ formatNumber(row.unitBoard, 4) }}</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column prop="actualUsage" :label="actualUsageLabel" min-width="140" align="center">
+          <template #default="{ row }">
+            <span class="yield-cell" v-if="row.isYield">{{ formatNumber(row.actualUsage) }}</span>
+            <span v-else>{{ formatNumber(row.actualUsage) }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="blockSubtotal" label="鐮屽潡鍚堣" min-width="120" align="center">
+          <template #default="{ row }">
+            <span class="yield-cell" v-if="row.isYield">{{ formatNumber(row.blockSubtotal) }}</span>
+            <span v-else>{{ formatNumber(row.blockSubtotal) }}</span>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-card>
+  </div>
+</template>
+
+<script setup>
+import { computed, reactive, ref } from "vue";
+import { ElMessage } from "element-plus";
+
+const getCurrentMonth = () => {
+  const now = new Date();
+  const year = now.getFullYear();
+  const month = String(now.getMonth() + 1).padStart(2, "0");
+  return `${year}-${month}`;
+};
+
+const queryForm = reactive({
+  month: getCurrentMonth(),
+});
+
+const yieldRow = reactive({
+  itemName: "浜ч噺",
+  isYield: true,
+  a35: 1000,
+  a50: 900,
+  board: 780,
+  actualUsage: 0,
+  blockSubtotal: 0,
+});
+
+const materialRows = ref(
+  [
+    "绮夌叅鐏�",
+    "姘存偿",
+    "鐭崇伆",
+    "閾濈矇",
+    "鐭宠啅",
+    "鑴辨ā鍓�",
+    "鎵撳寘甯�",
+    "鍐锋尋涓�",
+    "姘у寲闀�",
+    "鍗℃墸",
+    "闃茶厫鍓�",
+  ].map((name, idx) => ({
+    itemName: name,
+    isYield: false,
+    a35: Number((15 + idx * 0.5).toFixed(2)),
+    a50: Number((13 + idx * 0.45).toFixed(2)),
+    board: Number((10 + idx * 0.4).toFixed(2)),
+    unitA35: 0,
+    unitA50: 0,
+    unitBoard: 0,
+    actualUsage: 0,
+    blockSubtotal: 0,
+  }))
+);
+
+const monthTitle = computed(() => {
+  const monthText = String(queryForm.month || "");
+  if (!monthText.includes("-")) return "";
+  return `${Number(monthText.split("-")[1])}鏈坄;
+});
+
+const actualUsageLabel = computed(() => `${monthTitle.value}瀹為檯鐢ㄩ噺`);
+
+const tableRows = computed(() => [yieldRow, ...materialRows.value]);
+
+function getRowClassName({ row }) {
+  if (row?.isYield) return "is-fixed-yield-row";
+  return "";
+}
+
+function updateYieldTotals() {
+  yieldRow.actualUsage = Number(
+    materialRows.value.reduce((sum, row) => sum + Number(row.actualUsage || 0), 0).toFixed(2)
+  );
+  yieldRow.blockSubtotal = Number(
+    materialRows.value.reduce((sum, row) => sum + Number(row.blockSubtotal || 0), 0).toFixed(2)
+  );
+}
+
+function recalculateRow(row) {
+  if (row?.isYield) return;
+
+  const a35Yield = Number(yieldRow.a35 || 0);
+  const a50Yield = Number(yieldRow.a50 || 0);
+  const boardYield = Number(yieldRow.board || 0);
+
+  row.unitA35 = a35Yield > 0 ? row.a35 / a35Yield : 0;
+  row.unitA50 = a50Yield > 0 ? row.a50 / a50Yield : 0;
+  row.unitBoard = boardYield > 0 ? row.board / boardYield : 0;
+
+  row.actualUsage = Number(row.a35 || 0) + Number(row.a50 || 0) + Number(row.board || 0);
+  row.blockSubtotal = Number(row.a35 || 0) + Number(row.a50 || 0);
+
+  updateYieldTotals();
+}
+
+function initializeRows() {
+  materialRows.value.forEach((row) => recalculateRow(row));
+  updateYieldTotals();
+}
+
+function handleQuery() {
+  initializeRows();
+  ElMessage.success(`宸插姞杞� ${queryForm.month} 鏁版嵁`);
+}
+
+function handleReset() {
+  queryForm.month = getCurrentMonth();
+  handleQuery();
+}
+
+function handleImport() {
+  ElMessage.info("璇锋帴鍏ュ鍏ユ帴鍙f垨涓婁紶缁勪欢");
+}
+
+function handleExport() {
+  ElMessage.success(`宸茶Е鍙� ${queryForm.month} 瀵煎嚭`);
+}
+
+function formatNumber(value, fraction = 2) {
+  const n = Number(value);
+  if (!Number.isFinite(n)) return "-";
+  return n.toLocaleString("zh-CN", {
+    minimumFractionDigits: fraction,
+    maximumFractionDigits: fraction,
+  });
+}
+
+initializeRows();
+</script>
+
+<style scoped>
+.monthly-suc-page {
+  padding: 16px;
+  background: #f6f8fa;
+  min-height: calc(100vh - 100px);
+}
+
+.query-card,
+.table-card {
+  margin-bottom: 16px;
+}
+
+.toolbar-right {
+  margin-left: auto !important;
+}
+
+.suc-table :deep(.cell) {
+  font-size: 16px;
+}
+
+.yield-cell {
+  font-weight: 800;
+}
+
+.single-table :deep(.el-table__body tr.is-fixed-yield-row td) {
+  position: sticky;
+  top: 0;
+  z-index: 6;
+  background: #f3f6fb !important;
+  font-weight: 800;
+}
+
+.yellow-input :deep(.el-input__wrapper) {
+  background: #fff200;
+  box-shadow: inset 0 0 0 1px #ddd;
+}
+</style>
\ No newline at end of file

--
Gitblit v1.9.3