原材料送检记录
This commit is contained in:
@@ -16,6 +16,7 @@ enum Api {
|
||||
queryPrinters = '/xslmes/mesXslRawMaterialCard/queryPrinters',
|
||||
prepareNativePrint = '/xslmes/mesXslRawMaterialCard/prepareNativePrint',
|
||||
printPdf = '/xslmes/mesXslRawMaterialCard/printPdf',
|
||||
createInspectRecordByCard = '/xslmes/mesXslRawMaterialInspectRecord/createByCard',
|
||||
}
|
||||
|
||||
export const getExportUrl = Api.exportXls;
|
||||
@@ -63,3 +64,6 @@ export const prepareNativePrint = (id: string) =>
|
||||
/** id + 前端生成的 pdfBase64;printerName 空则用默认队列 */
|
||||
export const printPdf = (data: { id: string; printerName?: string; pdfBase64: string; fileName?: string }) =>
|
||||
defHttp.post({ url: Api.printPdf, data, timeout: 3 * 60 * 1000 });
|
||||
|
||||
export const createInspectRecordByCard = (rawMaterialCardId: string) =>
|
||||
defHttp.post({ url: Api.createInspectRecordByCard, params: { rawMaterialCardId } });
|
||||
|
||||
@@ -99,6 +99,7 @@
|
||||
getExportUrl,
|
||||
updatePriority,
|
||||
prepareNativePrint,
|
||||
createInspectRecordByCard,
|
||||
} from './MesXslRawMaterialCard.api';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import {
|
||||
@@ -431,6 +432,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
async function handleSendInspect(record: Recordable) {
|
||||
await createInspectRecordByCard(record.id as string);
|
||||
record.testResult = '0';
|
||||
record.hasPendingInspect = true;
|
||||
createMessage.success('已生成送检记录');
|
||||
reload();
|
||||
}
|
||||
|
||||
function handleSuccess() {
|
||||
(selectedRowKeys.value = []) && reload();
|
||||
}
|
||||
@@ -452,6 +461,12 @@
|
||||
onClick: handlePrintRow.bind(null, record),
|
||||
auth: 'xslmes:mes_xsl_raw_material_card:edit',
|
||||
},
|
||||
{
|
||||
label: '送检',
|
||||
onClick: handleSendInspect.bind(null, record),
|
||||
auth: 'xslmes:mes_xsl_raw_material_card:edit',
|
||||
ifShow: () => (!record.testResult || record.testResult === '0') && !record.hasPendingInspect,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
|
||||
enum Api {
|
||||
list = '/xslmes/mesXslRawMaterialInspectRecord/list',
|
||||
queryById = '/xslmes/mesXslRawMaterialInspectRecord/queryById',
|
||||
queryLineListByRecordId = '/xslmes/mesXslRawMaterialInspectRecord/queryLineListByRecordId',
|
||||
prepareResultEntry = '/xslmes/mesXslRawMaterialInspectRecord/prepareResultEntry',
|
||||
saveInspectResult = '/xslmes/mesXslRawMaterialInspectRecord/saveInspectResult',
|
||||
exportXls = '/xslmes/mesXslRawMaterialInspectRecord/exportXls',
|
||||
}
|
||||
|
||||
export const getExportUrl = Api.exportXls;
|
||||
export const list = (params) => defHttp.get({ url: Api.list, params });
|
||||
export const queryById = (params) => defHttp.get({ url: Api.queryById, params });
|
||||
export const queryLineListByRecordId = (params) => defHttp.get({ url: Api.queryLineListByRecordId, params });
|
||||
export const prepareResultEntry = (id: string) => defHttp.post({ url: Api.prepareResultEntry, params: { id } });
|
||||
export const saveInspectResult = (params) => defHttp.post({ url: Api.saveInspectResult, params });
|
||||
@@ -0,0 +1,80 @@
|
||||
import { BasicColumn, FormSchema } from '/@/components/Table';
|
||||
import { JVxeColumn, JVxeTypes } from '/@/components/jeecg/JVxeTable/types';
|
||||
|
||||
export const columns: BasicColumn[] = [
|
||||
{ title: '条码', align: 'center', dataIndex: 'barcode', width: 180 },
|
||||
{ title: '批次号', align: 'center', dataIndex: 'batchNo', width: 160 },
|
||||
{ title: '物料名称', align: 'center', dataIndex: 'materialName', width: 180 },
|
||||
{ title: '检验状态', align: 'center', dataIndex: 'inspectStatus_dictText', width: 120 },
|
||||
{ title: '送检时间', align: 'center', dataIndex: 'inspectTime', width: 170 },
|
||||
{ title: '判定时间', align: 'center', dataIndex: 'resultTime', width: 170 },
|
||||
];
|
||||
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
{ label: '条码', field: 'barcode', component: 'Input', colProps: { span: 6 } },
|
||||
{ label: '批次号', field: 'batchNo', component: 'Input', colProps: { span: 6 } },
|
||||
{ label: '物料名称', field: 'materialName', component: 'Input', colProps: { span: 6 } },
|
||||
{
|
||||
label: '检验状态',
|
||||
field: 'inspectStatus',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: { dictCode: 'xslmes_inspect_status' },
|
||||
colProps: { span: 6 },
|
||||
},
|
||||
];
|
||||
|
||||
export const lineJVxeColumns: JVxeColumn[] = [
|
||||
{
|
||||
title: '检验项目',
|
||||
key: 'inspectItemName',
|
||||
type: JVxeTypes.input,
|
||||
width: 220,
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
title: '容许最小值',
|
||||
key: 'allowMin',
|
||||
type: JVxeTypes.inputNumber,
|
||||
width: 120,
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
title: '包含最小值',
|
||||
key: 'includeMinFlag',
|
||||
type: JVxeTypes.checkbox,
|
||||
width: 110,
|
||||
align: 'center',
|
||||
customValue: [1, 0],
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
title: '容许最大值',
|
||||
key: 'allowMax',
|
||||
type: JVxeTypes.inputNumber,
|
||||
width: 120,
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
title: '包含最大值',
|
||||
key: 'includeMaxFlag',
|
||||
type: JVxeTypes.checkbox,
|
||||
width: 110,
|
||||
align: 'center',
|
||||
customValue: [1, 0],
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
title: '检验值',
|
||||
key: 'inspectValue',
|
||||
type: JVxeTypes.inputNumber,
|
||||
width: 120,
|
||||
validateRules: [{ required: true, message: '${title}必填' }],
|
||||
},
|
||||
{
|
||||
title: '判定',
|
||||
key: 'passFlag_dictText',
|
||||
type: JVxeTypes.input,
|
||||
width: 100,
|
||||
disabled: true,
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,70 @@
|
||||
<template>
|
||||
<div>
|
||||
<BasicTable @register="registerTable">
|
||||
<template #tableTitle>
|
||||
<a-button
|
||||
type="primary"
|
||||
v-auth="'xslmes:mes_xsl_raw_material_inspect_record:exportXls'"
|
||||
preIcon="ant-design:export-outlined"
|
||||
@click="onExportXls"
|
||||
>
|
||||
导出
|
||||
</a-button>
|
||||
</template>
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)" />
|
||||
</template>
|
||||
</BasicTable>
|
||||
<MesXslRawMaterialInspectRecordResultModal @register="registerResultModal" @success="reload" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" name="xslmes-mesXslRawMaterialInspectRecord" setup>
|
||||
import { BasicTable, TableAction } from '/@/components/Table';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import { columns, searchFormSchema } from './MesXslRawMaterialInspectRecord.data';
|
||||
import { getExportUrl, list } from './MesXslRawMaterialInspectRecord.api';
|
||||
import MesXslRawMaterialInspectRecordResultModal from './modules/MesXslRawMaterialInspectRecordResultModal.vue';
|
||||
|
||||
const [registerResultModal, { openModal: openResultModal }] = useModal();
|
||||
|
||||
const { tableContext, onExportXls } = useListPage({
|
||||
tableProps: {
|
||||
title: '原材料送检记录',
|
||||
api: list,
|
||||
columns,
|
||||
canResize: true,
|
||||
formConfig: { labelWidth: 100, schemas: searchFormSchema, autoSubmitOnEnter: true },
|
||||
actionColumn: { width: 180, fixed: 'right' },
|
||||
},
|
||||
exportConfig: {
|
||||
name: '原材料送检记录',
|
||||
url: getExportUrl,
|
||||
},
|
||||
});
|
||||
const [registerTable, { reload }] = tableContext;
|
||||
|
||||
function handleEntryResult(record: Recordable) {
|
||||
openResultModal(true, { record, editable: true });
|
||||
}
|
||||
|
||||
function handleDetail(record: Recordable) {
|
||||
openResultModal(true, { record, editable: false });
|
||||
}
|
||||
|
||||
function getTableAction(record: Recordable) {
|
||||
return [
|
||||
{
|
||||
label: '录入检验结果',
|
||||
onClick: handleEntryResult.bind(null, record),
|
||||
auth: 'xslmes:mes_xsl_raw_material_inspect_record:edit',
|
||||
ifShow: () => record.inspectStatus === '0',
|
||||
},
|
||||
{
|
||||
label: '查看',
|
||||
onClick: handleDetail.bind(null, record),
|
||||
},
|
||||
];
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,141 @@
|
||||
<template>
|
||||
<BasicModal
|
||||
v-bind="$attrs"
|
||||
destroyOnClose
|
||||
:title="title"
|
||||
width="1100px"
|
||||
@register="registerModal"
|
||||
@ok="handleSubmit"
|
||||
>
|
||||
<a-descriptions bordered :column="2" size="small">
|
||||
<a-descriptions-item label="条码">{{ mainRecord.barcode || '-' }}</a-descriptions-item>
|
||||
<a-descriptions-item label="批次号">{{ mainRecord.batchNo || '-' }}</a-descriptions-item>
|
||||
<a-descriptions-item label="物料名称">{{ mainRecord.materialName || '-' }}</a-descriptions-item>
|
||||
<a-descriptions-item label="检验状态">{{ mainRecord.inspectStatus_dictText || '-' }}</a-descriptions-item>
|
||||
<a-descriptions-item label="送检时间">{{ mainRecord.inspectTime || '-' }}</a-descriptions-item>
|
||||
<a-descriptions-item label="判定时间">{{ mainRecord.resultTime || '-' }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
<a-divider orientation="left">检验明细</a-divider>
|
||||
<JVxeTable
|
||||
v-if="tableReady"
|
||||
ref="lineTableRef"
|
||||
row-number
|
||||
keep-source
|
||||
:max-height="400"
|
||||
:loading="lineLoading"
|
||||
:columns="tableColumns"
|
||||
:dataSource="lineDataSource"
|
||||
:disabled="!editable"
|
||||
/>
|
||||
</BasicModal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref } from 'vue';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import type { JVxeTableInstance } from '/@/components/jeecg/JVxeTable/types';
|
||||
import { lineJVxeColumns } from '../MesXslRawMaterialInspectRecord.data';
|
||||
import { prepareResultEntry, queryById, queryLineListByRecordId, saveInspectResult } from '../MesXslRawMaterialInspectRecord.api';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
|
||||
const emit = defineEmits(['register', 'success']);
|
||||
const { createMessage } = useMessage();
|
||||
const editable = ref(false);
|
||||
const tableReady = ref(false);
|
||||
const lineLoading = ref(false);
|
||||
const lineDataSource = ref<Recordable[]>([]);
|
||||
const lineTableRef = ref<JVxeTableInstance>();
|
||||
const recordId = ref('');
|
||||
const mainRecord = ref<Recordable>({});
|
||||
|
||||
const tableColumns = computed(() => {
|
||||
if (editable.value) {
|
||||
return lineJVxeColumns;
|
||||
}
|
||||
return lineJVxeColumns.map((c) => {
|
||||
if (c.key === 'inspectValue') {
|
||||
return { ...c, disabled: true };
|
||||
}
|
||||
return c;
|
||||
});
|
||||
});
|
||||
|
||||
function mapPassFlagText(list: Recordable[]) {
|
||||
return (list || []).map((row) => {
|
||||
const passFlag = String(row?.passFlag ?? '');
|
||||
let passText = '';
|
||||
if (passFlag === '0') passText = '待检';
|
||||
else if (passFlag === '1') passText = '合格';
|
||||
else if (passFlag === '2') passText = '不合格';
|
||||
return { ...row, passFlag_dictText: passText };
|
||||
});
|
||||
}
|
||||
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
||||
tableReady.value = false;
|
||||
lineDataSource.value = [];
|
||||
editable.value = !!data?.editable;
|
||||
recordId.value = data?.record?.id || '';
|
||||
setModalProps({
|
||||
confirmLoading: false,
|
||||
showCancelBtn: true,
|
||||
showOkBtn: editable.value,
|
||||
okText: '保存',
|
||||
});
|
||||
if (!recordId.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
lineLoading.value = true;
|
||||
try {
|
||||
const mainRaw = await queryById({ id: recordId.value });
|
||||
mainRecord.value = (mainRaw as any)?.id != null ? (mainRaw as Recordable) : ((mainRaw as any)?.result ?? {});
|
||||
if (editable.value) {
|
||||
const linesRaw = await prepareResultEntry(recordId.value);
|
||||
const list = Array.isArray(linesRaw) ? linesRaw : ((linesRaw as any)?.result ?? []);
|
||||
lineDataSource.value = mapPassFlagText(list || []);
|
||||
} else {
|
||||
const linesRaw = await queryLineListByRecordId({ id: recordId.value });
|
||||
const list = Array.isArray(linesRaw) ? linesRaw : ((linesRaw as any)?.result ?? []);
|
||||
lineDataSource.value = mapPassFlagText(list || []);
|
||||
}
|
||||
} finally {
|
||||
lineLoading.value = false;
|
||||
tableReady.value = true;
|
||||
}
|
||||
});
|
||||
|
||||
const title = computed(() => (editable.value ? '录入检验结果' : '送检记录详情'));
|
||||
|
||||
async function handleSubmit() {
|
||||
if (!editable.value) {
|
||||
closeModal();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const lineRef = lineTableRef.value as any;
|
||||
if (lineRef?.validateTable) {
|
||||
const err = await lineRef.validateTable();
|
||||
if (err) {
|
||||
createMessage.warning('请完善检验值');
|
||||
return;
|
||||
}
|
||||
}
|
||||
const tableData = (lineRef?.getTableData?.() || []) as Recordable[];
|
||||
const lineList = tableData.map((item) => ({
|
||||
id: item.id,
|
||||
inspectValue: item.inspectValue,
|
||||
}));
|
||||
setModalProps({ confirmLoading: true });
|
||||
await saveInspectResult({
|
||||
id: recordId.value,
|
||||
lineList,
|
||||
});
|
||||
createMessage.success('保存成功');
|
||||
closeModal();
|
||||
emit('success');
|
||||
} finally {
|
||||
setModalProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user