<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  for：【XSLMES-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
                :value="sheetForm.specName"
                readonly
                placeholder="请点击选择混炼示方"
                :disabled="!showFooter"
                :bordered="false"
                :class="['form-input', 'mixing-picker-input', { 'is-filled': !!sheetForm.specName }]"
                @click="openSpecPicker"
              />
            </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  for：【XSLMES-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  for：【XSLMES-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  for：【XSLMES-20260525-A42】橡胶及配合剂明细底部固定合计行----------- -->
          </div>
          <!--update-begin---author:cursor ---date:20260522  for：【XSLMES-20260522-A18】TCU温度条件表移至橡胶及配合剂下方----------- -->
          <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  for：【XSLMES-20260522-A18】TCU温度条件表移至橡胶及配合剂下方----------- -->
        </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  for：【XSLMES-20260526-A58】混合步骤参照历史示方按钮----------- -->
                <a-button v-if="showFooter" size="small" @click="openHistoryStepPicker">参照历史混合步骤</a-button>
                <!--update-end---author:cursor ---date:20260526  for：【XSLMES-20260526-A58】混合步骤参照历史示方按钮----------- -->
                <a-button v-if="showFooter" size="small" type="primary" @click="addStepRow">新增行</a-button>
              </div>
            </div>
            <!--update-begin---author:cursor ---date:20260522  for：【XSLMES-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  for：【XSLMES-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" />
  <MesXslMixingSpecSelectModal @register="registerSpecPickerModal" @edit="onSpecPickerEdit" @referenceAdd="onSpecPickerReferenceAdd" />
</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,
  cloneMixingSpecPageForReferenceAdd,
  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';
import MesXslMixingSpecSelectModal from './MesXslMixingSpecSelectModal.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:20260526  for：【XSLMES-20260526-A59】规格点击选择混炼示方-----------
const [registerSpecPickerModal, { openModal: openSpecPickerModalInner, closeModal: closeSpecPickerModal, setModalProps: setSpecPickerModalProps }] = useModal();
//update-end---author:cursor ---date:20260526  for：【XSLMES-20260526-A59】规格点击选择混炼示方-----------

//update-begin---author:cursor ---date:20260525  for：【XSLMES-20260525-A52】关闭混炼示方弹窗时同步关闭嵌套选料弹窗-----------
function closeNestedPickers() {
  closeMixingMaterialModal();
  closeMachineModal();
  closeIssueNumberModal();
  closeHistoryStepModal();
  closeSpecPickerModal();
  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 || '' });
}

//update-begin---author:cursor ---date:20260526  for：【XSLMES-20260526-A59】规格点击选择混炼示方-----------
function openSpecPicker() {
  if (!showFooter.value) {
    return;
  }
  setSpecPickerModalProps({ zIndex: 1500 });
  openSpecPickerModalInner(true, { machineId: sheetForm.machineId || '' });
}

async function applyMixingSpecPageData(row: Recordable, mode: 'edit' | 'referenceAdd') {
  const pageData = mode === 'referenceAdd' ? cloneMixingSpecPageForReferenceAdd(row) : row;
  isUpdate.value = mode === 'edit';
  Object.assign(sheetForm, pageData || {});
  if (mode === 'referenceAdd') {
    sheetForm.id = '';
    const userInfo = userStore.getUserInfo || {};
    refreshSignDisplay({
      createBy_dictText: userInfo.realname,
      createBy: userInfo.username,
    });
  } else {
    refreshSignDisplay(pageData || {});
  }
  await loadMachineEffectiveVolume(sheetForm.machineId);
  await loadMixerStepOptions(sheetForm.machineId);
  await syncSheetToForm();
  materialData.value = ensureMixingDetailRows(pageData?.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(pageData?.stepList || [], DEFAULT_MIXING_STEP_ROW_COUNT);
  downStepData.value = ensureMixingDetailRows(pageData?.downStepList || [], DEFAULT_MIXING_DOWN_STEP_ROW_COUNT);
  tcuData.value = ensureTcuDefaultRows(pageData?.tcuList || []);
}

async function onSpecPickerEdit(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;
    if (!row?.id) {
      createMessage.warning('未找到混炼示方数据');
      return;
    }
    await applyMixingSpecPageData(row, 'edit');
    createMessage.success(`已加载示方「${row.specName || ''}」`);
  } catch {
    createMessage.error('加载混炼示方失败');
  }
}

async function onSpecPickerReferenceAdd(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;
    if (!row?.id) {
      createMessage.warning('未找到混炼示方数据');
      return;
    }
    await applyMixingSpecPageData(row, 'referenceAdd');
    createMessage.success(`已参照示方「${row.specName || ''}」新增`);
  } catch {
    createMessage.error('参照混炼示方失败');
  }
}
//update-end---author:cursor ---date:20260526  for：【XSLMES-20260526-A59】规格点击选择混炼示方-----------

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;
    await applyMixingSpecPageData(row, 'edit');
  } 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:not(.is-filled) input::placeholder) {
    color: #bfbfbf;
  }

  :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>
