feat(mes): 适配通用质检缺陷记录 API,更新 IQC 缺陷列表组件

配合后端 mes_qc_defect_record 通用化重构,前端同步适配。

主要变更:
1. 新增 api/mes/qc/defect-record/index.ts 通用缺陷记录 API
2. IqcDefectList.vue 切换至 QcDefectRecordApi,字段映射调整
   (defectName→name, defectLevel→level, defectQuantity→quantity, iqcId→qcId)
3. 新增 qcType=1 参数标识 IQC 类型
pull/871/MERGE
YunaiV 2026-02-21 16:52:03 +08:00
parent 473a0d9017
commit 87d10eacb8
3 changed files with 94 additions and 67 deletions

View File

@ -0,0 +1,37 @@
import request from '@/config/axios'
// TODO @AIdefect/record/index.ts
// MES 质检缺陷记录 VO
export interface QcDefectRecordVO {
id: number // 编号
qcType: number // 检验类型
qcId: number // 检验单 ID
lineId: number // 检验行 ID
name: string // 缺陷描述
level: number // 缺陷等级
quantity: number // 缺陷数量
remark: string // 备注
}
// MES 质检缺陷记录 API
export const QcDefectRecordApi = {
// 查询质检缺陷记录分页
getDefectRecordPage: async (params: any) => {
return await request.get({ url: `/mes/qc/defect-record/page`, params })
},
// 新增质检缺陷记录
createDefectRecord: async (data: QcDefectRecordVO) => {
return await request.post({ url: `/mes/qc/defect-record/create`, data })
},
// 修改质检缺陷记录
updateDefectRecord: async (data: QcDefectRecordVO) => {
return await request.put({ url: `/mes/qc/defect-record/update`, data })
},
// 删除质检缺陷记录
deleteDefectRecord: async (id: number) => {
return await request.delete({ url: `/mes/qc/defect-record/delete?id=` + id })
}
}

View File

