已修改10个文件
3868 ■■■■ 文件已修改
src/api/productionManagement/processRouteItem.js 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/PIMTable/PIMTable.vue 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/basicData/parameterMaintenance/index.vue 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/processRoute/index.vue 1472 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productStructure/Detail/index.vue 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productStructure/index.vue 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionProcess/index.vue 93 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/qualityManagement/metricBinding/index.vue 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/qualityManagement/rawMaterialInspection/components/formDia.vue 1112 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/qualityManagement/rawMaterialInspection/index.vue 1116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/productionManagement/processRouteItem.js
@@ -36,3 +36,34 @@
    method: "delete",
  });
}
// 获取工序参数列表
export function getProcessParamList(query) {
  return request({
    url: `/ProcessRouteItemParam/pageList`,
    method: "get",
    params: query,
  });
}
// 工艺路线参数新增
export function addProcessRouteItemParam(data) {
  return request({
    url: "/ProcessRouteItemParam/save",
    method: "post",
    data: data,
  });
}
// 工艺路线参数修改
export function editProcessRouteItemParam(data) {
  return request({
    url: "/ProcessRouteItemParam/edit",
    method: "put",
    data: data,
  });
}
// 工艺路线参数修改
export function delProcessRouteItemParam(id) {
  return request({
    url: `/ProcessRouteItemParam/remove/${id}`,
    method: "delete",
  });
}
src/components/PIMTable/PIMTable.vue
@@ -41,7 +41,8 @@
                     :align="item.align"
                     :sortable="!!item.sortable"
                     :type="item.type"
                     :width="item.width">
                     :width="item.width"
                     :class-name="item.className || ''">
      <template #header="scope">
        <div class="pim-table-header-cell">
          <div class="pim-table-header-title">
@@ -171,6 +172,7 @@
        <!-- 可点击的文字 -->
        <div v-else-if="item.dataType == 'link'"
             class="cell link"
             :class="item.className || ''"
             style="width: 100%"
             @click="goLink(scope.row, item.linkMethod)">
          <span v-if="!item.formatData">{{ scope.row[item.prop] }}</span>
