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