@ -2,13 +2,15 @@
<template>
<div>
<!-- 操作栏 -->
<!-- // TODO @AI使 mes:qc-record:create todo
@芋艿说下这个情况 -->
<el-row class="mb-10px">
<el-button
type="primary"
plain
size="small"
@click="openForm('create')"
v-hasPermi="['mes:qc-iqc:create']"
v-hasPermi="['mes:qc-defect-record:create']"
>
<Icon icon="ep:plus" class="mr-5px" /> 新增缺陷记录
</el-button>
@ -16,13 +18,13 @@
<!-- 列表 -->
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
<el-table-column label="缺陷描述" align="center" prop="defectName" min-width="200" />
<el-table-column label="缺陷等级" align="center" prop="defectLevel" width="120">
<el-table-column label="缺陷描述" align="center" prop="name" min-width="200" />
<el-table-column label="缺陷等级" align="center" prop="level" width="120">
<template #default="scope">
<dict-tag :type="DICT_TYPE.MES_DEFECT_LEVEL" :value="scope.row.defectLevel" />
<dict-tag :type="DICT_TYPE.MES_DEFECT_LEVEL" :value="scope.row.level" />
</template>
</el-table-column>
<el-table-column label="缺陷数量" align="center" prop="defectQuantity" width="100" />
<el-table-column label="缺陷数量" align="center" prop="quantity" width="100" />
<el-table-column label="备注" align="center" prop="remark" min-width="150" />
<el-table-column
label="创建时间"
@ -37,7 +39,7 @@
link
type="primary"
@click="openForm('update', scope.row.id)"
v-hasPermi="['mes:qc-iqc:update']"
v-hasPermi="['mes:qc-defect-record:update']"
>
编辑
</el-button>
@ -45,7 +47,7 @@
link
type="danger"
@click="handleDelete(scope.row.id)"
v-hasPermi="['mes:qc-iqc:update']"
v-hasPermi="['mes:qc-defect-record:update']"
>
删除
</el-button>
@ -63,7 +65,6 @@
v-loading="formLoading"
>
<el-form-item label="检验行" prop="lineId">
<!-- TODO @AI使用组件 -->
<el-select v-model="formData.lineId" placeholder="请选择检验行" filterable class="!w-1/1">
<el-option
v-for="line in lineList"
@ -75,11 +76,11 @@
/>
</el-select>
</el-form-item>
<el-form-item label="缺陷描述" prop="defectName">
<el-input v-model="formData.defectName" placeholder="请输入缺陷描述" />
<el-form-item label="缺陷描述" prop="name">
<el-input v-model="formData.name" placeholder="请输入缺陷描述" />
</el-form-item>
<el-form-item label="缺陷等级" prop="defectLevel">
<el-select v-model="formData.defectLevel" placeholder="请选择缺陷等级" class="!w-1/1">
<el-form-item label="缺陷等级" prop="level">
<el-select v-model="formData.level" placeholder="请选择缺陷等级" class="!w-1/1">
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.MES_DEFECT_LEVEL)"
:key="dict.value"
@ -88,9 +89,9 @@
/>
</el-select>
</el-form-item>
<el-form-item label="缺陷数量" prop="defectQuantity">
<el-form-item label="缺陷数量" prop="quantity">
<el-input-number
v-model="formData.defectQuantity"
v-model="formData.quantity"
:min="1"
placeholder="请输入"
class="!w-1/1"
@ -111,7 +112,7 @@
<script setup lang="ts">
import { dateFormatter } from '@/utils/formatTime'
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
import { QcIqcDefectApi, QcIqcDefectVO } from '@/api/mes/qc/iqc/defect'
import { QcDefectRecordApi, QcDefectRecordVO } from '@/api/mes/qc/defect-record'
import { QcIqcLineApi, QcIqcLineVO } from '@/api/mes/qc/iqc/line'
defineOptions({ name: 'IqcDefectList' })
@ -125,7 +126,7 @@ const message = useMessage()
const { t } = useI18n()
const loading = ref(false)
const list = ref<QcIqcDefectVO[]>([])
const list = ref<QcDefectRecordVO[]>([])
const lineList = ref<QcIqcLineVO[]>([]) //
/** 查询列表 */
@ -133,10 +134,11 @@ const getList = async () => {
if (!props.iqcId) return
loading.value = true
try {
const data = await QcIqcDefectApi.getIqcDefectPage({
const data = await QcDefectRecordApi.getDefectRecordPage({
pageNo: 1,
pageSize: 100,
iqcId: props.iqcId,
qcType: 1,
qcId: props.iqcId,
lineId: props.lineId
})
list.value = data.list
@ -164,17 +166,18 @@ const formType = ref('')
const formRef = ref()
const formData = ref({
id: undefined,
iqcId: undefined as number | undefined,
qcType: 1 as number,
qcId: undefined as number | undefined,
lineId: undefined as number | undefined,
defectName: undefined,
defectLevel: undefined,
defectQuantity: 1,
name: undefined,
level: undefined,
quantity: 1,
remark: undefined
})
const formRules = reactive({
lineId: [{ required: true, message: '检验行不能为空', trigger: 'change' }],
defectName: [{ required: true, message: '缺陷描述不能为空', trigger: 'blur' }],
defectLevel: [{ required: true, message: '缺陷等级不能为空', trigger: 'change' }]
name: [{ required: true, message: '缺陷描述不能为空', trigger: 'blur' }],
level: [{ required: true, message: '缺陷等级不能为空', trigger: 'change' }]
})
/** 添加/修改操作 */
@ -183,7 +186,7 @@ const openForm = async (type: string, id?: number) => {
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
formData.value.iqcId = props.iqcId
formData.value.qcId = props.iqcId
// lineId prop lineId
if (props.lineId) {
formData.value.lineId = props.lineId
@ -211,12 +214,12 @@ const submitForm = async () => {
if (!valid) return
formLoading.value = true
try {
const data = formData.value as unknown as QcIqcDefectVO
const data = formData.value as unknown as QcDefectRecordVO
if (formType.value === 'create') {
await QcIqcDefectApi.createIqcDefect(data)
await QcDefectRecordApi.createDefectRecord(data)
message.success(t('common.createSuccess'))
} else {
await QcIqcDefectApi.updateIqcDefect(data)
await QcDefectRecordApi.updateDefectRecord(data)
message.success(t('common.updateSuccess'))
}
dialogVisible.value = false
@ -230,11 +233,12 @@ const submitForm = async () => {
const resetForm = () => {
formData.value = {
id: undefined,
iqcId: undefined,
qcType: 1,
qcId: undefined,
lineId: undefined,
defectName: undefined,
defectLevel: undefined,
defectQuantity: 1,
name: undefined,
level: undefined,
quantity: 1,
remark: undefined
}
formRef.value?.resetFields()
@ -244,7 +248,7 @@ const resetForm = () => {
const handleDelete = async (id: number) => {
try {
await message.delConfirm()
await QcIqcDefectApi.deleteIqcDefect(id)
await QcDefectRecordApi.deleteDefectRecord(id)
message.success(t('common.delSuccess'))
await getList()
} catch {}

View File

@ -12,7 +12,7 @@
<el-row :gutter="16">
<el-col :span="8">
<el-form-item label="检验单编号" prop="code">
<!-- TODO @芋艿自动编码未迁移暂用手动输入 -->
<!-- TODO @AI参考别的模块搞一下 -->
<el-input v-model="formData.code" placeholder="请输入检验单编号" />
</el-form-item>
</el-col>
@ -21,6 +21,7 @@
<el-input v-model="formData.name" placeholder="请输入检验单名称" />
</el-form-item>
</el-col>
<!-- TODO @AI貌似不用填写这个字段哈 -->
<el-col :span="8">
<el-form-item label="检验模板" prop="templateId">
<el-select
@ -42,13 +43,14 @@
<el-divider content-position="left">物料与供应商</el-divider>
<el-row :gutter="16">
<el-col :span="8">
<el-form-item label="产品物料" prop="itemId">
<MdItemSelect v-model="formData.itemId" placeholder="请选择产品物料" class="!w-1/1" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="供应商" prop="vendorId">
<MdVendorSelect
v-model="formData.vendorId"
placeholder="请选择供应商"
class="!w-1/1"
/>
<MdVendorSelect v-model="formData.vendorId" placeholder="请选择供应商" class="!w-1/1" />
</el-form-item>
</el-col>
<el-col :span="8">
@ -57,21 +59,10 @@
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="8">
<el-form-item label="产品物料" prop="itemId">
<MdItemSelect
v-model="formData.itemId"
placeholder="请选择产品物料"
class="!w-1/1"
/>
</el-form-item>
</el-col>
</el-row>
<el-divider content-position="left">检测情况</el-divider>
<el-row :gutter="16">
<el-col :span="6">
<el-col :span="8">
<el-form-item label="接收数量" prop="receivedQuantity">
<el-input-number
v-model="formData.receivedQuantity"
@ -82,17 +73,7 @@
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="检测数量" prop="checkQuantity">
<el-input-number
v-model="formData.checkQuantity"
:min="0"
placeholder="请输入"
class="!w-1/1"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-col :span="8">
<el-form-item label="合格品数量" prop="qualifiedQuantity">
<el-input-number
v-model="formData.qualifiedQuantity"
@ -102,7 +83,7 @@
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-col :span="8">
<el-form-item label="不合格品数量" prop="unqualifiedQuantity">
<el-input-number
v-model="formData.unqualifiedQuantity"
@ -136,6 +117,7 @@
/>
</el-form-item>
</el-col>
<!-- TODO @AI应该不用填写 -->
<el-col :span="8">
<el-form-item label="检测人员" prop="inspectorUserId">
<UserSelect
@ -218,13 +200,16 @@
<el-tab-pane label="检验项" name="line">
<IqcLineList :iqc-id="formData.id" />
</el-tab-pane>
<!-- TODO @AI应该是 IqcDefectList可以重构到 /Users/yunai/Java/yudao-all-in-one/yudao-ui-admin-vue3/src/views/mes/qc/defect/record/components/ 提供给每个模块使用传递 qc-idqc-type -->
<el-tab-pane label="缺陷记录" name="defect">
<IqcDefectList :iqc-id="formData.id" />
</el-tab-pane>
<!-- TODO @AI检测结果缺少一个 List -->
</el-tabs>
</template>
<template #footer>
<!-- TODO @AI不需要 status 判断 -->
<el-button
@click="submitForm"
type="primary"
@ -233,6 +218,7 @@
>
</el-button>
<!-- TODO @AI不需要 完成 操作 -->
<el-button
@click="handleComplete"
type="success"
@ -247,7 +233,7 @@
</template>
<script setup lang="ts">
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { QcIqcApi, QcIqcVO } from '@/api/mes/qc/iqc'
import { QcTemplateApi } from '@/api/mes/qc/template'
import MdVendorSelect from '@/views/mes/md/vendor/components/MdVendorSelect.vue'
@ -286,6 +272,7 @@ const formData = ref({
maxUnqualifiedQuantity: undefined,
receivedQuantity: undefined,
checkQuantity: undefined,
// TODO @AIqualifiedQuantityunqualifiedQuantity 使 undefined
qualifiedQuantity: 0,
unqualifiedQuantity: 0,
checkResult: undefined,
@ -325,8 +312,7 @@ const open = async (type: string, id?: number) => {
if (id) {
formLoading.value = true
try {
const data = await QcIqcApi.getIqc(id)
formData.value = data
formData.value = await QcIqcApi.getIqc(id)
} finally {
formLoading.value = false
}
@ -400,7 +386,7 @@ const resetForm = () => {
inspectDate: undefined,
inspectorUserId: undefined,
remark: undefined,
status: 0,
status: 0, // TODO @AI
criticalRate: 0,
majorRate: 0,
minorRate: 0,