feat(mes/qc): 迁移待检任务(pendinginspect)

迁移待检任务列表页到 antd 和 ele。新增分页查询 API,列表展示
来源单据类型、检验类型、物料、数量、供应商/工单/客户等字段。
pull/350/head
YunaiV 2026-05-29 22:08:51 +08:00
parent b4e7573d10
commit 76e9df6e8e
6 changed files with 678 additions and 0 deletions

View File

@ -0,0 +1,41 @@
import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace MesQcPendingInspectApi {
/** MES 待检任务 */
export interface PendingInspect {
sourceDocType?: number; // 来源单据类型MesBizTypeConstants
sourceDocId?: number; // 来源单据 ID
sourceLineId?: number; // 来源单据行 ID
sourceDocCode?: string; // 来源单据编号
qcType?: number; // 检验类型MesQcTypeEnum
itemId?: number; // 物料 ID
itemCode?: string; // 物料编码
itemName?: string; // 物料名称
specification?: string; // 规格型号
unitName?: string; // 单位名称
quantity?: number; // 待检数量
// 供应商IQC 场景)
vendorId?: number; // 供应商 ID
vendorName?: string; // 供应商名称
// 工单/工作站/任务IPQC/RQC 场景)
workOrderId?: number; // 生产工单 ID
workstationId?: number; // 工作站 ID
workstationName?: string; // 工作站名称
taskId?: number; // 生产任务 ID
taskCode?: string; // 生产任务编码
// 客户OQC/RQC 场景)
clientId?: number; // 客户 ID
clientName?: string; // 客户名称
recordTime?: number; // 记录时间epoch ms
}
}
/** 查询待检任务分页 */
export function getPendingInspectPage(params: PageParam) {
return requestClient.get<PageResult<MesQcPendingInspectApi.PendingInspect>>(
'/mes/qc/pending-inspect/page',
{ params },
);
}

View File

@ -0,0 +1,103 @@
import type { VbenFormSchema } from '#/adapter/form';
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { MesQcPendingInspectApi } from '#/api/mes/qc/pendinginspect';
import { markRaw } from 'vue';
import { DICT_TYPE } from '@vben/constants';
import { getDictOptions } from '@vben/hooks';
import MdItemSelect from '#/views/mes/md/item/components/md-item-select.vue';
/** 列表的搜索表单 */
export function useGridFormSchema(): VbenFormSchema[] {
return [
{
fieldName: 'sourceDocCode',
label: '来源单据编号',
component: 'Input',
componentProps: {
allowClear: true,
placeholder: '请输入来源单据编号',
},
},
{
fieldName: 'itemId',
label: '产品物料',
component: markRaw(MdItemSelect),
componentProps: {
placeholder: '请选择产品物料',
},
},
{
fieldName: 'qcType',
label: '检验类型',
component: 'Select',
componentProps: {
allowClear: true,
options: getDictOptions(DICT_TYPE.MES_QC_TYPE, 'number'),
placeholder: '请选择检验类型',
},
},
];
}
/** 列表的字段 */
export function useGridColumns(): VxeTableGridOptions<MesQcPendingInspectApi.PendingInspect>['columns'] {
return [
{
field: 'sourceDocType',
title: '来源单据类型',
width: 130,
cellRender: {
name: 'CellDict',
props: { type: DICT_TYPE.MES_QC_SOURCE_DOC_TYPE },
},
},
{
field: 'sourceDocCode',
title: '来源单据编号',
width: 160,
},
{
field: 'qcType',
title: '检验类型',
minWidth: 150,
cellRender: {
name: 'CellDict',
props: { type: DICT_TYPE.MES_QC_TYPE },
},
},
{
field: 'itemCode',
title: '物料编码',
minWidth: 130,
},
{
field: 'itemName',
title: '物料名称',
minWidth: 150,
},
{
field: 'specification',
title: '规格型号',
width: 130,
},
{
field: 'quantity',
title: '待检数量',
width: 100,
},
{
field: 'unitName',
title: '单位',
width: 80,
},
{
title: '操作',
width: 130,
fixed: 'right',
slots: { default: 'actions' },
},
];
}

View File

