Files
qhmes/jeecgboot-vue3/src/views/xslmes/mesXslRubberQuickTestStd/components/MesXslRubberQuickTestStdModal.vue
2026-06-16 15:35:54 +08:00

307 lines
12 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<BasicModal
v-bind="$attrs"
destroyOnClose
:title="title"
width="1100px"
@register="registerModal"
@ok="handleSubmit"
>
<BasicForm @register="registerForm">
<template #stdNameDisplay="{ model }">
<a-input :value="formatStdName(model)" disabled placeholder="选择实验方法和胶料后自动生成" />
</template>
<template #testMethodPicker="{ model, field }">
<a-input-group compact style="display: flex; width: 100%">
<a-input v-model:value="model[field]" read-only placeholder="请选择实验方法" style="flex: 1" />
<a-button type="primary" :disabled="isDetail" @click="openMethodSelect">选择</a-button>
</a-input-group>
</template>
<template #rubberMaterialPicker="{ model, field }">
<a-input-group compact style="display: flex; width: 100%">
<a-input v-model:value="model[field]" read-only placeholder="请选择胶料信息" style="flex: 1" />
<a-button type="primary" :disabled="isDetail" @click="openMaterialSelect">选择</a-button>
</a-input-group>
</template>
<template #issueNumberPicker="{ model, field }">
<a-input-group compact style="display: flex; width: 100%">
<a-input v-model:value="model[field]" read-only placeholder="请选择发行编号" style="flex: 1" />
<a-button type="primary" :disabled="isDetail" @click="openPsSelect">选择</a-button>
<a-button v-if="model.issueNumber && !isDetail" @click="clearIssueNumber(model)">清除</a-button>
</a-input-group>
</template>
<template #issueDeptPicker="{ model, field }">
<a-input-group compact style="display: flex; width: 100%">
<a-input v-model:value="model[field]" read-only placeholder="请选择发行部门" style="flex: 1" />
<a-button type="primary" :disabled="isDetail" @click="openDeptSelect">选择</a-button>
<a-button v-if="model.issueDeptId && !isDetail" @click="clearIssueDept(model)">清除</a-button>
</a-input-group>
</template>
</BasicForm>
<a-divider orientation="left">标准明细由实验方法带出数据点不可增删</a-divider>
<JVxeTable
v-if="tableReady"
ref="lineTableRef"
toolbar
row-number
keep-source
:insert-row="false"
:remove-btn="false"
:max-height="380"
:loading="lineLoading"
:columns="lineJVxeColumns"
:dataSource="lineDataSource"
:disabled="isDetail"
:toolbar-config="{ btn: [] }"
:add-btn-cfg="{ enabled: false }"
/>
<MesXslRubberQuickTestMethodSelectModal @register="registerMethodModal" @select="onMethodSelect" />
<MesMaterialSelectModal @register="registerMaterialModal" @select="onMaterialSelect" />
<MesXslRubberQuickTestStdMixerPsSelectModal @register="registerPsModal" @select="onPsSelect" />
<DeptSelectModal @register="registerDeptModal" @getSelectResult="onIssueDeptSelect" />
</BasicModal>
</template>
<script lang="ts" setup>
import { computed, ref, unref } from 'vue';
import { BasicModal, useModalInner, useModal } from '/@/components/Modal';
import { BasicForm, useForm } from '/@/components/Form/index';
import type { JVxeTableInstance } from '/@/components/jeecg/JVxeTable/types';
import { useMessage } from '/@/hooks/web/useMessage';
import { formSchema, lineJVxeColumns } from '../MesXslRubberQuickTestStd.data';
import { saveOrUpdate, queryById, queryLineListByStdId } from '../MesXslRubberQuickTestStd.api';
import { queryLineListByMethodId } from '../../mesXslRubberQuickTestMethod/MesXslRubberQuickTestMethod.api';
import MesXslRubberQuickTestMethodSelectModal from './MesXslRubberQuickTestMethodSelectModal.vue';
import MesXslRubberQuickTestStdMixerPsSelectModal from './MesXslRubberQuickTestStdMixerPsSelectModal.vue';
import MesMaterialSelectModal from '/@/views/mes/material/modules/MesMaterialSelectModal.vue';
import DeptSelectModal from '/@/components/Form/src/jeecg/components/modal/DeptSelectModal.vue';
const emit = defineEmits(['register', 'success']);
const { createMessage } = useMessage();
const isUpdate = ref(false);
const isDetail = ref(false);
const tableReady = ref(false);
const lineLoading = ref(false);
const lineDataSource = ref<Recordable[]>([]);
const lineTableRef = ref<JVxeTableInstance>();
const lastMethodId = ref<string>('');
const [registerForm, { resetFields, setFieldsValue, validate, setProps, getFieldsValue }] = useForm({
labelWidth: 120,
schemas: formSchema,
showActionButtonGroup: false,
baseColProps: { span: 12 },
});
const [registerMethodModal, { openModal: openMethodModal }] = useModal();
const [registerMaterialModal, { openModal: openMaterialModal }] = useModal();
const [registerPsModal, { openModal: openPsModal }] = useModal();
const [registerDeptModal, { openModal: openDeptModal }] = useModal();
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
tableReady.value = false;
lineDataSource.value = [];
lastMethodId.value = '';
await resetFields();
setModalProps({ confirmLoading: false, showCancelBtn: data?.showFooter, showOkBtn: data?.showFooter });
isUpdate.value = !!data?.isUpdate;
isDetail.value = !data?.showFooter;
setProps({ disabled: !data?.showFooter });
if (unref(isUpdate) && data?.record?.id) {
lineLoading.value = true;
try {
const mainRaw = await queryById({ id: data.record.id });
const m = (mainRaw as any)?.id != null ? mainRaw : (mainRaw as any)?.result ?? mainRaw;
const linesRaw = await queryLineListByStdId({ id: data.record.id });
const list = Array.isArray(linesRaw) ? linesRaw : (linesRaw as any)?.result ?? [];
await setFieldsValue({ ...m });
lineDataSource.value = list || [];
lastMethodId.value = m?.testMethodId || '';
} finally {
lineLoading.value = false;
}
} else {
await setFieldsValue({ enableStatus: '1', auditStatus: '0' });
}
tableReady.value = true;
});
const title = computed(() =>
!unref(isUpdate) ? '新增胶料快检实验标准' : unref(isDetail) ? '实验标准详情' : '编辑胶料快检实验标准',
);
/** 标准名称 = 实验方法名称 + _ + 胶料名称 */
function formatStdName(model?: Recordable) {
const methodName = String(model?.testMethodName ?? '').trim();
const materialName = String(model?.rubberMaterialName ?? '').trim();
return methodName && materialName ? `${methodName}_${materialName}` : '';
}
function methodLineToStdRow(ml: Recordable, existing?: Recordable): Recordable {
return {
dataPointId: ml.dataPointId,
pointName: ml.pointName,
lowerLimit: existing?.lowerLimit ?? null,
lowerWarn: existing?.lowerWarn ?? null,
targetValue: existing?.targetValue ?? null,
upperWarn: existing?.upperWarn ?? null,
upperLimit: existing?.upperLimit ?? null,
};
}
async function loadLinesFromMethod(methodId: string, mergeExisting = true) {
if (!methodId) {
lineDataSource.value = [];
return;
}
lineLoading.value = true;
try {
const linesRaw = await queryLineListByMethodId({ id: methodId });
const methodLines = Array.isArray(linesRaw) ? linesRaw : (linesRaw as any)?.result ?? [];
const existingMap = new Map<string, Recordable>();
if (mergeExisting) {
const current = (lineTableRef.value as any)?.getTableData?.() || lineDataSource.value || [];
for (const row of current as Recordable[]) {
if (row?.dataPointId) {
existingMap.set(String(row.dataPointId), row);
}
}
}
lineDataSource.value = (methodLines || []).map((ml: Recordable) =>
methodLineToStdRow(ml, existingMap.get(String(ml.dataPointId))),
);
} finally {
lineLoading.value = false;
}
}
function openMethodSelect() {
const vals = getFieldsValue();
openMethodModal(true, { testMethodId: vals?.testMethodId || '' });
}
async function onMethodSelect(payload: Recordable) {
const methodId = payload?.testMethodId || '';
await setFieldsValue({
testMethodId: methodId,
testMethodName: payload?.testMethodName || '',
});
if (methodId !== lastMethodId.value) {
lastMethodId.value = methodId;
await loadLinesFromMethod(methodId, false);
}
}
function openMaterialSelect() {
const vals = getFieldsValue();
openMaterialModal(true, { materialId: vals?.rubberMaterialId || '' });
}
async function onMaterialSelect(payload: Recordable) {
await setFieldsValue({
rubberMaterialId: payload.materialId || '',
rubberMaterialName: payload.materialName || '',
});
}
function openPsSelect() {
const vals = getFieldsValue();
openPsModal(true, { psCompileId: vals?.psCompileId || '' });
}
async function onPsSelect(payload: Recordable) {
await setFieldsValue({
psCompileId: payload.psCompileId || '',
issueNumber: payload.issueNumber || '',
issueDate: payload.issueDate || undefined,
issueDeptId: payload.issueDeptId || undefined,
issueDeptName: payload.issueDeptName || undefined,
});
}
function clearIssueNumber(model: Recordable) {
model.psCompileId = '';
model.issueNumber = '';
}
function openDeptSelect() {
openDeptModal(true, { isUpdate: false });
}
function resolveIssueDeptSelection(options: Recordable[] = [], values: Recordable[] = []) {
const opt = options?.[0] || {};
let id = '';
let name = opt.label != null ? String(opt.label) : '';
if (opt.value != null && opt.value !== '') {
if (typeof opt.value === 'string' || typeof opt.value === 'number') {
id = String(opt.value);
} else if (typeof opt.value === 'object') {
const row = opt.value as Recordable;
id = String(row.id ?? row.key ?? row.value ?? '');
if (!name) {
name = String(row.departName ?? row.title ?? row.label ?? '');
}
}
}
const rawValue = values?.[0];
if (!id && rawValue != null && rawValue !== '') {
id = String(rawValue);
}
return { id, name };
}
async function onIssueDeptSelect(options: Recordable[], values: Recordable[]) {
const { id, name } = resolveIssueDeptSelection(options, values);
await setFieldsValue({
issueDeptId: id,
issueDeptName: name,
});
}
function clearIssueDept(model: Recordable) {
model.issueDeptId = '';
model.issueDeptName = '';
}
async function handleSubmit() {
try {
const formVals = getFieldsValue();
const stdName = formatStdName(formVals);
if (!formVals?.testMethodId) {
createMessage.warning('请选择实验方法');
return;
}
if (!stdName) {
createMessage.warning('请先选择实验方法和胶料以生成实验标准名称');
return;
}
const values = await validate();
const lineRef = lineTableRef.value as any;
const tableData = (lineRef?.getTableData?.() || lineDataSource.value || []) as Recordable[];
const lineList = tableData
.filter((r) => r && r.dataPointId)
.map((r) => ({
dataPointId: r.dataPointId,
pointName: r.pointName,
lowerLimit: r.lowerLimit,
lowerWarn: r.lowerWarn,
targetValue: r.targetValue,
upperWarn: r.upperWarn,
upperLimit: r.upperLimit,
}));
if (!lineList.length) {
createMessage.warning('请先选择实验方法以带出数据点明细');
return;
}
setModalProps({ confirmLoading: true });
await saveOrUpdate({ ...values, stdName, lineList }, unref(isUpdate));
closeModal();
emit('success');
} finally {
setModalProps({ confirmLoading: false });
}
}
</script>