@@ -178,6 +180,7 @@
        <!-- 默认纯展示数据 -->
        <div v-else
             class="cell"
             :class="item.className || ''"
             style="width: 100%">
          <span v-if="!item.formatData">{{ scope.row[item.prop] }}</span>
          <span v-else>{{
src/views/basicData/parameterMaintenance/index.vue
@@ -31,10 +31,10 @@
                :column="tableColumn"
                :tableData="tableData"
                :page="page"
                height="calc(100vh - 280px)"
                height="calc(100vh - 320px)"
                :tableLoading="tableLoading"
                :isSelection="false"
                :isShowPagination="false"
                :isShowPagination="true"
                @pagination="pagination">
      </PIMTable>
    </div>
@@ -442,12 +442,16 @@
  const getList = () => {
    tableLoading.value = true;
    // 调用新接口 /baseParam/list
    getBaseParamList({ paramName: searchForm.paramName })
    getBaseParamList({
      paramName: searchForm.paramName,
      current: page.current,
      size: page.size,
    })
      .then(res => {
        tableLoading.value = false;
        if (res.code === 200) {
          tableData.value = res.data || [];
          page.total = res.data?.length || 0;
          tableData.value = res.data?.records || [];
          page.total = res.data?.total || 0;
        } else {
          ElMessage.error(res.msg || "查询失败");
        }
src/views/productionManagement/processRoute/index.vue
@@ -17,12 +17,12 @@
          <div class="route-info">
            <span class="route-name"><el-icon style="margin-right: 8px;line-height: 30px;">
                <ScaleToOriginal />
              </el-icon>{{ route.routeName }}<el-tag style="margin-left: 8px"
                      :type="route.status == 1 ? 'warning' : 'success'">{{ route.status == 1 ? '草稿' : '批准' }}</el-tag></span>
            <span class="route-code">{{ route.routeCode }}</span>
              </el-icon>{{route.routeCode }}<el-tag style="margin-left: 8px"
                      :type="!route.status ? 'warning' : 'success'">{{ !route.status ? '草稿' : '批准' }}</el-tag></span>
            <!-- <span class="route-code">{{ route.routeCode }}</span> -->
          </div>
          <div class="route-actions">
            <el-button v-if="route.status === '1'"
            <el-button v-if="!route.status"
                       link
                       type="success"
                       @click="handleApproveRoute(route)">
@@ -31,7 +31,7 @@
              </el-icon>
              批准
            </el-button>
            <el-button v-if="route.status === '2'"
            <el-button v-if="route.status"
                       link
                       type="warning"
                       @click="handleRevokeApproveRoute(route)">
@@ -72,14 +72,14 @@
                <Document />
              </el-icon>
              <span class="meta-label">BOM:</span>
              <span class="meta-value">{{ route.bomId || '-' }}</span>
              <span class="meta-value">{{ route.bomNo || '-' }}</span>
            </span>
            <span class="meta-item">
              <el-icon>
                <Document />
              </el-icon>
              <span class="meta-label">路线描述:</span>
              <span class="meta-value">{{ route.routeDesc || '暂无描述' }}</span>
              <span class="meta-label">备注:</span>
              <span class="meta-value">{{ route.description || '暂无描述' }}</span>
            </span>
          </div>
          <div class="expand-btn-wrapper">
@@ -112,6 +112,13 @@
                  <div class="process-number">{{ index + 1 }}</div>
                  <div class="process-actions">
                    <el-button link
                               type="primary"
                               @click="handleEditProcessSelect(route, index, process)">
                      <el-icon>
                        <Edit />
                      </el-icon>
                    </el-button>
                    <el-button link
                               type="danger"
                               @click="handleDeleteProcess(route.id, process)">
                      <el-icon>
@@ -121,9 +128,9 @@
                  </div>
                </div>
                <div class="process-node-body">
                  <div class="process-code">{{ process.processCode }}</div>
                  <!-- <div class="process-code">{{ process.processId }}</div> -->
                  <div class="process-name">{{ process.processName }}</div>
                  <div class="process-desc">{{ process.processDesc || '暂无描述' }}</div>
                  <!-- <div class="process-desc">{{ process.remark || '暂无描述' }}</div> -->
                </div>
                <div class="process-node-footer">
                  <!-- <el-tag size="small"
@@ -135,7 +142,7 @@
                             size="small"
                             @click="toggleProcessParams(process)">
                    {{ process.expanded ? '收起参数' : '展开参数' }}
                    ({{ process.paramList?.length || 0 }})
                    ({{ process.paramCount }})
                  </el-button>
                </div>
                <div v-if="process.expanded"
@@ -156,14 +163,17 @@
                         :key="param.id"
                         class="param-item">
                      <div class="param-info">
                        <span class="param-code">{{ param.parameterCode }}</span>
                        <span class="param-name">{{ param.parameterName }}</span>
                        <span class="param-code">{{ param.paramName }}</span>
                        <!-- <span class="param-name">{{ param.paramName }}</span> -->
                        <!-- <el-tag size="small"
                                style="margin-right: 20px;"
                                :type="getParamTypeTag(param.parameterType)">
                          {{ param.parameterType }}
                        </el-tag> -->
                        <span class="param-value">标准值:{{ param.standardValue }} {{ param.unit }}</span>
                        <span v-if="param.valueMode==1"
                              class="param-value">标准值:{{ param.standardValue || "-" }} {{ param.unit }}</span>
                        <span v-else
                              class="param-value">标准值:{{ param.minValue || "-" }}-{{ param.maxValue || "-" }} {{ param.unit }}</span>
                      </div>
                      <div class="param-actions">
                        <el-button link
@@ -201,11 +211,18 @@
              <span>新增工序</span>
            </div>
          </div>
          <el-empty v-if="!route.processList || route.processList.length === 0"
                    description="暂无工序"
                    :image-size="80" />
        </div>
      </div>
    </div>
    <!-- 分页控件 -->
    <div class="pagination-container">
      <el-pagination v-model:current-page="routePage.current"
                     v-model:page-size="routePage.size"
                     :page-sizes="[10, 20, 50, 100]"
                     layout="total, sizes, prev, pager, next, jumper"
                     :total="routePage.total"
                     @size-change="handleRouteSizeChange"
                     @current-change="handleRouteCurrentChange" />
    </div>
    <!-- 工艺路线新增/编辑对话框 -->
    <el-dialog v-model="routeDialogVisible"
@@ -218,7 +235,7 @@
        <el-form-item label="产品名称"
                      prop="productModelId">
          <el-button type="primary"
                     @click="showProductSelectDialog = true">
                     @click="handleProcessProductSelectClick2">
            {{ routeForm.productName && routeForm.productModelName 
              ? `${routeForm.productName} - ${routeForm.productModelName}` 
              : '选择产品' }}
@@ -240,16 +257,12 @@
        <el-form-item label="路线编码"
                      prop="routeCode">
          <el-input v-model="routeForm.routeCode"
                    placeholder="请输入路线编码" />
                    disabled
                    placeholder="自动生成" />
        </el-form-item>
        <el-form-item label="路线名称"
                      prop="routeName">
          <el-input v-model="routeForm.routeName"
                    placeholder="请输入路线名称" />
        </el-form-item>
        <el-form-item label="路线描述"
                      prop="routeDesc">
          <el-input v-model="routeForm.routeDesc"
        <el-form-item label="备注"
                      prop="description">
          <el-input v-model="routeForm.description"
                    type="textarea"
                    :rows="3"
                    placeholder="请输入路线描述" />
@@ -283,18 +296,18 @@
               ref="processFormRef"
               label-width="120px">
        <el-form-item label="工序编码"
                      prop="processCode">
          <el-input v-model="processForm.processCode"
                      prop="no">
          <el-input v-model="processForm.no"
                    placeholder="请输入工序编码" />
        </el-form-item>
        <el-form-item label="工序名称"
                      prop="processName">
          <el-input v-model="processForm.processName"
                      prop="name">
          <el-input v-model="processForm.name"
                    placeholder="请输入工序名称" />
        </el-form-item>
        <el-form-item label="工序描述"
                      prop="processDesc">
          <el-input v-model="processForm.processDesc"
                      prop="remark">
          <el-input v-model="processForm.remark"
                    type="textarea"
                    :rows="3"
                    placeholder="请输入工序描述" />
@@ -302,8 +315,8 @@
        <el-form-item label="状态"
                      prop="status">
          <el-radio-group v-model="processForm.status">
            <el-radio label="1">启用</el-radio>
            <el-radio label="0">停用</el-radio>
            <el-radio :label="true">启用</el-radio>
            <el-radio :label="false">停用</el-radio>
          </el-radio-group>
        </el-form-item>
      </el-form>
@@ -341,20 +354,20 @@
                    border
                    highlight-current-row
                    @current-change="handleProcessSelect">
            <el-table-column prop="processCode"
            <el-table-column prop="no"
                             label="工序编号"
                             width="100" />
            <el-table-column prop="processName"
            <el-table-column prop="name"
                             label="工序名称" />
            <el-table-column prop="processDesc"
            <el-table-column prop="remark"
                             label="工序描述" />
            <el-table-column prop="status"
                             label="状态"
                             width="80">
              <template #default="scope">
                <el-tag size="small"
                        :type="scope.row.status === '1' ? 'success' : 'info'">
                  {{ scope.row.status === '1' ? '启用' : '停用' }}
                        :type="scope.row.status ? 'success' : 'info'">
                  {{ scope.row.status ? '启用' : '停用' }}
                </el-tag>
              </template>
            </el-table-column>
@@ -364,26 +377,51 @@
        <div class="process-detail-area">
          <div class="area-title">工序详情</div>
          <el-form v-if="selectedProcessItem"
                   :model="selectedProcessItem"
                   :model="processForm"
                   label-width="100px"
                   class="process-detail-form">
            <el-form-item label="工序编号">
              <span class="detail-text">{{ selectedProcessItem.processCode }}</span>
              <span class="detail-text">{{ selectedProcessItem.no }}</span>
            </el-form-item>
            <el-form-item label="工序名称">
              <span class="detail-text">{{ selectedProcessItem.processName }}</span>
              <span class="detail-text">{{ selectedProcessItem.name }}</span>
            </el-form-item>
            <el-form-item label="工序描述">
              <span class="detail-text">{{ selectedProcessItem.processDesc || '-' }}</span>
              <span class="detail-text">{{ selectedProcessItem.remark || '-' }}</span>
            </el-form-item>
            <el-form-item label="状态">
              <el-tag size="small"
                      :type="selectedProcessItem.status === '1' ? 'success' : 'info'">
                {{ selectedProcessItem.status === '1' ? '启用' : '停用' }}
                      :type="selectedProcessItem.status ? 'success' : 'info'">
                {{ selectedProcessItem.status ? '启用' : '停用' }}
              </el-tag>
            </el-form-item>
            <el-form-item label="参数数量">
              <span class="detail-text">{{ selectedProcessItem.paramCount || 0 }}个</span>
            <el-form-item label="是否质检">
              <el-tag size="small"
                      :type="selectedProcessItem.isQuality ? 'success' : 'info'">
                {{ selectedProcessItem.isQuality ? '质检' : '非质检' }}
              </el-tag>
            </el-form-item>
            <el-form-item label="产品名称"
                          prop="productModelId">
              <el-button type="primary"
                         @click="handleProcessProductSelectClick">
                {{ processForm.productName && processForm.model
                  ? `${processForm.productName} - ${processForm.model}`
                  : '选择产品' }}
              </el-button>
            </el-form-item>
            <el-form-item label="单位"
                          prop="unit">
              <el-input v-model="processForm.unit"
                        :placeholder="processForm.productModelId ? '根据选择的产品自动带出' : '请先选择产品' "
                        clearable
                        :disabled="true" />
            </el-form-item>
            <el-form-item label="是否质检"
                          prop="isQuality">
              <el-switch v-model="processForm.isQuality"
                         :active-value="true"
                         inactive-value="false" />
            </el-form-item>
          </el-form>
          <el-empty v-else
@@ -394,7 +432,7 @@
        <span class="dialog-footer">
          <el-button @click="selectProcessDialogVisible = false">取消</el-button>
          <el-button type="primary"
                     :disabled="!selectedProcessItem"
                     :disabled="!selectedProcessItem || !processForm.productModelId"
                     @click="handleProcessSelectSubmit">确定</el-button>
        </span>
      </template>
@@ -489,11 +527,203 @@
        </span>
      </template>
    </el-dialog>
    <!-- 选择参数对话框 -->
    <el-dialog v-model="selectParamDialogVisible"
               title="选择参数"
               width="1000px">
      <div class="param-select-container">
        <!-- 左侧参数列表 -->
        <div class="param-list-area">
          <div class="area-title">可选参数</div>
          <div class="search-box">
            <el-input v-model="paramSearchKeyword"
                      placeholder="请输入参数名称搜索"
                      clearable
                      size="small"
                      @input="handleParamSearch">
              <template #prefix>
                <el-icon>
                  <Search />
                </el-icon>
              </template>
            </el-input>
          </div>
          <el-table :data="filteredParamList"
                    height="300"
                    border
                    highlight-current-row
                    @current-change="handleParamSelect">
            <el-table-column prop="paramName"
                             label="参数名称" />
            <el-table-column prop="paramType"
                             label="参数类型">
              <template #default="scope">
                <el-tag size="small"
                        :type="getParamTypeTag(scope.row.paramType)">
                  {{ getParamTypeText(scope.row.paramType) }}
                </el-tag>
              </template>
            </el-table-column>
          </el-table>
          <!-- 分页控件 -->
          <div class="pagination-container"
               style="margin-top: 10px;">
            <el-pagination v-model:current-page="paramPage.current"
                           v-model:page-size="paramPage.size"
                           :page-sizes="[10, 20, 50, 100]"
                           layout="total, sizes, prev, pager, next, jumper"
                           :total="paramPage.total"
                           @size-change="handleParamSizeChange"
                           @current-change="handleParamCurrentChange"
                           size="small" />
          </div>
        </div>
        <!-- 右侧参数详情 -->
        <div class="param-detail-area">
          <div class="area-title">参数详情</div>
          <el-form v-if="selectedParam"
                   :model="selectedParam"
                   label-width="100px"
                   class="param-detail-form">
            <el-form-item label="参数名称">
              <span class="detail-text">{{ selectedParam.paramName }}</span>
            </el-form-item>
            <el-form-item label="参数模式">
              <el-tag size="small"
                      :type="selectedParam.valueMode == '1' ? 'success' : 'warning'">
                {{ selectedParam.valueMode == '1' ? '单值' : '区间' }}
              </el-tag>
            </el-form-item>
            <el-form-item label="参数类型">
              <el-tag size="small"
                      :type="getParamTypeTag(selectedParam.paramType)">
                {{ getParamTypeText(selectedParam.paramType) }}
              </el-tag>
            </el-form-item>
            <el-form-item label="参数格式">
              <span class="detail-text">{{ selectedParam.paramFormat || '-' }}</span>
            </el-form-item>
            <el-form-item label="单位">
              <span class="detail-text">{{ selectedParam.unit || '-' }}</span>
            </el-form-item>
            <el-form-item label="标准值"
                          v-if="selectedParam.valueMode == '1' && selectedParam.paramType == '1'">
              <el-input v-model="selectedParam.standardValue"
                        type="number"
                        placeholder="请输入默认值" />
            </el-form-item>
            <el-form-item label="最小值"
                          v-if="selectedParam.valueMode == '2' && selectedParam.paramType == '1'">
              <el-input v-model="selectedParam.minValue"
                        type="number"
                        placeholder="请输入最小值" />
            </el-form-item>
            <el-form-item label="最大值"
                          v-if="selectedParam.valueMode == '2' && selectedParam.paramType == '1'">
              <el-input v-model="selectedParam.maxValue"
                        type="number"
                        placeholder="请输入最大值" />
            </el-form-item>
            <el-form-item label="排序">
              <el-input v-model="selectedParam.sort"
                        type="number"
                        placeholder="请输入排序" />
            </el-form-item>
            <el-form-item label="是否必填">
              <el-switch v-model="selectedParam.isRequired"
                         :active-value="1"
                         :inactive-value="0" />
            </el-form-item>
          </el-form>
          <el-empty v-else
                    description="请从左侧选择参数" />
        </div>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="selectParamDialogVisible = false">取消</el-button>
          <el-button type="primary"
                     :disabled="!selectedParam"
                     @click="handleParamSelectSubmit">确定</el-button>
        </span>
      </template>
    </el-dialog>
    <!-- 编辑参数对话框 -->
    <el-dialog v-model="editParamDialogVisible"
               title="编辑参数"
               width="600px">
      <el-form :model="editParamForm"
               :rules="editParamRules"
               ref="editParamFormRef"
               label-width="120px">
        <el-form-item label="参数名称">
          <span class="detail-text">{{ editParamForm.paramName }}</span>
        </el-form-item>
        <el-form-item label="参数模式">
          <el-tag size="small"
                  :type="editParamForm.valueMode == '1' ? 'success' : 'warning'">
            {{ editParamForm.valueMode == '1' ? '单值' : '区间' }}
          </el-tag>
        </el-form-item>
        <el-form-item label="参数类型">
          <el-tag size="small"
                  :type="getParamTypeTag(editParamForm.paramType)">
            {{ getParamTypeText(editParamForm.paramType) }}
          </el-tag>
        </el-form-item>
        <el-form-item label="参数格式">
          <span class="detail-text">{{ editParamForm.paramFormat || '-' }}</span>
        </el-form-item>
        <el-form-item label="单位">
          <span class="detail-text">{{ editParamForm.unit || '-' }}</span>
        </el-form-item>
        <el-form-item label="标准值"
                      v-if="editParamForm.valueMode == '1' && editParamForm.paramType == '1'"
                      prop="standardValue">
          <el-input v-model="editParamForm.standardValue"
                    type="number"
                    placeholder="请输入标准值" />
        </el-form-item>
        <el-form-item label="最小值"
                      v-if="editParamForm.valueMode == '2' && editParamForm.paramType == '1'"
                      prop="minValue">
          <el-input v-model="editParamForm.minValue"
                    type="number"
                    placeholder="请输入最小值" />
        </el-form-item>
        <el-form-item label="最大值"
                      v-if="editParamForm.valueMode == '2' && editParamForm.paramType == '1'"
                      prop="maxValue">
          <el-input v-model="editParamForm.maxValue"
                    type="number"
                    placeholder="请输入最大值" />
        </el-form-item>
        <el-form-item label="排序"
                      prop="sort">
          <el-input v-model="editParamForm.sort"
                    type="number"
                    placeholder="请输入排序" />
        </el-form-item>
        <el-form-item label="是否必填"
                      prop="isRequired">
          <el-switch v-model="editParamForm.isRequired"
                     :active-value="1"
                     :inactive-value="0" />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="editParamDialogVisible = false">取消</el-button>
          <el-button type="primary"
                     @click="handleEditParamSubmit">确定</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>
<script setup>
  import { ref, reactive, getCurrentInstance } from "vue";
  import { ref, reactive, getCurrentInstance, onMounted } from "vue";
  import { ElMessage, ElMessageBox } from "element-plus";
  import {
    Plus,
@@ -510,11 +740,31 @@
  } from "@element-plus/icons-vue";
  import { listType } from "@/api/system/dict/type";
  import { getByModel } from "@/api/productionManagement/productBom.js";
  import { add, update, del } from "@/api/productionManagement/processRoute.js";
  import {
    addOrUpdateProcessRouteItem,
    batchDeleteProcessRouteItem,
    sortProcessRouteItem,
    findProcessRouteItemList,
    getProcessParamList,
    addProcessRouteItemParam,
    editProcessRouteItemParam,
    delProcessRouteItemParam,
  } from "@/api/productionManagement/processRouteItem.js";
  import { list as getProcessListApi } from "@/api/productionManagement/productionProcess.js";
  import { getBaseParamList } from "@/api/basicData/parameterMaintenance.js";
  import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue";
  // 工艺路线列表
  const routeList = ref([]);
  const dictTypes = ref([]);
  // 工艺路线分页
  const routePage = reactive({
    current: 1,
    size: 10,
    total: 0,
  });
  // 获取全局实例
  const { proxy } = getCurrentInstance();
@@ -534,17 +784,14 @@
    productModelName: "",
    bomId: null,
    routeCode: "",
    routeName: "",
    routeDesc: "",
    status: "1",
    description: "",
    status: true,
  });
  const routeRules = {
    productModelId: [
      { required: true, message: "请选择产品", trigger: "change" },
    ],
    bomId: [{ required: true, message: "请选择BOM", trigger: "change" }],
    routeCode: [{ required: true, message: "请输入路线编码", trigger: "blur" }],
    routeName: [{ required: true, message: "请输入路线名称", trigger: "blur" }],
  };
  // 工序对话框
@@ -554,14 +801,14 @@
  const currentRouteId = ref(null);
  const processForm = reactive({
    id: null,
    processCode: "",
    processName: "",
    processDesc: "",
    status: "1",
    no: "",
    name: "",
    remark: "",
    status: true,
  });
  const processRules = {
    processCode: [{ required: true, message: "请输入工序编码", trigger: "blur" }],
    processName: [{ required: true, message: "请输入工序名称", trigger: "blur" }],
    no: [{ required: true, message: "请输入工序编码", trigger: "blur" }],
    name: [{ required: true, message: "请输入工序名称", trigger: "blur" }],
  };
  // 选择工序对话框
@@ -599,133 +846,209 @@
    ],
  };
  // 选择参数对话框
  const selectParamDialogVisible = ref(false);
  const availableParamList = ref([]);
  const filteredParamList = ref([]);
  const selectedParam = ref(null);
  const paramSearchKeyword = ref("");
  // 可选参数分页
  const paramPage = reactive({
    current: 1,
    size: 10,
    total: 0,
  });
  // 编辑参数对话框
  const editParamDialogVisible = ref(false);
  const editParamFormRef = ref(null);
  const editParamForm = reactive({
    id: null,
    processId: null,
    paramId: null,
    paramName: "",
    valueMode: "1",
    standardValue: null,
    minValue: null,
    maxValue: null,
    sort: 1,
    isRequired: 0,
  });
  const editParamRules = reactive({
    standardValue: [
      {
        required: true,
        message: "请输入标准值",
        trigger: "blur",
        validator: (rule, value, callback) => {
          if (value === null || value === undefined || value === "") {
            callback(new Error("请输入标准值"));
          } else {
            callback();
          }
        },
      },
    ],
    minValue: [
      {
        required: true,
        message: "请输入最小值",
        trigger: "blur",
        validator: (rule, value, callback) => {
          if (value === null || value === undefined || value === "") {
            callback(new Error("请输入最小值"));
          } else {
            callback();
          }
        },
      },
    ],
    maxValue: [
      {
        required: true,
        message: "请输入最大值",
        trigger: "blur",
        validator: (rule, value, callback) => {
          if (value === null || value === undefined || value === "") {
            callback(new Error("请输入最大值"));
          } else {
            callback();
          }
        },
      },
    ],
    sort: [
      {
        required: true,
        message: "请输入排序",
        trigger: "blur",
        validator: (rule, value, callback) => {
          if (value === null || value === undefined || value === "") {
            callback(new Error("请输入排序"));
          } else if (isNaN(value) || value < 1) {
            callback(new Error("排序必须是大于0的整数"));
          } else {
            callback();
          }
        },
      },
    ],
  });
  // 拖拽相关
  const draggedItem = ref(null);
  const draggedRouteId = ref(null);
  // 获取工艺路线列表
  const getRouteList = () => {
    routeList.value = [
      {
        id: 1,
        productModelId: 1,
        productName: "标准砌块",
        productModelName: "3.5型",
        bomId: 1,
        routeCode: "ROUTE001",
        routeName: "标准砌块生产线",
        routeDesc: "标准砌块生产流程",
        status: "1",
        expanded: false,
        processList: [
          {
            id: 1,
            processCode: "PROC001",
            processName: "原料配比",
            processDesc: "原材料配比工序",
            status: "1",
    // 导入 listPage 方法
    import("@/api/productionManagement/processRoute.js").then(({ listPage }) => {
      listPage({ pageNum: routePage.current, pageSize: routePage.size })
        .then(res => {
          // 处理返回的数据,映射到页面需要的格式
          routeList.value = (res.data?.records || []).map(item => ({
            id: item.id,
            productModelId: item.productModelId,
            productName: item.productName,
            productModelName: item.model || item.productModelName,
            bomId: item.bomId,
            bomNo: item.bomNo,
            routeCode: item.processRouteCode || item.routeCode,
            description: item.description || item.description,
            status: item.status,
            expanded: false,
            paramList: [
              {
                id: 1,
                parameterCode: "P001",
                parameterName: "水泥比例",
                parameterType2: "1",
                parameterType: "数值格式",
                parameterFormat: "",
                standardValue: "30",
                unit: "%",
              },
              {
                id: 2,
                parameterCode: "P002",
                parameterName: "砂比例",
                parameterType2: "1",
                parameterType: "数值格式",
                parameterFormat: "",
                standardValue: "60",
                unit: "%",
              },
            ],
          },
          {
            id: 2,
            processCode: "PROC002",
            processName: "搅拌混合",
            processDesc: "搅拌混合工序",
            status: "1",
            expanded: false,
            paramList: [
              {
                id: 3,
                parameterCode: "P003",
                parameterName: "搅拌时间",
                parameterType2: "1",
                parameterType: "数值格式",
                parameterFormat: "",
                standardValue: "5",
                unit: "分钟",
              },
            ],
          },
          {
            id: 3,
            processCode: "PROC003",
            processName: "浇筑成型",
            processDesc: "浇筑成型工序",
            status: "1",
            expanded: false,
            paramList: [],
          },
        ],
      },
      {
        id: 2,
        productModelId: 2,
        productName: "板材",
        productModelName: "5.0型",
        bomId: 2,
        routeCode: "ROUTE002",
        routeName: "板材生产线",
        routeDesc: "板材生产流程",
        status: "1",
        expanded: false,
        processList: [
          {
            id: 4,
            processCode: "PROC004",
            processName: "切割加工",
            processDesc: "切割加工工序",
            status: "1",
            expanded: false,
            paramList: [
              {
                id: 4,
                parameterCode: "P004",
                parameterName: "切割尺寸",
                parameterType2: "1",
                parameterType: "文本格式",
                parameterFormat: "",
                standardValue: "600x200x100",
                unit: "mm",
              },
            ],
          },
        ],
      },
    ];
            processList: (item.processList || []).map(process => ({
              ...process,
              processId: process.processId || process.id,
              expanded: false,
            })),
          }));
          // 更新分页总数
          routePage.total = res.data?.total || 0;
        })
        .catch(err => {
          console.error("获取工艺路线列表失败:", err);
          routeList.value = [];
          routePage.total = 0;
        });
    });
  };
  // 展开/收起工艺路线
  const toggleExpand = route => {
    route.expanded = !route.expanded;
    if (route.expanded) {
      // 调用接口获取工序列表
      findProcessRouteItemList({ routeId: route.id })
        .then(res => {
          route.processList = (res.data || []).map(process => ({
            ...process,
            processId: process.processId || process.id,
            expanded: false,
          }));
        })
        .catch(err => {
          console.error("获取工序列表失败:", err);
          route.processList = [];
        });
    }
  };
  // 展开/收起工序参数
  const toggleProcessParams = process => {
    process.expanded = !process.expanded;
    if (process.expanded && process.id) {
      // 调用接口获取参数列表
      getProcessParamList({
        routeItemId: process.id,
        pageNum: 1,
        pageSize: 1000,
      })
        .then(res => {
          if (res.code === 200) {
            process.paramList = res.data?.records || [];
            process.paramCount = process.paramList.length;
          } else {
            ElMessage.error(res.msg || "获取参数列表失败");
            process.paramList = [];
            process.paramCount = 0;
          }
        })
        .catch(err => {
          console.error("获取参数列表失败:", err);
          ElMessage.error("获取参数列表失败");
          process.paramList = [];
          process.paramCount = 0;
        });
    }
  };
  const toggleProcessParams2 = process => {
    if (process.expanded && process.id) {
      // 调用接口获取参数列表
      getProcessParamList({
        routeItemId: process.id,
        pageNum: 1,
        pageSize: 1000,
      })
        .then(res => {
          if (res.code === 200) {
            process.paramList = res.data?.records || [];
            process.paramCount = process.paramList.length;
          } else {
            ElMessage.error(res.msg || "获取参数列表失败");
            process.paramList = [];
            process.paramCount = 0;
          }
        })
        .catch(err => {
          console.error("获取参数列表失败:", err);
          ElMessage.error("获取参数列表失败");
          process.paramList = [];
          process.paramCount = 0;
        });
    }
  };
  // 工艺路线操作
  const handleAddRoute = () => {
    isRouteEdit.value = false;
@@ -735,9 +1058,8 @@
    routeForm.productModelName = "";
    routeForm.bomId = null;
    routeForm.routeCode = "";
    routeForm.routeName = "";
    routeForm.routeDesc = "";
    routeForm.status = "1";
    routeForm.description = "";
    routeForm.status = false;
    bomOptions.value = [];
    routeDialogVisible.value = true;
  };
@@ -750,8 +1072,7 @@
    routeForm.productModelName = route.productModelName;
    routeForm.bomId = route.bomId;
    routeForm.routeCode = route.routeCode;
    routeForm.routeName = route.routeName;
    routeForm.routeDesc = route.routeDesc;
    routeForm.description = route.description;
    routeForm.status = route.status;
    routeDialogVisible.value = true;
  };
