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

1705 lines
62 KiB
Vue
Raw Normal View History

<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;
}
2026-05-25 20:42:13 +08:00
//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>