// 标准成本导入
|
<template>
|
<div class="standard-cost-ledger-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="选择月份"
|
@change="handleQuery"
|
/>
|
</el-form-item>
|
<el-form-item label="批次号">
|
<el-select
|
v-model="queryForm.batchNo"
|
clearable
|
filterable
|
placeholder="全部批次"
|
style="width: 220px"
|
@change="handleQuery"
|
>
|
<el-option
|
v-for="item in batchOptions"
|
:key="item.value"
|
:label="item.label"
|
:value="item.value"
|
/>
|
</el-select>
|
</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>
|
</el-card>
|
|
<el-card shadow="never" class="ledger-card">
|
<template #header>
|
<div class="card-header">
|
<span>标准成本导入台账</span>
|
<span class="meta">共 {{ filteredLedgerRows.length }} 条导入记录</span>
|
</div>
|
</template>
|
<el-table
|
:data="filteredLedgerRows"
|
border
|
highlight-current-row
|
@current-change="handleLedgerRowChange"
|
>
|
<el-table-column prop="month" label="月份" width="120" />
|
<el-table-column prop="batchNo" label="批次号" width="180" />
|
<el-table-column prop="importTime" label="导入时间" min-width="180" />
|
<el-table-column prop="importUser" label="导入人" width="120" />
|
<el-table-column prop="remark" label="备注" min-width="220" show-overflow-tooltip />
|
</el-table>
|
</el-card>
|
|
<el-card shadow="never" class="matrix-card">
|
<template #header>
|
<div class="card-header">
|
<span>标准成本明细({{ activeLedgerRow?.month || "-" }})</span>
|
<span class="meta">批次:{{ activeLedgerRow?.batchNo || "-" }}</span>
|
</div>
|
</template>
|
<el-table :data="matrixRows" border class="matrix-table" :row-class-name="getRowClassName">
|
<el-table-column prop="itemName" label="项目名称" min-width="180" />
|
<el-table-column
|
v-for="column in productColumns"
|
:key="column.key"
|
:prop="column.key"
|
:label="column.label"
|
min-width="130"
|
align="right"
|
>
|
<template #default="{ row }">
|
{{ formatNumber(row[column.key]) }}
|
</template>
|
</el-table-column>
|
</el-table>
|
</el-card>
|
</div>
|
</template>
|
|
<script setup>
|
import { computed, ref } from "vue";
|
|
const getCurrentMonth = () => {
|
const now = new Date();
|
const year = now.getFullYear();
|
const month = String(now.getMonth() + 1).padStart(2, "0");
|
return `${year}-${month}`;
|
};
|
|
const queryForm = ref({
|
month: getCurrentMonth(),
|
batchNo: "",
|
});
|
|
const ledgerRows = ref([
|
{
|
id: 1,
|
month: "2026-01",
|
batchNo: "SC-202601-001",
|
importTime: "2026-01-05 09:18:22",
|
importUser: "王会计",
|
remark: "月初标准成本导入",
|
matrix: buildMatrixData(),
|
},
|
{
|
id: 2,
|
month: "2026-02",
|
batchNo: "SC-202602-001",
|
importTime: "2026-02-03 10:08:16",
|
importUser: "李会计",
|
remark: "按产品更新人工与费用口径",
|
matrix: buildMatrixData({
|
yieldA35: 1050,
|
yieldA50: 920,
|
yieldBoard: 840,
|
directMaterialA35: 12.4,
|
directMaterialA50: 11.9,
|
directMaterialBoard: 9.2,
|
}),
|
},
|
{
|
id: 3,
|
month: "2026-03",
|
batchNo: "SC-202603-001",
|
importTime: "2026-03-04 14:32:09",
|
importUser: "王会计",
|
remark: "按月导入标准成本",
|
matrix: buildMatrixData({
|
yieldA35: 1100,
|
yieldA50: 960,
|
yieldBoard: 900,
|
directMaterialA35: 12.9,
|
directMaterialA50: 12.1,
|
directMaterialBoard: 9.6,
|
}),
|
},
|
]);
|
|
const activeLedgerId = ref(ledgerRows.value[0]?.id || null);
|
|
const batchOptions = computed(() => {
|
return ledgerRows.value.map((row) => ({
|
label: `${row.batchNo}(${row.month})`,
|
value: row.batchNo,
|
}));
|
});
|
|
const filteredLedgerRows = computed(() => {
|
return ledgerRows.value.filter((row) => {
|
const byMonth = !queryForm.value.month || row.month === queryForm.value.month;
|
const byBatch = !queryForm.value.batchNo || row.batchNo === queryForm.value.batchNo;
|
return byMonth && byBatch;
|
});
|
});
|
|
const activeLedgerRow = computed(() => {
|
const list = filteredLedgerRows.value;
|
const target = list.find((row) => row.id === activeLedgerId.value);
|
return target || list[0] || null;
|
});
|
|
const matrixRows = computed(() => activeLedgerRow.value?.matrix || []);
|
|
const productColumns = [
|
{ key: "a35", label: "加气块-A3.5" },
|
{ key: "a50", label: "加气块-A5.0" },
|
{ key: "board", label: "板材" },
|
{ key: "total", label: "综合" },
|
];
|
|
function buildMatrixData(override = {}) {
|
const yieldA35 = override.yieldA35 ?? 980;
|
const yieldA50 = override.yieldA50 ?? 860;
|
const yieldBoard = override.yieldBoard ?? 800;
|
const directMaterialA35 = override.directMaterialA35 ?? 12.6;
|
const directMaterialA50 = override.directMaterialA50 ?? 11.7;
|
const directMaterialBoard = override.directMaterialBoard ?? 9.1;
|
const manufacturingA35 = 3.2;
|
const manufacturingA50 = 3.5;
|
const manufacturingBoard = 2.8;
|
const mgmtA35 = 1.4;
|
const mgmtA50 = 1.2;
|
const mgmtBoard = 1.0;
|
const salesA35 = 0.9;
|
const salesA50 = 0.8;
|
const salesBoard = 0.7;
|
const financeA35 = 0.4;
|
const financeA50 = 0.3;
|
const financeBoard = 0.2;
|
const offSeasonA35 = 1.1;
|
const offSeasonA50 = 1.0;
|
const offSeasonBoard = 0.8;
|
|
const subtotalA35 = directMaterialA35 + manufacturingA35;
|
const subtotalA50 = directMaterialA50 + manufacturingA50;
|
const subtotalBoard = directMaterialBoard + manufacturingBoard;
|
|
const totalA35 = subtotalA35 + mgmtA35 + salesA35 + financeA35 + offSeasonA35;
|
const totalA50 = subtotalA50 + mgmtA50 + salesA50 + financeA50 + offSeasonA50;
|
const totalBoard = subtotalBoard + mgmtBoard + salesBoard + financeBoard + offSeasonBoard;
|
|
return [
|
{
|
itemName: "产量",
|
a35: yieldA35,
|
a50: yieldA50,
|
board: yieldBoard,
|
total: yieldA35 + yieldA50 + yieldBoard,
|
},
|
{
|
itemName: "直接材料单方成本",
|
a35: directMaterialA35,
|
a50: directMaterialA50,
|
board: directMaterialBoard,
|
total: (directMaterialA35 + directMaterialA50 + directMaterialBoard) / 3,
|
},
|
{
|
itemName: "制造费用",
|
a35: manufacturingA35,
|
a50: manufacturingA50,
|
board: manufacturingBoard,
|
total: (manufacturingA35 + manufacturingA50 + manufacturingBoard) / 3,
|
},
|
{
|
itemName: "生产成本小计",
|
a35: subtotalA35,
|
a50: subtotalA50,
|
board: subtotalBoard,
|
total: (subtotalA35 + subtotalA50 + subtotalBoard) / 3,
|
isSubtotal: true,
|
},
|
{
|
itemName: "管理费用",
|
a35: mgmtA35,
|
a50: mgmtA50,
|
board: mgmtBoard,
|
total: (mgmtA35 + mgmtA50 + mgmtBoard) / 3,
|
},
|
{
|
itemName: "销售费用",
|
a35: salesA35,
|
a50: salesA50,
|
board: salesBoard,
|
total: (salesA35 + salesA50 + salesBoard) / 3,
|
},
|
{
|
itemName: "财务费用",
|
a35: financeA35,
|
a50: financeA50,
|
board: financeBoard,
|
total: (financeA35 + financeA50 + financeBoard) / 3,
|
},
|
{
|
itemName: "淡季费用-生产成本",
|
a35: offSeasonA35,
|
a50: offSeasonA50,
|
board: offSeasonBoard,
|
total: (offSeasonA35 + offSeasonA50 + offSeasonBoard) / 3,
|
},
|
{
|
itemName: "合计",
|
a35: totalA35,
|
a50: totalA50,
|
board: totalBoard,
|
total: (totalA35 + totalA50 + totalBoard) / 3,
|
},
|
];
|
}
|
|
function handleQuery() {
|
if (filteredLedgerRows.value.length > 0) {
|
activeLedgerId.value = filteredLedgerRows.value[0].id;
|
return;
|
}
|
activeLedgerId.value = null;
|
}
|
|
function handleReset() {
|
queryForm.value.month = getCurrentMonth();
|
queryForm.value.batchNo = "";
|
handleQuery();
|
}
|
|
function handleLedgerRowChange(row) {
|
if (!row) return;
|
activeLedgerId.value = row.id;
|
}
|
|
function getRowClassName({ row }) {
|
return row.isSubtotal ? "is-subtotal-row" : "";
|
}
|
|
function formatNumber(value) {
|
if (typeof value !== "number") return "-";
|
if (Number.isInteger(value)) return value.toLocaleString("zh-CN");
|
return value.toLocaleString("zh-CN", { minimumFractionDigits: 2, maximumFractionDigits: 2 });
|
}
|
</script>
|
|
<style scoped>
|
.standard-cost-ledger-page {
|
padding: 16px;
|
background: #f6f8fa;
|
min-height: calc(100vh - 100px);
|
}
|
|
.query-card,
|
.ledger-card,
|
.matrix-card {
|
margin-bottom: 16px;
|
}
|
|
.card-header {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
font-size: 16px;
|
font-weight: 600;
|
}
|
|
.meta {
|
font-size: 13px;
|
color: #909399;
|
font-weight: 400;
|
}
|
|
.matrix-table :deep(.is-subtotal-row td) {
|
background: #fff200 !important;
|
}
|
</style>
|