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

View File

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