@ -0,0 +1,193 @@
<script lang="ts" setup>
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { MesQcIpqcApi } from '#/api/mes/qc/ipqc';
import type { MesQcIqcApi } from '#/api/mes/qc/iqc';
import type { MesQcOqcApi } from '#/api/mes/qc/oqc';
import type { MesQcPendingInspectApi } from '#/api/mes/qc/pendinginspect';
import type { MesQcRqcApi } from '#/api/mes/qc/rqc';
import { DocAlert, Page, useVbenModal } from '@vben/common-ui';
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
import { getPendingInspectPage } from '#/api/mes/qc/pendinginspect';
import { MesQcTypeEnum } from '#/views/mes/utils/constants';
import IpqcForm from '../ipqc/modules/form.vue';
import IqcForm from '../iqc/modules/form.vue';
import OqcForm from '../oqc/modules/form.vue';
import RqcForm from '../rqc/modules/form.vue';
import { useGridColumns, useGridFormSchema } from './data';
const [IqcFormModal, iqcFormModalApi] = useVbenModal({
connectedComponent: IqcForm,
destroyOnClose: true,
});
const [IpqcFormModal, ipqcFormModalApi] = useVbenModal({
connectedComponent: IpqcForm,
destroyOnClose: true,
});
const [OqcFormModal, oqcFormModalApi] = useVbenModal({
connectedComponent: OqcForm,
destroyOnClose: true,
});
const [RqcFormModal, rqcFormModalApi] = useVbenModal({
connectedComponent: RqcForm,
destroyOnClose: true,
});
/** 刷新表格 */
function handleRefresh() {
gridApi.query();
}
/** 创建来料检验单IQC */
function handleCreateIqc(row: MesQcPendingInspectApi.PendingInspect) {
const prefill: MesQcIqcApi.Iqc = {
itemId: row.itemId,
name: `${row.sourceDocCode} 来料检验单`,
receivedQuantity: row.quantity,
receiveDate: row.recordTime,
sourceDocCode: row.sourceDocCode,
sourceDocId: row.sourceDocId,
sourceDocType: row.sourceDocType,
sourceLineId: row.sourceLineId,
vendorId: row.vendorId,
};
iqcFormModalApi.setData({ formType: 'create', prefill }).open();
}
/** 创建过程检验单IPQC */
function handleCreateIpqc(row: MesQcPendingInspectApi.PendingInspect) {
const prefill: MesQcIpqcApi.Ipqc = {
checkQuantity: row.quantity,
inspectDate: row.recordTime,
itemId: row.itemId,
name: `${row.sourceDocCode} 过程检验单`,
sourceDocCode: row.sourceDocCode,
sourceDocId: row.sourceDocId,
sourceDocType: row.sourceDocType,
sourceLineId: row.sourceLineId,
taskId: row.taskId,
workOrderId: row.workOrderId,
workstationId: row.workstationId,
};
ipqcFormModalApi.setData({ formType: 'create', prefill }).open();
}
/** 创建出货检验单OQC */
function handleCreateOqc(row: MesQcPendingInspectApi.PendingInspect) {
const prefill: MesQcOqcApi.Oqc = {
clientId: row.clientId,
itemId: row.itemId,
name: `${row.sourceDocCode} 出货检验单`,
outDate: row.recordTime,
outQuantity: row.quantity,
sourceDocCode: row.sourceDocCode,
sourceDocId: row.sourceDocId,
sourceDocType: row.sourceDocType,
sourceLineId: row.sourceLineId,
};
oqcFormModalApi.setData({ formType: 'create', prefill }).open();
}
/** 创建退货检验单RQC */
function handleCreateRqc(row: MesQcPendingInspectApi.PendingInspect) {
const prefill: MesQcRqcApi.Rqc = {
checkQuantity: row.quantity,
inspectDate: row.recordTime,
itemId: row.itemId,
name: `${row.sourceDocCode} 退料检验单`,
sourceDocCode: row.sourceDocCode,
sourceDocId: row.sourceDocId,
sourceDocType: row.sourceDocType,
sourceLineId: row.sourceLineId,
};
rqcFormModalApi.setData({ formType: 'create', prefill }).open();
}
const [Grid, gridApi] = useVbenVxeGrid({
formOptions: {
schema: useGridFormSchema(),
},
gridOptions: {
columns: useGridColumns(),
height: 'auto',
keepSource: true,
proxyConfig: {
ajax: {
query: async ({ page }, formValues) => {
return await getPendingInspectPage({
pageNo: page.currentPage,
pageSize: page.pageSize,
...formValues,
});
},
},
},
rowConfig: {
isHover: true,
},
toolbarConfig: {
refresh: true,
search: true,
},
} as VxeTableGridOptions<MesQcPendingInspectApi.PendingInspect>,
});
</script>
<template>
<Page auto-content-height>
<template #doc>
<DocAlert
title="【质量】待检任务、检验结果、缺陷记录"
url="https://doc.iocoder.cn/mes/qc/pending-inspect/"
/>
</template>
<IqcFormModal @success="handleRefresh" />
<IpqcFormModal @success="handleRefresh" />
<OqcFormModal @success="handleRefresh" />
<RqcFormModal @success="handleRefresh" />
<Grid table-title="">
<template #actions="{ row }">
<TableAction
:actions="[
{
label: '来料检验',
type: 'link',
icon: ACTION_ICON.ADD,
auth: ['mes:qc-iqc:create'],
ifShow: row.qcType === MesQcTypeEnum.IQC,
onClick: handleCreateIqc.bind(null, row),
},
{
label: '过程检验',
type: 'link',
icon: ACTION_ICON.ADD,
auth: ['mes:qc-ipqc:create'],
ifShow: row.qcType === MesQcTypeEnum.IPQC,
onClick: handleCreateIpqc.bind(null, row),
},
{
label: '出货检验',
type: 'link',
icon: ACTION_ICON.ADD,
auth: ['mes:qc-oqc:create'],
ifShow: row.qcType === MesQcTypeEnum.OQC,
onClick: handleCreateOqc.bind(null, row),
},
{
label: '退料检验',
type: 'link',
icon: ACTION_ICON.ADD,
auth: ['mes:qc-rqc:create'],
ifShow: row.qcType === MesQcTypeEnum.RQC,
onClick: handleCreateRqc.bind(null, row),
},
]"
/>
</template>
</Grid>
</Page>
</template>

