新增混炼示方生成预览与批量创建功能,优化相关字段及用户交互,修复界面显示问题,增强系统稳定性和用户体验。

This commit is contained in:
geht
2026-05-22 19:43:41 +08:00
parent f3e3a99ebc
commit c85657d199
30 changed files with 1786 additions and 61 deletions

View File

@@ -28,22 +28,28 @@
</td>
<th class="formTitle" colspan="1">发行编号</th>
<td class="formValue" colspan="3">
<a-select
v-model:value="sheetForm.issueNumber"
show-search
allow-clear
:options="issueNumberOptions"
<a-input
:value="sheetForm.issueNumber"
readonly
placeholder="请点击选择密炼PS"
:disabled="!showFooter"
:filter-option="selectFilterOption"
:bordered="false"
class="form-input"
style="width: 100%"
:class="['form-input', 'mixing-picker-input', { 'is-filled': !!sheetForm.issueNumber }]"
@click="openIssueNumberPicker"
/>
</td>
</tr>
<tr>
<td class="formValue" colspan="2" rowspan="2">
<a-input v-model:value="sheetForm.machineName" :disabled="!showFooter" :bordered="false" class="form-input" />
<a-input
:value="sheetForm.machineName"
readonly
placeholder="请点击选择设备台账"
:disabled="!showFooter"
:bordered="false"
:class="['form-input', 'mixing-picker-input', { 'is-filled': !!sheetForm.machineName }]"
@click="openMachinePicker"
/>
</td>
</tr>
<tr>
@@ -63,16 +69,13 @@
<tr>
<th class="formTitle required" rowspan="2">用途</th>
<td class="formValue" colspan="3" rowspan="2">
<a-select
<a-input
v-model:value="sheetForm.purpose"
show-search
placeholder="请输入用途"
allow-clear
:options="purposeOptions"
:disabled="!showFooter"
:filter-option="selectFilterOption"
:bordered="false"
class="form-input"
style="width: 100%"
/>
</td>
<th class="formTitle" colspan="1">母胶比重</th>
@@ -81,7 +84,13 @@
</td>
<th class="formTitle">段数</th>
<td class="formValue" colspan="2">
<a-input-number v-model:value="sheetForm.stageCount" :disabled="!showFooter" :precision="0" :bordered="false" class="form-input" style="width: 100%" />
<a-input
v-model:value="sheetForm.stageCount"
placeholder="如 2/3"
:disabled="!showFooter"
:bordered="false"
class="form-input"
/>
</td>
<th class="formTitle" colspan="1">纯混炼时间()</th>
<td class="formValue">
@@ -253,7 +262,28 @@
:disabled="!showFooter"
@resizable-change="handleStepColumnResize"
@column-resizable-change="handleStepColumnResize"
/>
>
<template #actionNameSlot="{ row }">
<MesXslMixingStepSelectCell
:row="row"
field="actionName"
:options="mixerActionSelectOptions"
:disabled="!showFooter"
:machine-id="sheetForm.machineId"
:placeholder="stepSelectPlaceholder"
/>
</template>
<template #comboModeSlot="{ row }">
<MesXslMixingStepSelectCell
:row="row"
field="comboMode"
:options="mixerConditionSelectOptions"
:disabled="!showFooter"
:machine-id="sheetForm.machineId"
:placeholder="stepSelectPlaceholder"
/>
</template>
</JVxeTable>
</div>
<!--update-end---author:cursor ---date:20260522 forXSLMES-20260522-A21混合步骤与下密炼机列宽同步可调----------- -->
</div>
@@ -282,7 +312,28 @@
:disabled="!showFooter"
@resizable-change="handleStepColumnResize"
@column-resizable-change="handleStepColumnResize"
/>
>
<template #actionNameSlot="{ row }">
<MesXslMixingStepSelectCell
:row="row"
field="actionName"
:options="mixerActionSelectOptions"
:disabled="!showFooter"
:machine-id="sheetForm.machineId"
:placeholder="stepSelectPlaceholder"
/>
</template>
<template #comboModeSlot="{ row }">
<MesXslMixingStepSelectCell
:row="row"
field="comboMode"
:options="mixerConditionSelectOptions"
:disabled="!showFooter"
:machine-id="sheetForm.machineId"
:placeholder="stepSelectPlaceholder"
/>
</template>
</JVxeTable>
</div>
</div>
</div>
@@ -317,13 +368,17 @@
</div>
<BasicForm v-show="false" @register="registerForm" />
<MesXslEquipmentLedgerSelectModal @register="registerMachineModal" @select="onMachineSelect" />
<MesXslMixerPsCompileSelectModal @register="registerIssueNumberModal" @select="onIssueNumberSelect" />
</div>
</BasicModal>
</template>
<script lang="ts" setup>
import { computed, reactive, ref, unref } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import dayjs from 'dayjs';
import { BasicModal, useModal, useModalInner } from '/@/components/Modal';
import { BasicForm, useForm } from '/@/components/Form/index';
import { useMessage } from '/@/hooks/web/useMessage';
import { useUserStore } from '/@/store/modules/user';
@@ -351,14 +406,23 @@ import {
createEmptyMaterialRows,
createEmptyStepRows,
createEmptyDownStepRows,
normalizeMixingDetailRows,
ensureMixingDetailRows,
DEFAULT_MIXING_MATERIAL_ROW_COUNT,
DEFAULT_MIXING_STEP_ROW_COUNT,
DEFAULT_MIXING_DOWN_STEP_ROW_COUNT,
buildDefaultMixingTcuRows,
MIXING_MATERIAL_MIN_COLUMN_WIDTH,
MIXING_TCU_MIN_COLUMN_WIDTH,
MIXING_STEP_MIN_COLUMN_WIDTH,
} from '../MesXslMixingSpec.data';
import { saveOrUpdate, queryById, queryIssueNumberOptions, queryPurposeOptions } from '../MesXslMixingSpec.api';
import { saveOrUpdate, queryById } from '../MesXslMixingSpec.api';
import MesXslMixingMaterialColumnSetting from './MesXslMixingMaterialColumnSetting.vue';
import MesXslMixingTableRowHeightSetting from './MesXslMixingTableRowHeightSetting.vue';
import MesXslMixingStepSelectCell from './MesXslMixingStepSelectCell.vue';
import { list as mixerActionList } from '/@/views/xslmes/mesXslMixerAction/MesXslMixerAction.api';
import { list as mixerConditionList } from '/@/views/xslmes/mesXslMixerCondition/MesXslMixerCondition.api';
import MesXslEquipmentLedgerSelectModal from '/@/views/xslmes/mesXslEquipInspectConfig/components/MesXslEquipmentLedgerSelectModal.vue';
import MesXslMixerPsCompileSelectModal from '/@/views/xslmes/mesXslMixerPsCompile/components/MesXslMixerPsCompileSelectModal.vue';
const emit = defineEmits(['register', 'success']);
const { createMessage } = useMessage();
@@ -366,8 +430,11 @@ const userStore = useUserStore();
const isUpdate = ref(false);
const showFooter = ref(true);
const issueNumberOptions = ref<{ label: string; value: string }[]>([]);
const purposeOptions = ref<{ label: string; value: string }[]>([]);
const mixerPsCompilePickerId = ref('');
//update-begin---author:cursor ---date:20260522 for【XSLMES-20260522-A34】混合步骤动作/组合下拉选项-----------
const mixerActionOptions = ref<{ title: string; value: string }[]>([]);
const mixerConditionOptions = ref<{ title: string; value: string }[]>([]);
//update-end---author:cursor ---date:20260522 for【XSLMES-20260522-A34】混合步骤动作/组合下拉选项-----------
const materialRef = ref();
const stepRef = ref();
@@ -414,10 +481,12 @@ const tcuTableLayoutKey = computed(
() => `${tcuHeightPref.value.rowHeight}-${tcuHeightPref.value.visibleRowCount}-${tcuTableWidth.value}`,
);
const stepTableLayoutKey = computed(
() => `${stepHeightPref.value.rowHeight}-${stepHeightPref.value.visibleRowCount}-${visibleStepColumns.value.length}`,
() =>
`${stepHeightPref.value.rowHeight}-${stepHeightPref.value.visibleRowCount}-${mixerActionOptions.value.length}-${mixerConditionOptions.value.length}`,
);
const downStepTableLayoutKey = computed(
() => `${downStepHeightPref.value.rowHeight}-${downStepHeightPref.value.visibleRowCount}-${visibleStepColumns.value.length}`,
() =>
`${downStepHeightPref.value.rowHeight}-${downStepHeightPref.value.visibleRowCount}-${mixerActionOptions.value.length}-${mixerConditionOptions.value.length}`,
);
//update-end---author:cursor ---date:20260522 for【XSLMES-20260522-A32】四明细表行高/展示行数设置持久化-----------
@@ -478,8 +547,58 @@ function handleTcuColumnResize(params: Recordable) {
//update-begin---author:cursor ---date:20260522 for【XSLMES-20260522-A21】混合步骤与下密炼机列宽同步可调-----------
const stepColumnWidths = ref<Record<string, number>>(loadMixingStepColumnWidths());
function extractPageRecords(raw: Recordable) {
if (Array.isArray(raw?.records)) {
return raw.records;
}
if (Array.isArray(raw?.result?.records)) {
return raw.result.records;
}
if (Array.isArray(raw)) {
return raw;
}
return [];
}
function buildMixerSelectOptions(records: Recordable[], labelKey: string) {
const seen = new Set<string>();
const options: { title: string; value: string }[] = [];
records.forEach((item) => {
const label = String(item?.[labelKey] || '').trim();
if (!label || seen.has(label)) {
return;
}
seen.add(label);
options.push({ title: label, value: label });
});
return options;
}
async function loadMixerStepOptions(equipmentId?: string) {
if (!equipmentId) {
mixerActionOptions.value = [];
mixerConditionOptions.value = [];
return;
}
const params = { equipmentId, pageNo: 1, pageSize: 500 };
const [actionRaw, conditionRaw] = await Promise.all([mixerActionList(params), mixerConditionList(params)]);
mixerActionOptions.value = buildMixerSelectOptions(extractPageRecords(actionRaw), 'actionName');
mixerConditionOptions.value = buildMixerSelectOptions(extractPageRecords(conditionRaw), 'conditionName');
}
const visibleStepColumns = computed(() => applyMixingStepColumnWidths(stepColumns, stepColumnWidths.value));
//update-begin---author:cursor ---date:20260522 for【XSLMES-20260522-A35】混合步骤动作/组合列常显下拉倒三角-----------
const mixerActionSelectOptions = computed(() =>
mixerActionOptions.value.map((item) => ({ label: item.title, value: item.value })),
);
const mixerConditionSelectOptions = computed(() =>
mixerConditionOptions.value.map((item) => ({ label: item.title, value: item.value })),
);
const stepSelectPlaceholder = computed(() => '');
//update-end---author:cursor ---date:20260522 for【XSLMES-20260522-A35】混合步骤动作/组合列常显下拉倒三角-----------
function handleStepColumnResize(params: Recordable) {
const column = params?.resizeColumn ?? params?.column;
const key = column?.params?.key ?? column?.field;
@@ -505,6 +624,7 @@ const sheetForm = reactive<Recordable>({
id: '',
specName: '',
purpose: '',
machineId: '',
machineName: '',
makeDate: '',
issueNumber: '',
@@ -514,7 +634,7 @@ const sheetForm = reactive<Recordable>({
motherRubberSg: null,
finalRubberSg: null,
applyFactory: '',
stageCount: null,
stageCount: '',
pureMixSec: null,
recycleCarbonKg: null,
autoSmallPrintSetting: '',
@@ -587,27 +707,43 @@ const [registerForm, { resetFields, setFieldsValue, validate, setProps }] = useF
baseColProps: { span: 8 },
});
const selectFilterOption = (input: string, option: any) => String(option?.label || '').toLowerCase().includes(input.toLowerCase());
//update-begin---author:cursor ---date:20260522 for【XSLMES-20260522-A33】混炼示方主表选择弹窗-----------
const [registerMachineModal, { openModal: openMachineModalInner }] = useModal();
const [registerIssueNumberModal, { openModal: openIssueNumberModalInner }] = useModal();
async function applyAutoCompleteSource() {
//update-begin---author:cursor ---date:20260522 for【XSLMES-20260522-A17】混炼示方用途/发行编号联想-----------
const issueRows = await queryIssueNumberOptions({});
const purposeRows = await queryPurposeOptions({});
const toOptions = (rows: any) => {
const list = Array.isArray(rows) ? rows : rows?.result || [];
return list.map((item) => ({ label: item.label, value: item.value }));
};
issueNumberOptions.value = toOptions(issueRows);
purposeOptions.value = toOptions(purposeRows);
//update-end---author:cursor ---date:20260522 for【XSLMES-20260522-A17】混炼示方用途/发行编号联想-----------
function openMachinePicker() {
if (!showFooter.value) {
return;
}
openMachineModalInner(true, { equipmentLedgerId: sheetForm.machineId || '' });
}
async function onMachineSelect(payload: Recordable | null) {
sheetForm.machineId = payload?.equipmentLedgerId || '';
sheetForm.machineName = payload?.equipmentName || '';
await loadMixerStepOptions(sheetForm.machineId);
}
function openIssueNumberPicker() {
if (!showFooter.value) {
return;
}
openIssueNumberModalInner(true, { psCompileId: mixerPsCompilePickerId.value || '' });
}
function onIssueNumberSelect(payload: Recordable | null) {
if (!payload) {
return;
}
mixerPsCompilePickerId.value = payload.psCompileId || '';
sheetForm.issueNumber = payload.psCode || '';
}
//update-end---author:cursor ---date:20260522 for【XSLMES-20260522-A33】混炼示方主表选择弹窗-----------
function ensureTcuDefaultRows(rows: Recordable[] = []) {
//update-begin---author:cursor ---date:20260522 for【XSLMES-20260522-A17】TCU子表默认固定两行-----------
const up = rows.find((r) => r.sectionType === 'up_mixer') || { sectionType: 'up_mixer' };
const down = rows.find((r) => r.sectionType === 'down_mixer') || { sectionType: 'down_mixer', drugWeighPos: undefined };
return [up, down];
//update-end---author:cursor ---date:20260522 for【XSLMES-20260522-A17】TCU子表默认固定两行-----------
//update-begin---author:cursor ---date:20260522 for【XSLMES-20260522-A33】TCU默认两行及上密炼机药品称默认值-----------
return buildDefaultMixingTcuRows(rows);
//update-end---author:cursor ---date:20260522 for【XSLMES-20260522-A33】TCU默认两行及上密炼机药品称默认值-----------
}
function handleTcuValueChange(event) {
@@ -629,8 +765,10 @@ function resetSheetForm() {
sheetForm[key] =
key === 'specName' ||
key === 'purpose' ||
key === 'machineId' ||
key === 'machineName' ||
key === 'issueNumber' ||
key === 'stageCount' ||
key.endsWith('By') ||
key === 'applyFactory' ||
key === 'autoSmallPrintSetting'
@@ -644,6 +782,7 @@ function resetSheetForm() {
sheetForm.auditTime = '';
sheetForm.approveTime = '';
sheetForm.changeDate = '';
mixerPsCompilePickerId.value = '';
refreshSignDisplay({});
}
@@ -670,25 +809,29 @@ const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data
stepData.value = [];
downStepData.value = [];
tcuData.value = ensureTcuDefaultRows([]);
await loadMixerStepOptions('');
isUpdate.value = !!data?.isUpdate;
showFooter.value = !!data?.showFooter;
await setProps({ disabled: !showFooter.value });
setModalProps({ showOkBtn: showFooter.value, showCancelBtn: showFooter.value, confirmLoading: false });
await applyAutoCompleteSource();
if (isUpdate.value && data?.record?.id) {
const raw = await queryById({ id: data.record.id });
const row = raw?.result || raw;
Object.assign(sheetForm, row || {});
refreshSignDisplay(row || {});
await loadMixerStepOptions(sheetForm.machineId);
await syncSheetToForm();
//update-begin---author:cursor ---date:20260522 for【XSLMES-20260522-A22】明细表默认空行数-----------
materialData.value = normalizeMixingDetailRows(row?.materialList || []);
stepData.value = normalizeMixingDetailRows(row?.stepList || []);
downStepData.value = normalizeMixingDetailRows(row?.downStepList || []);
//update-end---author:cursor ---date:20260522 for【XSLMES-20260522-A22】明细表默认空行数-----------
//update-begin---author:cursor ---date:20260522 for【XSLMES-20260522-A39】编辑页明细补齐默认空行与新增一致-----------
materialData.value = ensureMixingDetailRows(row?.materialList || [], DEFAULT_MIXING_MATERIAL_ROW_COUNT);
stepData.value = ensureMixingDetailRows(row?.stepList || [], DEFAULT_MIXING_STEP_ROW_COUNT);
downStepData.value = ensureMixingDetailRows(row?.downStepList || [], DEFAULT_MIXING_DOWN_STEP_ROW_COUNT);
//update-end---author:cursor ---date:20260522 for【XSLMES-20260522-A39】编辑页明细补齐默认空行与新增一致-----------
tcuData.value = ensureTcuDefaultRows(row?.tcuList || []);
} else {
const userInfo = userStore.getUserInfo || {};
//update-begin---author:cursor ---date:20260522 for【XSLMES-20260522-A33】新增混炼示方制作日期默认当天-----------
sheetForm.makeDate = dayjs().format('YYYY-MM-DD');
//update-end---author:cursor ---date:20260522 for【XSLMES-20260522-A33】新增混炼示方制作日期默认当天-----------
refreshSignDisplay({
createBy_dictText: userInfo.realname,
createBy: userInfo.username,
@@ -856,6 +999,15 @@ async function handleSubmit() {
:deep(.form-input.ant-picker-suffix) {
color: #999;
}
:deep(.mixing-picker-input) {
cursor: pointer;
}
:deep(.mixing-picker-input.is-filled) {
color: #262626;
}
}
//update-end---author:cursor ---date:20260522 for【XSLMES-20260522-A17】顶部施工表对齐旧系统13列表格-----------
@@ -1099,6 +1251,20 @@ async function handleSubmit() {
font-weight: 600;
}
//update-begin---author:cursor ---date:20260522 for【XSLMES-20260522-A35】混合步骤动作/组合列常显下拉倒三角-----------
.panel-right :deep(.vxe-body--column.col--actionName),
.panel-right :deep(.vxe-body--column.col--comboMode) {
padding: 0 !important;
overflow: visible !important;
}
.panel-right :deep(.vxe-body--column.col--actionName .vxe-cell),
.panel-right :deep(.vxe-body--column.col--comboMode .vxe-cell) {
padding: 0 !important;
overflow: visible !important;
}
//update-end---author:cursor ---date:20260522 for【XSLMES-20260522-A35】混合步骤动作/组合列常显下拉倒三角-----------
.sheet-sign-footer {
border-top: 1px solid #d9d9d9;
background: #fff;
@@ -1171,4 +1337,10 @@ async function handleSubmit() {
background: #fcfdfd;
}
}
//update-begin---author:cursor ---date:20260522 for【XSLMES-20260522-A36】动作/组合下拉挂到body避免被表格裁切-----------
.mixing-step-select-dropdown {
z-index: 2100 !important;
}
//update-end---author:cursor ---date:20260522 for【XSLMES-20260522-A36】动作/组合下拉挂到body避免被表格裁切-----------
</style>

View File

@@ -0,0 +1,109 @@
<template>
<a-select
:value="row[field]"
:options="options"
:disabled="disabled"
:open="dropdownOpen"
allow-clear
show-search
:bordered="false"
size="small"
class="mixing-step-select"
popup-class-name="mixing-step-select-dropdown"
:placeholder="placeholder"
:get-popup-container="getPopupContainer"
@update:value="handleChange"
@dropdown-visible-change="handleDropdownVisibleChange"
@click.stop
/>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { useMessage } from '/@/hooks/web/useMessage';
const props = defineProps<{
row: Recordable;
field: string;
options: { label: string; value: string }[];
disabled?: boolean;
placeholder?: string;
machineId?: string;
}>();
const { createMessage } = useMessage();
const dropdownOpen = ref(false);
function handleChange(value: string | undefined) {
props.row[props.field] = value;
}
//update-begin---author:cursor ---date:20260522 for【XSLMES-20260522-A37】未选机台点击动作/组合提示请先选择机台-----------
function handleDropdownVisibleChange(visible: boolean) {
if (props.disabled) {
dropdownOpen.value = false;
return;
}
if (visible && !props.machineId) {
createMessage.warning('请先选择机台');
dropdownOpen.value = false;
return;
}
dropdownOpen.value = visible;
}
//update-end---author:cursor ---date:20260522 for【XSLMES-20260522-A37】未选机台点击动作/组合提示请先选择机台-----------
//update-begin---author:cursor ---date:20260522 for【XSLMES-20260522-A36】动作/组合下拉挂到body避免被表格裁切-----------
function getPopupContainer() {
return document.body;
}
//update-end---author:cursor ---date:20260522 for【XSLMES-20260522-A36】动作/组合下拉挂到body避免被表格裁切-----------
</script>
<style lang="less" scoped>
.mixing-step-select {
width: 100%;
height: 100%;
display: flex;
align-items: center;
:deep(.ant-select) {
width: 100%;
height: 100%;
}
:deep(.ant-select-selector) {
border: none !important;
box-shadow: none !important;
background: transparent !important;
padding: 0 18px 0 2px !important;
min-height: 24px !important;
height: 100% !important;
display: flex !important;
align-items: center !important;
}
:deep(.ant-select-selection-item),
:deep(.ant-select-selection-placeholder) {
line-height: 1.2 !important;
text-align: center;
padding-inline-end: 0 !important;
}
:deep(.ant-select-selection-search-input) {
height: 100% !important;
}
:deep(.ant-select-arrow) {
right: 2px;
margin-top: -3px;
color: #666;
font-size: 10px;
pointer-events: none;
}
:deep(.ant-select-clear) {
right: 14px;
}
}
</style>