@@ -762,53 +1083,115 @@
      cancelButtonText: "取消",
      type: "warning",
    }).then(() => {
      ElMessage.success("删除成功");
      getRouteList();
      del(route.id)
        .then(res => {
          ElMessage.success("删除成功");
          getRouteList();
        })
        .catch(err => {
          ElMessage.error("删除失败");
        });
    });
  };
  const handleRouteSubmit = () => {
    routeFormRef.value.validate(valid => {
      if (valid) {
        ElMessage.success(isRouteEdit.value ? "编辑成功" : "新增成功");
        routeDialogVisible.value = false;
        getRouteList();
        // 构建提交数据
        const submitData = {
          ...routeForm,
          // 注意:API 期望的字段名可能与表单字段名不同
          productId: routeForm.productModelId,
          productModelId: routeForm.productModelId,
          description: routeForm.description,
        };
        if (isRouteEdit.value) {
          // 编辑操作
          update(submitData)
            .then(res => {
              ElMessage.success("编辑成功");
              routeDialogVisible.value = false;
              getRouteList();
            })
            .catch(err => {
              ElMessage.error("编辑失败");
            });
        } else {
          // 新增操作
          add(submitData)
            .then(res => {
              ElMessage.success("新增成功");
              routeDialogVisible.value = false;
              getRouteList();
            })
            .catch(err => {
              ElMessage.error("新增失败");
            });
        }
      }
    });
  };
  const isform2 = ref(null);
  const handleProcessProductSelectClick = () => {
    isform2.value = true;
    showProductSelectDialog.value = true;
  };
  const handleProcessProductSelectClick2 = () => {
    isform2.value = false;
    showProductSelectDialog.value = true;
  };
  // 产品选择处理
  const handleProductSelect = async products => {
    if (products && products.length > 0) {
      const product = products[0];
      // 先查询BOM列表(必选)
      try {
        const res = await getByModel(product.id);
        // 处理返回的BOM数据:可能是数组、对象或包含data字段
        let bomList = [];
        if (Array.isArray(res)) {
          bomList = res;
        } else if (res && res.data) {
          bomList = Array.isArray(res.data) ? res.data : [res.data];
        } else if (res && typeof res === "object") {
          bomList = [res];
        }
    if (isform2.value) {
      // 帮我写工序中的选择产品的回调,并且把字段加进processForm
      if (products && products.length > 0) {
        const product = products[0];
        console.log("product:", product);
        // 把product中的字段添加到processForm中
        // Object.assign(processForm, product);
        processForm.productModelId = product.id;
        processForm.productName = product.productName;
        processForm.model = product.model;
        processForm.unit = product.unit || "";
        console.log("processForm:", processForm);
        if (bomList.length > 0) {
          routeForm.productModelId = product.id;
          routeForm.productName = product.productName;
          routeForm.productModelName = product.model;
          routeForm.bomId = undefined; // 重置BOM选择
          bomOptions.value = bomList;
          showProductSelectDialog.value = false;
          // 触发表单验证更新
          proxy.$refs["routeFormRef"]?.validateField("productModelId");
        } else {
        // 触发表单验证更新
        proxy.$refs["processFormRef"]?.validateField("productModelId");
      }
    } else {
      if (products && products.length > 0) {
        const product = products[0];
        // 先查询BOM列表(必选)
        try {
          const res = await getByModel(product.id);
          // 处理返回的BOM数据:可能是数组、对象或包含data字段
          let bomList = [];
          if (Array.isArray(res)) {
            bomList = res;
          } else if (res && res.data) {
            bomList = Array.isArray(res.data) ? res.data : [res.data];
          } else if (res && typeof res === "object") {
            bomList = [res];
          }
          console.log("bomList:", bomList);
          if (bomList.length > 0) {
            routeForm.productModelId = product.id;
            routeForm.productName = product.productName;
            routeForm.productModelName = product.model;
            routeForm.bomId = undefined; // 重置BOM选择
            bomOptions.value = bomList;
            showProductSelectDialog.value = false;
            // 触发表单验证更新
            proxy.$refs["routeFormRef"]?.validateField("productModelId");
          } else {
            proxy.$modal.msgError("该产品没有BOM,请先创建BOM");
          }
        } catch (error) {
          // 如果接口返回404或其他错误,说明没有BOM
          proxy.$modal.msgError("该产品没有BOM,请先创建BOM");
        }
      } catch (error) {
        // 如果接口返回404或其他错误,说明没有BOM
        proxy.$modal.msgError("该产品没有BOM,请先创建BOM");
      }
    }
  };
@@ -819,8 +1202,15 @@
      cancelButtonText: "取消",
      type: "info",
    }).then(() => {
      route.status = "2";
      ElMessage.success("批准成功");
      // 调用修改接口,只修改status字段为批准状态
      update({ id: route.id, status: true })
        .then(res => {
          ElMessage.success("批准成功");
          getRouteList();
        })
        .catch(err => {
          ElMessage.error("批准失败");
        });
    });
  };
@@ -830,61 +1220,56 @@
      cancelButtonText: "取消",
      type: "warning",
    }).then(() => {
      route.status = "1";
      ElMessage.success("撤销批准成功");
      // 调用修改接口,只修改status字段为草稿状态
      update({ id: route.id, status: false })
        .then(res => {
          ElMessage.success("撤销批准成功");
          getRouteList();
        })
        .catch(err => {
          ElMessage.error("撤销批准失败");
        });
    });
  };
  // 工序操作
  const handleSelectProcess = (route, index) => {
    console.log("route:", route);
    currentRouteId.value = route.id;
    currentRouteIndex.value = index;
    // 获取可选工序列表(假数据)
    availableProcessList.value = [
      {
        id: 1,
        processCode: "PROC001",
        processName: "原料配比",
        processDesc: "原材料配比工序",
        status: "1",
        paramCount: 3,
      },
      {
        id: 2,
        processCode: "PROC002",
        processName: "搅拌混合",
        processDesc: "搅拌混合工序",
        status: "1",
        paramCount: 2,
      },
      {
        id: 3,
        processCode: "PROC003",
        processName: "浇筑成型",
        processDesc: "浇筑成型工序",
        status: "1",
        paramCount: 4,
      },
      {
        id: 4,
        processCode: "PROC004",
        processName: "蒸压养护",
        processDesc: "蒸压养护工序",
        status: "0",
        paramCount: 2,
      },
      {
        id: 5,
        processCode: "PROC005",
        processName: "切割加工",
        processDesc: "切割加工工序",
        status: "1",
        paramCount: 3,
      },
    ];
    // 重置搜索和选择状态
    filteredProcessList.value = availableProcessList.value;
    processSearchKeyword.value = "";
    selectedProcessItem.value = null;
    selectProcessDialogVisible.value = true;
  };
  const dragSort = ref(0);
  const currentId = ref(null);
  // 修改工序
  const handleEditProcessSelect = (route, index, process) => {
    console.log("route:", route);
    console.log("process:", process);
    currentId.value = process.id;
    currentRouteId.value = route.id;
    currentRouteIndex.value = index;
    // 重置搜索和选择状态
    filteredProcessList.value = availableProcessList.value;
    processSearchKeyword.value = "";
    // 设置选中的工序
    filteredProcessList.value.map(item => {
      if (item.id === process.processId) {
        selectedProcessItem.value = item;
      }
    });
    dragSort.value = process.dragSort;
    // selectedProcessItem.value = process;
    // 填充产品选择表单
    processForm.productModelId = process.productModelId;
    processForm.productName = process.productName;
    processForm.model = process.model;
    processForm.processId = process.no;
    // processForm.name = process.name;
    processForm.unit = process.unit || "";
    processForm.isQuality = process.isQuality || false;
    selectProcessDialogVisible.value = true;
  };
@@ -892,9 +1277,9 @@
    currentRouteId.value = routeId;
    isProcessEdit.value = true;
    processForm.id = process.id;
    processForm.processCode = process.processCode;
    processForm.processName = process.processName;
    processForm.processDesc = process.processDesc;
    processForm.no = process.no;
    processForm.name = process.name;
    processForm.remark = process.remark;
    processForm.status = process.status;
    processDialogVisible.value = true;
  };
@@ -905,8 +1290,30 @@
      cancelButtonText: "取消",
      type: "warning",
    }).then(() => {
      ElMessage.success("删除成功");
      getRouteList();
      // 调用API删除工序
      batchDeleteProcessRouteItem([process.id])
        .then(res => {
          ElMessage.success("删除成功");
          // 调用接口更新工序列表
          findProcessRouteItemList({ routeId: routeId })
            .then(res => {
              const route = routeList.value.find(r => r.id === routeId);
              if (route) {
                route.processList = (res.data || []).map(process => ({
                  ...process,
                  processId: process.processId || process.id,
                  expanded: false,
                }));
              }
            })
            .catch(err => {
              console.error("获取工序列表失败:", err);
            });
        })
        .catch(err => {
          ElMessage.error("删除失败");
          console.error("删除工序失败:", err);
        });
    });
  };
@@ -915,7 +1322,25 @@
      if (valid) {
        ElMessage.success(isProcessEdit.value ? "编辑成功" : "新增成功");
        processDialogVisible.value = false;
        getRouteList();
        // 调用接口更新工序列表
        if (currentRouteId.value) {
          findProcessRouteItemList({ routeId: currentRouteId.value })
            .then(res => {
              const route = routeList.value.find(
                r => r.id === currentRouteId.value
              );
              if (route) {
                route.processList = (res.data || []).map(process => ({
                  ...process,
                  processId: process.processId || process.id,
                  expanded: false,
                }));
              }
            })
            .catch(err => {
              console.error("获取工序列表失败:", err);
            });
        }
      }
    });
  };
@@ -926,14 +1351,34 @@
    if (!keyword) {
      filteredProcessList.value = availableProcessList.value;
    } else {
      filteredProcessList.value = availableProcessList.value.filter(item =>
        item.processName.toLowerCase().includes(keyword)
      filteredProcessList.value = availableProcessList.value.filter(
        item =>
          (item.name && item.name.toLowerCase().includes(keyword)) ||
          (item.no && item.no.toLowerCase().includes(keyword))
      );
    }
  };
  const handleProcessSelect = row => {
    selectedProcessItem.value = row;
    // 重置产品选择表单
    processForm.productModelId = undefined;
    processForm.productName = "";
    processForm.productModelName = "";
    processForm.unit = "";
    processForm.isQuality = row.isQuality || false;
  };
  // 处理工序选择时的产品选择
  const handleProcessProductSelect = async products => {
    if (products && products.length > 0) {
      const product = products[0];
      processForm.productModelId = product.id;
      processForm.productName = product.productName;
      processForm.productModelName = product.model;
      processForm.unit = product.unit || "";
      showProductSelectDialog.value = false;
    }
  };
  const handleProcessSelectSubmit = () => {
@@ -942,61 +1387,101 @@
      return;
    }
    // 检查工序是否已存在
    const route = routeList.value[currentRouteIndex.value];
    const exists = route.processList.some(
      p => p.id === selectedProcessItem.value.id
    );
    if (exists) {
      ElMessage.warning("该工序已存在于工艺路线中");
    if (!processForm.productModelId) {
      ElMessage.warning("请选择产品");
      return;
    }
    // 添加工序到工艺路线
    const newProcess = {
      id: Date.now(),
      processCode: selectedProcessItem.value.processCode,
      processName: selectedProcessItem.value.processName,
      processDesc: selectedProcessItem.value.processDesc,
      status: selectedProcessItem.value.status,
      paramList: [],
      expanded: false,
    // 构建请求参数
    const params = {
      routeId: currentRouteId.value,
      processId: selectedProcessItem.value.id,
      dragSort: routePage.total + 1,
      ...processForm,
    };
    route.processList.push(newProcess);
    ElMessage.success("添加工序成功");
    selectProcessDialogVisible.value = false;
    // 如果是修改操作,添加id参数
    if (selectedProcessItem.value.id) {
      params.id = currentId.value;
      params.dragSort = dragSort.value;
    }
    // 调用API添加工序或修改工序
    addOrUpdateProcessRouteItem(params)
      .then(res => {
        ElMessage.success(
          selectedProcessItem.value.id ? "修改工序成功" : "添加工序成功"
        );
        selectProcessDialogVisible.value = false;
        // 调用接口更新工序列表
        findProcessRouteItemList({ routeId: currentRouteId.value })
          .then(res => {
            const route = routeList.value.find(
              r => r.id === currentRouteId.value
            );
            if (route) {
              route.processList = (res.data || []).map(process => ({
                ...process,
                processId: process.processId || process.id,
                expanded: false,
              }));
            }
          })
          .catch(err => {
            console.error("获取工序列表失败:", err);
          });
      })
      .catch(err => {
        ElMessage.error(
          selectedProcessItem.value.id ? "修改工序失败" : "添加工序失败"
        );
        console.error(
          selectedProcessItem.value.id ? "修改工序失败:" : "添加工序失败:",
          err
        );
      });
  };
  // 参数操作
  const handleAddParam = (routeId, process) => {
    currentRouteId.value = routeId;
    currentProcessId.value = process.id;
    isParamEdit.value = false;
    paramForm.id = null;
    paramForm.parameterCode = "";
    paramForm.parameterName = "";
    paramForm.parameterType2 = "1";
    paramForm.parameterType = "";
    paramForm.parameterFormat = "";
    paramForm.standardValue = "";
    paramForm.unit = "";
    paramDialogVisible.value = true;
    selectedParam.value = null;
    paramSearchKeyword.value = "";
    paramPage.current = 1;
    // 获取可选参数列表
    getBaseParamList({
      paramName: paramSearchKeyword.value,
      current: paramPage.current,
      size: paramPage.size,
    }).then(res => {
      if (res.code === 200) {
        filteredParamList.value = res.data?.records || [];
        paramPage.total = res.data?.total || 0;
      } else {
        ElMessage.error(res.msg || "查询失败");
      }
    });
    selectParamDialogVisible.value = true;
  };
  const handleEditParam = (routeId, process, param) => {
    currentRouteId.value = routeId;
    currentProcessId.value = process.id;
    isParamEdit.value = true;
    paramForm.id = param.id;
    paramForm.parameterCode = param.parameterCode;
    paramForm.parameterName = param.parameterName;
    paramForm.parameterType2 = param.parameterType2 || "1";
    paramForm.parameterType = param.parameterType;
    paramForm.parameterFormat = param.parameterFormat;
    paramForm.standardValue = param.standardValue;
    paramForm.unit = param.unit;
    paramDialogVisible.value = true;
    editParamForm.id = param.id;
    editParamForm.processId = process.id;
    editParamForm.paramId = param.paramId;
    editParamForm.paramName = param.parameterName || param.paramName;
    editParamForm.valueMode = param.parameterType2 || param.valueMode || "1";
    editParamForm.standardValue = param.standardValue;
    editParamForm.minValue = param.minValue;
    editParamForm.maxValue = param.maxValue;
    editParamForm.sort = param.sort || 1;
    editParamForm.isRequired = param.isRequired || 0;
    editParamForm.paramType = param.parameterType || param.paramType;
    editParamForm.paramFormat = param.parameterFormat || param.paramFormat;
    editParamForm.unit = param.unit || param.unit;
    editParamDialogVisible.value = true;
  };
  const handleDeleteParam = (routeId, process, param) => {
@@ -1005,8 +1490,17 @@
      cancelButtonText: "取消",
      type: "warning",
    }).then(() => {
      ElMessage.success("删除成功");
      getRouteList();
      // 调用API删除参数
      delProcessRouteItemParam(param.id)
        .then(res => {
          ElMessage.success("删除成功");
          // 刷新参数列表
          toggleProcessParams2(process);
        })
        .catch(err => {
          ElMessage.error("删除参数失败");
          console.error("删除参数失败:", err);
        });
    });
  };