View File

@ -0,0 +1,41 @@
import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace MesQcPendingInspectApi {
/** MES 待检任务 */
export interface PendingInspect {
sourceDocType?: number; // 来源单据类型MesBizTypeConstants
sourceDocId?: number; // 来源单据 ID
sourceLineId?: number; // 来源单据行 ID
sourceDocCode?: string; // 来源单据编号
qcType?: number; // 检验类型MesQcTypeEnum
itemId?: number; // 物料 ID
itemCode?: string; // 物料编码
itemName?: string; // 物料名称
specification?: string; // 规格型号
unitName?: string; // 单位名称
quantity?: number; // 待检数量
// 供应商IQC 场景)
vendorId?: number; // 供应商 ID
vendorName?: string; // 供应商名称
// 工单/工作站/任务IPQC/RQC 场景)
workOrderId?: number; // 生产工单 ID
workstationId?: number; // 工作站 ID
workstationName?: string; // 工作站名称
taskId?: number; // 生产任务 ID
taskCode?: string; // 生产任务编码
// 客户OQC/RQC 场景)
clientId?: number; // 客户 ID
clientName?: string; // 客户名称
recordTime?: number; // 记录时间epoch ms
}
}
/** 查询待检任务分页 */
export function getPendingInspectPage(params: PageParam) {
return requestClient.get<PageResult<MesQcPendingInspectApi.PendingInspect>>(
'/mes/qc/pending-inspect/page',
{ params },
);
}

View File

