张诺
2 天以前 195770f92f7d739ffba6447fdbf3a3d5b9e009fa
src/views/qualityManagement/metricMaintenance/index.vue
@@ -1,7 +1,14 @@
<template>
  <div class="app-container metric-maintenance">
    <!-- 左侧:检测标准列表 -->
    <div class="left-panel">
    <el-tabs v-model="activeTab" @tab-change="handleTabChange" class="metric-tabs">
      <el-tab-pane label="原材料检验" name="0" />
      <el-tab-pane label="过程检验" name="1" />
      <el-tab-pane label="出厂检验" name="2" />
    </el-tabs>
    <el-row :gutter="16" class="metric-maintenance-row">
      <!-- 左侧:检测标准列表 -->
      <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12" class="left-col">
        <div class="left-panel">
      <div class="toolbar">
        <div class="toolbar-left"></div>
        <div class="toolbar-right">
@@ -19,6 +26,7 @@
        :isSelection="true"
        :tableLoading="tableLoading"
        :rowClassName="rowClassNameCenter"
        :rowClick="handleTableRowClick"
        @selection-change="handleSelectionChange"
        @pagination="handlePagination"
        :total="page.total"
@@ -50,21 +58,6 @@
            @clear="handleQuery"
          />
        </template>
        <template #inspectTypeHeader>
          <el-select
            v-model="searchForm.inspectType"
            placeholder="类别"
            clearable
            size="small"
            style="width: 120px"
            @change="handleQuery"
            @clear="handleQuery"
          >
            <el-option label="原材料检验" value="0" />
            <el-option label="过程检验" value="1" />
            <el-option label="出厂检验" value="2" />
          </el-select>
        </template>
        <template #stateHeader>
          <el-select
            v-model="searchForm.state"
@@ -81,10 +74,12 @@
          </el-select>
        </template>
      </PIMTable>
    </div>
        </div>
      </el-col>
    <!-- 右侧:标准参数列表 -->
    <div class="right-panel">
      <!-- 右侧:标准参数列表 -->
      <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12" class="right-col">
        <div class="right-panel">
      <div class="right-header">
        <div class="title">标准参数</div>
        <div class="desc" v-if="currentStandard">
@@ -131,7 +126,9 @@
          </template>
        </el-table-column>
      </el-table>
    </div>
        </div>
      </el-col>
    </el-row>
    <!-- 新增 / 编辑检测标准 -->
    <StandardFormDialog
@@ -140,6 +137,7 @@
      :operation-type="standardOperationType"
      :form="standardForm"
      :rules="standardRules"
      :inspect-type="activeTab"
      :process-options="processOptions"
      @confirm="submitStandardForm"
      @close="closeStandardDialog"
@@ -150,6 +148,7 @@
      ref="paramFormDialogRef"
      v-model="paramDialogVisible"
      :operation-type="paramOperationType"
      :inspectType="activeTab.value"
      :form="paramForm"
      @confirm="submitParamForm"
      @close="closeParamDialog"
