|
|
|
|
@ -11,15 +11,16 @@
|
|
|
|
|
:goals="taskGoals"
|
|
|
|
|
:requirements="taskRequirement"
|
|
|
|
|
:show-material="false"
|
|
|
|
|
:show-toolbar="false"
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
<section class="task-card hardware-workbench">
|
|
|
|
|
<div class="workbench-head hardware-workbench-head">
|
|
|
|
|
<div>
|
|
|
|
|
<p class="section-eyebrow">BOM cost workspace</p>
|
|
|
|
|
<h2>智能硬件成本估算</h2>
|
|
|
|
|
<h2>{{ currentStepTitle }}</h2>
|
|
|
|
|
</div>
|
|
|
|
|
<TrainingMaterialButton :material-name="taskConfig?.materialName" :material-url="taskConfig?.materialUrl" />
|
|
|
|
|
<TrainingTaskToolbar class="hardware-cost-toolbar" :task-key="TASK_KEY" />
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<nav class="step-indicator" aria-label="智能硬件成本估算步骤">
|
|
|
|
|
@ -45,13 +46,6 @@
|
|
|
|
|
</nav>
|
|
|
|
|
|
|
|
|
|
<section v-if="currentStep === 1" class="step-card hardware-step-card">
|
|
|
|
|
<div class="workbench-head">
|
|
|
|
|
<div>
|
|
|
|
|
<p class="section-eyebrow">Step 01 · BOM selection</p>
|
|
|
|
|
<h2>核心元器件选型组合</h2>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<section class="cost-brief">
|
|
|
|
|
<span class="cost-brief__index">01</span>
|
|
|
|
|
<p>在目标成本约束下,权衡性能与成本,为每个元器件选择合适档位。请基于案例资料中的“元器件选型库”,完成核心元器件的选型组合。</p>
|
|
|
|
|
@ -103,11 +97,7 @@
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
<section v-else-if="currentStep === 2" class="step-card hardware-step-card">
|
|
|
|
|
<div class="workbench-head">
|
|
|
|
|
<div>
|
|
|
|
|
<p class="section-eyebrow">Step 02 · Volume costing</p>
|
|
|
|
|
<h2>批量成本核算与约束验证</h2>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="step-utility-actions">
|
|
|
|
|
<button type="button" class="btn-nav" :disabled="exporting || !costRows.length" @click="exportStepTwo">{{ exporting ? "导出中…" : "导出成本核算表" }}</button>
|
|
|
|
|
</div>
|
|
|
|
|
<section class="cost-brief">
|
|
|
|
|
@ -166,11 +156,7 @@
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
<section v-else-if="currentStep === 3" class="step-card hardware-step-card">
|
|
|
|
|
<div class="workbench-head">
|
|
|
|
|
<div>
|
|
|
|
|
<p class="section-eyebrow">Step 03 · Manufacturing costing</p>
|
|
|
|
|
<h2>制造费用与单件总成本核算</h2>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="step-utility-actions">
|
|
|
|
|
<button type="button" class="btn-nav" :disabled="exportingStepThree" @click="exportStepThree">
|
|
|
|
|
{{ exportingStepThree ? "导出中…" : "导出单件总成本表" }}
|
|
|
|
|
</button>
|
|
|
|
|
@ -225,11 +211,7 @@
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
<section v-else class="step-card hardware-step-card">
|
|
|
|
|
<div class="workbench-head">
|
|
|
|
|
<div>
|
|
|
|
|
<p class="section-eyebrow">Step 04 · Cost optimisation</p>
|
|
|
|
|
<h2>成本结构可视化与优化决策</h2>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="step-utility-actions">
|
|
|
|
|
<span class="step-chip">以第 2、3 步核算结果为依据</span>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
@ -311,7 +293,7 @@
|
|
|
|
|
<script setup>
|
|
|
|
|
import { computed, getCurrentInstance, onMounted, reactive, ref } from "vue";
|
|
|
|
|
import TrainingAiSidebar from "@/views/components/TrainingAiSidebar.vue";
|
|
|
|
|
import TrainingMaterialButton from "@/views/components/TrainingMaterialButton.vue";
|
|
|
|
|
import TrainingTaskToolbar from "@/views/components/TrainingTaskToolbar.vue";
|
|
|
|
|
import TrainingTaskBrief from "@/views/components/TrainingTaskBrief.vue";
|
|
|
|
|
import { getTrainingTaskByKey } from "@/api/trainingTask";
|
|
|
|
|
import { parseTrainingArray } from "@/views/training/taskKeyMap";
|
|
|
|
|
@ -326,6 +308,12 @@ const MAX_ROWS = 40;
|
|
|
|
|
const { proxy } = getCurrentInstance();
|
|
|
|
|
const taskConfig = ref({});
|
|
|
|
|
const currentStep = ref(1);
|
|
|
|
|
const currentStepTitle = computed(() => ({
|
|
|
|
|
1: "核心元器件选型组合",
|
|
|
|
|
2: "批量成本核算与约束验证",
|
|
|
|
|
3: "制造费用与单件总成本核算",
|
|
|
|
|
4: "成本结构可视化与优化决策",
|
|
|
|
|
})[currentStep.value] || "智能硬件成本估算");
|
|
|
|
|
let rowSeed = 1;
|
|
|
|
|
const rows = ref([createExampleRow()]);
|
|
|
|
|
const savedStepOneItems = ref([]);
|
|
|
|
|
@ -845,6 +833,18 @@ onMounted(async () => {
|
|
|
|
|
line-height: 1.3;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.hardware-cost-page .hardware-cost-toolbar {
|
|
|
|
|
align-self: center;
|
|
|
|
|
justify-content: flex-end;
|
|
|
|
|
max-width: 100%;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.hardware-cost-page .step-utility-actions {
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: flex-end;
|
|
|
|
|
margin: 0 0 16px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.hardware-cost-page .hardware-workbench > .step-indicator {
|
|
|
|
|
margin: 0 0 30px !important;
|
|
|
|
|
}
|
|
|
|
|
@ -934,6 +934,11 @@ onMounted(async () => {
|
|
|
|
|
.step-tab.complete + .step-connector::after { border-color: #63e6f1; }
|
|
|
|
|
|
|
|
|
|
@media (max-width: 900px) {
|
|
|
|
|
.hardware-cost-page .hardware-cost-toolbar {
|
|
|
|
|
width: 100%;
|
|
|
|
|
justify-content: flex-start;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.step-indicator {
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
align-items: stretch;
|
|
|
|
|
|