@ -0,0 +1,103 @@
import type { VbenFormSchema } from '#/adapter/form';
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { MesQcPendingInspectApi } from '#/api/mes/qc/pendinginspect';
import { markRaw } from 'vue';
import { DICT_TYPE } from '@vben/constants';
import { getDictOptions } from '@vben/hooks';
import MdItemSelect from '#/views/mes/md/item/components/md-item-select.vue';
/** 列表的搜索表单 */
export function useGridFormSchema(): VbenFormSchema[] {
return [
{
fieldName: 'sourceDocCode',
label: '来源单据编号',
component: 'Input',
componentProps: {
clearable: true,
placeholder: '请输入来源单据编号',
},
},
{
fieldName: 'itemId',
label: '产品物料',
component: markRaw(MdItemSelect),
componentProps: {
placeholder: '请选择产品物料',
},
},
{
fieldName: 'qcType',
label: '检验类型',
component: 'Select',
componentProps: {
clearable: true,
options: getDictOptions(DICT_TYPE.MES_QC_TYPE, 'number'),
placeholder: '请选择检验类型',
},
},
];
}
/** 列表的字段 */
export function useGridColumns(): VxeTableGridOptions<MesQcPendingInspectApi.PendingInspect>['columns'] {
return [
{
field: 'sourceDocType',
title: '来源单据类型',
width: 130,
cellRender: {
name: 'CellDict',
props: { type: DICT_TYPE.MES_QC_SOURCE_DOC_TYPE },
},
},
{
field: 'sourceDocCode',
title: '来源单据编号',
width: 160,
},
{
field: 'qcType',
title: '检验类型',
minWidth: 150,
cellRender: {
name: 'CellDict',
props: { type: DICT_TYPE.MES_QC_TYPE },
},
},
{
field: 'itemCode',
title: '物料编码',
minWidth: 130,
},
{
field: 'itemName',
title: '物料名称',
minWidth: 150,
},
{
field: 'specification',
title: '规格型号',
width: 130,
},
{
field: 'quantity',
title: '待检数量',
width: 100,
},
{
field: 'unitName',
title: '单位',
width: 80,
},
{
title: '操作',
width: 130,
fixed: 'right',
slots: { default: 'actions' },
},
];
}

View File

