| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // åæç产ç»è®¡åè |
| | | <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> |