yyb
12 小时以前 34181c0a1eb1aaf37d8942e36d11ab539d9f306c
原料生产统计单耗表
已添加1个文件
283 ■■■■■ 文件已修改
src/views/costAccounting/monthlySUCRawMaterial/index.vue 283 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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("请接入导入接口或上传组件");
}
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>