Files
qhmes/jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingSpecModal.vue

1705 lines
62 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
:width="'96%'"
:defaultFullscreen="true"
wrapClassName="mixing-spec-modal-wrap"
@register="registerModal"
@cancel="closeNestedPickers"
@ok="handleSubmit"
>
<template #title>{{ title }}</template>
<div class="mixing-sheet">
<!--update-begin---author:cursor ---date:20260522 forXSLMES-20260522-A17顶部施工表对齐旧系统13列表格----------- -->
<table class="mixing-form-table">
<tbody>
<tr class="form-title-row">
<th class="formTitle" colspan="13">TBR混合施工表</th>
</tr>
<tr>
<th class="formTitle required" rowspan="3">规格</th>
<td class="formValue" colspan="3" rowspan="3">
<a-input v-model:value="sheetForm.specName" :disabled="!showFooter" :bordered="false" class="form-input" />
</td>
<th class="formTitle" colspan="2">机台</th>
<th class="formTitle" colspan="1">制作日期</th>
<td class="formValue" colspan="2">
<a-date-picker v-model:value="sheetForm.makeDate" value-format="YYYY-MM-DD" :disabled="!showFooter" :bordered="false" class="form-input" style="width: 100%" />
</td>
<th class="formTitle" colspan="1">发行编号</th>
<td class="formValue" colspan="3">
<a-input
:value="sheetForm.issueNumber"
readonly
placeholder="请点击选择密炼PS"
:disabled="!showFooter"
:bordered="false"
:class="['form-input', 'mixing-picker-input', { 'is-filled': !!sheetForm.issueNumber }]"
@click="openIssueNumberPicker"
/>
</td>
</tr>
<tr>
<td class="formValue" colspan="2" rowspan="2">
<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>
<th class="formTitle" colspan="1">换算系数</th>
<td class="formValue" colspan="2">
<a-input-number
v-model:value="sheetForm.convertFactor"
:disabled="!showFooter"
:precision="6"
:bordered="false"
class="form-input"
style="width: 100%"
@update:value="handleConvertFactorChange"
/>
</td>
<th class="formTitle" colspan="1">填充体积</th>
<td class="formValue" colspan="1">
<a-input-number v-model:value="sheetForm.fillVolume" :disabled="!showFooter" :precision="6" :bordered="false" class="form-input" style="width: 100%" />
</td>
<th class="formTitle" colspan="1">回收炭黑()</th>
<td class="formValue">
<a-input-number v-model:value="sheetForm.recycleCarbonSec" :disabled="!showFooter" :precision="0" :bordered="false" class="form-input" style="width: 100%" />
</td>
</tr>
<tr>
<th class="formTitle required" rowspan="2">用途</th>
<td class="formValue" colspan="3" rowspan="2">
<a-input
v-model:value="sheetForm.purpose"
placeholder="请输入用途"
allow-clear
:disabled="!showFooter"
:bordered="false"
class="form-input"
/>
</td>
<th class="formTitle" colspan="1">母胶比重</th>
<td class="formValue">
<a-input-number v-model:value="sheetForm.motherRubberSg" :disabled="!showFooter" :precision="6" :bordered="false" class="form-input" style="width: 100%" @update:value="recalcFillVolume" />
</td>
<th class="formTitle">段数</th>
<td class="formValue" colspan="2">
<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">
<a-input-number v-model:value="sheetForm.pureMixSec" :disabled="!showFooter" :precision="0" :bordered="false" class="form-input" style="width: 100%" />
</td>
<th class="formTitle" colspan="1">回收炭黑(KG)</th>
<td class="formValue">
<a-input-number v-model:value="sheetForm.recycleCarbonKg" :disabled="!showFooter" :precision="6" :bordered="false" class="form-input" style="width: 100%" />
</td>
</tr>
<tr>
<th class="formTitle" colspan="1">终炼胶比重</th>
<td class="formValue">
<a-input-number v-model:value="sheetForm.finalRubberSg" :disabled="!showFooter" :precision="6" :bordered="false" class="form-input" style="width: 100%" @update:value="recalcFillVolume" />
</td>
<th class="formTitle" colspan="1">适用工厂</th>
<td class="formValue" colspan="2">
<a-input v-model:value="sheetForm.applyFactory" :disabled="!showFooter" :bordered="false" class="form-input" />
</td>
<th class="formTitle" colspan="1">自动小料打印设定</th>
<td class="formValue">
<a-input v-model:value="sheetForm.autoSmallPrintSetting" :disabled="!showFooter" :bordered="false" class="form-input" />
</td>
<th class="formTitle" colspan="1">设定车数</th>
<td class="formValue">
<a-input-number v-model:value="sheetForm.setTrainCount" :disabled="!showFooter" :precision="0" :bordered="false" class="form-input" style="width: 100%" />
</td>
</tr>
<tr>
<td colspan="13" class="form-nested-wrap">
<table class="mixing-form-table mixing-form-nested">
<tbody>
<tr>
<th class="formTitle" colspan="12">配方参数设定</th>
</tr>
<tr>
<th class="formTitle">侧壁水温</th>
<td class="formValue">
<a-input-number v-model:value="sheetForm.sideWallWaterTemp" :disabled="!showFooter" :precision="6" :bordered="false" class="form-input" style="width: 100%" />
</td>
<th class="formTitle">超时排胶时间</th>
<td class="formValue">
<a-input-number v-model:value="sheetForm.overtimeDischargeSec" :disabled="!showFooter" :precision="0" :bordered="false" class="form-input" style="width: 100%" />
</td>
<th class="formTitle">超温排胶时间</th>
<td class="formValue">
<a-input-number v-model:value="sheetForm.overtempDischargeSec" :disabled="!showFooter" :precision="0" :bordered="false" class="form-input" style="width: 100%" />
</td>
<th class="formTitle">超温排胶温度</th>
<td class="formValue">
<a-input-number v-model:value="sheetForm.overtempDischargeTemp" :disabled="!showFooter" :precision="6" :bordered="false" class="form-input" style="width: 100%" />
</td>
<th class="formTitle">卸料门水温</th>
<td class="formValue">
<a-input-number v-model:value="sheetForm.doorWaterTemp" :disabled="!showFooter" :precision="6" :bordered="false" class="form-input" style="width: 100%" />
</td>
<th class="formTitle">转子水温</th>
<td class="formValue">
<a-input-number v-model:value="sheetForm.rotorWaterTemp" :disabled="!showFooter" :precision="6" :bordered="false" class="form-input" style="width: 100%" />
</td>
</tr>
<tr>
<th class="formTitle">最高进料温度</th>
<td class="formValue">
<a-input-number v-model:value="sheetForm.maxFeedTemp" :disabled="!showFooter" :precision="6" :bordered="false" class="form-input" style="width: 100%" />
</td>
<td class="formValue blank" colspan="10"></td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
<!--update-end---author:cursor ---date:20260522 forXSLMES-20260522-A17顶部施工表对齐旧系统13列表格----------- -->
<div class="sheet-panels">
<div class="panel panel-left" :style="materialPanelStyle">
<div class="panel-head">
<span>橡胶及配合剂</span>
<div v-if="showFooter" class="panel-head-actions" @click.stop>
<MesXslMixingMaterialColumnSetting v-model:hidden-keys="materialHiddenColumnKeys" />
<MesXslMixingTableRowHeightSetting table-key="material" v-model:preference="materialHeightPref" />
<a-button size="small" type="primary" @click="addMaterialRow">新增行</a-button>
</div>
<div v-else class="panel-head-actions" @click.stop>
<MesXslMixingTableRowHeightSetting table-key="material" v-model:preference="materialHeightPref" />
</div>
</div>
<div class="material-table-wrap" :style="{ height: `${materialMainTableHeight}px` }">
<!--update-begin---author:cursor ---date:20260525 forXSLMES-20260525-A42橡胶及配合剂明细底部固定合计行----------- -->
<div class="material-table-stack" :style="{ width: `${materialTableWidth}px` }">
<div class="material-table-body" :style="{ height: `${materialBodyTableHeight}px` }">
<JVxeTable
:key="materialTableLayoutKey"
ref="materialRef"
row-number
keep-source
bordered
:fit="false"
:column-config="{ resizable: true }"
:row-config="materialRowConfig"
size="mini"
:height="materialBodyTableHeight"
:scroll-x="{ enabled: false }"
:scroll-y="{ enabled: true }"
:columns="visibleMaterialColumns"
:dataSource="materialData"
:disabled="!showFooter"
@value-change="handleMaterialValueChange"
@resizable-change="handleMaterialColumnResize"
@column-resizable-change="handleMaterialColumnResize"
>
<template #mixerMaterialNameSlot="{ row }">
<div
class="mixing-material-name-cell"
:class="{ 'is-disabled': !showFooter }"
:style="{ minHeight: `${materialHeightPref.rowHeight}px` }"
@click.stop="openMixingMaterialPicker(row)"
>
<span v-if="row.mixerMaterialName" class="mixing-material-name-text">{{ row.mixerMaterialName }}</span>
</div>
</template>
</JVxeTable>
</div>
<div class="material-table-footer">
<div class="material-table-footer-row">
<div
class="material-footer-seq"
:style="{ width: `${MIXING_MATERIAL_ROW_NUMBER_WIDTH}px`, height: `${materialHeightPref.rowHeight}px` }"
></div>
<div
v-for="cell in materialFooterCells"
:key="cell.key"
class="material-footer-cell"
:class="{ 'is-label': cell.isLabel, 'is-total': cell.isTotal }"
:style="{ width: `${cell.width}px`, height: `${materialHeightPref.rowHeight}px` }"
>
{{ cell.text }}
</div>
</div>
</div>
</div>
<!--update-end---author:cursor ---date:20260525 forXSLMES-20260525-A42橡胶及配合剂明细底部固定合计行----------- -->
</div>
<!--update-begin---author:cursor ---date:20260522 forXSLMES-20260522-A18TCU温度条件表移至橡胶及配合剂下方----------- -->
<div class="left-panel-section left-panel-section-tcu">
<div class="panel-head">
<span>TCU温度条件</span>
<div class="panel-head-actions" @click.stop>
<MesXslMixingTableRowHeightSetting table-key="tcu" v-model:preference="tcuHeightPref" />
</div>
</div>
<div class="tcu-table-wrap" :style="tcuTableWrapStyle">
<JVxeTable
:key="tcuTableLayoutKey"
ref="tcuRef"
row-number
keep-source
bordered
:fit="false"
:column-config="{ resizable: true }"
:row-config="tcuRowConfig"
:show-header-overflow="false"
size="mini"
:height="tcuTableHeight"
:scroll-x="{ enabled: false }"
:columns="visibleTcuColumns"
:dataSource="tcuData"
:disabled="!showFooter"
@value-change="handleTcuValueChange"
@resizable-change="handleTcuColumnResize"
@column-resizable-change="handleTcuColumnResize"
/>
</div>
</div>
<!--update-end---author:cursor ---date:20260522 forXSLMES-20260522-A18TCU温度条件表移至橡胶及配合剂下方----------- -->
</div>
<div class="panel panel-right">
<div class="panel panel-step-main">
<div class="panel-head">
<span>混合步骤</span>
<div class="panel-head-actions" @click.stop>
<MesXslMixingTableRowHeightSetting table-key="step" v-model:preference="stepHeightPref" />
<!--update-begin---author:cursor ---date:20260526 forXSLMES-20260526-A58混合步骤参照历史示方按钮----------- -->
<a-button v-if="showFooter" size="small" @click="openHistoryStepPicker">参照历史混合步骤</a-button>
<!--update-end---author:cursor ---date:20260526 forXSLMES-20260526-A58混合步骤参照历史示方按钮----------- -->
<a-button v-if="showFooter" size="small" type="primary" @click="addStepRow">新增行</a-button>
</div>
</div>
<!--update-begin---author:cursor ---date:20260522 forXSLMES-20260522-A21混合步骤与下密炼机列宽同步可调----------- -->
<div class="step-table-wrap" :style="{ height: `${stepMainTableHeight}px` }">
<JVxeTable
:key="stepTableLayoutKey"
ref="stepRef"
row-number
keep-source
bordered
:fit="true"
:column-config="{ resizable: true }"
:row-config="stepRowConfig"
size="mini"
:height="stepMainTableHeight"
:scroll-y="{ enabled: true }"
:columns="visibleStepColumns"
:dataSource="stepData"
: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>
<div class="panel panel-down-step">
<div class="panel-head">
<span>下密炼机混炼条件</span>
<div class="panel-head-actions" @click.stop>
<MesXslMixingTableRowHeightSetting table-key="downStep" v-model:preference="downStepHeightPref" />
<a-button v-if="showFooter" size="small" type="primary" @click="addDownStepRow">新增行</a-button>
</div>
</div>
<div class="step-table-wrap step-table-wrap--compact" :style="{ height: `${downStepTableHeight}px` }">
<JVxeTable
:key="downStepTableLayoutKey"
ref="downStepRef"
row-number
keep-source
bordered
:fit="true"
:column-config="{ resizable: true }"
:row-config="downStepRowConfig"
size="mini"
:height="downStepTableHeight"
:columns="visibleStepColumns"
:dataSource="downStepData"
: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>
</div>
<!-- 页脚审批签字区五列只读展示 -->
<div class="sheet-sign-footer">
<div class="sign-grid sign-grid-head">
<div class="sign-cell sign-title">起草人</div>
<div class="sign-cell sign-title">校对人</div>
<div class="sign-cell sign-title">审核人</div>
<div class="sign-cell sign-title">批准人</div>
<div class="sign-cell sign-title sign-title-stack">
<span>变更人</span>
<span>变更日期</span>
</div>
</div>
<div class="sign-grid sign-grid-name">
<div class="sign-cell sign-value sign-text">{{ signDisplay.draftBy || '—' }}</div>
<div class="sign-cell sign-value sign-text">{{ signDisplay.proofreadBy || '—' }}</div>
<div class="sign-cell sign-value sign-text">{{ signDisplay.auditBy || '—' }}</div>
<div class="sign-cell sign-value sign-text">{{ signDisplay.approveBy || '—' }}</div>
<div class="sign-cell sign-value sign-text">{{ signDisplay.changeBy || '—' }}</div>
</div>
<div class="sign-grid sign-grid-time">
<div class="sign-cell sign-value sign-text">{{ signDisplay.draftTime || '—' }}</div>
<div class="sign-cell sign-value sign-text">{{ signDisplay.proofreadTime || '—' }}</div>
<div class="sign-cell sign-value sign-text">{{ signDisplay.auditTime || '—' }}</div>
<div class="sign-cell sign-value sign-text">{{ signDisplay.approveTime || '—' }}</div>
<div class="sign-cell sign-value sign-text">{{ signDisplay.changeDate || '—' }}</div>
</div>
</div>
<BasicForm v-show="false" @register="registerForm" />
</div>
</BasicModal>
<MesXslEquipmentLedgerSelectModal @register="registerMachineModal" @select="onMachineSelect" />
<MesXslMixerPsCompileSelectModal @register="registerIssueNumberModal" @select="onIssueNumberSelect" />
<MesXslMixingMaterialSelectModal @register="registerMixingMaterialModal" @select="onMixingMaterialSelect" />
<MesXslMixingSpecStepHistorySelectModal @register="registerHistoryStepModal" @select="onHistoryStepSelect" />
</template>
<script lang="ts" setup>
import { computed, reactive, ref, unref } from 'vue';
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';
import {
mainSchema,
materialColumns,
stepColumns,
tcuColumns,
loadMixingMaterialHiddenColumnKeys,
loadMixingMaterialColumnWidths,
saveMixingMaterialColumnWidths,
applyMixingMaterialColumnVisibility,
applyMixingMaterialColumnWidths,
calcMixingMaterialTableWidth,
calcMixingDetailTableViewportHeight,
buildMixingTableRowConfig,
loadMixingTableHeightPreference,
calcMixingTcuTableWidth,
loadMixingTcuColumnWidths,
saveMixingTcuColumnWidths,
applyMixingTcuColumnWidths,
loadMixingStepColumnWidths,
saveMixingStepColumnWidths,
applyMixingStepColumnWidths,
createEmptyMaterialRows,
createEmptyStepRows,
createEmptyDownStepRows,
ensureMixingDetailRows,
DEFAULT_MIXING_MATERIAL_ROW_COUNT,
DEFAULT_MIXING_STEP_ROW_COUNT,
DEFAULT_MIXING_DOWN_STEP_ROW_COUNT,
buildDefaultMixingTcuRows,
applyMixingMaterialFromSelection,
fillMixingMaterialAccumWeight,
calcMixingMaterialUnitWeightTotal,
calcMixingMaterialAccumWeightTotal,
buildMixingMaterialFooterCells,
normalizeMixingConvertFactor,
initMaterialBaseUnitWeights,
applyConvertFactorToMaterialRows,
syncMaterialBaseUnitWeightFromDisplay,
calcMixingFillVolume,
resolveMixingSpecificGravity,
cloneMixingHistoryStepRows,
MIXING_MATERIAL_ROW_NUMBER_WIDTH,
MIXING_MATERIAL_FOOTER_ROW_HEIGHT,
MIXING_MATERIAL_MIN_COLUMN_WIDTH,
MIXING_TCU_MIN_COLUMN_WIDTH,
MIXING_STEP_MIN_COLUMN_WIDTH,
} from '../MesXslMixingSpec.data';
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 { queryById as queryEquipmentById } from '/@/views/xslmes/mesXslEquipmentLedger/MesXslEquipmentLedger.api';
import MesXslMixerPsCompileSelectModal from '/@/views/xslmes/mesXslMixerPsCompile/components/MesXslMixerPsCompileSelectModal.vue';
import MesXslMixingMaterialSelectModal from './MesXslMixingMaterialSelectModal.vue';
import MesXslMixingSpecStepHistorySelectModal from './MesXslMixingSpecStepHistorySelectModal.vue';
const emit = defineEmits(['register', 'success']);
const { createMessage } = useMessage();
const userStore = useUserStore();
const isUpdate = ref(false);
const showFooter = ref(true);
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 materialPickerRow = ref<Recordable | null>(null);
const stepRef = ref();
const downStepRef = ref();
const tcuRef = ref();
const materialData = ref<Recordable[]>([]);
const stepData = ref<Recordable[]>([]);
const downStepData = ref<Recordable[]>([]);
const tcuData = ref<Recordable[]>([]);
//update-begin---author:cursor ---date:20260522 for【XSLMES-20260522-A17】橡胶及配合剂明细列展示设置-----------
const materialHiddenColumnKeys = ref<string[]>(loadMixingMaterialHiddenColumnKeys());
const materialColumnWidths = ref<Record<string, number>>(loadMixingMaterialColumnWidths());
const visibleMaterialColumns = computed(() =>
applyMixingMaterialColumnWidths(
applyMixingMaterialColumnVisibility(materialColumns, materialHiddenColumnKeys.value),
materialColumnWidths.value,
),
);
const materialTableWidth = computed(() => calcMixingMaterialTableWidth(visibleMaterialColumns.value, materialColumnWidths.value));
const materialTableColumnKey = computed(() => materialHiddenColumnKeys.value.join('|') || 'all');
//update-begin---author:cursor ---date:20260522 for【XSLMES-20260522-A32】四明细表行高/展示行数设置持久化-----------
const materialHeightPref = ref(loadMixingTableHeightPreference('material'));
const tcuHeightPref = ref(loadMixingTableHeightPreference('tcu'));
const stepHeightPref = ref(loadMixingTableHeightPreference('step'));
const downStepHeightPref = ref(loadMixingTableHeightPreference('downStep'));
const materialMainTableHeight = computed(() => calcMixingDetailTableViewportHeight('material', materialHeightPref.value));
//update-begin---author:cursor ---date:20260525 for【XSLMES-20260525-A42】橡胶及配合剂明细底部固定合计行-----------
const materialBodyTableHeight = computed(() =>
Math.max(materialMainTableHeight.value - MIXING_MATERIAL_FOOTER_ROW_HEIGHT, 80),
);
const materialUnitWeightTotal = ref<number | null>(null);
//update-begin---author:cursor ---date:20260525 for【XSLMES-20260525-A46】换算系数/单重/机台有效体积联动填充体积-----------
const machineEffectiveVolume = ref('');
//update-end---author:cursor ---date:20260525 for【XSLMES-20260525-A46】换算系数/单重/机台有效体积联动填充体积-----------
const materialAccumWeightTotal = ref<number | null>(null);
const materialFooterCells = computed(() =>
buildMixingMaterialFooterCells(visibleMaterialColumns.value, materialColumnWidths.value, {
unitWeight: materialUnitWeightTotal.value,
accumWeight: materialAccumWeightTotal.value,
}),
);
//update-end---author:cursor ---date:20260525 for【XSLMES-20260525-A42】橡胶及配合剂明细底部固定合计行-----------
const stepMainTableHeight = computed(() => calcMixingDetailTableViewportHeight('step', stepHeightPref.value));
const tcuTableHeight = computed(() => calcMixingDetailTableViewportHeight('tcu', tcuHeightPref.value));
const downStepTableHeight = computed(() => calcMixingDetailTableViewportHeight('downStep', downStepHeightPref.value));
const materialRowConfig = computed(() => buildMixingTableRowConfig(materialHeightPref.value));
const tcuRowConfig = computed(() => buildMixingTableRowConfig(tcuHeightPref.value));
const stepRowConfig = computed(() => buildMixingTableRowConfig(stepHeightPref.value));
const downStepRowConfig = computed(() => buildMixingTableRowConfig(downStepHeightPref.value));
const materialTableLayoutKey = computed(
() => `${materialTableColumnKey.value}-${materialHeightPref.value.rowHeight}-${materialHeightPref.value.visibleRowCount}`,
);
const tcuTableLayoutKey = computed(
() => `${tcuHeightPref.value.rowHeight}-${tcuHeightPref.value.visibleRowCount}-${tcuTableWidth.value}`,
);
const stepTableLayoutKey = computed(
() =>
`${stepHeightPref.value.rowHeight}-${stepHeightPref.value.visibleRowCount}-${mixerActionOptions.value.length}-${mixerConditionOptions.value.length}`,
);
const downStepTableLayoutKey = computed(
() =>
`${downStepHeightPref.value.rowHeight}-${downStepHeightPref.value.visibleRowCount}-${mixerActionOptions.value.length}-${mixerConditionOptions.value.length}`,
);
//update-end---author:cursor ---date:20260522 for【XSLMES-20260522-A32】四明细表行高/展示行数设置持久化-----------
function handleMaterialColumnResize(params: Recordable) {
const column = params?.resizeColumn ?? params?.column;
const key = column?.params?.key ?? column?.field;
if (!key || column?.type === 'seq') {
return;
}
const width = Math.max(
MIXING_MATERIAL_MIN_COLUMN_WIDTH,
Math.round(Number(params?.resizeWidth ?? column?.renderWidth ?? column?.width)),
);
if (!width || Number.isNaN(width)) {
return;
}
materialColumnWidths.value = {
...materialColumnWidths.value,
[String(key)]: width,
};
saveMixingMaterialColumnWidths(materialColumnWidths.value);
}
//update-begin---author:cursor ---date:20260525 for【XSLMES-20260525-A41】橡胶及配合剂明细累计按种类分组合计-----------
/** JVxe getTableData 为浅拷贝,批量改值需用 fullData 原行并强制 refresh */
function resolveMaterialTableRawRows(): Recordable[] {
const fullData = materialRef.value?.getXTable?.()?.getTableData?.()?.fullData as Recordable[] | undefined;
if (Array.isArray(fullData) && fullData.length) {
return fullData;
}
return (materialRef.value?.getTableData?.() || materialData.value || []) as Recordable[];
}
function refreshMaterialTableView() {
materialRef.value?.getXTable?.()?.updateData?.();
}
function applyMaterialAccumWeight(rows?: Recordable[]) {
const targetRows = rows || resolveMaterialTableRawRows();
fillMixingMaterialAccumWeight(targetRows);
materialUnitWeightTotal.value = calcMixingMaterialUnitWeightTotal(targetRows);
materialAccumWeightTotal.value = calcMixingMaterialAccumWeightTotal(targetRows);
refreshMaterialTableView();
recalcFillVolume();
}
//update-begin---author:cursor ---date:20260525 for【XSLMES-20260525-A46】换算系数/单重/机台有效体积联动填充体积-----------
async function loadMachineEffectiveVolume(machineId?: string) {
const id = machineId || sheetForm.machineId;
if (!id) {
machineEffectiveVolume.value = '';
return;
}
try {
const raw = await queryEquipmentById({ id });
const row = (raw as Recordable)?.id != null ? raw : (raw as Recordable)?.result;
machineEffectiveVolume.value = row?.effectiveVolume || '';
} catch {
machineEffectiveVolume.value = '';
}
}
function recalcFillVolume() {
if (!showFooter.value) {
return;
}
const totalWeight =
materialUnitWeightTotal.value ?? calcMixingMaterialUnitWeightTotal(resolveMaterialTableRawRows());
const specificGravity = resolveMixingSpecificGravity(sheetForm);
const next = calcMixingFillVolume(totalWeight, specificGravity, machineEffectiveVolume.value);
if (next != null) {
sheetForm.fillVolume = next;
}
}
//update-end---author:cursor ---date:20260525 for【XSLMES-20260525-A46】换算系数/单重/机台有效体积联动填充体积-----------
//update-begin---author:cursor ---date:20260525 for【XSLMES-20260525-A43】换算系数联动明细单重实时计算-----------
const lastConvertFactor = ref<number>(1);
const convertFactorApplying = ref(false);
function applyConvertFactorToMaterials(factor: unknown) {
const rows = resolveMaterialTableRawRows();
applyConvertFactorToMaterialRows(rows, factor, lastConvertFactor.value);
lastConvertFactor.value = normalizeMixingConvertFactor(factor);
applyMaterialAccumWeight(rows);
}
function handleConvertFactorChange(value: unknown) {
if (!showFooter.value || convertFactorApplying.value) {
return;
}
applyConvertFactorToMaterials(value);
recalcFillVolume();
}
function stripMaterialRowForSave(row: Recordable) {
if (!row) {
return row;
}
const { baseUnitWeight: _baseUnitWeight, ...rest } = row;
return rest;
}
//update-end---author:cursor ---date:20260525 for【XSLMES-20260525-A43】换算系数联动明细单重实时计算-----------
function recalcMaterialAccumWeight() {
applyMaterialAccumWeight();
}
function handleMaterialValueChange(event) {
const key = event?.column?.key;
const row = event?.row;
//update-begin---author:cursor ---date:20260525 for【XSLMES-20260525-A43】换算系数联动明细单重实时计算-----------
if (key === 'unitWeight' && row) {
syncMaterialBaseUnitWeightFromDisplay(row, sheetForm.convertFactor);
}
//update-end---author:cursor ---date:20260525 for【XSLMES-20260525-A43】换算系数联动明细单重实时计算-----------
if (key === 'unitWeight' || key === 'materialKind') {
recalcMaterialAccumWeight();
}
}
//update-end---author:cursor ---date:20260525 for【XSLMES-20260525-A41】橡胶及配合剂明细累计按种类分组合计-----------
//update-end---author:cursor ---date:20260522 for【XSLMES-20260522-A17】橡胶及配合剂明细列展示设置-----------
//update-begin---author:cursor ---date:20260522 for【XSLMES-20260522-A19】TCU温度条件表列宽可调且表头换行-----------
const tcuColumnWidths = ref<Record<string, number>>(loadMixingTcuColumnWidths());
const visibleTcuColumns = computed(() => applyMixingTcuColumnWidths(tcuColumns, tcuColumnWidths.value));
const tcuTableWidth = computed(() => calcMixingTcuTableWidth(visibleTcuColumns.value, tcuColumnWidths.value));
const tcuTableWrapStyle = computed(() => ({
width: `${tcuTableWidth.value}px`,
height: `${tcuTableHeight.value}px`,
}));
const materialPanelStyle = computed(() => ({
width: `${Math.max(materialTableWidth.value, tcuTableWidth.value)}px`,
maxWidth: '100%',
}));
function handleTcuColumnResize(params: Recordable) {
const column = params?.resizeColumn ?? params?.column;
const key = column?.params?.key ?? column?.field;
if (!key || column?.type === 'seq') {
return;
}
const width = Math.max(
MIXING_TCU_MIN_COLUMN_WIDTH,
Math.round(Number(params?.resizeWidth ?? column?.renderWidth ?? column?.width)),
);
if (!width || Number.isNaN(width)) {
return;
}
tcuColumnWidths.value = {
...tcuColumnWidths.value,
[String(key)]: width,
};
saveMixingTcuColumnWidths(tcuColumnWidths.value);
}
//update-end---author:cursor ---date:20260522 for【XSLMES-20260522-A19】TCU温度条件表列宽可调且表头换行-----------
//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;
if (!key || column?.type === 'seq') {
return;
}
const width = Math.max(
MIXING_STEP_MIN_COLUMN_WIDTH,
Math.round(Number(params?.resizeWidth ?? column?.renderWidth ?? column?.width)),
);
if (!width || Number.isNaN(width)) {
return;
}
stepColumnWidths.value = {
...stepColumnWidths.value,
[String(key)]: width,
};
saveMixingStepColumnWidths(stepColumnWidths.value);
}
//update-end---author:cursor ---date:20260522 for【XSLMES-20260522-A21】混合步骤与下密炼机列宽同步可调-----------
const sheetForm = reactive<Recordable>({
id: '',
specName: '',
purpose: '',
machineId: '',
machineName: '',
makeDate: '',
issueNumber: '',
convertFactor: null,
fillVolume: null,
recycleCarbonSec: null,
motherRubberSg: null,
finalRubberSg: null,
applyFactory: '',
stageCount: '',
pureMixSec: null,
recycleCarbonKg: null,
autoSmallPrintSetting: '',
setTrainCount: null,
sideWallWaterTemp: null,
overtimeDischargeSec: null,
overtempDischargeSec: null,
overtempDischargeTemp: null,
doorWaterTemp: null,
rotorWaterTemp: null,
maxFeedTemp: null,
draftBy: '',
draftTime: '',
proofreadBy: '',
proofreadTime: '',
auditBy: '',
auditTime: '',
approveBy: '',
approveTime: '',
changeDate: '',
});
//update-begin---author:cursor ---date:20260522 for【XSLMES-20260522-A17】页脚签章区只读展示-----------
const signDisplay = reactive({
draftBy: '',
draftTime: '',
proofreadBy: '',
proofreadTime: '',
auditBy: '',
auditTime: '',
approveBy: '',
approveTime: '',
changeBy: '',
changeDate: '',
});
function formatSignDateTime(value?: string) {
if (!value) {
return '';
}
const text = String(value);
return text.length >= 19 ? text.slice(0, 19) : text.slice(0, 10);
}
function formatSignDate(value?: string) {
if (!value) {
return '';
}
return String(value).slice(0, 10);
}
function refreshSignDisplay(row: Recordable = {}) {
signDisplay.draftBy = row.draftBy || row.createBy_dictText || row.createBy || '';
signDisplay.draftTime = formatSignDateTime(row.draftTime || row.createTime);
signDisplay.proofreadBy = row.proofreadBy || row.proofreadBy_dictText || '';
signDisplay.proofreadTime = formatSignDateTime(row.proofreadTime);
signDisplay.auditBy = row.auditBy || row.auditBy_dictText || '';
signDisplay.auditTime = formatSignDateTime(row.auditTime);
signDisplay.approveBy = row.approveBy || row.approveBy_dictText || '';
signDisplay.approveTime = formatSignDateTime(row.approveTime);
signDisplay.changeBy = row.updateBy_dictText || row.updateBy || '';
signDisplay.changeDate = formatSignDate(row.changeDate || row.updateTime);
}
//update-end---author:cursor ---date:20260522 for【XSLMES-20260522-A17】页脚签章区只读展示-----------
const [registerForm, { resetFields, setFieldsValue, validate, setProps }] = useForm({
labelWidth: 96,
schemas: mainSchema,
showActionButtonGroup: false,
baseColProps: { span: 8 },
});
//update-begin---author:cursor ---date:20260522 for【XSLMES-20260522-A33】混炼示方主表选择弹窗-----------
const [registerMachineModal, { openModal: openMachineModalInner, closeModal: closeMachineModal }] = useModal();
const [registerIssueNumberModal, { openModal: openIssueNumberModalInner, closeModal: closeIssueNumberModal }] = useModal();
const [registerMixingMaterialModal, { openModal: openMixingMaterialModalInner, closeModal: closeMixingMaterialModal, setModalProps: setMixingMaterialModalProps }] = useModal();
//update-begin---author:cursor ---date:20260526 for【XSLMES-20260526-A58】参照历史混合步骤选择弹窗-----------
const [registerHistoryStepModal, { openModal: openHistoryStepModalInner, closeModal: closeHistoryStepModal, setModalProps: setHistoryStepModalProps }] = useModal();
//update-end---author:cursor ---date:20260526 for【XSLMES-20260526-A58】参照历史混合步骤选择弹窗-----------
//update-begin---author:cursor ---date:20260525 for【XSLMES-20260525-A52】关闭混炼示方弹窗时同步关闭嵌套选料弹窗-----------
function closeNestedPickers() {
closeMixingMaterialModal();
closeMachineModal();
closeIssueNumberModal();
closeHistoryStepModal();
materialPickerRow.value = null;
}
//update-end---author:cursor ---date:20260525 for【XSLMES-20260525-A52】关闭混炼示方弹窗时同步关闭嵌套选料弹窗-----------
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 || '';
machineEffectiveVolume.value = payload?.effectiveVolume || '';
if (sheetForm.machineId && !machineEffectiveVolume.value) {
await loadMachineEffectiveVolume(sheetForm.machineId);
}
recalcFillVolume();
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 || '';
}
function openMixingMaterialPicker(row: Recordable) {
if (!showFooter.value || !row) {
return;
}
materialPickerRow.value = row;
//update-begin---author:cursor ---date:20260525 for【XSLMES-20260525-A52】选料弹窗层级高于全屏父弹窗-----------
setMixingMaterialModalProps({ zIndex: 1500 });
openMixingMaterialModalInner(true, { picker: true, ts: Date.now() });
//update-end---author:cursor ---date:20260525 for【XSLMES-20260525-A52】选料弹窗层级高于全屏父弹窗-----------
}
function onMixingMaterialSelect(payload: Recordable | null) {
if (!payload || !materialPickerRow.value) {
return;
}
//update-begin---author:cursor ---date:20260525 for【XSLMES-20260525-A53】选料回填种类仅使用配置解析结果-----------
applyMixingMaterialFromSelection(materialPickerRow.value, payload, payload.materialKind || '');
//update-end---author:cursor ---date:20260525 for【XSLMES-20260525-A53】选料回填种类仅使用配置解析结果-----------
recalcMaterialAccumWeight();
materialPickerRow.value = null;
}
//update-begin---author:cursor ---date:20260526 for【XSLMES-20260526-A58】参照历史混合步骤回填明细-----------
function openHistoryStepPicker() {
if (!showFooter.value) {
return;
}
setHistoryStepModalProps({ zIndex: 1500 });
openHistoryStepModalInner(true, {
machineId: sheetForm.machineId || '',
excludeSpecId: sheetForm.id || '',
});
}
async function onHistoryStepSelect(payload: Recordable | null) {
if (!payload?.mixingSpecId) {
return;
}
try {
const raw = await queryById({ id: payload.mixingSpecId });
const row = (raw as Recordable)?.specName != null ? raw : (raw as Recordable)?.result;
const clonedSteps = cloneMixingHistoryStepRows(row?.stepList || []);
if (!clonedSteps.length) {
createMessage.warning('所选混炼示方没有可参照的混合步骤');
return;
}
stepData.value = ensureMixingDetailRows(clonedSteps, DEFAULT_MIXING_STEP_ROW_COUNT);
createMessage.success(`已参照「${payload.specName || row?.specName || ''}」混合步骤`);
} catch {
createMessage.error('加载历史混合步骤失败');
}
}
//update-end---author:cursor ---date:20260526 for【XSLMES-20260526-A58】参照历史混合步骤回填明细-----------
//update-end---author:cursor ---date:20260522 for【XSLMES-20260522-A33】混炼示方主表选择弹窗-----------
function ensureTcuDefaultRows(rows: Recordable[] = []) {
//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) {
//update-begin---author:cursor ---date:20260522 for【XSLMES-20260522-A17】下密炼机禁用药品称量位置-----------
const row = event?.row;
const key = event?.column?.key;
if (!row || key !== 'drugWeighPos') {
return;
}
if (row.sectionType === 'down_mixer') {
row.drugWeighPos = undefined;
createMessage.warning('下密炼机不允许选择药品称量位置');
}
//update-end---author:cursor ---date:20260522 for【XSLMES-20260522-A17】下密炼机禁用药品称量位置-----------
}
function resetSheetForm() {
Object.keys(sheetForm).forEach((key) => {
sheetForm[key] =
key === 'specName' ||
key === 'purpose' ||
key === 'machineId' ||
key === 'machineName' ||
key === 'issueNumber' ||
key === 'stageCount' ||
key.endsWith('By') ||
key === 'applyFactory' ||
key === 'autoSmallPrintSetting'
? ''
: null;
});
sheetForm.id = '';
sheetForm.makeDate = '';
sheetForm.draftTime = '';
sheetForm.proofreadTime = '';
sheetForm.auditTime = '';
sheetForm.approveTime = '';
sheetForm.changeDate = '';
mixerPsCompilePickerId.value = '';
machineEffectiveVolume.value = '';
refreshSignDisplay({});
}
async function syncSheetToForm() {
await setFieldsValue({ ...sheetForm });
}
function addMaterialRow() {
materialRef.value?.addRows?.({});
}
function addStepRow() {
stepRef.value?.addRows?.({});
}
function addDownStepRow() {
downStepRef.value?.addRows?.({});
}
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
await resetFields();
resetSheetForm();
materialData.value = [];
materialUnitWeightTotal.value = null;
materialAccumWeightTotal.value = null;
lastConvertFactor.value = 1;
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 });
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 loadMachineEffectiveVolume(sheetForm.machineId);
await loadMixerStepOptions(sheetForm.machineId);
await syncSheetToForm();
//update-begin---author:cursor ---date:20260522 for【XSLMES-20260522-A39】编辑页明细补齐默认空行与新增一致-----------
materialData.value = ensureMixingDetailRows(row?.materialList || [], DEFAULT_MIXING_MATERIAL_ROW_COUNT);
convertFactorApplying.value = true;
initMaterialBaseUnitWeights(materialData.value, sheetForm.convertFactor, true);
lastConvertFactor.value = normalizeMixingConvertFactor(sheetForm.convertFactor);
applyMaterialAccumWeight(materialData.value);
convertFactorApplying.value = false;
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,
});
//update-begin---author:cursor ---date:20260522 for【XSLMES-20260522-A22】明细表默认空行数-----------
materialData.value = createEmptyMaterialRows();
lastConvertFactor.value = normalizeMixingConvertFactor(sheetForm.convertFactor);
stepData.value = createEmptyStepRows();
downStepData.value = createEmptyDownStepRows();
//update-end---author:cursor ---date:20260522 for【XSLMES-20260522-A22】明细表默认空行数-----------
await syncSheetToForm();
}
});
const title = computed(() => (!showFooter.value && unref(isUpdate) ? '混炼示方详情' : !unref(isUpdate) ? '新增混炼示方' : '编辑混炼示方'));
async function handleSubmit() {
await syncSheetToForm();
const formValues = await validate();
const materialList = resolveMaterialTableRawRows();
applyMaterialAccumWeight(materialList);
const stepList = stepRef.value?.getTableData?.() || stepData.value;
const downStepList = downStepRef.value?.getTableData?.() || downStepData.value;
const tcuList = ensureTcuDefaultRows((tcuRef.value?.getTableData?.() || tcuData.value) as Recordable[]);
const cleanRows = (rows: Recordable[]) => (rows || []).filter((row) => Object.values(row || {}).some((v) => v != null && v !== ''));
const payload = {
...formValues,
materialList: cleanRows(materialList).map(stripMaterialRowForSave),
stepList: cleanRows(stepList),
downStepList: cleanRows(downStepList),
tcuList: tcuList.map((row) => ({
...row,
drugWeighPos: row.sectionType === 'down_mixer' ? undefined : row.drugWeighPos,
})),
};
setModalProps({ confirmLoading: true });
try {
await saveOrUpdate(payload, unref(isUpdate));
createMessage.success(unref(isUpdate) ? '编辑成功' : '新增成功');
closeModal();
emit('success');
} finally {
setModalProps({ confirmLoading: false });
}
}
</script>
<style lang="less" scoped>
//update-begin---author:cursor ---date:20260522 for【XSLMES-20260522-A17】顶部施工表对齐旧系统13列表格-----------
@form-border: #ccc;
@form-label-bg: #f5f5f5;
@form-bg: #fcfdfd;
.mixing-sheet {
border: 1px solid @form-border;
background: @form-bg;
overflow-x: auto;
}
.mixing-form-table {
width: 100%;
min-width: 1350px;
border-collapse: collapse;
table-layout: fixed;
background: @form-bg;
th.formTitle {
height: 28px;
padding: 0 4px;
border: 1px solid @form-border;
background: @form-label-bg;
color: #333;
font-size: 12px;
font-weight: 600;
text-align: center;
vertical-align: middle;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
th.formTitle.required::before {
content: '*';
color: #ff4d4f;
margin-right: 2px;
}
td.formValue {
height: 28px;
padding: 0;
border: 1px solid @form-border;
background: #fff;
text-align: center;
vertical-align: middle;
}
td.formValue.blank {
background: #fff;
}
td.form-nested-wrap {
padding: 0;
border: 1px solid @form-border;
background: @form-bg;
}
tr.form-title-row th.formTitle {
height: 40px;
font-size: 16px;
font-weight: 700;
letter-spacing: 2px;
}
}
.mixing-form-nested {
min-width: 100%;
border: none;
th.formTitle,
td.formValue {
border: 1px solid @form-border;
}
}
.formValue {
:deep(.form-input.ant-input),
:deep(.form-input.ant-input-number),
:deep(.form-input.ant-picker),
:deep(.form-input.ant-select .ant-select-selector) {
width: 100% !important;
height: 26px !important;
min-height: 26px;
border: none !important;
box-shadow: none !important;
border-radius: 0 !important;
background: transparent !important;
text-align: center;
font-size: 12px;
color: #333;
padding: 0 4px !important;
}
:deep(.form-input.ant-input-number-input),
:deep(.form-input.ant-picker-input > input) {
text-align: center;
font-size: 12px;
height: 24px;
}
:deep(.form-input.ant-input-number-handler-wrap) {
display: none;
}
:deep(.form-input.ant-select-selection-item),
:deep(.form-input.ant-select-selection-placeholder) {
text-align: center;
line-height: 24px !important;
padding-inline-end: 16px !important;
}
:deep(.form-input.ant-select-arrow) {
right: 4px;
font-size: 10px;
color: #999;
}
:deep(.form-input.ant-picker-suffix) {
color: #999;
}
:deep(.mixing-picker-input) {
cursor: pointer;
}
:deep(.mixing-picker-input.is-filled) {
color: #262626;
}
:deep(.mixing-material-name-cell) {
display: flex;
align-items: center;
width: 100%;
height: 100%;
box-sizing: border-box;
padding: 2px 4px;
cursor: pointer;
}
:deep(.mixing-material-name-cell.is-disabled) {
cursor: not-allowed;
opacity: 0.65;
}
:deep(.mixing-material-name-text) {
color: #262626;
}
}
//update-end---author:cursor ---date:20260522 for【XSLMES-20260522-A17】顶部施工表对齐旧系统13列表格-----------
.sheet-panels {
display: flex;
align-items: stretch;
gap: 0;
}
.panel-left {
flex: 0 0 auto;
align-self: stretch;
min-height: 0;
overflow: hidden;
display: flex;
flex-direction: column;
.material-table-wrap {
overflow-x: auto;
overflow-y: hidden;
display: flex;
flex-direction: column;
:deep(.jeecg-j-vxe-table),
:deep(.j-vxe-table-box),
:deep(.vxe-grid),
:deep(.vxe-table) {
max-width: none;
}
:deep(.vxe-header--column .vxe-resizable) {
cursor: col-resize;
}
}
//update-begin---author:cursor ---date:20260525 for【XSLMES-20260525-A42】橡胶及配合剂明细底部固定合计行-----------
.material-table-stack {
display: flex;
flex-direction: column;
flex-shrink: 0;
min-width: min-content;
}
.material-table-body {
flex: 0 0 auto;
overflow: hidden;
:deep(.vxe-table--footer-wrapper) {
display: none;
}
:deep(.col--mixerMaterialName .vxe-cell) {
padding: 0;
height: 100%;
}
:deep(.col--mixerMaterialName .vxe-cell > div) {
height: 100%;
}
}
.material-table-footer {
flex-shrink: 0;
border: 1px solid #e8e8e8;
border-top: none;
background: #fafafa;
box-sizing: border-box;
}
.material-table-footer-row {
display: flex;
align-items: stretch;
box-sizing: border-box;
font-size: 12px;
}
.material-footer-seq,
.material-footer-cell {
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
border-right: 1px solid #e8e8e8;
box-sizing: border-box;
padding: 0 2px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
&:last-child {
border-right: none;
}
}
.material-footer-seq {
background: #fafafa;
}
.material-footer-cell.is-label,
.material-footer-cell.is-total {
font-weight: 600;
color: #262626;
}
//update-end---author:cursor ---date:20260525 for【XSLMES-20260525-A42】橡胶及配合剂明细底部固定合计行-----------
//update-begin---author:cursor ---date:20260522 for【XSLMES-20260522-A26】TCU紧凑两行且胶料表向下扩展-----------
.material-table-wrap--fill {
flex: 1;
display: flex;
flex-direction: column;
min-height: 0;
height: 100%;
:deep(.jeecg-j-vxe-table),
:deep(.ant-spin-nested-loading),
:deep(.ant-spin-container),
:deep(.j-vxe-table-box),
:deep(.vxe-grid) {
width: 100% !important;
height: 100% !important;
min-height: 0;
}
:deep(.vxe-table--render-wrapper),
:deep(.vxe-table--layout-wrapper),
:deep(.vxe-table--viewport-wrapper),
:deep(.vxe-table--main-wrapper) {
height: 100% !important;
}
:deep(.vxe-table--body-wrapper.body--wrapper) {
flex: 1;
min-height: 0;
}
}
.left-panel-section-tcu {
flex-shrink: 0;
border-top: 1px solid #d9d9d9;
}
//update-end---author:cursor ---date:20260522 for【XSLMES-20260522-A26】TCU紧凑两行且胶料表向下扩展-----------
.tcu-table-wrap {
flex-shrink: 0;
overflow-x: auto;
overflow-y: hidden;
:deep(.jeecg-j-vxe-table),
:deep(.ant-spin-nested-loading),
:deep(.ant-spin-container),
:deep(.j-vxe-table-box),
:deep(.vxe-grid) {
height: 100% !important;
}
:deep(.jeecg-j-vxe-table),
:deep(.j-vxe-table-box),
:deep(.vxe-grid),
:deep(.vxe-table) {
max-width: none;
}
:deep(.vxe-header--column .vxe-resizable) {
cursor: col-resize;
}
:deep(.vxe-header--row),
:deep(.vxe-header--column) {
height: auto !important;
}
:deep(.vxe-header--column .vxe-cell),
:deep(.vxe-header--column .vxe-cell--title) {
white-space: normal !important;
word-break: break-all;
line-height: 1.3;
height: auto !important;
overflow: visible !important;
text-overflow: clip !important;
}
}
:deep(.vxe-table) {
font-size: 12px;
}
:deep(.vxe-header--column),
:deep(.vxe-body--column) {
padding: 0 2px;
}
:deep(.vxe-header--column) {
background: #f5f5f5;
font-weight: 600;
}
}
.panel-right {
flex: 1 1 0;
min-width: 0;
min-height: 0;
border-right: none;
display: grid;
grid-template-rows: 1fr auto;
.panel-step-main {
display: flex;
flex-direction: column;
min-height: 0;
overflow: hidden;
}
.panel-down-step {
display: flex;
flex-direction: column;
flex-shrink: 0;
}
.step-table-wrap {
width: 100%;
min-height: 0;
overflow: hidden;
:deep(.jeecg-j-vxe-table),
:deep(.ant-spin-nested-loading),
:deep(.ant-spin-container),
:deep(.j-vxe-table-box),
:deep(.vxe-grid) {
width: 100% !important;
height: 100% !important;
min-height: 0;
}
:deep(.jeecg-j-vxe-table),
:deep(.ant-spin-nested-loading),
:deep(.ant-spin-container),
:deep(.j-vxe-table-box),
:deep(.vxe-grid) {
display: flex;
flex-direction: column;
}
:deep(.vxe-table) {
width: 100% !important;
flex: 1;
min-height: 0;
}
:deep(.vxe-table--body-inner-wrapper),
:deep(.vxe-table--header-inner-wrapper) {
width: 100% !important;
}
:deep(.vxe-header--column .vxe-resizable) {
cursor: col-resize;
}
}
.step-table-wrap--fill {
flex: 1;
display: flex;
flex-direction: column;
min-height: 0;
height: 100%;
:deep(.vxe-table--render-wrapper),
:deep(.vxe-table--layout-wrapper),
:deep(.vxe-table--viewport-wrapper),
:deep(.vxe-table--main-wrapper) {
height: 100% !important;
}
:deep(.vxe-table--body-wrapper.body--wrapper) {
flex: 1;
min-height: 0;
}
}
.step-table-wrap--compact {
flex: none;
}
}
.panel {
border-right: 1px solid #d9d9d9;
border-bottom: 1px solid #d9d9d9;
}
.panel-head {
height: 32px;
border-bottom: 1px solid #d9d9d9;
background: #fafafa;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 10px;
font-size: 13px;
font-weight: 600;
color: #262626;
.panel-head-actions {
display: flex;
align-items: center;
gap: 8px;
}
}
.panel-right :deep(.vxe-table) {
font-size: 12px;
}
.panel-right :deep(.vxe-header--column) {
background: #f5f5f5;
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;
}
.sign-grid {
display: grid;
grid-template-columns: repeat(5, 1fr);
border-bottom: 1px solid #ececec;
&:last-child {
border-bottom: none;
}
}
.sign-cell {
min-height: 32px;
border-right: 1px solid #ececec;
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
&:last-child {
border-right: none;
}
}
.sign-cell.sign-title {
background: #fafafa;
font-size: 12px;
font-weight: 600;
color: #434343;
box-shadow: inset 1px 1px 2px rgba(0, 0, 0, 0.08);
}
.sign-cell.sign-title-stack {
flex-direction: column;
gap: 2px;
line-height: 1.2;
padding: 4px 0;
}
.sign-cell.sign-value {
padding: 2px 8px;
min-height: 34px;
}
.sign-cell.sign-text {
font-size: 12px;
color: #262626;
justify-content: center;
text-align: center;
word-break: break-all;
}
</style>
<style lang="less">
.mixing-spec-modal-wrap {
.ant-modal-header {
border-bottom: 1px solid #dcdcdc;
}
.ant-modal-body {
padding: 12px 16px 16px;
background: #f0f2f5;
}
.mixing-sheet {
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>