@@ -1032,12 +1526,178 @@
  const getParamTypeTag = type => {
    const typeMap = {
      数值格式: "primary",
      文本格式: "info",
      下拉选项: "warning",
      时间格式: "success",
      1: "primary",
      2: "info",
      3: "warning",
      4: "success",
    };
    return typeMap[type] || "default";
  };
  const getParamTypeText = type => {
    const typeMap = {
      1: "数值格式",
      2: "文本格式",
      3: "下拉选项",
      4: "时间格式",
    };
    return typeMap[type] || "未知参数类型";
  };
  // 选择参数相关方法
  const handleParamSearch = () => {
    // 重置分页
    paramPage.current = 1;
    // 重新加载数据
    getBaseParamList({
      paramName: paramSearchKeyword.value,
      current: paramPage.current,
      size: paramPage.size,
    }).then(res => {
      if (res.code === 200) {
        filteredParamList.value = res.data?.records || [];
        paramPage.total = res.data?.total || 0;
      } else {
        ElMessage.error(res.msg || "查询失败");
      }
    });
  };
  const handleParamSelect = row => {
    selectedParam.value = row;
  };
  // 处理分页大小变化
  const handleParamSizeChange = size => {
    paramPage.size = size;
    getBaseParamList({
      paramName: paramSearchKeyword.value,
      current: paramPage.current,
      size: paramPage.size,
    }).then(res => {
      if (res.code === 200) {
        filteredParamList.value = res.data?.records || [];
        paramPage.total = res.data?.total || 0;
      } else {
        ElMessage.error(res.msg || "查询失败");
      }
    });
  };
  // 处理当前页码变化
  const handleParamCurrentChange = current => {
    paramPage.current = current;
    getBaseParamList({
      paramName: paramSearchKeyword.value,
      current: paramPage.current,
      size: paramPage.size,
    }).then(res => {
      if (res.code === 200) {
        filteredParamList.value = res.data?.records || [];
        paramPage.total = res.data?.total || 0;
      } else {
        ElMessage.error(res.msg || "查询失败");
      }
    });
  };
  // 工艺路线分页处理
  const handleRouteSizeChange = size => {
    routePage.size = size;
    getRouteList();
  };
  const handleRouteCurrentChange = current => {
    routePage.current = current;
    getRouteList();
  };
  const handleParamSelectSubmit = () => {
    if (!selectedParam.value) {
      ElMessage.warning("请先选择一个参数");
      return;
    }
    // 找到对应的工艺路线和工序
    const route = routeList.value.find(r => r.id === currentRouteId.value);
    const process = route?.processList.find(p => p.id === currentProcessId.value);
    if (route && process) {
      // 检查参数是否已存在
      // const exists = process.paramList?.some(
      //   p =>
      //     p.paramId === selectedParam.value.id ||
      //     p.parameterCode === selectedParam.value.paramCode
      // );
      // if (exists) {
      //   ElMessage.warning("该参数已存在于工序中");
      //   return;
      // }
      // 判断参数类型,只有数值类型才传标准值、最大值和最小值
      const isNumericMode = selectedParam.value.valueMode === 1;
      // 调用API新增参数
      addProcessRouteItemParam({
        routeItemId: process.id,
        paramId: selectedParam.value.id,
        standardValue: isNumericMode
          ? selectedParam.value.standardValue || ""
          : "",
        minValue: isNumericMode ? selectedParam.value.minValue || 0 : null,
        maxValue: isNumericMode ? selectedParam.value.maxValue || 0 : null,
        isRequired: selectedParam.value.isRequired || 0,
      })
        .then(res => {
          ElMessage.success("添加参数成功");
          selectParamDialogVisible.value = false;
          // 刷新参数列表
          toggleProcessParams2(process);
        })
        .catch(err => {
          ElMessage.error("添加参数失败");
          console.error("添加参数失败:", err);
        });
    }
  };
  const handleEditParamSubmit = () => {
    editParamFormRef.value.validate(valid => {
      if (valid) {
        // 判断参数类型,只有数值类型才传标准值、最大值和最小值
        const isNumericMode = editParamForm.valueMode == 1;
        // 调用API修改参数
        editProcessRouteItemParam({
          id: editParamForm.id,
          routeItemId: currentProcessId.value,
          paramId: editParamForm.paramId,
          standardValue: isNumericMode ? editParamForm.standardValue || "" : "",
          minValue: isNumericMode ? editParamForm.minValue || 0 : null,
          maxValue: isNumericMode ? editParamForm.maxValue || 0 : null,
          isRequired: editParamForm.isRequired || 0,
        })
          .then(res => {
            ElMessage.success("编辑成功");
            editParamDialogVisible.value = false;
            // 找到对应的工艺路线和工序
            const route = routeList.value.find(
              r => r.id === currentRouteId.value
            );
            const process = route?.processList.find(
              p => p.id === currentProcessId.value
            );
            // 刷新参数列表
            if (process) {
              toggleProcessParams2(process);
            }
          })
          .catch(err => {
            ElMessage.error("编辑参数失败");
            console.error("编辑参数失败:", err);
          });
      }
    });
  };
  // 拖拽排序
@@ -1059,9 +1719,37 @@
    const route = routeList.value.find(r => r.id === routeId);
    if (route && route.processList) {
      const draggedProcess = route.processList[draggedItem.value];
      route.processList.splice(draggedItem.value, 1);
      route.processList.splice(dropIndex, 0, draggedProcess);
      ElMessage.success("排序成功");
      // 计算新的排序值
      const newDragSort = dropIndex + 1;
      // 调用API排序工序
      sortProcessRouteItem({
        id: draggedProcess.id,
        dragSort: newDragSort,
      })
        .then(res => {
          // 调用接口获取最新的工序列表
          findProcessRouteItemList({ routeId: routeId })
            .then(res => {
              if (route) {
                route.processList = (res.data || []).map(process => ({
                  ...process,
                  processId: process.processId || process.id,
                  expanded: false,
                }));
              }
              ElMessage.success("排序成功");
            })
            .catch(err => {
              console.error("获取工序列表失败:", err);
              ElMessage.success("排序成功");
            });
        })
        .catch(err => {
          ElMessage.error("排序失败");
          console.error("排序工序失败:", err);
        });
    }
  };
@@ -1079,13 +1767,35 @@
  getRouteList();
  getDictTypes();
  // 页面加载时获取工序列表
  onMounted(() => {
    getProcessListApi()
      .then(res => {
        // 处理返回的数据,映射到页面需要的格式
        availableProcessList.value = (res.data || []).map(item => ({
          id: item.id,
          no: item.no || item.no,
          name: item.name || item.name,
          remark: item.remark || item.remark,
          status: item.status,
          isQuality: item.isQuality,
        }));
        filteredProcessList.value = availableProcessList.value;
      })
      .catch(() => {
        ElMessage.error("获取工序列表失败");
      });
  });
</script>
<style scoped lang="scss">
  .app-container {
    padding: 20px;
    padding-bottom: 80px;
    background-color: #f0f2f5;
    min-height: calc(100vh - 84px);
    overflow: hidden;
  }
  .route-header {
@@ -1125,9 +1835,31 @@
  }
  .route-card-list {
    display: flex;
    flex-direction: column;
    display: grid;
    grid-template-columns: repeat(1, 1fr);
    gap: 20px;
    max-height: calc(100vh - 240px);
    overflow-y: auto;
    padding-right: 10px;
  }
  /* 自定义滚动条样式 */
  .route-card-list::-webkit-scrollbar {
    width: 8px;
  }
  .route-card-list::-webkit-scrollbar-track {
    background: #f1f1f1;
    border-radius: 4px;
  }
  .route-card-list::-webkit-scrollbar-thumb {
    background: #c1c1c1;
    border-radius: 4px;
  }
  .route-card-list::-webkit-scrollbar-thumb:hover {
    background: #a8a8a8;
  }
  .route-card {
@@ -1473,7 +2205,7 @@
          align-items: center;
          justify-content: center;
          min-width: 100px;
          height: 175px;
          height: 137px;
          border: 2px dashed #dcdfe6;
          border-radius: 12px;
          background: #fafafa;
@@ -1570,4 +2302,116 @@
      }
    }
  }
  // 选择参数对话框样式
  .param-select-container {
    display: flex;
    gap: 20px;
    height: 450px;
    .param-list-area {
      // flex: 1;
      width: 380px;
      display: flex;
      flex-direction: column;
      .area-title {
        font-size: 14px;
        font-weight: 600;
        color: #303133;
        margin-bottom: 12px;
        padding-bottom: 8px;
        border-bottom: 1px solid #ebeef5;
      }
      .search-box {
        margin-bottom: 12px;
        .el-input {
          width: 100%;
        }
      }
    }
    .param-detail-area {
      // width: 380px;
      flex: 1;
      display: flex;
      flex-direction: column;
      background: #f5f7fa;
      border-radius: 8px;
      padding: 16px;
      .area-title {
        font-size: 14px;
        font-weight: 600;
        color: #303133;
        margin-bottom: 16px;
        padding-bottom: 8px;
        border-bottom: 1px solid #ebeef5;
      }
      .param-detail-form {
        .el-form-item {
          margin-bottom: 12px;
          .el-form-item__label {
            color: #606266;
            font-weight: 500;
          }
        }
        .detail-text {
          color: #303133;
          font-weight: 500;
        }
      }
    }
  }
  // 分页控件样式
  .pagination-container {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    display: flex;
    justify-content: flex-end;
    padding: 16px 20px;
    background-color: #fff !important;
    border-top: 1px solid #ebeef5;
    box-shadow: 0 -2px 12px 0 rgba(0, 0, 0, 0.1);
    z-index: 100;
    .el-pagination {
      .el-pagination__sizes {
        margin-right: 16px;
      }
      .el-pagination__jump {
        margin-left: 16px;
      }
      .el-pagination__total {
        color: #606266;
        font-size: 14px;
      }
      .el-pagination__button {
        border-radius: 4px;
        transition: all 0.3s ease;
        &:hover:not(:disabled) {
          color: #409eff;
          border-color: #409eff;
        }
      }
      .el-pagination__button--active {
        background-color: #409eff;
        border-color: #409eff;
        color: #fff;
      }
    }
  }
</style>
src/views/productionManagement/productStructure/Detail/index.vue
@@ -141,6 +141,8 @@
      </el-table-column>
      <el-table-column label="BOM编号"
                       prop="bomNo" />
      <el-table-column label="产品编码"
                       prop="productCode" />
      <el-table-column label="产品名称"
                       prop="productName" />
      <el-table-column label="规格型号"