@ -0,0 +1,197 @@
<script lang="ts" setup>
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { MesQcIpqcApi } from '#/api/mes/qc/ipqc';
import type { MesQcIqcApi } from '#/api/mes/qc/iqc';
import type { MesQcOqcApi } from '#/api/mes/qc/oqc';
import type { MesQcPendingInspectApi } from '#/api/mes/qc/pendinginspect';
import type { MesQcRqcApi } from '#/api/mes/qc/rqc';
import { DocAlert, Page, useVbenModal } from '@vben/common-ui';
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
import { getPendingInspectPage } from '#/api/mes/qc/pendinginspect';
import { MesQcTypeEnum } from '#/views/mes/utils/constants';
import IpqcForm from '../ipqc/modules/form.vue';
import IqcForm from '../iqc/modules/form.vue';
import OqcForm from '../oqc/modules/form.vue';
import RqcForm from '../rqc/modules/form.vue';
import { useGridColumns, useGridFormSchema } from './data';
const [IqcFormModal, iqcFormModalApi] = useVbenModal({
connectedComponent: IqcForm,
destroyOnClose: true,
});
const [IpqcFormModal, ipqcFormModalApi] = useVbenModal({
connectedComponent: IpqcForm,
destroyOnClose: true,
});
const [OqcFormModal, oqcFormModalApi] = useVbenModal({
connectedComponent: OqcForm,
destroyOnClose: true,
});
const [RqcFormModal, rqcFormModalApi] = useVbenModal({
connectedComponent: RqcForm,
destroyOnClose: true,
});
/** 刷新表格 */
function handleRefresh() {
gridApi.query();
}
/** 创建来料检验单IQC */
function handleCreateIqc(row: MesQcPendingInspectApi.PendingInspect) {
const prefill: MesQcIqcApi.Iqc = {
itemId: row.itemId,
name: `${row.sourceDocCode} 来料检验单`,
receivedQuantity: row.quantity,
receiveDate: row.recordTime,
sourceDocCode: row.sourceDocCode,
sourceDocId: row.sourceDocId,
sourceDocType: row.sourceDocType,
sourceLineId: row.sourceLineId,
vendorId: row.vendorId,
};
iqcFormModalApi.setData({ formType: 'create', prefill }).open();
}
/** 创建过程检验单IPQC */
function handleCreateIpqc(row: MesQcPendingInspectApi.PendingInspect) {
const prefill: MesQcIpqcApi.Ipqc = {
checkQuantity: row.quantity,
inspectDate: row.recordTime,
itemId: row.itemId,
name: `${row.sourceDocCode} 过程检验单`,
sourceDocCode: row.sourceDocCode,
sourceDocId: row.sourceDocId,
sourceDocType: row.sourceDocType,
sourceLineId: row.sourceLineId,
taskId: row.taskId,
workOrderId: row.workOrderId,
workstationId: row.workstationId,
};
ipqcFormModalApi.setData({ formType: 'create', prefill }).open();
}
/** 创建出货检验单OQC */
function handleCreateOqc(row: MesQcPendingInspectApi.PendingInspect) {
const prefill: MesQcOqcApi.Oqc = {
clientId: row.clientId,
itemId: row.itemId,
name: `${row.sourceDocCode} 出货检验单`,
outDate: row.recordTime,
outQuantity: row.quantity,
sourceDocCode: row.sourceDocCode,
sourceDocId: row.sourceDocId,
sourceDocType: row.sourceDocType,
sourceLineId: row.sourceLineId,
};
oqcFormModalApi.setData({ formType: 'create', prefill }).open();
}
/** 创建退货检验单RQC */
function handleCreateRqc(row: MesQcPendingInspectApi.PendingInspect) {
const prefill: MesQcRqcApi.Rqc = {
checkQuantity: row.quantity,
inspectDate: row.recordTime,
itemId: row.itemId,
name: `${row.sourceDocCode} 退料检验单`,
sourceDocCode: row.sourceDocCode,
sourceDocId: row.sourceDocId,
sourceDocType: row.sourceDocType,
sourceLineId: row.sourceLineId,
};
rqcFormModalApi.setData({ formType: 'create', prefill }).open();
}
const [Grid, gridApi] = useVbenVxeGrid({
formOptions: {
schema: useGridFormSchema(),
},
gridOptions: {
columns: useGridColumns(),
height: 'auto',
keepSource: true,
proxyConfig: {
ajax: {
query: async ({ page }, formValues) => {
return await getPendingInspectPage({
pageNo: page.currentPage,
pageSize: page.pageSize,
...formValues,
});
},
},
},
rowConfig: {
isHover: true,
},
toolbarConfig: {
refresh: true,
search: true,
},
} as VxeTableGridOptions<MesQcPendingInspectApi.PendingInspect>,
});
</script>
<template>
<Page auto-content-height>
<template #doc>
<DocAlert
title="【质量】待检任务、检验结果、缺陷记录"
url="https://doc.iocoder.cn/mes/qc/pending-inspect/"
/>
</template>
<IqcFormModal @success="handleRefresh" />
<IpqcFormModal @success="handleRefresh" />
<OqcFormModal @success="handleRefresh" />
<RqcFormModal @success="handleRefresh" />
<Grid table-title="">
<template #actions="{ row }">
<TableAction
:actions="[
{
label: '来料检验',
type: 'primary',
link: true,
icon: ACTION_ICON.ADD,
auth: ['mes:qc-iqc:create'],
ifShow: row.qcType === MesQcTypeEnum.IQC,
onClick: handleCreateIqc.bind(null, row),
},
{
label: '过程检验',
type: 'primary',
link: true,
icon: ACTION_ICON.ADD,
auth: ['mes:qc-ipqc:create'],
ifShow: row.qcType === MesQcTypeEnum.IPQC,
onClick: handleCreateIpqc.bind(null, row),
},
{
label: '出货检验',
type: 'primary',
link: true,
icon: ACTION_ICON.ADD,
auth: ['mes:qc-oqc:create'],
ifShow: row.qcType === MesQcTypeEnum.OQC,
onClick: handleCreateOqc.bind(null, row),
},
{
label: '退料检验',
type: 'primary',
link: true,
icon: ACTION_ICON.ADD,
auth: ['mes:qc-rqc:create'],
ifShow: row.qcType === MesQcTypeEnum.RQC,
onClick: handleCreateRqc.bind(null, row),
},
]"
/>
</template>
</Grid>
</Page>
</template>