From 80adf052e0b58abd634ca9b67f8569ccc468c430 Mon Sep 17 00:00:00 2001
From: yyb <995253665@qq.com>
Date: 星期一, 23 三月 2026 15:11:36 +0800
Subject: [PATCH] Merge branch 'dev_银川_中盛建材' of http://114.132.189.42:9002/r/product-inventory-management into dev_银川_中盛建材

---
 src/views/productionManagement/productionReporting/reportingDialog.vue | 1647 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 1,647 insertions(+), 0 deletions(-)

diff --git a/src/views/productionManagement/productionReporting/reportingDialog.vue b/src/views/productionManagement/productionReporting/reportingDialog.vue
new file mode 100644
index 0000000..1c8ad3f
--- /dev/null
+++ b/src/views/productionManagement/productionReporting/reportingDialog.vue
@@ -0,0 +1,1647 @@
+<template>
+  <div class="reporting-page">
+    <!-- 椤甸潰澶撮儴 -->
+    <PageHeader content="鐢熶骇宸ュ崟鎶ュ伐">
+    </PageHeader>
+    <!-- 姝ラ鎸囩ず鍣� -->
+    <div class="step-indicator">
+      <div v-for="(step, index) in steps"
+           :key="index"
+           class="step-item"
+           :class="{ 
+          'active': index === activeStep, 
+          'completed': index < activeStep 
+        }">
+        <div class="step-circle">
+          <span v-if="index < activeStep"
+                class="step-check">
+            <el-icon>
+              <Check />
+            </el-icon>
+          </span>
+          <span v-else
+                class="step-number">{{ index + 1 }}</span>
+        </div>
+        <div class="step-content">
+          <div class="step-title">{{ step.title }}</div>
+          <div class="step-description">{{ step.description }}</div>
+        </div>
+        <div class="step-line"
+             v-if="index < steps.length - 1"></div>
+      </div>
+    </div>
+    <!-- 椤甸潰鍐呭 -->
+    <div class="page-content">
+      <!-- 绗竴姝ワ細閫夋嫨鐢熶骇璁㈠崟 -->
+      <div v-if="activeStep === 0"
+           class="step-panel">
+        <div class="panel-header">
+          <div>
+            <h3 class="panel-title">閫夋嫨鐢熶骇璁㈠崟</h3>
+            <p class="panel-subtitle">璇蜂粠浠ヤ笅鍒楄〃涓�夋嫨闇�瑕佹姤宸ョ殑鐢熶骇璁㈠崟</p>
+          </div>
+          <div class="header-actions">
+            <el-button @click="activeStep--"
+                       v-if="activeStep > 0"
+                       :disabled="isSubmitting">
+              <el-icon>
+                <ArrowLeft />
+              </el-icon> 涓婁竴姝�
+            </el-button>
+            <el-button type="primary"
+                       @click="handleNextStep"
+                       v-if="activeStep < 3"
+                       :disabled="isSubmitting">
+              涓嬩竴姝� <el-icon>
+                <ArrowRight />
+              </el-icon>
+            </el-button>
+          </div>
+        </div>
+        <el-form :model="form"
+                 ref="formRef"
+                 class="form-container">
+          <el-form-item label="鐢熶骇璁㈠崟"
+                        prop="orderId"
+                        required>
+            <el-select v-model="orderId"
+                       placeholder="璇烽�夋嫨鐢熶骇璁㈠崟"
+                       clearable
+                       filterable
+                       class="form-select"
+                       :loading="orderLoading"
+                       @change="handleOrderChange">
+              <el-option v-for="order in orderList"
+                         :key="order.id"
+                         :label="`${order.npsNo} - ${order.productName} ${order.model}`"
+                         :value="order.id" />
+            </el-select>
+          </el-form-item>
+        </el-form>
+      </div>
+      <!-- 绗簩姝ワ細濉啓鍩虹淇℃伅 -->
+      <div v-else-if="activeStep === 1"
+           class="step-panel">
+        <div class="panel-header">
+          <div>
+            <h3 class="panel-title">濉啓鍩虹淇℃伅</h3>
+            <p class="panel-subtitle">璇峰~鍐欐姤宸ョ殑鍩烘湰淇℃伅</p>
+          </div>
+          <div class="header-actions">
+            <el-button @click="activeStep--"
+                       v-if="activeStep > 0"
+                       :disabled="isSubmitting">
+              <el-icon>
+                <ArrowLeft />
+              </el-icon> 涓婁竴姝�
+            </el-button>
+            <el-button type="primary"
+                       @click="handleNextStep"
+                       v-if="activeStep < 3"
+                       :disabled="isSubmitting">
+              涓嬩竴姝� <el-icon>
+                <ArrowRight />
+              </el-icon>
+            </el-button>
+          </div>
+        </div>
+        <el-form :model="form"
+                 :rules="rules"
+                 ref="formRef"
+                 class="form-container">
+          <div class="form-grid">
+            <el-form-item label="鐢熶骇璁㈠崟鍙�"
+                          prop="npsNo"
+                          class="form-item">
+              <el-input disabled
+                        v-model="form.npsNo"
+                        class="form-input" />
+            </el-form-item>
+            <el-form-item label="浜у搧缂栫爜"
+                          prop="materialCode"
+                          class="form-item">
+              <el-input disabled
+                        v-model="form.materialCode"
+                        class="form-input" />
+            </el-form-item>
+            <el-form-item label="浜у搧鍚嶇О"
+                          prop="productName"
+                          class="form-item">
+              <el-input disabled
+                        v-model="form.productName"
+                        class="form-input" />
+            </el-form-item>
+            <el-form-item label="瑙勬牸"
+                          prop="specification"
+                          class="form-item">
+              <el-input disabled
+                        v-model="form.specification"
+                        class="form-input" />
+            </el-form-item>
+            <el-form-item label="鍒涘缓鏃堕棿"
+                          prop="createTime"
+                          class="form-item">
+              <el-date-picker disabled
+                              v-model="form.createTime"
+                              type="datetime"
+                              placeholder="璇烽�夋嫨鍒涘缓鏃堕棿"
+                              class="form-input" />
+            </el-form-item>
+            <el-form-item label="鐝粍"
+                          prop="teamName"
+                          required
+                          class="form-item">
+              <el-select v-model="form.teamName"
+                         placeholder="璇烽�夋嫨鐝粍"
+                         class="form-select">
+                <el-option label="鐧界彮"
+                           value="鐧界彮" />
+                <el-option label="澶滅彮"
+                           value="澶滅彮" />
+              </el-select>
+            </el-form-item>
+            <el-form-item label="鍒涘缓浜�"
+                          prop="createBy"
+                          required
+                          class="form-item">
+              <el-select v-model="form.createBy"
+                         placeholder="璇烽�夋嫨鍒涘缓浜�"
+                         class="form-select"
+                         :loading="userLoading">
+                <el-option v-for="user in userList"
+                           :key="user.id"
+                           :label="user.nickName || user.userName"
+                           :value="user.nickName || user.userName" />
+              </el-select>
+            </el-form-item>
+          </div>
+        </el-form>
+      </div>
+      <!-- 绗笁姝ワ細鏌ョ湅宸ュ簭鍙傛暟 -->
+      <div v-else-if="activeStep === 2"
+           class="step-panel process-panel">
+        <div class="panel-header">
+          <div>
+            <h3 class="panel-title">宸ュ簭鍙傛暟绠$悊</h3>
+            <p class="panel-subtitle">璇锋煡鐪嬪苟濉啓鍚勫伐搴忕殑鍙傛暟淇℃伅</p>
+          </div>
+          <div class="header-actions">
+            <el-button @click="activeStep--"
+                       v-if="activeStep > 0"
+                       :disabled="isSubmitting">
+              <el-icon>
+                <ArrowLeft />
+              </el-icon> 涓婁竴姝�
+            </el-button>
+            <el-button type="primary"
+                       @click="handleNextStep"
+                       v-if="activeStep < 3"
+                       :disabled="isSubmitting">
+              涓嬩竴姝� <el-icon>
+                <ArrowRight />
+              </el-icon>
+            </el-button>
+          </div>
+        </div>
+        <div class="process-container">
+          <!-- 宸︿晶宸ュ簭瀵艰埅 -->
+          <div class="process-nav">
+            <div v-for="process in processList"
+                 :key="process.processId"
+                 class="process-nav-item"
+                 :class="{ 'active': activeProcessId === process.processId + '' }"
+                 @click="handleProcessClick(process.processId)">
+              <span class="process-name">{{ process.processName }}</span>
+              <span class="process-badge"
+                    v-if="getProcessInfo(parseInt(process.processId)).postPersonnel">
+                {{ getProcessInfo(parseInt(process.processId)).postPersonnel }}
+              </span>
+            </div>
+          </div>
+          <!-- 鍙充晶宸ュ簭鍐呭 -->
+          <div class="process-content">
+            <div v-if="activeProcessId"
+                 class="process-details">
+              <!-- 鍥哄畾鍙傛暟 -->
+              <div class="param-section">
+                <div class="section-header">
+                  <h4 class="section-title">宸ュ簭鍩烘湰淇℃伅</h4>
+                </div>
+                <div class="param-form">
+                  <el-form :label-position="'top'">
+                    <div class="form-grid">
+                      <el-form-item label="宀椾綅浜哄憳"
+                                    class="form-item">
+                        <el-select v-model="getProcessInfo(parseInt(activeProcessId)).postPersonnel"
+                                   placeholder="璇烽�夋嫨宀椾綅浜哄憳"
+                                   class="form-select"
+                                   :loading="userLoading">
+                          <el-option v-for="user in userList"
+                                     :key="user.id"
+                                     :label="user.nickName || user.userName"
+                                     :value="user.nickName || user.userName" />
+                        </el-select>
+                      </el-form-item>
+                      <el-form-item label="璁惧寮傚父鎯呭喌"
+                                    class="form-item">
+                        <el-input v-model="getProcessInfo(parseInt(activeProcessId)).equipmentAbnormality"
+                                  placeholder="璇疯緭鍏ヨ澶囧紓甯告儏鍐�"
+                                  type="textarea"
+                                  :rows="2"
+                                  class="form-textarea" />
+                      </el-form-item>
+                      <el-form-item label="褰撶彮璁惧澶勭疆"
+                                    class="form-item">
+                        <el-input v-model="getProcessInfo(parseInt(activeProcessId)).equipmentHandling"
+                                  placeholder="璇疯緭鍏ュ綋鐝澶囧缃�"
+                                  type="textarea"
+                                  :rows="2"
+                                  class="form-textarea" />
+                      </el-form-item>
+                      <el-form-item label="宸ヨ壓浜哄憳浜ゅ緟"
+                                    class="form-item">
+                        <el-input v-model="getProcessInfo(parseInt(activeProcessId)).processInstructions"
+                                  placeholder="璇疯緭鍏ュ伐鑹轰汉鍛樹氦寰�"
+                                  type="textarea"
+                                  :rows="2"
+                                  class="form-textarea" />
+                      </el-form-item>
+                      <el-form-item label="涓婁紶鏂囦欢"
+                                    class="form-item"
+                                    :span="24">
+                        <el-upload class="upload-demo upload-block"
+                                   action="#"
+                                   :on-preview="handlePreview"
+                                   :on-remove="handleRemove"
+                                   :file-list="getProcessInfo(parseInt(activeProcessId)).files || []"
+                                   :auto-upload="false"
+                                   :accept="'.jpg,.png'"
+                                   :max-size="500000"
+                                   :on-change="handleFileChange">
+                          <el-button type="primary"
+                                     :icon="Upload">鐐瑰嚮涓婁紶</el-button>
+                          <template #tip>
+                            <div class="el-upload__tip">
+                              鍙兘涓婁紶jpg/png鏂囦欢锛屼笖涓嶈秴杩�500kb
+                            </div>
+                          </template>
+                        </el-upload>
+                      </el-form-item>
+                    </div>
+                  </el-form>
+                </div>
+              </div>
+              <!-- BOM淇℃伅 -->
+              <div class="param-section"
+                   v-if="getProcessStructures(parseInt(activeProcessId)).length > 0">
+                <div class="section-header">
+                  <h4 class="section-title">BOM淇℃伅</h4>
+                </div>
+                <div class="param-form">
+                  <el-form :label-position="'top'">
+                    <div class="form-grid">
+                      <el-form-item v-for="item in getProcessStructures(parseInt(activeProcessId))"
+                                    :key="item.id"
+                                    :label="`${item.productName} ${item.model}`"
+                                    class="form-item">
+                        <div class="consumable-input-group">
+                          <el-input-number v-model="getProcessInfo(parseInt(activeProcessId)).consumables[item.id]"
+                                           :min="0"
+                                           :model-value="getConsumableValue(parseInt(activeProcessId), item.id)"
+                                           @change="val => getProcessInfo(parseInt(activeProcessId)).consumables[item.id] = val"
+                                           class="consumable-input" />
+                          <span class="consumable-unit">{{ item.unit }}</span>
+                        </div>
+                      </el-form-item>
+                    </div>
+                  </el-form>
+                </div>
+              </div>
+              <!-- 鍙傛暟缁勫垪琛� -->
+              <div class="param-section">
+                <div class="section-header">
+                  <h4 class="section-title">鍙傛暟缁勭鐞�</h4>
+                  <div class="section-actions">
+                    <el-switch v-model="useTableView"
+                               active-text="琛ㄦ牸瑙嗗浘"
+                               inactive-text="鍗$墖瑙嗗浘"
+                               inline-prompt />
+                    <el-button type="primary"
+                               @click="addParamGroup(parseInt(activeProcessId))"
+                               :icon="Plus">
+                      鏂板鍙傛暟缁�
+                    </el-button>
+                  </div>
+                </div>
+                <!-- 鍗$墖瑙嗗浘 -->
+                <div v-if="!useTableView"
+                     class="param-cards">
+                  <div v-for="(group, index) in form.paramGroups[activeProcessId] || []"
+                       :key="index"
+                       class="param-card">
+                    <div class="card-header">
+                      <span class="card-title">鍙傛暟缁� {{ index + 1 }}</span>
+                      <el-button type="danger"
+                                 size="small"
+                                 @click="removeParamGroup(parseInt(activeProcessId), index)"
+                                 v-if="(form.paramGroups[activeProcessId] || []).length > 1"
+                                 circle>
+                        <el-icon>
+                          <Delete />
+                        </el-icon>
+                      </el-button>
+                    </div>
+                    <div class="card-body">
+                      <div class="param-grid">
+                        <el-form-item v-for="param in params"
+                                      :key="param.id"
+                                      :label="param.paramName"
+                                      :label-width="120"
+                                      :required="param.isRequired"
+                                      :prop="`paramGroups.${activeProcessId}.${index}.${param.id}`"
+                                      :rules="param.isRequired ? [{ required: true, message: `璇疯緭鍏�${param.paramName}`, trigger: 'blur' }] : []"
+                                      class="param-item">
+                          <template v-if="param.paramType == '1'">
+                            <!-- 鏁板瓧绫诲瀷 -->
+                            <div class="param-input-group">
+                              <el-input-number v-model="form.paramGroups[activeProcessId][index][param.id]"
+                                               controls-position="right"
+                                               :precision="getPrecision(param.paramFormat)"
+                                               class="param-input" />
+                              <span v-if="param.unit && param.unit != '/'"
+                                    class="param-unit">
+                                {{ param.unit }}
+                              </span>
+                            </div>
+                          </template>
+                          <template v-else-if="param.paramType == '2'">
+                            <!-- 鏂囨湰绫诲瀷 -->
+                            <div class="param-input-group">
+                              <el-input v-model="form.paramGroups[activeProcessId][index][param.id]"
+                                        class="param-input" />
+                              <span v-if="param.unit && param.unit != '/'"
+                                    class="param-unit">
+                                {{ param.unit }}
+                              </span>
+                            </div>
+                          </template>
+                          <template v-else-if="param.paramType == '3'">
+                            <!-- 瀛楀吀绫诲瀷 -->
+                            <div class="param-input-group">
+                              <el-select v-model="form.paramGroups[activeProcessId][index][param.id]"
+                                         placeholder="璇烽�夋嫨"
+                                         class="param-select"
+                                         style="width: 100%">
+                                <el-option v-for="option in dictOptions[param.paramFormat] || []"
+                                           :key="option.dictValue"
+                                           :label="option.dictLabel"
+                                           :value="option.dictValue" />
+                              </el-select>
+                              <span v-if="param.unit && param.unit != '/'"
+                                    class="param-unit">
+                                {{ param.unit }}
+                              </span>
+                            </div>
+                          </template>
+                          <template v-else-if="param.paramType == '4'">
+                            <!-- 鏃ユ湡绫诲瀷 -->
+                            <div class="param-input-group">
+                              <el-date-picker :value-format="param.paramFormat"
+                                              :format="param.paramFormat"
+                                              :type="param.paramFormat=='YYYY-MM-DD'?'date':'datetime'"
+                                              v-model="form.paramGroups[activeProcessId][index][param.id]"
+                                              class="param-input" />
+                              <span v-if="param.unit && param.unit != '/'"
+                                    class="param-unit">
+                                {{ param.unit }}
+                              </span>
+                            </div>
+                          </template>
+                          <template v-else>
+                            <!-- 鍏朵粬绫诲瀷 -->
+                            <div class="param-input-group">
+                              <el-input v-model="form.paramGroups[activeProcessId][index][param.id]"
+                                        class="param-input" />
+                              <span v-if="param.unit && param.unit != '/'"
+                                    class="param-unit">
+                                {{ param.unit }}
+                              </span>
+                            </div>
+                          </template>
+                        </el-form-item>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+                <!-- 琛ㄦ牸瑙嗗浘 -->
+                <div v-else
+                     class="param-table">
+                  <el-table :data="form.paramGroups[activeProcessId] || []"
+                            style="width: 100%"
+                            class="table-view">
+                    <!-- 鎿嶄綔鍒� -->
+                    <el-table-column label="鎿嶄綔"
+                                     width="100"
+                                     fixed>
+                      <template #default="{ $index }">
+                        <el-button type="danger"
+                                   size="small"
+                                   @click="removeParamGroup(parseInt(activeProcessId), $index)"
+                                   circle>
+                          <el-icon>
+                            <Delete />
+                          </el-icon>
+                        </el-button>
+                      </template>
+                    </el-table-column>
+                    <!-- 鍙傛暟鍒� -->
+                    <el-table-column v-for="param in params"
+                                     :key="param.id"
+                                     :min-width="200">
+                      <template #header>
+                        <span :class="{ 'required-label': param.isRequired }">{{ param.paramName }}</span>
+                      </template>
+                      <template #default="{ row }">
+                        <template v-if="param.paramType == '1'">
+                          <!-- 鏁板瓧绫诲瀷 -->
+                          <el-input-number v-model="row[param.id]"
+                                           controls-position="right"
+                                           :precision="getPrecision(param.paramFormat)"
+                                           class="table-input" />
+                        </template>
+                        <template v-else-if="param.paramType == '2'">
+                          <!-- 鏂囨湰绫诲瀷 -->
+                          <el-input v-model="row[param.id]"
+                                    class="table-input" />
+                        </template>
+                        <template v-else-if="param.paramType == '3'">
+                          <!-- 瀛楀吀绫诲瀷 -->
+                          <el-select v-model="row[param.id]"
+                                     placeholder="璇烽�夋嫨"
+                                     class="table-select">
+                            <el-option v-for="option in dictOptions[param.paramFormat] || []"
+                                       :key="option.dictValue"
+                                       :label="option.dictLabel"
+                                       :value="option.dictValue" />
+                          </el-select>
+                        </template>
+                        <template v-else-if="param.paramType == '4'">
+                          <!-- 鏃ユ湡绫诲瀷 -->
+                          <el-date-picker :value-format="param.paramFormat"
+                                          :format="param.paramFormat"
+                                          width="100%"
+                                          :type="param.paramFormat=='YYYY-MM-DD'?'date':'datetime'"
+                                          v-model="row[param.id]"
+                                          class="table-input table-select" />
+                        </template>
+                        <template v-else>
+                          <!-- 鍏朵粬绫诲瀷 -->
+                          <el-input v-model="row[param.id]"
+                                    class="table-input" />
+                        </template>
+                      </template>
+                    </el-table-column>
+                  </el-table>
+                </div>
+                <!-- 鏂板鍙傛暟缁勬寜閽� -->
+                <!-- <div class="param-actions">
+                  <el-button type="primary"
+                             @click="addParamGroup(parseInt(activeProcessId))"
+                             :icon="Plus">
+                    鏂板鍙傛暟缁�
+                  </el-button>
+                </div> -->
+              </div>
+            </div>
+            <div v-else
+                 class="empty-process">
+              <el-empty description="璇烽�夋嫨涓�涓伐搴�"
+                        :image-size="120" />
+            </div>
+          </div>
+        </div>
+      </div>
+      <!-- 绗洓姝ワ細濉啓浜ч噺淇℃伅 -->
+      <div v-else-if="activeStep === 3"
+           class="step-panel">
+        <div class="panel-header">
+          <div>
+            <h3 class="panel-title">濉啓浜ч噺淇℃伅</h3>
+            <p class="panel-subtitle">璇峰~鍐欐湰娆℃姤宸ョ殑浜ч噺鏁版嵁</p>
+          </div>
+          <div class="header-actions">
+            <el-button @click="activeStep--"
+                       v-if="activeStep > 0"
+                       :disabled="isSubmitting">
+              <el-icon>
+                <ArrowLeft />
+              </el-icon> 涓婁竴姝�
+            </el-button>
+            <el-button type="primary"
+                       @click="handleSubmit"
+                       v-if="activeStep === 3"
+                       :loading="isSubmitting">
+              <el-icon v-if="!isSubmitting">
+                <Check />
+              </el-icon>
+              <el-icon v-else>
+                <Loading />
+              </el-icon>
+              {{ isSubmitting ? '鎻愪氦涓�...' : '纭鎻愪氦' }}
+            </el-button>
+          </div>
+        </div>
+        <el-form :model="form"
+                 :rules="rules"
+                 ref="formRef"
+                 :label-position="'top'"
+                 class="form-container">
+          <div class="form-grid1">
+            <el-form-item label="浜у嚭鏂归噺"
+                          prop="outputVolume"
+                          required
+                          class="form-item">
+              <div class="volume-input-group">
+                <el-input-number v-model="form.outputVolume"
+                                 :min="0"
+                                 :precision="2"
+                                 @change="handleVolumeChange"
+                                 class="volume-input" />
+                <span class="volume-unit">鏂�</span>
+              </div>
+            </el-form-item>
+            <el-form-item label="涓嶅悎鏍兼柟閲�"
+                          prop="unqualifiedVolume"
+                          required
+                          class="form-item">
+              <div class="volume-input-group">
+                <el-input-number v-model="form.unqualifiedVolume"
+                                 :min="0"
+                                 :precision="2"
+                                 @change="handleVolumeChange"
+                                 class="volume-input" />
+                <span class="volume-unit">鏂�</span>
+              </div>
+            </el-form-item>
+            <el-form-item label="瀹屾垚鏂归噺"
+                          prop="completedVolume"
+                          required
+                          class="form-item">
+              <div class="volume-input-group">
+                <el-input-number v-model="form.completedVolume"
+                                 :min="0"
+                                 :precision="2"
+                                 class="volume-input" />
+                <span class="volume-unit">鏂�</span>
+              </div>
+            </el-form-item>
+          </div>
+        </el-form>
+      </div>
+    </div>
+    <!-- 搴曢儴鎸夐挳 -->
+  </div>
+</template>
+
+<script setup>
+  import { ref, reactive, computed, watch, onMounted } from "vue";
+  import { ElMessage, ElEmpty } from "element-plus";
+  import { useRouter, useRoute } from "vue-router";
+  import { getDicts } from "@/api/system/dict/data";
+  import { productOrderListPage } from "@/api/productionManagement/productionOrder.js";
+  import { productionRecordAdd } from "@/api/productionManagement/productProcessRoute.js";
+  import { userListNoPage } from "@/api/system/user.js";
+  import { getInfo } from "@/api/login.js";
+  import {
+    Check,
+    Close,
+    Delete,
+    Plus,
+    ArrowLeft,
+    ArrowRight,
+    Loading,
+    Upload,
+  } from "@element-plus/icons-vue";
+
+  const router = useRouter();
+
+  // 浠庤矾鐢卞弬鏁拌幏鍙栨暟鎹�
+  const route = useRoute();
+  const data = route.query.data ? JSON.parse(route.query.data) : {};
+
+  const dialogTitle = computed(() => (data.id ? "缂栬緫鎶ュ伐" : "鏂板鎶ュ伐"));
+
+  const formRef = ref(null);
+  const isSubmitting = ref(false);
+  const orderLoading = ref(false);
+  const processLoading = ref(false);
+  const activeStep = ref(0);
+
+  const steps = [
+    { title: "閫夋嫨鐢熶骇璁㈠崟", description: "閫夋嫨闇�瑕佹姤宸ョ殑鐢熶骇璁㈠崟" },
+    { title: "濉啓鍩虹淇℃伅", description: "濉啓鎶ュ伐鐨勫熀鏈俊鎭�" },
+    { title: "鏌ョ湅宸ュ簭鍙傛暟", description: "濉啓鍚勫伐搴忕殑鍙傛暟淇℃伅" },
+    { title: "濉啓浜ч噺淇℃伅", description: "濉啓鏈鎶ュ伐鐨勪骇閲忔暟鎹�" },
+  ];
+
+  // 璁$畻褰撳墠宸ュ簭鐨勫弬鏁扮粍鏁伴噺
+  const paramGroupCount = computed(() => {
+    if (!activeProcessId.value) return 0;
+    return (form.paramGroups[activeProcessId.value] || []).length;
+  });
+
+  const orderId = ref(data.orderId || "");
+  const processId = ref(data.processId || "");
+  const activeProcessId = ref("");
+  const orderList = ref([]);
+  const processList = ref([]);
+  const params = ref([]);
+  const dictOptions = ref({});
+  const userList = ref([]);
+  const userLoading = ref(false);
+  const useTableView = ref(false); // 鎺у埗鏄惁浣跨敤琛ㄦ牸瑙嗗浘
+
+  const form = reactive({
+    id: data.id || undefined,
+    orderId: data.orderId || "",
+    npsNo: data.npsNo || "",
+    teamName: data.teamName || "鐧界彮",
+    materialCode: data.materialCode || "",
+    productName: data.productName || "",
+    specification: data.specification || "",
+    outputVolume: data.outputVolume || 0,
+    unqualifiedVolume: data.unqualifiedVolume || 0,
+    completedVolume: data.completedVolume || 0,
+    createBy: data.createBy || "褰撳墠鐧诲綍浜�",
+    createTime: data.createTime || new Date(),
+    paramGroups: data.paramGroups || {}, // 瀛樺偍姣忎釜宸ュ簭鐨勫弬鏁扮粍
+    processInfo: data.processInfo || {}, // 瀛樺偍姣忎釜宸ュ簭鐨勫熀鏈俊鎭�
+  });
+
+  const rules = {
+    teamName: [{ required: true, message: "璇烽�夋嫨鐝粍", trigger: "blur" }],
+    outputVolume: [
+      { required: true, message: "璇疯緭鍏ヤ骇鍑烘柟閲�", trigger: "blur" },
+    ],
+    unqualifiedVolume: [
+      { required: true, message: "璇疯緭鍏ヤ笉鍚堟牸鏂归噺", trigger: "blur" },
+    ],
+    completedVolume: [
+      { required: true, message: "璇疯緭鍏ュ畬鎴愭柟閲�", trigger: "blur" },
+    ],
+    createBy: [{ required: true, message: "璇疯緭鍏ュ垱寤轰汉", trigger: "blur" }],
+  };
+
+  // 鍔犺浇鐢熶骇璁㈠崟鍒楄〃
+  const loadOrders = () => {
+    orderLoading.value = true;
+    productOrderListPage({ pageNum: 1, pageSize: 100 })
+      .then(res => {
+        orderList.value = res.data.records || [];
+      })
+      .finally(() => {
+        orderLoading.value = false;
+      });
+  };
+  const handleVolumeChange = () => {
+    form.completedVolume = form.outputVolume - form.unqualifiedVolume;
+  };
+
+  // 澶勭悊鐢熶骇璁㈠崟閫夋嫨
+  const handleOrderChange = val => {
+    if (val) {
+      const order = orderList.value.find(item => item.id === val);
+      if (order) {
+        form.orderId = val;
+        form.npsNo = order.npsNo;
+        form.materialCode = order.materialCode;
+        form.productName = order.productName;
+        form.specification = order.model;
+      }
+      // 鍔犺浇宸ュ簭鍒楄〃
+      loadProcesses(val);
+    } else {
+      form.orderId = "";
+      form.npsNo = "";
+      form.materialCode = "";
+      form.productName = "";
+      form.specification = "";
+      processId.value = "";
+      activeProcessId.value = "";
+      processList.value = [];
+      params.value = [];
+      form.params = {};
+    }
+  };
+
+  // 鍔犺浇宸ュ簭鍒楄〃
+  const loadProcesses = orderId => {
+    processLoading.value = true;
+    // 璋冪敤鏂扮殑鎺ュ彛
+    productionRecordAdd(orderId)
+      .then(res => {
+        if (res.code === 200) {
+          const data = res.data;
+          // 鎻愬彇宸ュ簭鍒楄〃
+          processList.value = data.productionOrderRouteItemVos || [];
+          // 瀛樺偍宸ュ簭缁撴瀯鏁版嵁
+          form.processStructures = {};
+          processList.value.forEach(process => {
+            form.processStructures[process.processId] =
+              process.orderStructureVos || [];
+          });
+          // 濡傛灉鏈夊伐搴忥紝榛樿閫夋嫨绗竴涓�
+          if (processList.value.length > 0) {
+            const firstProcess = processList.value[0];
+            activeProcessId.value = firstProcess.processId + "";
+            processId.value = firstProcess.processId;
+            form.processId = firstProcess.processId;
+            // 鍔犺浇绗竴涓伐搴忕殑鍙傛暟
+            loadParams(firstProcess.processId, orderId);
+          }
+        }
+      })
+      .finally(() => {
+        processLoading.value = false;
+      });
+  };
+
+  // 澶勭悊宸ュ簭瀵艰埅鐐瑰嚮
+  const handleProcessClick = selectedProcessId => {
+    activeProcessId.value = selectedProcessId + "";
+    processId.value = selectedProcessId;
+    form.processId = selectedProcessId;
+    // 鍔犺浇鍙傛暟鍒楄〃
+    loadParams(selectedProcessId, form.orderId);
+  };
+
+  // 鑾峰彇宸ュ簭鍩烘湰淇℃伅锛屼笉瀛樺湪鍒欏垵濮嬪寲
+  const getProcessInfo = processId => {
+    if (!form.processInfo) {
+      form.processInfo = {};
+    }
+    if (!form.processInfo[processId]) {
+      form.processInfo[processId] = {
+        postPersonnel: "",
+        equipmentAbnormality: "",
+        equipmentHandling: "",
+        processInstructions: "",
+        files: [],
+        consumables: {},
+      };
+    }
+    return form.processInfo[processId];
+  };
+
+  // 鑾峰彇宸ュ簭缁撴瀯鏁版嵁锛圔OM鍒楄〃锛�
+  const getProcessStructures = processId => {
+    return form.processStructures && form.processStructures[processId]
+      ? form.processStructures[processId]
+      : [];
+  };
+
+  // 鑾峰彇娑堣�楀搧鏁伴噺锛岄粯璁や负0
+  const getConsumableValue = (processId, itemId) => {
+    const processInfo = getProcessInfo(processId);
+    if (!processInfo.consumables[itemId]) {
+      processInfo.consumables[itemId] = 0;
+    }
+    return processInfo.consumables[itemId];
+  };
+
+  // 澶勭悊鏂囦欢棰勮
+  const handlePreview = file => {
+    // 妫�鏌ユ槸鍚︽槸鍥剧墖鏂囦欢
+    if (file.raw && file.raw.type.startsWith("image/")) {
+      // 鍒涘缓鍥剧墖棰勮
+      const imageUrl = URL.createObjectURL(file.raw);
+      const image = new Image();
+      image.src = imageUrl;
+
+      // 鍒涘缓棰勮瀹瑰櫒
+      const previewContainer = document.createElement("div");
+      previewContainer.style.position = "fixed";
+      previewContainer.style.top = "0";
+      previewContainer.style.left = "0";
+      previewContainer.style.width = "100%";
+      previewContainer.style.height = "100%";
+      previewContainer.style.backgroundColor = "rgba(0, 0, 0, 0.8)";
+      previewContainer.style.display = "flex";
+      previewContainer.style.alignItems = "center";
+      previewContainer.style.justifyContent = "center";
+      previewContainer.style.zIndex = "9999";
+      previewContainer.style.cursor = "pointer";
+
+      // 娣诲姞鍥剧墖
+      previewContainer.appendChild(image);
+      image.style.maxWidth = "90%";
+      image.style.maxHeight = "90%";
+
+      // 娣诲姞鍏抽棴鍔熻兘
+      previewContainer.addEventListener("click", () => {
+        URL.revokeObjectURL(imageUrl);
+        document.body.removeChild(previewContainer);
+      });
+
+      // 娣诲姞鍒版枃妗�
+      document.body.appendChild(previewContainer);
+    }
+  };
+
+  // 澶勭悊鏂囦欢鍒犻櫎
+  const handleRemove = (file, fileList) => {
+    const processId = parseInt(activeProcessId.value);
+    if (processId) {
+      const processInfo = getProcessInfo(processId);
+      processInfo.files = fileList;
+    }
+  };
+
+  // 澶勭悊鏂囦欢鍙樻洿
+  const handleFileChange = (file, fileList) => {
+    const processId = parseInt(activeProcessId.value);
+    if (processId) {
+      const processInfo = getProcessInfo(processId);
+      processInfo.files = fileList;
+    }
+  };
+
+  // 鑾峰彇瀛楀吀鏁版嵁
+  const getDictOptions = async dictType => {
+    if (!dictType) return [];
+    if (dictOptions.value[dictType]) return dictOptions.value[dictType];
+
+    try {
+      const res = await getDicts(dictType);
+      if (res.code === 200) {
+        dictOptions.value[dictType] = res.data;
+        return res.data;
+      }
+      return [];
+    } catch (error) {
+      console.error("鑾峰彇瀛楀吀鏁版嵁澶辫触:", error);
+      return [];
+    }
+  };
+
+  // 鍔犺浇鍙傛暟鍒楄〃
+  const loadParams = (processId, orderId) => {
+    // 浠庡凡鍔犺浇鐨勫伐搴忔暟鎹腑鑾峰彇鍙傛暟鍒楄〃
+    const process = processList.value.find(
+      p => p.processId === parseInt(processId)
+    );
+    if (process) {
+      params.value = process.orderRouteItemParaVos || [];
+
+      // 鍒濆鍖栧弬鏁扮粍
+      if (!form.paramGroups[processId]) {
+        form.paramGroups[processId] = [];
+      }
+      // 濡傛灉娌℃湁鍙傛暟缁勶紝娣诲姞涓�涓粯璁ゅ弬鏁扮粍
+      if (form.paramGroups[processId].length === 0) {
+        const defaultGroup = {};
+        for (const param of params.value) {
+          defaultGroup[param.id] = param.standardValue || "";
+          // 濡傛灉鏄瓧鍏哥被鍨嬪弬鏁帮紝鑾峰彇瀛楀吀鏁版嵁
+          if (param.paramType == "3" && param.paramFormat) {
+            getDictOptions(param.paramFormat);
+          }
+        }
+        form.paramGroups[processId].push(defaultGroup);
+      }
+    }
+  };
+
+  // 鑾峰彇灏忔暟绮惧害
+  const getPrecision = format => {
+    if (!format) return 2;
+    const match = format.match(/\.(\d+)/);
+    return match ? parseInt(match[1].length) : 2;
+  };
+
+  // 澶勭悊涓嬩竴姝�
+  const handleNextStep = () => {
+    if (activeStep.value === 0) {
+      // 绗竴姝ワ細楠岃瘉鐢熶骇璁㈠崟閫夋嫨
+      if (!orderId.value) {
+        ElMessage.error("璇烽�夋嫨鐢熶骇璁㈠崟");
+        return;
+      }
+      activeStep.value = 1;
+    } else if (activeStep.value === 1) {
+      // 绗簩姝ワ細楠岃瘉鍩虹淇℃伅
+      formRef.value.validate(valid => {
+        if (valid) {
+          activeStep.value = 2;
+        }
+      });
+    } else if (activeStep.value === 2) {
+      // 绗笁姝ワ細楠岃瘉鍙傛暟蹇呭~椤�
+      let isValid = true;
+      let errorMessage = "";
+
+      // 閬嶅巻鎵�鏈夊伐搴�
+      for (const process of processList.value) {
+        const processId = process.processId;
+        const paramGroups = form.paramGroups[processId] || [];
+        const processParams = process.orderRouteItemParaVos || [];
+
+        // 鑾峰彇蹇呭~鍙傛暟
+        const requiredParams = processParams.filter(p => p.isRequired);
+
+        if (requiredParams.length > 0) {
+          // 妫�鏌ユ瘡涓弬鏁扮粍涓殑蹇呭~鍙傛暟
+          for (
+            let groupIndex = 0;
+            groupIndex < paramGroups.length;
+            groupIndex++
+          ) {
+            const group = paramGroups[groupIndex];
+            for (const param of requiredParams) {
+              const value = group[param.id];
+              if (value === undefined || value === null || value === "") {
+                isValid = false;
+                errorMessage = `宸ュ簭銆�${process.processName}銆戝弬鏁扮粍${
+                  groupIndex + 1
+                }鐨勩��${param.paramName}銆戜负蹇呭~椤筦;
+                break;
+              }
+            }
+            if (!isValid) break;
+          }
+        }
+        if (!isValid) break;
+      }
+
+      if (!isValid) {
+        ElMessage.error(errorMessage);
+        return;
+      }
+
+      activeStep.value = 3;
+    }
+  };
+
+  // 澶勭悊鎻愪氦
+  const handleSubmit = () => {
+    formRef.value.validate(valid => {
+      if (valid) {
+        isSubmitting.value = true;
+        // 杩欓噷鍙互璋冪敤API杩涜鎻愪氦
+        setTimeout(() => {
+          ElMessage.success(data.id ? "淇敼鎴愬姛" : "鏂板鎴愬姛");
+          router.back();
+          isSubmitting.value = false;
+        }, 1000);
+      }
+    });
+  };
+
+  // 澶勭悊鍙栨秷
+  const handleCancel = () => {
+    router.back();
+  };
+
+  // 鏂板鍙傛暟缁�
+  const addParamGroup = processId => {
+    if (!form.paramGroups[processId]) {
+      form.paramGroups[processId] = [];
+    }
+    // 鍒涘缓涓�涓柊鐨勫弬鏁扮粍锛屼娇鐢ㄩ粯璁ゅ��
+    const newGroup = {};
+    params.value.forEach(param => {
+      newGroup[param.id] = param.standardValue || "";
+    });
+    form.paramGroups[processId].push(newGroup);
+  };
+
+  // 鍒犻櫎鍙傛暟缁�
+  const removeParamGroup = (processId, index) => {
+    if (form.paramGroups[processId] && form.paramGroups[processId].length > 1) {
+      form.paramGroups[processId].splice(index, 1);
+    }
+  };
+
+  // 鍔犺浇鐢ㄦ埛鍒楄〃
+  const loadUsers = () => {
+    userLoading.value = true;
+    userListNoPage()
+      .then(res => {
+        userList.value = res.data || [];
+      })
+      .finally(() => {
+        userLoading.value = false;
+      });
+  };
+
+  // 鑾峰彇褰撳墠鐧诲綍浜轰俊鎭�
+  const getCurrentUser = async () => {
+    try {
+      const res = await getInfo();
+      if (res && res.user) {
+        form.createBy = res.user.nickName || res.user.userName;
+      }
+    } catch (error) {
+      console.error("鑾峰彇褰撳墠鐧诲綍浜轰俊鎭け璐�:", error);
+    }
+  };
+
+  // 鍒濆鍖�
+  const init = () => {
+    // 鏃犺鏂板杩樻槸缂栬緫锛岄兘鍔犺浇璁㈠崟鍒楄〃鍜岀敤鎴峰垪琛�
+    loadOrders();
+    loadUsers();
+    getCurrentUser();
+
+    if (data.id) {
+      // 缂栬緫鏃惰缃〃鍗曟暟鎹�
+      Object.assign(form, data);
+      // 璁剧疆orderId
+      orderId.value = data.orderId || "";
+      // 濡傛灉鏈夎鍗旾D锛屽姞杞藉伐搴忓拰鍙傛暟
+      if (data.orderId) {
+        // 妯℃嫙閫夋嫨璁㈠崟鐨勬搷浣滐紝瑙﹀彂鏁版嵁鍔犺浇
+        setTimeout(() => {
+          handleOrderChange(data.orderId);
+        }, 100);
+      }
+    } else {
+      // 鏂板鏃惰缃粯璁ゅ��
+      form.createTime = new Date();
+    }
+    // 濮嬬粓浠庣涓�姝ュ紑濮�
+    activeStep.value = 0;
+  };
+
+  // 椤甸潰鍔犺浇鏃跺垵濮嬪寲
+  onMounted(() => {
+    init();
+  });
+</script>
+
+<style scoped>
+  /* 椤甸潰瀹瑰櫒 */
+  .reporting-page {
+    min-height: 100vh;
+    padding: 24px;
+    background-color: #f0f2f5;
+  }
+
+  /* 椤甸潰澶撮儴 */
+  .page-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 32px;
+    padding-bottom: 16px;
+    border-bottom: 1px solid #e8e8e8;
+  }
+
+  .page-title {
+    margin: 0;
+    font-size: 24px;
+    font-weight: 600;
+    color: #1f2329;
+  }
+
+  .header-actions {
+    display: flex;
+    gap: 12px;
+  }
+
+  /* 姝ラ鎸囩ず鍣� */
+  .step-indicator {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    margin-bottom: 32px;
+    padding: 0 16px;
+    padding-top: 16px;
+  }
+
+  .step-item {
+    display: flex;
+    align-items: center;
+    flex: 1;
+    position: relative;
+  }
+
+  .step-circle {
+    width: 40px;
+    height: 40px;
+    border-radius: 50%;
+    background-color: #f0f0f0;
+    color: #999;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    font-size: 16px;
+    font-weight: 600;
+    z-index: 2;
+    transition: all 0.3s ease;
+    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+  }
+
+  .step-item.active .step-circle {
+    background-color: #1890ff;
+    color: white;
+    box-shadow: 0 0 0 8px rgba(24, 144, 255, 0.1);
+  }
+
+  .step-item.completed .step-circle {
+    background-color: #52c41a;
+    color: white;
+    box-shadow: 0 0 0 8px rgba(82, 196, 26, 0.1);
+  }
+
+  .step-check {
+    font-size: 20px;
+  }
+
+  .step-content {
+    margin-left: 16px;
+    flex: 1;
+  }
+
+  .step-title {
+    font-size: 14px;
+    font-weight: 600;
+    color: #666;
+    margin-bottom: 4px;
+    transition: color 0.3s ease;
+  }
+
+  .step-item.active .step-title {
+    color: #1890ff;
+  }
+
+  .step-item.completed .step-title {
+    color: #52c41a;
+  }
+
+  .step-description {
+    font-size: 12px;
+    color: #999;
+  }
+
+  .step-line {
+    position: absolute;
+    top: 20px;
+    left: 50%;
+    right: -50%;
+    height: 2px;
+    background-color: #e8e8e8;
+    z-index: 1;
+    transition: all 0.3s ease;
+  }
+
+  .step-item.completed .step-line {
+    background-color: #52c41a;
+  }
+
+  /* 椤甸潰鍐呭 */
+  .page-content {
+    background-color: white;
+    border-radius: 12px;
+    padding: 0;
+    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
+    margin-bottom: 32px;
+    overflow: hidden;
+  }
+
+  /* 姝ラ闈㈡澘 */
+  .step-panel {
+    padding: 32px;
+  }
+
+  .panel-header {
+    margin-bottom: 24px;
+    display: flex;
+    justify-content: space-between;
+    align-items: flex-start;
+  }
+
+  .panel-title {
+    font-size: 18px;
+    font-weight: 600;
+    color: #1f2329;
+    margin: 0 0 8px 0;
+  }
+
+  .panel-subtitle {
+    font-size: 14px;
+    color: #666;
+    margin: 0;
+  }
+
+  .header-actions {
+    display: flex;
+    gap: 12px;
+    align-items: center;
+  }
+
+  /* 琛ㄥ崟瀹瑰櫒 */
+  .form-container {
+    width: 100%;
+  }
+
+  /* 涓婁紶缁勪欢鏍峰紡 */
+  .upload-block {
+    display: block;
+  }
+
+  .upload-block .el-upload__tip {
+    margin-top: 8px;
+  }
+
+  /* BOM杈撳叆缁勬牱寮� */
+  .consumable-input-group {
+    display: flex;
+    align-items: center;
+    gap: 8px;
+  }
+
+  .consumable-input {
+    flex: 1;
+  }
+
+  .consumable-unit {
+    font-size: 14px;
+    color: #666;
+    white-space: nowrap;
+  }
+
+  /* 蹇呭~鏍囪瘑鏍峰紡 */
+  .required-label::before {
+    content: "*";
+    color: #f56c6c;
+    margin-right: 4px;
+  }
+
+  .form-grid {
+    display: grid;
+    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
+    gap: 20px;
+  }
+  .form-grid1 {
+    display: grid;
+    grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));
+    gap: 20px;
+  }
+
+  .form-item {
+    margin-bottom: 0;
+  }
+
+  .form-select,
+  .form-input {
+    width: 100%;
+  }
+
+  .form-textarea {
+    width: 100%;
+    resize: vertical;
+  }
+
+  /* 浜ч噺杈撳叆缁� */
+  .volume-input-group {
+    display: flex;
+    align-items: center;
+    gap: 8px;
+  }
+
+  .volume-input {
+    flex: 1;
+    width: 100%;
+  }
+
+  .volume-unit {
+    font-size: 14px;
+    color: #666;
+    white-space: nowrap;
+  }
+
+  /* 宸ュ簭瀹瑰櫒 */
+  .process-container {
+    display: flex;
+    gap: 24px;
+    min-height: 500px;
+  }
+
+  /* 宸ュ簭瀵艰埅 */
+  .process-nav {
+    width: 200px;
+    background-color: #fafafa;
+    border-radius: 8px;
+    padding: 16px;
+    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
+    overflow-y: auto;
+  }
+
+  .process-nav-item {
+    padding: 12px 16px;
+    margin-bottom: 8px;
+    border-radius: 6px;
+    cursor: pointer;
+    transition: all 0.3s ease;
+    font-size: 14px;
+    font-weight: 500;
+    color: #666;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+  }
+
+  .process-nav-item:hover {
+    background-color: #e6f7ff;
+    color: #1890ff;
+  }
+
+  .process-nav-item.active {
+    background-color: #1890ff;
+    color: white;
+    box-shadow: 0 2px 8px rgba(24, 144, 255, 0.3);
+  }
+
+  .process-badge {
+    font-size: 12px;
+    background-color: rgba(255, 255, 255, 0.2);
+    padding: 2px 8px;
+    border-radius: 10px;
+  }
+
+  /* 宸ュ簭鍐呭 */
+  .process-content {
+    flex: 1;
+    overflow-y: auto;
+  }
+
+  .empty-process {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    height: 400px;
+  }
+
+  /* 鍙傛暟閮ㄥ垎 */
+  .param-section {
+    margin-bottom: 32px;
+    padding: 24px;
+    background-color: #fafafa;
+    border-radius: 8px;
+  }
+
+  .section-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 16px;
+  }
+
+  .section-title {
+    font-size: 16px;
+    font-weight: 600;
+    color: #1f2329;
+    margin: 0;
+  }
+
+  .section-actions {
+    display: flex;
+    gap: 8px;
+  }
+
+  /* 鍙傛暟琛ㄥ崟 */
+  .param-form {
+    background-color: white;
+    padding: 20px;
+    border-radius: 8px;
+    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
+  }
+
+  /* 鍙傛暟鍗$墖 */
+  .param-cards {
+    display: flex;
+    flex-direction: column;
+    gap: 16px;
+  }
+
+  .param-card {
+    background-color: white;
+    border-radius: 8px;
+    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
+    overflow: hidden;
+    transition: all 0.3s ease;
+  }
+
+  .param-card:hover {
+    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
+    transform: translateY(-2px);
+  }
+
+  .card-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding: 16px 20px;
+    background-color: #fafafa;
+    border-bottom: 1px solid #e8e8e8;
+  }
+
+  .card-title {
+    font-size: 14px;
+    font-weight: 600;
+    color: #1f2329;
+  }
+
+  .card-body {
+    padding: 20px;
+  }
+
+  /* 鍙傛暟缃戞牸 */
+  .param-grid {
+    display: grid;
+    grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
+    gap: 16px;
+  }
+
+  .param-item {
+    margin-bottom: 0;
+  }
+
+  .param-input-group {
+    display: flex;
+    align-items: center;
+    gap: 8px;
+    width: 100%;
+  }
+
+  .param-input,
+  .param-select {
+    flex: 1;
+  }
+
+  .param-unit {
+    font-size: 14px;
+    color: #666;
+    white-space: nowrap;
+  }
+
+  /* 琛ㄦ牸瑙嗗浘 */
+  .param-table {
+    margin: 16px 0;
+  }
+
+  .table-view {
+    border-radius: 8px;
+    overflow: hidden;
+  }
+
+  .table-view th {
+    background-color: #fafafa;
+    font-weight: 600;
+  }
+
+  .table-input,
+  .table-select {
+    width: 100%;
+  }
+
+  /* 鍙傛暟鎿嶄綔 */
+  .param-actions {
+    margin-top: 16px;
+    display: flex;
+    justify-content: flex-end;
+  }
+
+  /* 椤甸潰搴曢儴 */
+  .page-footer {
+    display: flex;
+    justify-content: center;
+    padding: 24px;
+    background-color: white;
+    border-top: 1px solid #e8e8e8;
+    border-radius: 0 0 12px 12px;
+  }
+
+  .footer-actions {
+    display: flex;
+    gap: 12px;
+  }
+
+  /* 鍝嶅簲寮忚璁� */
+  @media (max-width: 1024px) {
+    .form-grid {
+      grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
+    }
+
+    .param-grid {
+      grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
+    }
+  }
+
+  @media (max-width: 768px) {
+    .reporting-page {
+      padding: 16px;
+    }
+
+    .step-indicator {
+      flex-direction: column;
+      align-items: flex-start;
+      gap: 16px;
+      padding: 0;
+    }
+
+    .step-item {
+      flex-direction: row;
+      width: 100%;
+    }
+
+    .step-line {
+      display: none;
+    }
+
+    .step-panel {
+      padding: 20px;
+    }
+
+    .form-grid {
+      grid-template-columns: 1fr;
+    }
+
+    .process-container {
+      flex-direction: column;
+    }
+
+    .process-nav {
+      width: 100%;
+      margin-bottom: 16px;
+    }
+
+    .param-grid {
+      grid-template-columns: 1fr;
+    }
+
+    .footer-actions {
+      flex-direction: column;
+      width: 100%;
+    }
+
+    .footer-actions button {
+      width: 100%;
+    }
+  }
+
+  /* 婊氬姩鏉℃牱寮� */
+  .process-nav::-webkit-scrollbar,
+  .process-content::-webkit-scrollbar {
+    width: 6px;
+    height: 6px;
+  }
+
+  .process-nav::-webkit-scrollbar-track,
+  .process-content::-webkit-scrollbar-track {
+    background: #f1f1f1;
+    border-radius: 3px;
+  }
+
+  .process-nav::-webkit-scrollbar-thumb,
+  .process-content::-webkit-scrollbar-thumb {
+    background: #c1c1c1;
+    border-radius: 3px;
+  }
+
+  .process-nav::-webkit-scrollbar-thumb:hover,
+  .process-content::-webkit-scrollbar-thumb:hover {
+    background: #a8a8a8;
+  }
+
+  /* 鍔ㄧ敾鏁堟灉 */
+  @keyframes fadeIn {
+    from {
+      opacity: 0;
+      transform: translateY(10px);
+    }
+    to {
+      opacity: 1;
+      transform: translateY(0);
+    }
+  }
+
+  .step-panel {
+    animation: fadeIn 0.3s ease;
+  }
+
+  /* 鍔犺浇鐘舵�� */
+  .loading-overlay {
+    position: fixed;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    background-color: rgba(255, 255, 255, 0.8);
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    z-index: 9999;
+  }
+</style>
\ No newline at end of file

--
Gitblit v1.9.3