Files
qhmes/jeecgboot-vue3/src/views/xslmes/mesXslEquipmentLedger/components/MesXslEquipmentLedgerModal.vue
2026-07-29 10:23:32 +08:00

218 lines
8.0 KiB
Vue

<template>
<BasicModal
v-bind="$attrs"
@register="registerModal"
destroyOnClose
:title="title"
:width="MODAL_WIDTH"
:maxHeight="modalContentMaxHeight"
wrap-class-name="mes-xsl-equipment-ledger-modal"
@ok="handleSubmit"
>
<BasicForm @register="registerForm">
<template #manufacturerPicker="{ 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="openManufacturerSelect('manufacturer')">选择</a-button>
<a-button v-if="model.manufacturerId && !isDetail" @click="clearManufacturer(model)">清除</a-button>
</a-input-group>
</template>
<template #equipmentTypePicker="{ 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="openTypeSelect">选择</a-button>
<a-button v-if="model.equipmentTypeId && !isDetail" @click="clearType(model)">清除</a-button>
</a-input-group>
</template>
<template #factoryPicker="{ 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="openManufacturerSelect('factory')">选择</a-button>
<a-button v-if="model.factoryId && !isDetail" @click="clearFactory(model)">清除</a-button>
</a-input-group>
</template>
</BasicForm>
<MesXslManufacturerSelectModal
@register="registerManufacturerModal"
:modal-title="manufacturerModalTitle"
@select="onManufacturerSelect"
/>
<MesXslEquipmentTypeSelectModal @register="registerTypeModal" @select="onTypeSelect" />
</BasicModal>
</template>
<script lang="ts" setup>
import { computed, ref, unref, onMounted } from 'vue';
import { BasicModal, useModalInner, useModal } from '/@/components/Modal';
import { BasicForm, useForm } from '/@/components/Form/index';
import { useMessage } from '/@/hooks/web/useMessage';
import { formSchema } from '../MesXslEquipmentLedger.data';
import { fetchNextLedgerNo, saveOrUpdate } from '../MesXslEquipmentLedger.api';
import MesXslManufacturerSelectModal from './MesXslManufacturerSelectModal.vue';
import MesXslEquipmentTypeSelectModal from './MesXslEquipmentTypeSelectModal.vue';
const emit = defineEmits(['register', 'success']);
const { createMessage } = useMessage();
const isUpdate = ref(true);
const isDetail = ref(false);
/** 弹窗宽度;须配合 wrap-class-name 覆盖全局 .ant-modal{width:520px} */
const MODAL_WIDTH = 1200;
/** 仅纵向滚动(像素高度,供 ModalWrapper 使用);在基准高度上缩短 20% */
const MODAL_HEIGHT_SCALE = 0.8;
const modalContentMaxHeight = ref(Math.round(600 * MODAL_HEIGHT_SCALE));
onMounted(() => {
const base = Math.min(800, Math.max(480, window.innerHeight - 220));
modalContentMaxHeight.value = Math.round(base * MODAL_HEIGHT_SCALE);
});
const manufacturerPickTarget = ref<'manufacturer' | 'factory'>('manufacturer');
const manufacturerModalTitle = computed(() =>
manufacturerPickTarget.value === 'factory' ? '选择所属工厂' : '选择设备厂家',
);
const [registerManufacturerModal, { openModal: openManufacturerModal }] = useModal();
const [registerTypeModal, { openModal: openTypeModal }] = useModal();
const [registerForm, { resetFields, setFieldsValue, validate, setProps, getFieldsValue }] = useForm({
labelWidth: 110,
schemas: formSchema,
showActionButtonGroup: false,
baseColProps: { span: 12 },
});
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
await resetFields();
setModalProps({
width: MODAL_WIDTH,
confirmLoading: false,
showCancelBtn: data?.showFooter,
showOkBtn: data?.showFooter,
});
isUpdate.value = !!data?.isUpdate;
isDetail.value = !data?.showFooter;
if (unref(isUpdate)) await setFieldsValue({ ...data.record });
else {
try {
const nextNo = await fetchNextLedgerNo();
await setFieldsValue({ equipmentStatus: '0', enabledFlag: '1', ledgerNo: nextNo });
} catch {
await setFieldsValue({ equipmentStatus: '0', enabledFlag: '1', ledgerNo: '' });
}
}
setProps({ disabled: !data?.showFooter });
});
const title = computed(() =>
!unref(isUpdate) ? '新增设备台账' : unref(isDetail) ? '设备台账详情' : '编辑设备台账',
);
function openManufacturerSelect(target: 'manufacturer' | 'factory') {
manufacturerPickTarget.value = target;
const v = getFieldsValue();
openManufacturerModal(true, {
manufacturerId: target === 'factory' ? v?.factoryId : v?.manufacturerId,
});
}
function openTypeSelect() {
const v = getFieldsValue();
openTypeModal(true, { equipmentTypeId: v?.equipmentTypeId });
}
function onManufacturerSelect(payload: Recordable) {
if (manufacturerPickTarget.value === 'factory') {
setFieldsValue({
factoryId: payload.manufacturerId,
factoryName: payload.manufacturerName,
});
} else {
setFieldsValue({
manufacturerId: payload.manufacturerId,
manufacturerName: payload.manufacturerName,
});
}
}
function onTypeSelect(payload: Recordable) {
setFieldsValue({
equipmentTypeId: payload.equipmentTypeId || '',
equipmentTypeName: payload.equipmentTypeName || '',
equipmentCategoryId: payload.equipmentCategoryId || '',
equipmentCategoryName: payload.equipmentCategoryName || '',
processOperationId: payload.processOperationId || '',
processOperationName: payload.processOperationName || '',
});
}
function clearManufacturer(model: Recordable) {
model.manufacturerId = '';
model.manufacturerName = '';
}
function clearFactory(model: Recordable) {
model.factoryId = '';
model.factoryName = '';
}
function clearType(model: Recordable) {
model.equipmentTypeId = '';
model.equipmentTypeName = '';
model.equipmentCategoryId = '';
model.equipmentCategoryName = '';
model.processOperationId = '';
model.processOperationName = '';
}
async function handleSubmit() {
try {
// validate 结果可能不含隐藏字段最新值,与 getFieldsValue 合并
const values = { ...(getFieldsValue() || {}), ...(await validate()) };
if (!values.equipmentTypeId) {
createMessage.warning('请选择设备类型');
return;
}
if (!values.processOperationId) {
createMessage.warning('所选设备类型未绑定工序,请先维护设备类型');
return;
}
if (!values.equipmentCategoryId) {
createMessage.warning('所选设备类型未绑定设备类别,请先维护设备类型');
return;
}
setModalProps({ confirmLoading: true });
await saveOrUpdate(values, isUpdate.value);
closeModal();
emit('success');
} catch (e) {
// 表单校验失败时 ant-design 会标红;此处避免未捕获异常导致“点保存无反应”
console.warn('[设备台账] 保存校验未通过', e);
} finally {
setModalProps({ confirmLoading: false });
}
}
</script>
<style lang="less">
/* 覆盖 jeecg components/Modal/src/index.less 中 .ant-modal { width: 520px } */
.ant-modal-wrap.mes-xsl-equipment-ledger-modal > .ant-modal,
.mes-xsl-equipment-ledger-modal .ant-modal {
width: min(1200px, calc(100vw - 48px)) !important;
max-width: min(1200px, calc(100vw - 48px)) !important;
}
.mes-xsl-equipment-ledger-modal {
.scroll-container .scrollbar__wrap {
overflow-x: hidden !important;
overflow-y: auto !important;
}
.scrollbar__view > div {
overflow-x: hidden;
}
}
</style>