@@ -192,6 +194,7 @@
  // 从路由参数获取产品信息
  const routeBomNo = computed(() => route.query.bomNo || "");
  const routeProductCode = computed(() => route.query.productCode || "");
  const routeProductName = computed(() => route.query.productName || "");
  const routeProductModelName = computed(
    () => route.query.productModelName || ""
src/views/productionManagement/productStructure/index.vue
@@ -50,7 +50,7 @@
                      prop="productModelId">
          <el-button type="primary"
                     @click="showProductSelectDialog = true">
            {{ form.productName || '选择产品' }}
            {{ form.productName || '选择产品' }}-{{ form.productModelName }}
          </el-button>
        </el-form-item>
        <el-form-item label="版本号"
@@ -132,6 +132,12 @@
      minWidth: 140,
    },
    {
      label: "产品编码",
      prop: "productCode",
      minWidth: 160,
    },
    {
      label: "产品名称",
      prop: "productName",
src/views/productionManagement/productionProcess/index.vue
@@ -70,7 +70,7 @@
          <el-button type="primary"
                     size="small"
                     :disabled="!selectedProcess"
                     @click="handleSelectParam">
                     @click="openParamDialog">
            <el-icon>
              <Plus />
            </el-icon>选择参数
@@ -167,7 +167,7 @@
            </el-input>
          </div>
          <el-table :data="filteredParamList"
                    height="360"
                    height="300"
                    border
                    highlight-current-row
                    @current-change="handleParamSelect">
@@ -183,6 +183,18 @@
              </template>
            </el-table-column>
          </el-table>
          <!-- 分页控件 -->
          <div class="pagination-container"
               style="margin-top: 10px;">
            <el-pagination v-model:current-page="paramPage.current"
                           v-model:page-size="paramPage.size"
                           :page-sizes="[10, 20, 50, 100]"
                           layout="total, sizes, prev, pager, next, jumper"
                           :total="paramPage.total"
                           @size-change="handleParamSizeChange"
                           @current-change="handleParamCurrentChange"
                           size="small" />
          </div>
        </div>
        <!-- 右侧参数详情 -->
        <div class="param-detail-area">
@@ -343,11 +355,6 @@
  // 参数列表数据
  const paramList = ref([]);
  const paramLoading = ref(false);
  const paramPage = reactive({
    current: 1,
    size: 10,
    total: 0,
  });
  // 数据字典
  const dictTypes = ref([]);
@@ -370,13 +377,11 @@
    name: [{ required: true, message: "请输入工序名称", trigger: "blur" }],
    salaryQuota: [
      {
        required: true,
        required: false,
        message: "请输入工资定额",
        trigger: "blur",
        validator: (rule, value, callback) => {
          if (value === null || value === undefined || value === "") {
            callback(new Error("请输入工资定额"));
          } else if (isNaN(value) || value < 0) {
          if (isNaN(value) || value < 0) {
            callback(new Error("工资定额必须是非负数字"));
          } else {
            callback();
@@ -392,6 +397,13 @@
  const filteredParamList = ref([]);
  const selectedParam = ref(null);
  const paramSearchKeyword = ref("");
  // 可选参数分页
  const paramPage = reactive({
    current: 1,
    size: 10,
    total: 0,
  });
  // 编辑参数对话框
  const editParamDialogVisible = ref(false);
@@ -669,6 +681,29 @@
      }
    });
  };
  const openParamDialog = () => {
    paramSearchKeyword.value = "";
    if (!selectedProcess.value) {
      ElMessage.warning("请先选择一个工序");
      return;
    }
    // 获取可选参数列表
    getBaseParamList({
      paramName: paramSearchKeyword.value,
      current: paramPage.current,
      size: paramPage.size,
    }).then(res => {
      if (res.code === 200) {
        filteredParamList.value = res.data?.records || [];
        paramPage.total = res.data?.total || 0;
      } else {
        ElMessage.error(res.msg || "查询失败");
      }
    });
    console.log(filteredParamList.value, "可选参数列表");
    selectedParam.value = null;
    paramDialogVisible.value = true;
  };
  // 参数操作
  const handleSelectParam = () => {
@@ -677,10 +712,14 @@
      return;
    }
    // 获取可选参数列表
    getBaseParamList({ paramName: paramSearchKeyword.value }).then(res => {
    getBaseParamList({
      paramName: paramSearchKeyword.value,
      current: paramPage.current,
      size: paramPage.size,
    }).then(res => {
      if (res.code === 200) {
        filteredParamList.value = res.data || [];
        page.total = res.data?.length || 0;
        filteredParamList.value = res.data?.records || [];
        paramPage.total = res.data?.total || 0;
      } else {
        ElMessage.error(res.msg || "查询失败");
      }
@@ -695,14 +734,22 @@
  };
  const handleParamSearch = () => {
    const keyword = paramSearchKeyword.value.trim().toLowerCase();
    if (!keyword) {
      filteredParamList.value = availableParamList.value;
    } else {
      filteredParamList.value = availableParamList.value.filter(item =>
        item.paramName.toLowerCase().includes(keyword)
      );
    }
    // 重置分页
    paramPage.current = 1;
    // 重新加载数据
    handleSelectParam();
  };
  // 处理分页大小变化
  const handleParamSizeChange = size => {
    paramPage.size = size;
    handleSelectParam();
  };
  // 处理当前页码变化
  const handleParamCurrentChange = current => {
    paramPage.current = current;
    handleSelectParam();
  };
  const getParamTypeText = type => {
    const typeMap = {
@@ -975,7 +1022,7 @@
      th {
        background: transparent;
        font-weight: 600;
        color: #ffffff;
        // color: #ffffff;
        border-bottom: none;
        padding: 16px 0;
      }
src/views/qualityManagement/metricBinding/index.vue
@@ -6,8 +6,8 @@
      <el-col :xs="24"
              :sm="24"
              :md="12"
              :lg="14"
              :xl="14"
              :lg="12"
              :xl="12"
              class="left-col">
        <div class="panel left-panel">
          <PIMTable rowKey="id"
@@ -82,8 +82,8 @@
      <el-col :xs="24"
              :sm="24"
              :md="12"
              :lg="10"
              :xl="10"
              :lg="12"
              :xl="12"
              class="right-col">
        <div class="panel right-panel">
          <div class="right-header">
@@ -122,6 +122,12 @@
            <el-table-column prop="productName"
                             label="产品名称"
                             min-width="140" />
            <el-table-column prop="materialCode"
                             label="物料编码"
                             min-width="140" />
            <el-table-column prop="model"
                             label="规格型号"
                             min-width="140" />
            <el-table-column label="操作"
                             width="120"
                             fixed="right"
src/views/qualityManagement/rawMaterialInspection/components/formDia.vue
@@ -1,467 +1,751 @@
<template>
  <div>
    <el-dialog
        v-model="dialogFormVisible"
        :title="operationType === 'add' ? '新增原材料检验' : '编辑原材料检验'"
        width="70%"
        @close="closeDia"
    >
      <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="供应商:" prop="supplier">
              <el-select
                  v-model="form.supplier"
                  placeholder="请选择"
                  clearable
                  :disabled="supplierQuantityDisabled"
              >
                <el-option
                    v-for="item in supplierList"
                    :key="item.id"
                    :label="item.supplierName"
                    :value="item.supplierName"
                />
    <el-dialog v-model="dialogFormVisible"
               :title="operationType === 'add' ? '新增原材料检验' : '编辑原材料检验'"
               width="70%"
               @close="closeDia">
      <el-form :model="form"
               label-width="100px"
               label-position="left"
               :rules="rules"
               ref="formRef"
               class="inspection-form">
        <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item label="供应商:"
                          prop="supplier">
              <el-input v-model="form.supplier"
                        placeholder="请输入"
                        clearable />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="产品:"
                          prop="productId">
              <el-button type="primary"
                         @click="openProductSelectDialog"
                         :disabled="operationType === 'edit'"
                         class="product-select-btn">{{form.productName || "选择产品"}}{{form.model?(" - "+form.model):""}}</el-button>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="试样编号:"
                          prop="sampleCode">
              <el-input v-model="form.sampleCode"
                        placeholder="请输入"
                        clearable />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="车牌号:"
                          prop="licensePlateNumber">
              <el-input v-model="form.licensePlateNumber"
                        placeholder="请输入"
                        clearable />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="检测性质:"
                          prop="inspectNature">
              <el-select v-model="form.inspectNature"
                         style="width: 100%">
                <el-option label="日常检测"
                           value="日常检测" />
                <el-option label="入场验收"
                           value="入场验收" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="产品名称:" prop="productId">
              <el-tree-select
                  v-model="form.productId"
                  placeholder="请选择"
                  clearable
                  check-strictly
                  @change="getModels"
                  :data="productOptions"
                  :render-after-expand="false"
                  :disabled="operationType === 'edit'"
                  style="width: 100%"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="规格型号:" prop="productModelId">
              <el-select v-model="form.productModelId" placeholder="请选择" clearable :disabled="operationType === 'edit'"
                         filterable readonly @change="handleChangeModel">
                <el-option v-for="item in modelOptions" :key="item.id" :label="item.model" :value="item.id" />
          <el-col :span="8">
            <el-form-item label="试样状态:"
                          prop="sampleState">
              <el-select v-model="form.sampleState"
                         style="width: 100%">
                <el-option label="固体"
                           value="固体" />
                <el-option label="颗粒"
                           value="颗粒" />
                <el-option label="膏体"
                           value="膏体" />
                <el-option label="粉末"
                           value="粉末" />
                <el-option label="液体"
                           value="液体" />
                <el-option label="气体"
                           value="气体" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="指标选择:" prop="testStandardId">
              <el-select
                v-model="form.testStandardId"
                placeholder="请选择指标"
                clearable
                @change="handleTestStandardChange"
                style="width: 100%"
              >
                <el-option
                  v-for="item in testStandardOptions"
                  :key="item.id"
                  :label="item.standardName || item.standardNo"
                  :value="item.id"
                />
          <el-col :span="8">
            <el-form-item label="单位:"
                          prop="unit">
              <el-input v-model="form.unit"
                        disabled />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="指标选择:"
                          prop="testStandardId">
              <el-select v-model="form.testStandardId"
                         placeholder="请选择指标"
                         clearable
                         @change="handleTestStandardChange"
                         style="width: 100%">
                <el-option v-for="item in testStandardOptions"
                           :key="item.id"
                           :label="item.standardName || item.standardNo"
                           :value="item.id" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="单位:" prop="unit">
              <el-input v-model="form.unit" disabled/>
          <el-col :span="8">
            <el-form-item label="检测单位:"
                          prop="checkCompany">
              <el-input v-model="form.checkCompany"
                        placeholder="请输入"
                        clearable />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="数量:" prop="quantity">
              <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="form.quantity" placeholder="请输入"
                               clearable :precision="2" :disabled="supplierQuantityDisabled"/>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="检测单位:" prop="checkCompany">
              <el-input v-model="form.checkCompany" placeholder="请输入" clearable/>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="检测结果:" prop="checkResult">
              <el-select v-model="form.checkResult">
                <el-option label="合格" value="合格"/>
                <el-option label="不合格" value="不合格"/>
          <el-col :span="8">
            <el-form-item label="检测结果:"
                          prop="checkResult">
              <el-select v-model="form.checkResult"
                         style="width: 100%">
                <el-option label="合格"
                           value="合格" />
                <el-option label="不合格"
                           value="不合格" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="检验员:" prop="checkName">
              <el-select v-model="form.checkName" placeholder="请选择" clearable style="width: 100%">
                <el-option v-for="item in userList" :key="item.nickName" :label="item.nickName" :value="item.nickName"/>
          <el-col :span="8">
            <el-form-item label="检验员:"
                          prop="checkName">
              <el-select v-model="form.checkName"
                         placeholder="请选择"
                         clearable
                         style="width: 100%">
                <el-option v-for="item in userList"
                           :key="item.nickName"
                           :label="item.nickName"
                           :value="item.nickName" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="检测日期:" prop="checkTime">
              <el-date-picker
                  v-model="form.checkTime"
                  type="date"
                  placeholder="请选择日期"
                  value-format="YYYY-MM-DD"
                  format="YYYY-MM-DD"
                  clearable
                  style="width: 100%"
              />
          <el-col :span="8">
            <el-form-item label="检测日期:"
                          prop="checkTime">
              <el-date-picker v-model="form.checkTime"
                              type="date"
                              placeholder="请选择日期"
                              value-format="YYYY-MM-DD"
                              format="YYYY-MM-DD"
                              clearable
                              style="width: 100%" />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="取样日期:"
                          prop="sampleTime">
              <el-date-picker v-model="form.sampleTime"
                              type="date"
                              placeholder="请选择日期"
                              value-format="YYYY-MM-DD"
                              format="YYYY-MM-DD"
                              clearable
                              style="width: 100%" />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
<!--      <div style="margin-bottom: 10px;text-align: right">-->
<!--        <el-button type="danger" plain @click="handleDelete">删除</el-button>-->
<!--      </div>-->
      <PIMTable
          rowKey="id"
          :column="tableColumn"
          :tableData="tableData"
          :tableLoading="tableLoading"
          height="400"
      >
      <!--      <div style="margin-bottom: 10px;text-align: right">-->
      <!--        <el-button type="danger" plain @click="handleDelete">删除</el-button>-->
      <!--      </div>-->
      <PIMTable rowKey="id"
                :column="tableColumn"
                :tableData="tableData"
                :tableLoading="tableLoading"
                height="400">
        <template #slot="{ row }">
          <el-input v-model="row.testValue" clearable/>
          <el-input v-model="row.testValue"
                    clearable />
        </template>
      </PIMTable>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitForm">确认</el-button>
          <el-button type="primary"
                     @click="submitForm">确认</el-button>
          <el-button @click="closeDia">取消</el-button>
        </div>
      </template>
    </el-dialog>
    <!-- 产品选择对话框 -->
    <ProductSelectDialog v-model="productSelectDialogVisible"
                         :single="true"
                         @confirm="handleProductSelect" />
  </div>
</template>
<script setup>
import {ref, reactive, toRefs, computed, getCurrentInstance, nextTick} from "vue";
import {getOptions} from "@/api/procurementManagement/procurementLedger.js";
import {modelList, productTreeList} from "@/api/basicData/product.js";
import {qualityInspectAdd, qualityInspectUpdate} from "@/api/qualityManagement/rawMaterialInspection.js";
import {qualityInspectParamDel, qualityInspectParamInfo} from "@/api/qualityManagement/qualityInspectParam.js";
import {qualityInspectDetailByProductId, getQualityTestStandardParamByTestStandardId} from "@/api/qualityManagement/metricMaintenance.js";
import {userListNoPage} from "@/api/system/user.js";
  import {
    ref,
    reactive,
    toRefs,
    computed,
    getCurrentInstance,
    nextTick,
  } from "vue";
  import { getOptions } from "@/api/procurementManagement/procurementLedger.js";
  import { modelList, productTreeList } from "@/api/basicData/product.js";
  import {
    qualityInspectAdd,
    qualityInspectUpdate,
  } from "@/api/qualityManagement/rawMaterialInspection.js";
  import {
    qualityInspectParamDel,
    qualityInspectParamInfo,
  } from "@/api/qualityManagement/qualityInspectParam.js";
  import {
    qualityInspectDetailByProductId,
    getQualityTestStandardParamByTestStandardId,
  } from "@/api/qualityManagement/metricMaintenance.js";
  import { userListNoPage } from "@/api/system/user.js";
  import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue";
const {proxy} = getCurrentInstance()
const emit = defineEmits(['close'])
  const { proxy } = getCurrentInstance();
  const emit = defineEmits(["close"]);
const dialogFormVisible = ref(false);
const operationType = ref('')
const data = reactive({
  form: {
    checkTime: "",
    supplier: "",
    checkName: "",
    productName: "",
    productId: "",
    productModelId: "",
    model: "",
    testStandardId: "",
    unit: "",
    quantity: "",
    checkCompany: "",
    checkResult: "",
  },
  rules: {
    checkTime: [{required: true, message: "请输入", trigger: "blur"},],
    supplier: [{required: true, message: "请输入", trigger: "blur"}],
    checkName: [{required: false, message: "请输入", trigger: "blur"}],
    productId: [{required: true, message: "请输入", trigger: "blur"}],
    productModelId: [{required: true, message: "请选择产品型号", trigger: "change"}],
    testStandardId: [{required: false, message: "请选择指标", trigger: "change"}],
    unit: [{required: false, message: "请输入", trigger: "blur"}],
    quantity: [{required: true, message: "请输入", trigger: "blur"}],
    checkCompany: [{required: false, message: "请输入", trigger: "blur"}],
    checkResult: [{required: true, message: "请选择检测结果", trigger: "change"}],
  },
});
const tableColumn = ref([
  {
    label: "指标",
    prop: "parameterItem",
  },
  {
    label: "单位",
    prop: "unit",
  },
  {
    label: "标准值",
    prop: "standardValue",
  },
  {
    label: "内控值",
    prop: "controlValue",
  },
  {
    label: "检验值",
    prop: "testValue",
    dataType: 'slot',
    slot: 'slot',
  },
]);
const tableData = ref([]);
const tableLoading = ref(false);
  const dialogFormVisible = ref(false);
  const operationType = ref("");
  const data = reactive({
    form: {
      checkTime: "",
      supplier: "",
      checkName: "",
      productName: "",
      productId: "",
      productModelId: "",
      model: "",
      testStandardId: "",
      unit: "",
      quantity: "",
      checkCompany: "",
      checkResult: "",
      inspectNature: "",
      sampleCode: "",
      sampleState: "",
      licensePlateNumber: "",
      sampleTime: "",
    },
    rules: {
      checkTime: [{ required: false, message: "请输入", trigger: "blur" }],
      supplier: [{ required: true, message: "请输入", trigger: "blur" }],
      checkName: [{ required: false, message: "请输入", trigger: "blur" }],
      productId: [{ required: true, message: "请输入", trigger: "blur" }],
      productModelId: [
        { required: true, message: "请选择产品型号", trigger: "change" },
      ],
      testStandardId: [
        { required: false, message: "请选择指标", trigger: "change" },
      ],
      unit: [{ required: false, message: "请输入", trigger: "blur" }],
      quantity: [{ required: true, message: "请输入", trigger: "blur" }],
      checkCompany: [{ required: false, message: "请输入", trigger: "blur" }],
      checkResult: [
        { required: false, message: "请选择检测结果", trigger: "change" },
      ],
      inspectNature: [
        { required: false, message: "请选择检测性质", trigger: "change" },
      ],
      sampleState: [
        { required: false, message: "请选择试样状态", trigger: "change" },
      ],
      sampleCode: [{ required: false, message: "请输入", trigger: "blur" }],
      licensePlateNumber: [
        { required: false, message: "请输入", trigger: "blur" },
      ],
      sampleTime: [{ required: false, message: "请输入", trigger: "blur" }],
    },
  });
  const tableColumn = ref([
    {
      label: "指标",
      prop: "parameterItem",
    },
    {
      label: "单位",
      prop: "unit",
    },
    {
      label: "标准值",
      prop: "standardValue",
    },
    {
      label: "内控值",
      prop: "controlValue",
    },
    {
      label: "检验值",
      prop: "testValue",
      dataType: "slot",
      slot: "slot",
    },
  ]);
  const tableData = ref([]);
  const tableLoading = ref(false);
const {form, rules} = toRefs(data);
const supplierList = ref([]);
const productOptions = ref([]);
const currentProductId = ref(0);
const testStandardOptions = ref([]); // 指标选择下拉框数据
const modelOptions = ref([]);
const userList = ref([]); // 检验员下拉列表
  const { form, rules } = toRefs(data);
  const supplierList = ref([]);
  const productOptions = ref([]);
  const currentProductId = ref(0);
  const testStandardOptions = ref([]); // 指标选择下拉框数据
  const modelOptions = ref([]);
  const userList = ref([]); // 检验员下拉列表
  const productSelectDialogVisible = ref(false);
// 编辑时:productMainId 或 purchaseLedgerId 任一有值则供应商、数量置灰
const supplierQuantityDisabled = computed(() => {
  const v = form.value || {};
  return !!(v.productMainId != null || v.purchaseLedgerId != null);
});
// 打开弹框
const openDialog = async (type, row) => {
  operationType.value = type;
  getOptions().then((res) => {
    supplierList.value = res.data;
  // 编辑时:productMainId 或 purchaseLedgerId 任一有值则供应商、数量置灰
  const supplierQuantityDisabled = computed(() => {
    const v = form.value || {};
    return !!(v.productMainId != null || v.purchaseLedgerId != null);
  });
  try {
    const userRes = await userListNoPage();
    userList.value = userRes.data || [];
  } catch (e) {
    console.error("加载检验员列表失败", e);
    userList.value = [];
  }
  // 先重置表单数据(保持字段完整,避免弹窗首次渲染时触发必填红框“闪一下”)
    form.value = {
    checkTime: "",
    supplier: "",
    checkName: "",
    productName: "",
    productId: "",
    productModelId: "",
    model: "",
    testStandardId: "",
    unit: "",
    quantity: "",
    checkCompany: "",
    checkResult: "",
  }
  testStandardOptions.value = [];
  tableData.value = [];
  // 先确保产品树已加载,否则编辑时产品/规格型号无法反显
  await getProductOptions();
  if (operationType.value === 'edit') {
    // 先保存 testStandardId,避免被清空
    const savedTestStandardId = row.testStandardId;
    form.value = {...row}
    currentProductId.value = row.productId || 0
    // 关键:编辑时加载规格型号下拉选项,才能反显 productModelId
    if (currentProductId.value) {
      try {
        const res = await modelList({ id: currentProductId.value });
        modelOptions.value = res || [];
        // 同步回填 model / unit(有些接口返回的 row 里可能没带全)
        if (form.value.productModelId) {
          handleChangeModel(form.value.productModelId);
        }
      } catch (e) {
        console.error("加载规格型号失败", e);
        modelOptions.value = [];
      }
    }
    // 编辑模式下,先加载指标选项,然后加载参数列表
    if (currentProductId.value) {
      // 先加载指标选项
      let params = {
        productId: currentProductId.value,
        inspectType: 0
      }
      qualityInspectDetailByProductId(params).then(res => {
        testStandardOptions.value = res.data || [];
        // 使用 nextTick 和 setTimeout 确保选项已经渲染到 DOM
        nextTick(() => {
          setTimeout(() => {
            // 如果编辑数据中有 testStandardId,则设置并加载对应的参数
            if (savedTestStandardId) {
              // 确保类型匹配(item.id 可能是数字或字符串)
              const matchedOption = testStandardOptions.value.find(item =>
                item.id == savedTestStandardId || String(item.id) === String(savedTestStandardId)
              );
              if (matchedOption) {
                // 确保使用匹配项的 id(保持类型一致)
                form.value.testStandardId = matchedOption.id;
                // 编辑保留原检验值,直接拉取原参数数据
                getQualityInspectParamList(row.id);
              } else {
                // 如果找不到匹配项,尝试直接使用原值
                console.warn('未找到匹配的指标选项,testStandardId:', savedTestStandardId, '可用选项:', testStandardOptions.value);
                form.value.testStandardId = savedTestStandardId;
                getQualityInspectParamList(row.id);
              }
            } else {
              // 否则使用旧的逻辑
              getQualityInspectParamList(row.id);
            }
          }, 100);
        });
      });
    } else {
      getQualityInspectParamList(row.id);
    }
  }
  // 最后再打开弹窗,并清理校验态,避免必填提示闪烁
  dialogFormVisible.value = true;
  nextTick(() => {
    proxy.$refs?.formRef?.clearValidate?.();
  });
}
const getProductOptions = () => {
  return productTreeList().then((res) => {
    productOptions.value = convertIdToValue(res);
    return productOptions.value;
  });
};
const getModels = (value) => {
  form.value.productModelId = undefined;
  form.value.unit = undefined;
  modelOptions.value = [];
  currentProductId.value = value
  form.value.productName = findNodeById(productOptions.value, value);
  modelList({ id: value }).then((res) => {
    modelOptions.value = res;
  })
  if (currentProductId.value) {
    getList();
  }
};
  // 打开弹框
  const openDialog = async (type, row) => {
    operationType.value = type;
    getOptions().then(res => {
      supplierList.value = res.data;
    });
const handleChangeModel = (value) => {
  form.value.model = modelOptions.value.find(item => item.id == value)?.model || '';
  form.value.unit = modelOptions.value.find(item => item.id == value)?.unit || '';
}
const findNodeById = (nodes, productId) => {
  for (let i = 0; i < nodes.length; i++) {
    if (nodes[i].value === productId) {
      return nodes[i].label; // 找到节点,返回该节点
    try {
      const userRes = await userListNoPage();
      userList.value = userRes.data || [];
    } catch (e) {
      console.error("加载检验员列表失败", e);
      userList.value = [];
    }
    if (nodes[i].children && nodes[i].children.length > 0) {
      const foundNode = findNodeById(nodes[i].children, productId);
      if (foundNode) {
        return foundNode; // 在子节点中找到,返回该节点
      }
    }
  }
  return null; // 没有找到节点,返回null
};
function convertIdToValue(data) {
  return data.map((item) => {
    const {id, children, ...rest} = item;
    const newItem = {
      ...rest,
      value: id, // 将 id 改为 value
    // 先重置表单数据(保持字段完整,避免弹窗首次渲染时触发必填红框“闪一下”)
    form.value = {
      checkTime: "",
      supplier: "",
      productName: "",
      productId: "",
      productModelId: "",
      model: "",
      testStandardId: "",
      unit: "",
      quantity: "",
      checkCompany: "",
      checkResult: "",
    };
    if (children && children.length > 0) {
      newItem.children = convertIdToValue(children);
    }
    return newItem;
  });
}
// 提交产品表单
const submitForm = () => {
  proxy.$refs.formRef.validate(valid => {
    if (valid) {
      form.value.inspectType = 0
            if (operationType.value === "add") {
                tableData.value.forEach((item) => {
                    delete item.id
                })
            }
      const data = {...form.value, qualityInspectParams: tableData.value}
      if (operationType.value === "add") {
        qualityInspectAdd(data).then(res => {
          proxy.$modal.msgSuccess("提交成功");
          closeDia();
        })
      } else {
        qualityInspectUpdate(data).then(res => {
          proxy.$modal.msgSuccess("提交成功");
          closeDia();
        })
      }
    }
  })
}
const getList = () => {
  if (!currentProductId.value) {
    testStandardOptions.value = [];
    tableData.value = [];
    return;
  }
  let params = {
    productId: currentProductId.value,
    inspectType: 0
  }
  qualityInspectDetailByProductId(params).then(res => {
    // 保存下拉框选项数据
    testStandardOptions.value = res.data || [];
    // 清空表格数据,等待用户选择指标
    tableData.value = [];
    // 清空指标选择
    form.value.testStandardId = '';
  })
}
    // 先确保产品树已加载,否则编辑时产品/规格型号无法反显
    await getProductOptions();
    if (operationType.value === "edit") {
      // 先保存 testStandardId,避免被清空
      const savedTestStandardId = row.testStandardId;
      form.value = { ...row };
      currentProductId.value = row.productId || 0;
      // 关键:编辑时加载规格型号下拉选项,才能反显 productModelId
      if (currentProductId.value) {
        try {
          const res = await modelList({ id: currentProductId.value });
          modelOptions.value = res || [];
          // 同步回填 model / unit(有些接口返回的 row 里可能没带全)
          if (form.value.productModelId) {
            handleChangeModel(form.value.productModelId);
          }
        } catch (e) {
          console.error("加载规格型号失败", e);
          modelOptions.value = [];
        }
      }
      // 编辑模式下,先加载指标选项,然后加载参数列表
      if (currentProductId.value) {
        // 先加载指标选项
        let params = {
          productId: currentProductId.value,
          inspectType: 0,
        };
        qualityInspectDetailByProductId(params).then(res => {
          testStandardOptions.value = res.data || [];
          // 使用 nextTick 和 setTimeout 确保选项已经渲染到 DOM
          nextTick(() => {
            setTimeout(() => {
              // 如果编辑数据中有 testStandardId,则设置并加载对应的参数
              if (savedTestStandardId) {
                // 确保类型匹配(item.id 可能是数字或字符串)
                const matchedOption = testStandardOptions.value.find(
                  item =>
                    item.id == savedTestStandardId ||
                    String(item.id) === String(savedTestStandardId)
                );
                if (matchedOption) {
                  // 确保使用匹配项的 id(保持类型一致)
                  form.value.testStandardId = matchedOption.id;
                  // 编辑保留原检验值,直接拉取原参数数据
                  getQualityInspectParamList(row.id);
                } else {
                  // 如果找不到匹配项,尝试直接使用原值
                  console.warn(
                    "未找到匹配的指标选项,testStandardId:",
                    savedTestStandardId,
                    "可用选项:",
                    testStandardOptions.value
                  );
                  form.value.testStandardId = savedTestStandardId;
                  getQualityInspectParamList(row.id);
                }
              } else {
                // 否则使用旧的逻辑
                getQualityInspectParamList(row.id);
              }
            }, 100);
          });
        });
      } else {
        getQualityInspectParamList(row.id);
      }
    }
    // 最后再打开弹窗,并清理校验态,避免必填提示闪烁
    dialogFormVisible.value = true;
    nextTick(() => {
      proxy.$refs?.formRef?.clearValidate?.();
    });
  };
  const getProductOptions = () => {
    return productTreeList().then(res => {
      productOptions.value = convertIdToValue(res);
      return productOptions.value;
    });
  };
  const getModels = value => {
    form.value.productModelId = undefined;
    form.value.unit = undefined;
    modelOptions.value = [];
    currentProductId.value = value;
    form.value.productName = findNodeById(productOptions.value, value);
    modelList({ id: value }).then(res => {
      modelOptions.value = res;
    });
    if (currentProductId.value) {
      getList();
    }
  };
// 指标选择变化处理
const handleTestStandardChange = (testStandardId) => {
  if (!testStandardId) {
    tableData.value = [];
    return;
  }
  tableLoading.value = true;
  getQualityTestStandardParamByTestStandardId(testStandardId).then(res => {
    tableData.value = res.data || [];
  }).catch(error => {
    console.error('获取标准参数失败:', error);
    tableData.value = [];
  }).finally(() => {
    tableLoading.value = false;
  })
}
  const handleChangeModel = value => {
    form.value.model =
      modelOptions.value.find(item => item.id == value)?.model || "";
    form.value.unit =
      modelOptions.value.find(item => item.id == value)?.unit || "";
  };
const getQualityInspectParamList = (id) => {
  qualityInspectParamInfo(id).then(res => {
    tableData.value = res.data;
  })
}
// 关闭弹框
const closeDia = () => {
  proxy.resetForm("formRef");
  tableData.value = [];
  testStandardOptions.value = [];
  form.value.testStandardId = '';
  dialogFormVisible.value = false;
  emit('close')
};
defineExpose({
  openDialog,
});
  const findNodeById = (nodes, productId) => {
    for (let i = 0; i < nodes.length; i++) {
      if (nodes[i].value === productId) {
        return nodes[i].label; // 找到节点,返回该节点
      }
      if (nodes[i].children && nodes[i].children.length > 0) {
        const foundNode = findNodeById(nodes[i].children, productId);
        if (foundNode) {
          return foundNode; // 在子节点中找到,返回该节点
        }
      }
    }
    return null; // 没有找到节点,返回null
  };
  function convertIdToValue(data) {
    return data.map(item => {
      const { id, children, ...rest } = item;
      const newItem = {
        ...rest,
        value: id, // 将 id 改为 value
      };
      if (children && children.length > 0) {
        newItem.children = convertIdToValue(children);
      }
      return newItem;
    });
  }
  // 提交产品表单
  const submitForm = () => {
    proxy.$refs.formRef.validate(valid => {
      if (valid) {
        form.value.inspectType = 0;
        if (operationType.value === "add") {
          tableData.value.forEach(item => {
            delete item.id;
          });
        }
        const data = { ...form.value, qualityInspectParams: tableData.value };
        if (operationType.value === "add") {
          qualityInspectAdd(data).then(res => {
            proxy.$modal.msgSuccess("提交成功");
            closeDia();
          });
        } else {
          qualityInspectUpdate(data).then(res => {
            proxy.$modal.msgSuccess("提交成功");
            closeDia();
          });
        }
      }
    });
  };
  const getList = () => {
    if (!currentProductId.value) {
      testStandardOptions.value = [];
      tableData.value = [];
      return;
    }
    let params = {
      productId: currentProductId.value,
      inspectType: 0,
    };
    qualityInspectDetailByProductId(params).then(res => {
      // 保存下拉框选项数据
      testStandardOptions.value = res.data || [];
      // 清空表格数据,等待用户选择指标
      tableData.value = [];
      // 清空指标选择
      form.value.testStandardId = "";
    });
  };
  // 指标选择变化处理
  const handleTestStandardChange = testStandardId => {
    if (!testStandardId) {
      tableData.value = [];
      return;
    }
    tableLoading.value = true;
    getQualityTestStandardParamByTestStandardId(testStandardId)
      .then(res => {
        tableData.value = res.data || [];
      })
      .catch(error => {
        console.error("获取标准参数失败:", error);
        tableData.value = [];
      })
      .finally(() => {
        tableLoading.value = false;
      });
  };
  const getQualityInspectParamList = id => {
    qualityInspectParamInfo(id).then(res => {
      tableData.value = res.data;
    });
  };
  // 打开产品选择对话框
  const openProductSelectDialog = () => {
    productSelectDialogVisible.value = true;
  };
  // 处理产品选择
  const handleProductSelect = products => {
    if (products && products.length > 0) {
      const product = products[0];
      form.value.productId = product.id;
      form.value.productName = product.productName;
      form.value.productModelId = product.id;
      form.value.model = product.model;
      form.value.unit = product.unit;
      currentProductId.value = product.id;
      // 加载指标选项
      getList();
    }
  };
  // 清空产品选择
  const clearProductSelection = () => {
    form.value.productId = "";
    form.value.productName = "";
    form.value.productModelId = "";
    form.value.model = "";
    form.value.unit = "";
    currentProductId.value = 0;
    testStandardOptions.value = [];
    tableData.value = [];
    form.value.testStandardId = "";
  };
  // 关闭弹框
  const closeDia = () => {
    proxy.resetForm("formRef");
    tableData.value = [];
    testStandardOptions.value = [];
    form.value.testStandardId = "";
    dialogFormVisible.value = false;
    emit("close");
  };
  defineExpose({
    openDialog,
  });
</script>
<style scoped>
  .inspection-form {
    background-color: #f9f9f9;
    border-radius: 8px;
    padding: 20px;
    margin-bottom: 20px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  }
</style>
  .product-select-btn {
    width: 100%;
    text-align: left;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    transition: all 0.3s ease;
  }
  .product-select-btn:hover {
    box-shadow: 0 2px 8px rgba(0, 122, 255, 0.3);
  }
  /* 增加表单项间距 */
  .el-form-item {
    margin-bottom: 15px;
  }
  /* 输入框和选择器的悬停效果 */
  :deep(.el-input__wrapper) {
    transition: all 0.3s ease;
  }
  :deep(.el-input__wrapper:hover) {
    box-shadow: 0 0 0 2px rgba(0, 122, 255, 0.2) !important;
  }
  :deep(.el-select) {
    transition: all 0.3s ease;
  }
  :deep(.el-select:hover .el-input__wrapper) {
    box-shadow: 0 0 0 2px rgba(0, 122, 255, 0.2) !important;
  }
  /* 日期选择器的悬停效果 */
  :deep(.el-date-picker) {
    transition: all 0.3s ease;
  }
  :deep(.el-date-picker:hover .el-input__wrapper) {
    box-shadow: 0 0 0 2px rgba(0, 122, 255, 0.2) !important;
  }
  /* 优化表格样式 */
  :deep(.el-table) {
    border-radius: 8px;
    overflow: hidden;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
    transition: all 0.3s ease;
  }
  :deep(.el-table:hover) {
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  }
  :deep(.el-table th) {
    background-color: #f5f7fa;
    font-weight: 600;
  }
  :deep(.el-table tr:hover) {
    background-color: #f0f9ff;
  }
  /* 表格输入框样式 */
  :deep(.el-table .el-input__wrapper) {
    box-shadow: none !important;
  }
  :deep(.el-table .el-input__wrapper:hover) {
    box-shadow: 0 0 0 2px rgba(0, 122, 255, 0.2) !important;
  }
  /* 优化对话框底部按钮 */
  .dialog-footer {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
    margin-top: 20px;
  }
  .dialog-footer .el-button {
    transition: all 0.3s ease;
    padding: 8px 20px;
    border-radius: 4px;
  }
  .dialog-footer .el-button:hover {
    transform: translateY(-1px);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
  }
  .dialog-footer .el-button--primary:hover {
    box-shadow: 0 2px 8px rgba(0, 122, 255, 0.4);
  }
  /* 表单验证状态样式 */
  :deep(.el-form-item__error) {
    font-size: 12px;
    color: #f56c6c;
    margin-top: 4px;
  }
  :deep(.el-form-item.is-error .el-input__wrapper) {
    box-shadow: 0 0 0 2px rgba(245, 108, 108, 0.2) !important;
  }
  :deep(.el-form-item.is-success .el-input__wrapper) {
    box-shadow: 0 0 0 2px rgba(103, 194, 58, 0.2) !important;
  }
  /* 响应式设计 */
  @media screen and (max-width: 1200px) {
    .el-col {
      :deep(.el-col) {
        &[class*="el-col-8"] {
          flex: 0 0 50%;
          max-width: 50%;
        }
      }
    }
  }
  @media screen and (max-width: 768px) {
    .el-col {
      :deep(.el-col) {
        &[class*="el-col-8"] {
          flex: 0 0 100%;
          max-width: 100%;
        }
      }
    }
    .inspection-form {
      padding: 15px;
    }
    .el-form {
      label-width: 80px !important;
    }
    .dialog-footer {
      flex-direction: column;
      align-items: stretch;
    }
    .dialog-footer .el-button {
      width: 100%;
    }
  }
</style>
src/views/qualityManagement/rawMaterialInspection/index.vue
@@ -3,316 +3,391 @@
    <div class="search_form">
      <div>
        <span class="search_title">供应商:</span>
        <el-input
            v-model="searchForm.supplier"
            style="width: 240px"
            placeholder="请输入供应商搜索"
            @change="handleQuery"
            clearable
            :prefix-icon="Search"
        />
        <span style="margin-left: 10px" class="search_title">检测日期:</span>
        <el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
                        placeholder="请选择" clearable @change="changeDaterange"/>
        <el-button type="primary" @click="handleQuery" style="margin-left: 10px"
        >搜索
        </el-button
        >
        <el-input v-model="searchForm.supplier"
                  style="width: 240px"
                  placeholder="请输入供应商搜索"
                  @change="handleQuery"
                  clearable
                  :prefix-icon="Search" />
        <span style="margin-left: 10px"
              class="search_title">检测日期:</span>
        <el-date-picker v-model="searchForm.entryDate"
                        value-format="YYYY-MM-DD"
                        format="YYYY-MM-DD"
                        type="daterange"
                        placeholder="请选择"
                        clearable
                        @change="changeDaterange" />
        <el-button type="primary"
                   @click="handleQuery"
                   style="margin-left: 10px">搜索
        </el-button>
      </div>
      <div>
        <el-button type="primary" @click="openForm('add')">新增</el-button>
        <el-button type="primary"
                   @click="openForm('add')">新增</el-button>
        <el-button @click="handleOut">导出</el-button>
        <el-button type="danger" plain @click="handleDelete">删除</el-button>
        <el-button type="danger"
                   plain
                   @click="handleDelete">删除</el-button>
      </div>
    </div>
    <div class="table_list">
      <PIMTable
          rowKey="id"
          :column="tableColumn"
          :tableData="tableData"
          :page="page"
          :isSelection="true"
          @selection-change="handleSelectionChange"
          :tableLoading="tableLoading"
          @pagination="pagination"
          :total="page.total"
      ></PIMTable>
      <PIMTable rowKey="id"
                :column="tableColumn"
                :tableData="tableData"
                :page="page"
                :isSelection="true"
                @selection-change="handleSelectionChange"
                :tableLoading="tableLoading"
                @pagination="pagination"
                :total="page.total"></PIMTable>
    </div>
    <InspectionFormDia ref="inspectionFormDia" @close="handleQuery"></InspectionFormDia>
    <FormDia ref="formDia" @close="handleQuery"></FormDia>
    <files-dia ref="filesDia" @close="handleQuery"></files-dia>
    <el-dialog v-model="dialogFormVisible" title="编辑检验员" width="30%"
    <InspectionFormDia ref="inspectionFormDia"
                       @close="handleQuery"></InspectionFormDia>
    <FormDia ref="formDia"
             @close="handleQuery"></FormDia>
    <files-dia ref="filesDia"
               @close="handleQuery"></files-dia>
    <el-dialog v-model="dialogFormVisible"
               title="编辑检验员"
               width="30%"
               @close="closeDia">
      <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
        <el-form-item label="检验员:" prop="checkName">
          <el-select v-model="form.checkName" placeholder="请选择" clearable>
            <el-option v-for="item in userList" :key="item.nickName" :label="item.nickName"
                       :value="item.nickName"/>
      <el-form :model="form"
               label-width="140px"
               label-position="top"
               :rules="rules"
               ref="formRef">
        <el-form-item label="检验员:"
                      prop="checkName">
          <el-select v-model="form.checkName"
                     placeholder="请选择"
                     clearable>
            <el-option v-for="item in userList"
                       :key="item.nickName"
                       :label="item.nickName"
                       :value="item.nickName" />
          </el-select>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitForm">确认</el-button>
          <el-button type="primary"
                     @click="submitForm">确认</el-button>
          <el-button @click="closeDia">取消</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>
<script setup>
import {Search} from "@element-plus/icons-vue";
import {onMounted, ref, reactive, toRefs, getCurrentInstance, nextTick} from "vue";
import InspectionFormDia from "@/views/qualityManagement/rawMaterialInspection/components/inspectionFormDia.vue";
import FormDia from "@/views/qualityManagement/rawMaterialInspection/components/formDia.vue";
import {ElMessageBox} from "element-plus";
import {
  downloadQualityInspect,
  qualityInspectDel,
  qualityInspectListPage, qualityInspectUpdate,
  submitQualityInspect
} from "@/api/qualityManagement/rawMaterialInspection.js";
import FilesDia from "@/views/qualityManagement/rawMaterialInspection/components/filesDia.vue";
import dayjs from "dayjs";
import {userListNoPage} from "@/api/system/user.js";
import useUserStore from "@/store/modules/user";
  import { Search } from "@element-plus/icons-vue";
  import {
    onMounted,
    ref,
    reactive,
    toRefs,
    getCurrentInstance,
    nextTick,
  } from "vue";
  import InspectionFormDia from "@/views/qualityManagement/rawMaterialInspection/components/inspectionFormDia.vue";
  import FormDia from "@/views/qualityManagement/rawMaterialInspection/components/formDia.vue";
  import { ElMessageBox } from "element-plus";
  import {
    downloadQualityInspect,
    qualityInspectDel,
    qualityInspectListPage,
    qualityInspectUpdate,
    submitQualityInspect,
  } from "@/api/qualityManagement/rawMaterialInspection.js";
  import FilesDia from "@/views/qualityManagement/rawMaterialInspection/components/filesDia.vue";
  import dayjs from "dayjs";
  import { userListNoPage } from "@/api/system/user.js";
  import useUserStore from "@/store/modules/user";
const data = reactive({
  searchForm: {
    supplier: "",
    entryDate: undefined, // 录入日期
    entryDateStart: undefined,
    entryDateEnd: undefined,
  },
  rules: {
    checkName: [{required: true, message: "请选择", trigger: "change"}],
  },
});
const {searchForm, rules} = toRefs(data);
const tableColumn = ref([
  {
    label: "检测日期",
    prop: "checkTime",
    width: 120
  },
  {
    label: "采购订单号",
    prop: "purchaseContractNo",
    width: 120
  },
  {
    label: "供应商",
    prop: "supplier",
    width: 230
  },
  {
    label: "检验员",
    prop: "checkName",
  },
  {
    label: "产品名称",
    prop: "productName",
  },
  {
    label: "规格型号",
    prop: "model",
  },
  {
    label: "单位",
    prop: "unit",
  },
  {
    label: "数量",
    prop: "quantity",
    width: 120
  },
  {
    label: "检测单位",
    prop: "checkCompany",
    width: 120
  },
  {
    label: "检测结果",
    prop: "checkResult",
    dataType: "tag",
    formatType: (params) => {
      if (params === '不合格') {
        return "danger";
      } else if (params === '合格') {
        return "success";
      } else {
        return null;
      }
  const data = reactive({
    searchForm: {
      supplier: "",
      entryDate: undefined, // 录入日期
      entryDateStart: undefined,
      entryDateEnd: undefined,
    },
  },
  {
    label: "提交状态",
    prop: "inspectState",
    formatData: (params) => {
      if (params) {
        return "已提交";
      } else {
        return "未提交";
      }
    rules: {
      checkName: [{ required: true, message: "请选择", trigger: "change" }],
    },
  },
  {
    dataType: "action",
    label: "操作",
    align: "center",
    fixed: "right",
    width: 280,
    operation: [
      {
        name: "编辑",
        type: "text",
        clickFun: (row) => {
          openForm("edit", row);
        },
                disabled: (row) => {
                    // 已提交则禁用
                    if (row.inspectState == 1) return true;
                    // 如果检验员有值,只有当前登录用户能编辑
                    if (row.checkName) {
                        return row.checkName !== userStore.nickName;
                    }
                    return false;
                }
      },
      {
        name: "附件",
        type: "text",
        clickFun: (row) => {
          openFilesFormDia(row);
        },
      },
      {
        name: "提交",
        type: "text",
        clickFun: (row) => {
          submit(row.id);
        },
                disabled: (row) => {
                    // 已提交则禁用
                    if (row.inspectState == 1) return true;
                    // 如果检验员有值,只有当前登录用户能提交
                    if (row.checkName) {
                        return row.checkName !== userStore.nickName;
                    }
                    return false;
                }
      },
      {
        name: "分配检验员",
        type: "text",
        clickFun: (row) => {
          if (!row.checkName) {
            open(row)
          } else {
            proxy.$modal.msgError("检验员已存在");
          }
        },
                disabled: (row) => {
                    return row.inspectState == 1 || row.checkName;
                }
      },
      {
        name: "下载",
        type: "text",
        clickFun: (row) => {
          downLoadFile(row);
        },
      },
    ],
  },
]);
const tableData = ref([]);
const selectedRows = ref([]);
const tableLoading = ref(false);
const userList = ref([]);
const dialogFormVisible = ref(false);
const form = ref({
  checkName: ""
});
const page = reactive({
  current: 1,
  size: 100,
  total: 0
});
const currentRow = ref(null)
const formDia = ref()
const filesDia = ref()
const inspectionFormDia = ref()
const {proxy} = getCurrentInstance()
const userStore = useUserStore()
const changeDaterange = (value) => {
  searchForm.value.entryDateStart = undefined;
  searchForm.value.entryDateEnd = undefined;
  if (value) {
    searchForm.value.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
    searchForm.value.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
  }
  getList();
};
// 查询列表
/** 搜索按钮操作 */
const handleQuery = () => {
  page.current = 1;
  getList();
};
const pagination = (obj) => {
  page.current = obj.page;
  page.size = obj.limit;
  getList();
};
const getList = () => {
  tableLoading.value = true;
  const params = {...searchForm.value, ...page};
  params.entryDate = undefined
  qualityInspectListPage({...params, inspectType: 0}).then(res => {
    tableLoading.value = false;
    tableData.value = res.data.records
    page.total = res.data.total;
  }).catch(err => {
    tableLoading.value = false;
  })
};
// 表格选择数据
const handleSelectionChange = (selection) => {
  selectedRows.value = selection;
};
  });
  const { searchForm, rules } = toRefs(data);
  const tableColumn = ref([
    {
      label: "检测日期",
      prop: "checkTime",
      width: 150,
      className: "date-cell",
    },
    {
      label: "供应商",
      prop: "supplier",
      width: 130,
    },
    {
      label: "检验员",
      prop: "checkName",
      width: 120,
      className: "inspector-cell",
    },
    {
      label: "产品名称",
      prop: "productName",
      dataType: "tag",
    },
    {
      label: "规格型号",
      prop: "model",
    },
    {
      label: "单位",
      prop: "unit",
      width: 80,
    },
    {
      label: "数量",
      prop: "quantity",
      width: 120,
    },
    {
      label: "试样编号",
      prop: "sampleCode",
      width: 120,
// 打开弹框
const openForm = (type, row) => {
  nextTick(() => {
    formDia.value?.openDialog(type, row)
  })
};
// 打开附件弹框
const openFilesFormDia = (type, row) => {
  nextTick(() => {
    filesDia.value?.openDialog(type, row)
  })
};
      className: "volume-cell",
    },
    {
      label: "试样状态",
      prop: "sampleState",
      dataType: "tag",
      formatType: params => {
        if (params === "颗粒" || params === "固体" || params === "膏体") {
          return "success";
        } else {
          return "info";
        }
      },
    },
    {
      label: "检测性质",
      prop: "inspectNature",
      dataType: "tag",
      formatType: params => {
        if (params === "日常检验") {
          return "success";
        } else if (params === "入场验收") {
          return "warning";
        } else {
          return null;
        }
      },
    },
    {
      label: "取样日期",
      prop: "sampleTime",
      width: 150,
      className: "date-cell",
    },
    {
      label: "检测单位",
      prop: "checkCompany",
    },
    {
      label: "检测结果",
      prop: "checkResult",
      dataType: "tag",
      formatType: params => {
        if (params === "不合格") {
          return "danger";
        } else if (params === "合格") {
          return "success";
        } else {
          return null;
        }
      },
    },
    {
      label: "提交状态",
      prop: "inspectState",
      dataType: "tag",
      formatType: params => {
        if (params) {
          return "success";
        } else {
          return "info";
        }
      },
      formatData: params => {
        if (params) {
          return "已提交";
        } else {
          return "未提交";
        }
      },
    },
    {
      dataType: "action",
      label: "操作",
      align: "center",
      fixed: "right",
      width: 280,
      operation: [
        {
          name: "编辑",
          type: "text",
          clickFun: row => {
            openForm("edit", row);
          },
          disabled: row => {
            // 已提交则禁用
            if (row.inspectState == 1) return true;
            // 如果检验员有值,只有当前登录用户能编辑
            if (row.checkName) {
              return row.checkName !== userStore.nickName;
            }
            return false;
          },
        },
        {
          name: "附件",
          type: "text",
          clickFun: row => {
            openFilesFormDia(row);
          },
        },
        {
          name: "提交",
          type: "text",
          clickFun: row => {
            submit(row.id);
          },
          disabled: row => {
            // 已提交则禁用
            if (row.inspectState == 1) return true;
            // 如果检验员有值,只有当前登录用户能提交
            if (row.checkName) {
              return row.checkName !== userStore.nickName;
            }
            return false;
          },
        },
        {
          name: "分配检验员",
          type: "text",
          clickFun: row => {
            if (!row.checkName) {
              open(row);
            } else {
              proxy.$modal.msgError("检验员已存在");
            }
          },
          disabled: row => {
            return row.inspectState == 1 || row.checkName;
          },
        },
        {
          name: "下载",
          type: "text",
          clickFun: row => {
            downLoadFile(row);
          },
        },
      ],
    },
  ]);
  const tableData = ref([]);
  const selectedRows = ref([]);
  const tableLoading = ref(false);
  const userList = ref([]);
  const dialogFormVisible = ref(false);
  const form = ref({
    checkName: "",
  });
  const page = reactive({
    current: 1,
    size: 100,
    total: 0,
  });
  const currentRow = ref(null);
  const formDia = ref();
  const filesDia = ref();
  const inspectionFormDia = ref();
  const { proxy } = getCurrentInstance();
  const userStore = useUserStore();
  const changeDaterange = value => {
    searchForm.value.entryDateStart = undefined;
    searchForm.value.entryDateEnd = undefined;
    if (value) {
      searchForm.value.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
      searchForm.value.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
    }
    getList();
  };
  // 查询列表
  /** 搜索按钮操作 */
  const handleQuery = () => {
    page.current = 1;
    getList();
  };
  const pagination = obj => {
    page.current = obj.page;
    page.size = obj.limit;
    getList();
  };
  const getList = () => {
    tableLoading.value = true;
    const params = { ...searchForm.value, ...page };
    params.entryDate = undefined;
    qualityInspectListPage({ ...params, inspectType: 0 })
      .then(res => {
        tableLoading.value = false;
        tableData.value = res.data.records;
        page.total = res.data.total;
      })
      .catch(err => {
        tableLoading.value = false;
      });
  };
  // 表格选择数据
  const handleSelectionChange = selection => {
    selectedRows.value = selection;
  };
// 删除
const handleDelete = () => {
  let ids = [];
  if (selectedRows.value.length > 0) {
    ids = selectedRows.value.map((item) => item.id);
  } else {
    proxy.$modal.msgWarning("请选择数据");
    return;
  }
  ElMessageBox.confirm("选中的内容将被删除,是否确认删除?", "导出", {
    confirmButtonText: "确认",
    cancelButtonText: "取消",
    type: "warning",
  })
  // 打开弹框
  const openForm = (type, row) => {
    nextTick(() => {
      formDia.value?.openDialog(type, row);
    });
  };
  // 打开附件弹框
  const openFilesFormDia = (type, row) => {
    nextTick(() => {
      filesDia.value?.openDialog(type, row);
    });
  };
  // 删除
  const handleDelete = () => {
    let ids = [];
    if (selectedRows.value.length > 0) {
      ids = selectedRows.value.map(item => item.id);
    } else {
      proxy.$modal.msgWarning("请选择数据");
      return;
    }
    ElMessageBox.confirm("选中的内容将被删除,是否确认删除?", "导出", {
      confirmButtonText: "确认",
      cancelButtonText: "取消",
      type: "warning",
    })
      .then(() => {
        qualityInspectDel(ids).then((res) => {
        qualityInspectDel(ids).then(res => {
          proxy.$modal.msgSuccess("删除成功");
          getList();
        });
@@ -320,79 +395,432 @@
      .catch(() => {
        proxy.$modal.msg("已取消");
      });
};
// 导出
const handleOut = () => {
  ElMessageBox.confirm("选中的内容将被导出,是否确认导出?", "导出", {
    confirmButtonText: "确认",
    cancelButtonText: "取消",
    type: "warning",
  })
  };
  // 导出
  const handleOut = () => {
    ElMessageBox.confirm("选中的内容将被导出,是否确认导出?", "导出", {
      confirmButtonText: "确认",
      cancelButtonText: "取消",
      type: "warning",
    })
      .then(() => {
        proxy.download("/quality/qualityInspect/export", {inspectType: 0}, "原材料检验.xlsx");
        proxy.download(
          "/quality/qualityInspect/export",
          { inspectType: 0 },
          "原材料检验.xlsx"
        );
      })
      .catch(() => {
        proxy.$modal.msg("已取消");
      });
};
  };
// 提价
const submit = async (id) => {
  const res = await submitQualityInspect({id: id})
  if (res.code === 200) {
    proxy.$modal.msgSuccess("提交成功");
    getList();
  }
}
// 关闭弹框
const closeDia = () => {
  proxy.resetForm("formRef");
  dialogFormVisible.value = false;
};
const submitForm = () => {
  if (currentRow.value) {
    const data = {
      ...form.value,
      id: currentRow.value.id
    }
    qualityInspectUpdate(data).then(res => {
  // 提价
  const submit = async id => {
    const res = await submitQualityInspect({ id: id });
    if (res.code === 200) {
      proxy.$modal.msgSuccess("提交成功");
      closeDia();
      getList();
    })
  }
};
    }
  };
const open = async (row) => {
  let userLists = await userListNoPage();
  userList.value = userLists.data;
  currentRow.value = row
  dialogFormVisible.value = true
}
  // 关闭弹框
  const closeDia = () => {
    proxy.resetForm("formRef");
    dialogFormVisible.value = false;
  };
const downLoadFile = (row) => {
  downloadQualityInspect({ id: row.id }).then((blobData) => {
    const blob = new Blob([blobData], {
      type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
    })
    const downloadUrl = window.URL.createObjectURL(blob)
  const submitForm = () => {
    if (currentRow.value) {
      const data = {
        ...form.value,
        id: currentRow.value.id,
      };
      qualityInspectUpdate(data).then(res => {
        proxy.$modal.msgSuccess("提交成功");
        closeDia();
        getList();
      });
    }
  };
    const link = document.createElement('a')
    link.href = downloadUrl
    link.download = '原材料检验报告.docx'
    document.body.appendChild(link)
    link.click()
  const open = async row => {
    let userLists = await userListNoPage();
    userList.value = userLists.data;
    currentRow.value = row;
    dialogFormVisible.value = true;
  };
    document.body.removeChild(link)
    window.URL.revokeObjectURL(downloadUrl)
  })
};
  const downLoadFile = row => {
    downloadQualityInspect({ id: row.id }).then(blobData => {
      const blob = new Blob([blobData], {
        type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
      });
      const downloadUrl = window.URL.createObjectURL(blob);
onMounted(() => {
  getList();
});
      const link = document.createElement("a");
      link.href = downloadUrl;
      link.download = "原材料检验报告.docx";
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      window.URL.revokeObjectURL(downloadUrl);
    });
  };
  onMounted(() => {
    getList();
  });
</script>
<style scoped></style>
<style scoped lang="scss">
  .app-container {
    padding: 20px;
    background-color: #f5f7fa;
    min-height: 100vh;
  }
  .search_form {
    background-color: #fff;
    border-radius: 8px;
    padding: 20px;
    margin-bottom: 20px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 15px;
  }
  .search_form > div {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
  }
  .search_title {
    font-size: 14px;
    color: #303133;
    font-weight: 500;
  }
  .table_list {
    background-color: #fff;
    border-radius: 8px;
    padding: 20px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
  }
  /* 表格样式优化 */
  :deep(.el-table) {
    border-radius: 8px;
    overflow: hidden;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
    transition: all 0.3s ease;
  }
  :deep(.el-table:hover) {
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
  }
  :deep(.el-table th) {
    background-color: #f5f7fa;
    font-weight: 600;
    color: #303133;
    border-bottom: 2px solid #e4e7ed;
  }
  :deep(.el-table td) {
    border-bottom: 1px solid #ebeef5;
  }
  :deep(.el-table tr:hover) {
    background-color: #f0f9ff;
  }
  :deep(.el-table .el-table__row) {
    transition: background-color 0.3s ease;
  }
  /* 表格列样式 */
  :deep(.date-cell) {
    font-family: "Courier New", monospace;
    color: #606266;
  }
  :deep(.supplier-cell) {
    font-weight: 500;
    color: #303133;
  }
  :deep(.inspector-cell) {
    color: #409eff;
  }
  :deep(.product-cell) {
    font-weight: 500;
  }
  :deep(.model-cell) {
    color: #606266;
  }
  :deep(.unit-cell) {
    font-size: 12px;
    color: #909399;
  }
  :deep(.quantity-cell) {
    font-family: "Courier New", monospace;
    font-weight: 500;
    color: #303133;
  }
  :deep(.volume-cell) {
    font-family: "Courier New", monospace;
    color: #67c23a;
    font-weight: 500;
  }
  :deep(.state-cell) {
    font-weight: 500;
  }
  :deep(.nature-cell) {
    color: #606266;
  }
  :deep(.company-cell) {
    color: #606266;
  }
  :deep(.result-cell) {
    font-weight: 600;
  }
  :deep(.status-cell) {
    font-weight: 500;
  }
  /* 按钮样式优化 */
  .el-button {
    transition: all 0.3s ease;
    border-radius: 4px;
    font-weight: 500;
  }
  .el-button:hover {
    transform: translateY(-1px);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
  }
  .el-button--primary:hover {
    box-shadow: 0 2px 8px rgba(0, 122, 255, 0.4);
  }
  .el-button--danger:hover {
    box-shadow: 0 2px 8px rgba(245, 108, 108, 0.4);
  }
  /* 输入框样式优化 */
  :deep(.el-input__wrapper) {
    transition: all 0.3s ease;
    border-radius: 4px;
  }
  :deep(.el-input__wrapper:hover) {
    box-shadow: 0 0 0 2px rgba(0, 122, 255, 0.2) !important;
  }
  :deep(.el-input__wrapper.is-focus) {
    box-shadow: 0 0 0 2px rgba(0, 122, 255, 0.4) !important;
  }
  /* 日期选择器样式优化 */
  :deep(.el-date-editor) {
    transition: all 0.3s ease;
  }
  :deep(.el-date-editor:hover .el-input__wrapper) {
    box-shadow: 0 0 0 2px rgba(0, 122, 255, 0.2) !important;
  }
  /* 对话框样式优化 */
  :deep(.el-dialog) {
    border-radius: 8px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  }
  :deep(.el-dialog__header) {
    background-color: #f5f7fa;
    border-bottom: 1px solid #e4e7ed;
    padding: 15px 20px;
    margin: 0;
  }
  :deep(.el-dialog__title) {
    font-size: 16px;
    font-weight: 600;
    color: #303133;
  }
  :deep(.el-dialog__body) {
    padding: 20px;
  }
  :deep(.el-dialog__footer) {
    padding: 15px 20px;
    border-top: 1px solid #e4e7ed;
  }
  .dialog-footer {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
  }
  /* 表单样式优化 */
  :deep(.el-form-item__label) {
    font-weight: 500;
    color: #606266;
  }
  :deep(.el-select) {
    width: 100%;
  }
  /* 分页样式优化 */
  :deep(.el-pagination) {
    margin-top: 20px;
    display: flex;
    justify-content: flex-end;
  }
  :deep(.el-pagination button) {
    border-radius: 4px;
    transition: all 0.3s ease;
  }
  :deep(.el-pagination button:hover) {
    transform: translateY(-1px);
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  }
  /* 标签样式优化 */
  :deep(.el-tag) {
    border-radius: 4px;
    font-weight: 500;
  }
  :deep(.el-tag--success) {
    background-color: #f0f9ff;
    border-color: #b3d8ff;
    color: #409eff;
  }
  :deep(.el-tag--danger) {
    background-color: #fef0f0;
    border-color: #fbc4c4;
    color: #f56c6c;
  }
  /* 操作按钮样式 */
  :deep(.el-button--text) {
    padding: 0 8px;
    font-weight: 500;
    transition: all 0.3s ease;
  }
  :deep(.el-button--text:hover) {
    transform: translateY(-1px);
  }
  /* 响应式设计 */
  @media screen and (max-width: 1200px) {
    .search_form {
      flex-direction: column;
      align-items: stretch;
    }
    .search_form > div {
      width: 100%;
      justify-content: space-between;
    }
    .search_form > div:first-child {
      flex-wrap: wrap;
    }
    .search_title {
      width: 100%;
      margin-bottom: 8px;
    }
  }
  @media screen and (max-width: 768px) {
    .app-container {
      padding: 10px;
    }
    .search_form {
      padding: 15px;
    }
    .table_list {
      padding: 15px;
    }
    .search_form > div {
      flex-direction: column;
      align-items: stretch;
    }
    .search_form > div .el-input,
    .search_form > div .el-date-picker {
      width: 100% !important;
    }
    .search_form > div .el-button {
      width: 100%;
      margin-top: 10px;
    }
    :deep(.el-dialog) {
      width: 90% !important;
    }
    :deep(.el-table) {
      font-size: 12px;
    }
  }
  :deep(.el-table) {
    .el-table__body-wrapper {
      .quantity-cell,
      .volume-cell,
      .dimension-cell {
        font-weight: 600;
        color: #409eff;
        font-family: "Courier New", monospace;
        text-shadow: 0 1px 2px rgba(64, 158, 255, 0.2);
      }
      .spec-cell {
        color: #67c23a;
        font-weight: 500;
        padding: 4px 8px;
        border-radius: 4px;
      }
      .code-cell {
        color: #e6a23c;
        font-family: "Courier New", monospace;
        font-weight: 500;
        padding: 4px 8px;
        border-radius: 4px;
      }
    }
  }
</style>