// 原料生产统计单耗
|
<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("请接入导入接口或上传组件");
|
}
|
|
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>
|