@@ -179,6 +178,9 @@
import ParamFormDialog from './ParamFormDialog.vue'
const { proxy } = getCurrentInstance()
// 类别 Tab(0=原材料,1=过程,2=出厂)
const activeTab = ref('0')
// 左侧标准列表:整行内容居中(配合样式)
const rowClassNameCenter = () => 'row-center'
@@ -211,8 +213,17 @@
  standardRules: {
    standardNo: [{ required: true, message: '请输入标准编号', trigger: 'blur' }],
    standardName: [{ required: true, message: '请输入标准名称', trigger: 'blur' }],
    inspectType: [{ required: true, message: '请选择检测类型', trigger: 'change' }],
    processId: [{ required: true, message: '请选择工序', trigger: 'change' }]
    processId: [{
      validator: (_rule, value, callback) => {
        const inspectType = String(standardForm.value.inspectType ?? activeTab.value ?? '')
        if (inspectType === '1' && (value === '' || value === null || value === undefined)) {
          callback(new Error('请选择工序'))
          return
        }
        callback()
      },
      trigger: 'change'
    }]
  }
})
@@ -277,19 +288,22 @@
    dataType: 'slot',
    slot: 'standardNoCell',
    minWidth: 160,
    align: 'center',
    headerSlot: 'standardNoHeader'
  },
  {
    label: '标准名称',
    prop: 'standardName',
    minWidth: 180,
    align: 'center',
    headerSlot: 'standardNameHeader'
  },
  {
    label: '类别',
    prop: 'inspectType',
    headerSlot: 'inspectTypeHeader',
    align: 'center',
    dataType: 'tag',
    minWidth: 120,
    formatData: (val) => {
      const map = {
        0: '原材料检验',
@@ -301,12 +315,22 @@
  },
  {
    label: '工序',
    prop: 'processId'
    prop: 'processId',
    align: 'center',
    dataType: 'tag',
    visible: visible => activeTab.value === '1',
    formatData: (val) => {
      const target = processOptions.value.find(
        (item) => String(item.value) === String(val)
      )
      return target?.label || val
    }
  },
  {
    label: '状态',
    prop: 'state',
    headerSlot: 'stateHeader',
    align: 'center',
    dataType: 'tag',
    formatData: (val) => {
      const map = {
@@ -325,7 +349,8 @@
  {
    label: '备注',
    prop: 'remark',
    minWidth: 160
    minWidth: 160,
    align: 'center'
  },
  {
    dataType: 'action',
@@ -369,6 +394,19 @@
    ]
  }
])
const handleTabChange = () => {
  searchForm.value.standardNo = ''
  searchForm.value.standardName = ''
  searchForm.value.remark = ''
  searchForm.value.state = ''
  searchForm.value.processId = ''
  searchForm.value.inspectType = activeTab.value
  page.current = 1
  currentStandard.value = null
  detailTableData.value = []
  paramSelectedRows.value = []
  getStandardList()
}
// 查询列表
const getStandardList = () => {
@@ -440,7 +478,13 @@
  getStandardList()
}
// 左侧行点击,加载右侧参数
// 表格行点击,加载右侧参数
const handleTableRowClick = (row) => {
  currentStandard.value = row
  loadDetail(row.id)
}
// 左侧行点击,加载右侧参数(保留用于标准编号列的点击)
const handleStandardRowClick = (row) => {
  currentStandard.value = row
  loadDetail(row.id)
@@ -556,18 +600,28 @@
      standardName: '',
      remark: '',
      state: '0',
      inspectType: '',
      processId: ''
      inspectType: activeTab.value,
      processId: activeTab.value === '1' ? '' : null
    })
  } else if (type === 'edit' && row) {
    Object.assign(standardForm.value, row)
    Object.assign(standardForm.value, {
      ...row,
      // 确保 inspectType 和 state 转换为字符串,以匹配 el-select 的 value 类型
      inspectType: row.inspectType !== null && row.inspectType !== undefined ? String(row.inspectType) : '',
      state: row.state !== null && row.state !== undefined ? String(row.state) : '0',
      // 确保 processId 转换为字符串或数字(根据实际需要)
      processId: String(row.inspectType) === '1' && row.processId !== null && row.processId !== undefined ? row.processId : null
    })
  } else if (type === 'copy' && row) {
    const { id, ...rest } = row
    Object.assign(standardForm.value, {
      ...rest,
      id: undefined,
      standardNo: '',
      state: '0'
      state: '0',
      // 确保 inspectType 转换为字符串
      inspectType: activeTab.value,
      processId: activeTab.value === '1' ? (rest.processId ?? '') : null
    })
  }
  standardDialogVisible.value = true
@@ -580,6 +634,10 @@
const submitStandardForm = () => {
  const payload = { ...standardForm.value }
  payload.inspectType = activeTab.value
  if (String(payload.inspectType) !== '1') {
    payload.processId = null
  }
  const isEdit = standardOperationType.value === 'edit'
  if (isEdit) {
    qualityTestStandardUpdate(payload).then(() => {
@@ -657,6 +715,7 @@
}
onMounted(() => {
  searchForm.value.inspectType = activeTab.value
  getProcessList()
  getStandardList()
})
@@ -664,16 +723,39 @@
<style scoped>
.metric-maintenance {
  display: flex;
  gap: 16px;
  padding: 0;
  min-width: 0;
}
.metric-tabs {
  margin: 10px;
}
.metric-maintenance-row {
  width: 100%;
}
.metric-maintenance-row .left-col,
.metric-maintenance-row .right-col {
  margin-bottom: 16px;
}
.left-panel,
.right-panel {
  flex: 1;
  min-width: 0;
  background: #ffffff;
  padding: 16px;
  box-sizing: border-box;
  overflow: hidden;
  height: 100%;
  min-height: 400px;
}
@media (max-width: 768px) {
  .left-panel,
  .right-panel {
    padding: 12px;
  }
}
.toolbar {
@@ -681,6 +763,8 @@
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
  flex-wrap: wrap;
  gap: 8px;
}
.toolbar-left {
@@ -692,6 +776,9 @@
.toolbar-right {
  flex-shrink: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.search-label {
@@ -751,4 +838,23 @@
:deep(.center-table .el-table__body-wrapper td .cell) {
  text-align: center !important;
}
</style>
/* PIMTable 表头居中 */
:deep(.lims-table .pim-table-header-cell) {
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
:deep(.lims-table .pim-table-header-title) {
  text-align: center;
  width: 100%;
}
:deep(.lims-table .pim-table-header-extra) {
  width: 100%;
  margin-top: 4px;
}
</style>