Browse Source

修改推钢室页面

zhangafei 3 weeks ago
parent
commit
9dcec81bd2

+ 619 - 0
src/views/billet/operator/components/car - 副本.vue

@@ -0,0 +1,619 @@
+<template>
+  <a-spin :spinning="isSpinning" wrapperClassName="car-info-spin">
+    <a-tabs v-model:activeKey="activeKey" type="card" @change="tabChange">
+      <a-tab-pane :key="item" :tab="'车位' + item" v-for="item in carPosition[ccmNo]">
+        <div class="car-info-wrapper">
+          <div class="licensePlate"
+            >装运车辆:{{ vehicleInfo['info' + item] && vehicleInfo['info' + item].licensePlate ? vehicleInfo['info' + item].licensePlate : '' }}</div
+          >
+          <print-car-info
+            :ref="printCarInfoRefs[`infoRef${item}`]"
+            :carPositon="item"
+            :ccm-no="ccmNo"
+            :info="vehicleInfo['info' + item]"
+            @change="handleChange"
+            @refresh="refreshCarList"
+          />
+          <div class="print">
+            <a-button
+              type="primary"
+              v-if="vehicleInfo['info' + item] && vehicleInfo['info' + item].id"
+              @click="
+                () =>
+                  openPrintModal(true, {
+                    record: vehicleInfo['info' + item],
+                    typeConfigId: !vehicleInfo['info' + item].typeConfigId ? '1024' : vehicleInfo['info' + item].typeConfigId,
+                    type: 'offline',
+                  })
+              "
+              >打印</a-button
+            >
+          </div>
+          <div class="change-type flex items-center" v-if="vehicleInfo['info' + item] && Object.keys(vehicleInfo['info' + item]).includes('btype')">
+            <span>{{ vehicleInfo['info' + item].ccmNo_dictText }}</span>
+            <span>/</span>
+            <a-switch
+              v-model:checked="vehicleInfo['info' + item].btype"
+              checked-value="0"
+              @change="(checked) => handleBtypeChange(checked, vehicleInfo['info' + item])"
+              checked-children="热坯"
+              un-checked-value="1"
+              un-checked-children="冷坯"
+            />
+          </div>
+        </div>
+      </a-tab-pane>
+      <!-- <a-tab-pane key="2" tab="车位2" force-render>Content of Tab Pane 2</a-tab-pane> -->
+    </a-tabs>
+    <div class="flex justify-between refresh-wrapper" :style="{ left: carPosition[ccmNo].length * 70 + 20 + 'px' }">
+      <a-button size="large" type="primary" style="font-size: 18px" @click="refresh(1)"> 刷新 </a-button>
+      <RouterLink :to="'/shippingBill/' + ccmNo" target="_blank">
+        <a-button size="large" type="primary" style="font-size: 18px"> 装运列表 </a-button>
+      </RouterLink>
+    </div>
+    <div class="stack-divider flex justify-between items-center">
+      <div class="flex items-center">
+        {{ stackInfo.typeName || '' }}
+        <div style="margin-left: 20px">
+          <a-button size="large" type="primary" style="font-size: 18px" @click="refresh(2)"> 刷新 </a-button>
+        </div>
+      </div>
+      <div>
+        <a-button
+          type="primary"
+          v-if="vehicleInfo['info' + activeKey] && vehicleInfo['info' + activeKey].id && !vehicleInfo['info' + activeKey].outTime"
+          danger
+          @click="stackToCar"
+        >
+          堆垛装车
+        </a-button>
+        <a-button style="background-color: #f5f5f5; color: #838383" v-else disabled>堆垛装车</a-button>
+      </div>
+    </div>
+    <div class="stacking-wrapper selected-divider" id="operatorCC-stacking-wrapper">
+      <div class="selected-divider-row flex" :id="`stackLayer${pitem.value}`" v-for="pitem in stackingList" :key="pitem.value">
+        <!-- <a-divider orientation="left" class="stacking-list-divider">{{ pitem.label }}</a-divider> -->
+        <div class="p-layer">{{ pitem.value }}</div>
+        <div
+          v-for="item in stackingObj[pitem.value]"
+          class="p-stack-col stacking-list-row flex-1"
+          @click="handleStackClick(item)"
+          :class="{ 'selected-row': selectedAddressId.includes(item.id) }"
+        >
+          <a-dropdown :trigger="['contextmenu']">
+            <div class="stack-col" :class="{ 'hemp-texture': !!item.steelBillet.length }">{{ item.heatNo }}</div>
+            <template #overlay v-if="item.billetNos">
+              <a-menu @click="menuClick($event, item)" style="min-width: 100px">
+                <a-menu-item key="1" style="background-color: #b7eb8f; color: #000; text-align: center">更换位置</a-menu-item>
+              </a-menu>
+            </template>
+          </a-dropdown>
+        </div>
+      </div>
+    </div>
+  </a-spin>
+  <!-- 打印 -->
+  <printModal @register="registerPrintModal" />
+</template>
+<script setup lang="ts">
+  import { ref, onMounted, onUnmounted, h } from 'vue';
+  import printCarInfo from './printCarInfo.vue';
+  import { useTimeoutFn } from '/@/hooks/core/useTimeout';
+  import { list, edit } from '../../shippingBill/shippingBill.api';
+  import { getStackInfo, stackLoadSave, stackLocationChange } from '../../hotDelivery/hotDelivery.api';
+  import { getMachineConfig, MachineConfigType, destinationOptions } from '../../hotDelivery/common.data';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import printModal from '../../shippingBill/components/printModal.vue';
+  import { useModal } from '/@/components/Modal';
+  import { render } from '/@/utils/common/renderUtils';
+
+  // 注册打印modal
+  const [registerPrintModal, { openModal: openPrintModal }] = useModal();
+
+  const { createConfirm, createMessage } = useMessage();
+
+  const props = defineProps({
+    ccmNo: {
+      type: [String, Number],
+      default: '5',
+    },
+  });
+
+  const isSpinning = ref(false);
+
+  const activeKey = ref(1);
+  const carPosition = {
+    '5': [1, 2],
+    '6': [2, 3, 4],
+  };
+  // 车辆信息
+  const infoRef1 = ref();
+  const infoRef2 = ref();
+  const infoRef3 = ref();
+  const infoRef4 = ref();
+  const printCarInfoRefs = { infoRef1, infoRef2, infoRef3, infoRef4 };
+
+  // 5号机堆垛
+  const stackingList = ref<any[]>([]);
+  const stackingObj = ref<any>({});
+  const stackInfo = ref<any>({});
+
+  // 车位1车辆信息
+  // id: '',
+  // licensePlate: '',
+  // destination: '',
+  // typeConfigId: undefined,
+  // ccmNo: '',
+  // ccmNo_dictText: '',
+  // amountTotal: 0,
+  // steel: '',
+  // size: '',
+  // positionNum: '',
+  const vehicleInfo = ref<any>({
+    info1: {},
+    info2: {},
+    info3: {},
+    info4: {},
+  });
+
+  const getInfo = async (type?: number | undefined) => {
+    // 获取车位1车辆信息
+    try {
+      isSpinning.value = true;
+      if (type === 1 || type === undefined) {
+        const fetchArr: any = [];
+        carPosition[props.ccmNo].forEach((item) => {
+          fetchArr.push(
+            list({
+              column: 'createTime',
+              order: 'desc',
+              pageNo: 1,
+              pageSize: 1,
+              positionNum: item,
+              ...(item == 2 ? {} : { ccmNo: props.ccmNo }),
+            })
+          );
+        });
+
+        await Promise.all(fetchArr).then((res) => {
+          if (Array.isArray(res)) {
+            res.forEach((item, index) => {
+              if (item.records[0]) {
+                vehicleInfo.value[`info${index + 1}`] = {
+                  ...item.records[0],
+                  oldLicensePlate: item.records[0].licensePlate,
+                  oldTypeConfigId: item.records[0].typeConfigId === '1024' ? undefined : item.records[0].typeConfigId,
+                  typeConfigId: item.records[0].typeConfigId === '1024' ? undefined : item.records[0].typeConfigId,
+                  oldBrandNum: item.records[0].brandNum,
+                  oldSize: item.records[0].size,
+                };
+              }
+            });
+            setTimeout(() => {
+              printCarInfoRefs[`infoRef${activeKey.value}`] &&
+                printCarInfoRefs[`infoRef${activeKey.value}`].value &&
+                printCarInfoRefs[`infoRef${activeKey.value}`].value[0].getTableList();
+            }, 50);
+          }
+        });
+      }
+
+      const machineConfig = await getMachineConfig(props.ccmNo)[MachineConfigType.STACKING];
+
+      stackInfo.value = machineConfig[0];
+      if (type === 2 || type === undefined) {
+        await getStackInfoList(machineConfig[0].id);
+      }
+    } catch (error) {
+      console.log(error);
+    } finally {
+      isSpinning.value = false;
+      start();
+    }
+  };
+
+  const { start, stop } = useTimeoutFn(getInfo, 10000, true);
+
+  // 获取堆垛机堆垛信息
+  // 获取当前堆垛信息
+  const getStackInfoList = async (typeConfigId) => {
+    const stackingInfo = await getStackInfo({ typeConfigId });
+    let layerObj = {};
+    if (stackingInfo.length) {
+      stackingInfo.forEach((item) => {
+        if (!layerObj[item.layer]) layerObj[item.layer] = [];
+
+        layerObj[item.layer].push({ ...item, steelBillet: item.billetNos ? item.billetNos.split(',') : [] });
+      });
+    }
+    stackingObj.value = layerObj;
+    stackingList.value = Object.keys(layerObj)
+      .sort((a, b) => Number(b) - Number(a))
+      .map((item) => ({ label: `第${item}层`, value: item }));
+
+    // nextTick(() => {
+    //   const element = document.getElementById(`operatorCC-stacking-wrapper`);
+    //   if (element) {
+    //     element.scrollIntoView({
+    //       behavior: 'smooth',
+    //       block: 'center',
+    //       inline: 'center',
+    //     });
+    //   }
+    // });
+  };
+
+  // 修改类型
+  function handleBtypeChange(v, record) {
+    stop();
+    createConfirm({
+      iconType: 'warning',
+      title: '确认修改',
+      width: '460px',
+      content: () => {
+        return h('div', { style: { fontSize: '16px' } }, [
+          h('span', null, `是否将车牌为`),
+          h('span', { style: { fontSize: '18px', color: '#d48806' } }, `${record.licensePlate}`),
+          h('span', null, `的`),
+          h('span', { style: { fontSize: '18px', color: v === '1' ? '#cd201f' : '#3b5999' } }, `${v === '1' ? ' 热坯 ' : ' 冷坯 '}`),
+          h('span', null, `改为`),
+          h('span', { style: { fontSize: '18px', color: v === '1' ? '#3b5999' : '#cd201f' } }, `${v === '1' ? ' 冷坯 ' : ' 热坯 '}`),
+          h('span', null, `?`),
+        ]);
+      },
+      okText: '确认',
+      cancelText: '取消',
+      onOk: () => {
+        return edit({ id: record.id, btype: v }).then(() => {
+          getInfo();
+        });
+      },
+      onCancel: () => {
+        start();
+        record.btype = v === '1' ? '0' : '1';
+      },
+    });
+  }
+
+  // 修改牌号,车号,目的地
+  const handleChange = (options) => {
+    const { type, value, carPositon } = options;
+    console.log(options, value, value === undefined);
+    if (value === undefined) return;
+    stop();
+    createConfirm({
+      iconType: 'warning',
+      title: '确认修改',
+      width: '460px',
+      content: () => {
+        let title = '',
+          content: any = '';
+        if (type === 'licensePlate') {
+          title = '是否修改车牌号为:';
+          content = value;
+        } else if (type === 'destination') {
+          title = '是否修改目的地为:';
+          const curDestination = destinationOptions[props.ccmNo].find((item) => item.value === value);
+          content = curDestination ? curDestination.label : '';
+        } else if (type === 'brandNum') {
+          title = '是否修改牌号为:';
+          content = render.renderDict(value, 'billet_spec');
+        } else if (type === 'size') {
+          title = '是否修改定尺为:';
+          content = value;
+        }
+        return h('div', { style: { fontSize: '16px' } }, [
+          h('span', null, title),
+          h('span', { style: { fontSize: '18px', color: '#d48806' } }, content),
+        ]);
+      },
+      onOk: () => {
+        let params = { ...vehicleInfo.value[`info${carPositon}`] };
+        if (type === 'destination') {
+          const curDestination = destinationOptions[props.ccmNo].find((item) => item.value === value);
+          params.destination = curDestination.label;
+        }
+        return edit(params).then(() => {
+          getInfo();
+        });
+      },
+      onCancel: () => {
+        start();
+        if (type === 'licensePlate') {
+          vehicleInfo.value[`info${carPositon}`].licensePlate = vehicleInfo.value[`info${carPositon}`].oldLicensePlate;
+        } else if (type === 'destination') {
+          vehicleInfo.value[`info${carPositon}`].typeConfigId = vehicleInfo.value[`info${carPositon}`].oldTypeConfigId;
+        } else if (type === 'brandNum') {
+          vehicleInfo.value[`info${carPositon}`].brandNum = vehicleInfo.value[`info${carPositon}`].oldBrandNum;
+        } else if (type === 'size') {
+          vehicleInfo.value[`info${carPositon}`].size = vehicleInfo.value[`info${carPositon}`].oldSize;
+        }
+      },
+    });
+  };
+
+  // 选择堆垛位置装车
+  const selectedAddressId = ref<any[]>([]);
+  const selectedAddress = ref<any[]>([]);
+
+  const getSelectedStack = () => {
+    return selectedAddress.value || [];
+  };
+
+  // 右键换位置
+  const menuClick = (e, info) => {
+    if (e.key === '1') {
+      const selectedStackList = selectedAddress.value.filter((item) => !item.billetNos);
+      if (!selectedStackList.length) {
+        createMessage.error('请选择要移动的位置,且位置上没有钢坯!');
+        return;
+      }
+
+      if (selectedStackList.length > 1) {
+        createMessage.error('钢坯移动的空位置只能选择一个!');
+        return;
+      }
+      createConfirm({
+        iconType: 'warning',
+        title: '确认更换位置',
+        width: '460px',
+        content: () => {
+          return h('div', { style: { fontSize: '16px' } }, [
+            h('span', null, `是否将`),
+            h('span', { style: { fontSize: '18px', color: '#d48806' } }, `${info.layer}层${info.address}`),
+            h('span', null, `更换到`),
+            h('span', { style: { fontSize: '18px', color: '#cd201f' } }, `${selectedStackList[0].layer}层${selectedStackList[0].address}`),
+            h('span', null, `?`),
+          ]);
+        },
+        okText: '更换',
+        cancelText: '取消',
+        onOk: () => {
+          const params = {
+            stackId: info.id,
+            locationChangeId: selectedStackList[0].id,
+          };
+
+          return stackLocationChange(params).then(() => {
+            selectedAddressId.value = [];
+            selectedAddress.value = [];
+            refresh(2);
+          });
+        },
+      });
+    }
+  };
+
+  const tabChange = (key) => {
+    printCarInfoRefs[`infoRef${key}`] && printCarInfoRefs[`infoRef${key}`].value && printCarInfoRefs[`infoRef${key}`].value[0].getTableList();
+  };
+
+  const handleStackClick = (v) => {
+    const index = selectedAddressId.value.indexOf(v.id);
+    if (index > -1) {
+      selectedAddressId.value.splice(index, 1);
+      selectedAddress.value.splice(index, 1);
+    } else {
+      selectedAddressId.value.push(v.id);
+      selectedAddress.value.push(v);
+    }
+  };
+  const stackToCar = async () => {
+    try {
+      const valiDesRes = validateCarDestination();
+      if (!valiDesRes) {
+        return;
+      }
+      const selectedStackList = selectedAddress.value.filter((item) => item.billetNos);
+      if (!selectedStackList.length) {
+        createMessage.error('请选择有钢坯的堆垛位置装车!');
+        return;
+      }
+
+      const curDestination =
+        destinationOptions[props.ccmNo].find((item) => item.value === vehicleInfo.value[`info${activeKey.value}`].typeConfigId) || {};
+
+      const params = {
+        storageBill: vehicleInfo.value[`info${activeKey.value}`] || {},
+        belongTable: stackInfo.value?.belongTable,
+        billetHotsendTypeConfigId: stackInfo.value.id,
+        stackingAndLoadingVehiclesList: selectedStackList,
+        destination: vehicleInfo.value[`info${activeKey.value}`].destination,
+        destinationId: vehicleInfo.value[`info${activeKey.value}`].typeConfigId,
+        destinationTable: curDestination.belongTable,
+
+        billetHotsend: {
+          ccmNo: props.ccmNo,
+          isUpd: false,
+        },
+      };
+      stop();
+      isSpinning.value = true;
+      await stackLoadSave(params);
+
+      getInfo();
+    } catch (error) {
+      isSpinning.value = false;
+    } finally {
+      selectedAddressId.value = [];
+      selectedAddress.value = [];
+    }
+  };
+
+  // 验证是否有目的地
+  const validateCarDestination = () => {
+    const curVehicleInfo = vehicleInfo.value[`info${activeKey.value}`];
+    if (!curVehicleInfo.typeConfigId || !curVehicleInfo.destination || curVehicleInfo.typeConfigId == 1024) {
+      createMessage.error('请先选择装运单库名!');
+      printCarInfoRefs[`infoRef${activeKey.value}`].value && printCarInfoRefs[`infoRef${activeKey.value}`].value[0].focusDestination();
+      return false;
+    }
+    return true;
+  };
+
+  // 刷新
+  const refresh = (type) => {
+    stop();
+    getInfo(type);
+  };
+
+  onMounted(() => {
+    getInfo();
+  });
+
+  onUnmounted(() => {
+    stop();
+  });
+
+  const refreshCarList = () => {
+    selectedAddressId.value = [];
+    selectedAddress.value = [];
+    stop();
+    getInfo();
+  };
+
+  defineExpose({
+    getSelectedStack,
+    getStackInfo: () => stackInfo.value,
+    getCurrentCar: () => vehicleInfo.value[`info${activeKey.value}`],
+    refreshCarList: refreshCarList,
+    valirDest: validateCarDestination,
+  });
+</script>
+<style lang="less" scoped>
+  @import '../../hotDelivery/components/metal.less';
+  .car-info-spin {
+    position: relative;
+    height: 100%;
+
+    :deep(.ant-spin-container) {
+      display: flex;
+      flex-direction: column;
+      height: 100%;
+      overflow: hidden;
+    }
+
+    .refresh-wrapper {
+      position: absolute;
+      left: 100px;
+      right: 170px;
+    }
+
+    .ant-tabs {
+      color: #dadada;
+
+      :deep(.ant-tabs-tab) {
+        font-size: 16px;
+        background: #01396c;
+
+        &.ant-tabs-tab-active {
+          background: #0085ff;
+
+          .ant-tabs-tab-btn {
+            color: #fff;
+          }
+        }
+      }
+    }
+  }
+
+  .car-info-wrapper {
+    position: relative;
+    padding: 30px 10px 10px;
+    border: 1px solid var(--op-border-color);
+    border-radius: 6px;
+
+    .licensePlate {
+      width: 190px;
+      background-color: #010c3a;
+      position: absolute;
+      top: -15px;
+      left: 30px;
+      font-size: 16px;
+      color: var(--op-text-color-fff);
+      text-align: center;
+    }
+
+    .print {
+      position: absolute;
+      right: 22px;
+      top: 40px;
+    }
+
+    .change-type {
+      position: absolute;
+      right: 22px;
+      top: -50px;
+      gap: 10px;
+      color: var(--op-text-color-fff);
+      font-size: 20px;
+
+      .ant-switch {
+        background-color: #3b5999;
+
+        :deep(.ant-switch-inner) {
+          .ant-switch-inner-checked,
+          .ant-switch-inner-unchecked {
+            font-size: 17px;
+          }
+        }
+      }
+
+      .ant-switch.ant-switch-checked {
+        background-color: #cd201f;
+      }
+    }
+  }
+
+  .stack-divider {
+    font-size: 16px;
+    margin-top: 10px;
+    color: var(--op-text-color-fff);
+  }
+
+  .stacking-wrapper {
+    flex: 1;
+    overflow: auto;
+    padding: 0;
+    margin-top: 6px;
+    padding-bottom: 20px;
+
+    .selected-divider-row {
+      margin-top: 5px;
+      gap: 3px;
+    }
+
+    &.selected-divider .selected-divider-row .stacking-list-row {
+      cursor: pointer;
+      height: 24px;
+      line-height: 20px;
+      border: 1px solid var(--op-border-color);
+      border-radius: 4px;
+      font-size: 20px;
+    }
+
+    .stacking-list-divider {
+      margin: 0;
+      color: var(--vxe-danger-color, #f56c6c);
+    }
+
+    .stack-col {
+      overflow: hidden;
+    }
+
+    .p-stack-col {
+      padding-right: 0 !important;
+      max-width: 11%;
+    }
+
+    .p-layer {
+      width: 20px;
+      margin-right: 10px;
+      font-size: 20px;
+      color: #f50;
+      font-family: 'Kingsoft_Cloud_Font';
+      line-height: 24px;
+      text-align: center;
+    }
+  }
+</style>

+ 44 - 51
src/views/billet/operator/components/car.vue

@@ -58,7 +58,7 @@
           <a-button size="large" type="primary" style="font-size: 18px" @click="refresh(2)"> 刷新 </a-button>
         </div>
       </div>
-      <div>
+      <!-- <div>
         <a-button
           type="primary"
           v-if="vehicleInfo['info' + activeKey] && vehicleInfo['info' + activeKey].id && !vehicleInfo['info' + activeKey].outTime"
@@ -68,26 +68,21 @@
           堆垛装车
         </a-button>
         <a-button style="background-color: #f5f5f5; color: #838383" v-else disabled>堆垛装车</a-button>
-      </div>
+      </div> -->
     </div>
-    <div class="stacking-wrapper selected-divider" id="operatorCC-stacking-wrapper">
-      <div class="selected-divider-row flex" :id="`stackLayer${pitem.value}`" v-for="pitem in stackingList" :key="pitem.value">
-        <!-- <a-divider orientation="left" class="stacking-list-divider">{{ pitem.label }}</a-divider> -->
-        <div class="p-layer">{{ pitem.value }}</div>
-        <div
-          v-for="item in stackingObj[pitem.value]"
-          class="p-stack-col stacking-list-row flex-1"
-          @click="handleStackClick(item)"
-          :class="{ 'selected-row': selectedAddressId.includes(item.id) }"
-        >
-          <a-dropdown :trigger="['contextmenu']">
-            <div class="stack-col" :class="{ 'hemp-texture': !!item.steelBillet.length }">{{ item.heatNo }}</div>
-            <template #overlay v-if="item.billetNos">
-              <a-menu @click="menuClick($event, item)" style="min-width: 100px">
-                <a-menu-item key="1" style="background-color: #b7eb8f; color: #000; text-align: center">更换位置</a-menu-item>
-              </a-menu>
-            </template>
-          </a-dropdown>
+    <div class="stacking-wrapper selected-divider flex flex-wrap" id="operatorCC-stacking-wrapper">
+      <div class="selected-divider-row flex flex-col" :id="`stackLayer${pitem.heatNo}`" v-for="pitem in stackingList" :key="pitem.heatNo">
+        <div class="p-layer flex justify-between">
+          <span class="lu">炉号</span><span class="hao">{{ pitem.heatNo }}</span>
+        </div>
+        <div class="dtl-list">
+          <div class="dtl-item flex justify-between" v-for="m in pitem.details">
+            <span class="size">{{ m.stackingLength }}</span>
+            <span>
+              <span class="zhi">{{ m.stackingCount }}</span
+              > 支</span
+            >
+          </div>
         </div>
       </div>
     </div>
@@ -106,6 +101,7 @@
   import printModal from '../../shippingBill/components/printModal.vue';
   import { useModal } from '/@/components/Modal';
   import { render } from '/@/utils/common/renderUtils';
+  import { getStackInfoByCcmNo } from '../operator.api';
 
   // 注册打印modal
   const [registerPrintModal, { openModal: openPrintModal }] = useModal();
@@ -217,30 +213,8 @@
   // 获取堆垛机堆垛信息
   // 获取当前堆垛信息
   const getStackInfoList = async (typeConfigId) => {
-    const stackingInfo = await getStackInfo({ typeConfigId });
-    let layerObj = {};
-    if (stackingInfo.length) {
-      stackingInfo.forEach((item) => {
-        if (!layerObj[item.layer]) layerObj[item.layer] = [];
-
-        layerObj[item.layer].push({ ...item, steelBillet: item.billetNos ? item.billetNos.split(',') : [] });
-      });
-    }
-    stackingObj.value = layerObj;
-    stackingList.value = Object.keys(layerObj)
-      .sort((a, b) => Number(b) - Number(a))
-      .map((item) => ({ label: `第${item}层`, value: item }));
-
-    // nextTick(() => {
-    //   const element = document.getElementById(`operatorCC-stacking-wrapper`);
-    //   if (element) {
-    //     element.scrollIntoView({
-    //       behavior: 'smooth',
-    //       block: 'center',
-    //       inline: 'center',
-    //     });
-    //   }
-    // });
+    const stackingInfo = await getStackInfoByCcmNo({ ccmNo: props.ccmNo, typeConfigId });
+    stackingList.value = stackingInfo || [];
   };
 
   // 修改类型
@@ -577,10 +551,15 @@
     padding: 0;
     margin-top: 6px;
     padding-bottom: 20px;
+    gap: 10px 12px;
 
     .selected-divider-row {
-      margin-top: 5px;
-      gap: 3px;
+      width: 120px;
+      height: 90px;
+      background: #08184d;
+      border-radius: 2px;
+      border: 1px solid #001966;
+      padding: 6px;
     }
 
     &.selected-divider .selected-divider-row .stacking-list-row {
@@ -607,13 +586,27 @@
     }
 
     .p-layer {
-      width: 20px;
-      margin-right: 10px;
-      font-size: 20px;
-      color: #f50;
       font-family: 'Kingsoft_Cloud_Font';
       line-height: 24px;
-      text-align: center;
+      font-weight: 500;
+      font-size: 14px;
+      color: #cccccc;
+      border-bottom: 1px solid #0b2066;
+
+      .hao {
+        color: #99b1ff;
+      }
+    }
+
+    .dtl-item {
+      font-weight: 400;
+      font-size: 14px;
+      color: #808080;
+      margin-top: 6px;
+
+      .zhi {
+        color: #fff;
+      }
     }
   }
 </style>

+ 147 - 134
src/views/billet/operator/components/headTop.vue

@@ -3,44 +3,46 @@
     <a-col :span="3" class="head-no bg flex items-center justify-center"
       ><a-badge status="processing" /> 浇铸炉号:{{ info.billetHotsendChangeShift.heatNo }}
     </a-col>
-    <a-col :span="1" class="amount-no bg flex items-center justify-center">
+    <!-- <a-col :span="1" class="amount-no bg flex items-center justify-center">
       <a-statistic title="支数" :value="info.currentCastingFurnaceAmount || 0" />
     </a-col>
     <a-col :span="2" class="amount-no bg flex items-center justify-center">
       <a-statistic title="重量/t" :value="info.currentCastingFurnace ? info.currentCastingFurnace.toFixed(3) : 0" />
-    </a-col>
+    </a-col> -->
     <a-col :span="1" class="flex items-center justify-center">
       <a-button type="primary" class="change-heat" @click="switchHeatNo" :loading="changeHeatLoading">换炉</a-button>
     </a-col>
     <a-col :span="1" class="current-shift flex items-center justify-center">当班统计:</a-col>
     <a-col :span="1" class="flex items-center justify-center">
-      <a-statistic title="总支数" :value="info.billetHotsendChangeShift.shiftSum" />
+      <a-statistic title="总支数" :value="curAllNums" />
     </a-col>
     <a-col :span="2" class="flex items-center justify-center">
-      <a-statistic title="总重量/t" :value="info.billetHotsendChangeShift.shiftProduct ? info.billetHotsendChangeShift.shiftProduct.toFixed(3) : 0" />
+      <a-statistic title="总重量/t" :value="curAllWeight ? curAllWeight.toFixed(3) : 0" />
     </a-col>
     <a-col :span="3" class="flex flex-col" v-for="item of typeList">
       <div class="type-item">
-        <span class="type-title" :style="{ color: item.titleColor }">{{ item.title }}:</span> {{ item.amount }} 支 / {{ item.weight }} t
+        <span class="type-title" :style="{ color: item.titleColor }">{{ item.title }}:</span> {{ item.amount }} 支 /
+        {{ item.weight ? item.weight.toFixed(3) : 0 }} t
       </div>
       <div class="type-item" v-for="ele of item.dtlList">
         <div class="type-item-dtl">
-          <span class="type-title">{{ ele.size }}:</span> {{ ele.nums }} 支 / {{ ele.weight }} t
+          <span class="type-title">{{ ele.size }}:</span> {{ ele.nums }} 支 / {{ ele.weight ? ele.weight.toFixed(3) : 0 }} t
         </div>
       </div>
       <!-- 冷床 -->
-      <template v-if="item.title == '堆垛'">
+      <!-- <template v-if="item.title == '堆垛'">
         <template v-for="lc in coldBed">
           <div class="type-item" style="border-top: 1px solid #108ee9">
-            <span class="type-title" :style="{ color: lc.titleColor }">{{ lc.title }}:</span> {{ lc.amount }} 支 / {{ lc.weight }} t
+            <span class="type-title" :style="{ color: lc.titleColor }">{{ lc.title }}:</span> {{ lc.amount }} 支 /
+            {{ lc.weight ? lc.weight.toFixed(3) : 0 }} t
           </div>
           <div class="type-item" v-for="lele of lc.dtlList">
             <div class="type-item-dtl">
-              <span class="type-title">{{ lele.size }}:</span> {{ lele.nums }} 支 / {{ lele.weight }} t
+              <span class="type-title">{{ lele.size }}:</span> {{ lele.nums }} 支 / {{ lele.weight ? lele.weight.toFixed(3) : 0 }} t
             </div>
           </div>
         </template>
-      </template>
+      </template> -->
     </a-col>
     <a-col :span="2" class="paihao flex flex-col items-center justify-center"
       >当前牌号:<br /><component :is="renderDictTag(info.brandNum, 'billet_spec')"
@@ -114,9 +116,13 @@
     currentCastingFurnace: null,
   });
 
+  const curAllNums = ref(0);
+  const curAllWeight = ref(0);
+
   // typeList
   const typeList = ref<any>([
     { title: '棒一', titleColor: '#f50', amount: 0, weight: 0, dtlList: [] },
+    { title: '冷装', titleColor: '#108ee9', amount: 0, weight: 0, dtlList: [] },
     { title: '热装', titleColor: '#f50', amount: 0, weight: 0, dtlList: [] },
     { title: '堆垛', titleColor: '#b8ceff', amount: 0, weight: 0, dtlList: [] },
   ]);
@@ -133,6 +139,7 @@
       shift: info.value.billetHotsendChangeShift.shift,
       shiftGroup: info.value.billetHotsendChangeShift.shiftGroup,
       changeShiftId: info.value.billetHotsendChangeShift.id,
+      lastShiftInfo: info.value.lastBilletHotsendChangeShift,
     });
   };
 
@@ -154,135 +161,135 @@
       }
 
       // 获取明细
-      getSteelPileBaseInfo({ ccmNo: props.ccmNo }).then((dtlRes) => {
-        // 按照目的地分组
-        if (dtlRes) {
-          const destinationArr = dtlRes.reduce((acc, cur) => {
-            const bt = cur.belongTable || 'lc';
-            acc[bt] = acc[bt] || [];
-            acc[bt].push(cur);
-            return acc;
-          }, {});
-
-          // roll_club_one 棒一
-          // roll_club_two 棒二
-          // roll_club_three 棒三
-          // roll_out_shipp 上若
-          // roll_height 高线
-          // stacking_and_loading_vehicles 堆垛
-          let hotsendData: any = [],
-            hotSendSum = 0,
-            hotSendTotalWeight = 0,
-            hotchargeData: any = [],
-            hotChargeSum = 0,
-            hotChargeTotalWeight = 0,
-            stackingData: any = [],
-            stackingSum = 0,
-            stackingTotalWeight = 0;
-          // 计算棒一
-          if (destinationArr['roll_club_one']) {
-            hotsendData = Object.values(groupBy(destinationArr['roll_club_one'] || [], 'length')).map((one: any) => {
-              hotSendSum += one.nums;
-              hotSendTotalWeight += one.weight;
-              return {
-                ...one,
-                weight: one.weight.toFixed(3),
-                size: one.size / 1000,
-              };
-            });
-          }
-
-          // 计算热装
-          if (destinationArr['roll_club_two'] || destinationArr['roll_club_three'] || destinationArr['roll_out_shipp']) {
-            const concatArr = [
-              ...(destinationArr['roll_club_two'] || []),
-              ...(destinationArr['roll_club_three'] || []),
-              ...(destinationArr['roll_out_shipp'] || []),
-            ];
-            hotchargeData = Object.values(groupBy(concatArr, 'length')).map((one: any) => {
-              hotChargeSum += one.nums;
-              hotChargeTotalWeight += one.weight;
-              return {
-                ...one,
-                weight: one.weight.toFixed(3),
-                size: one.size / 1000,
-              };
-            });
-          }
-
-          // 计算堆垛
-          if (destinationArr['stacking_and_loading_vehicles']) {
-            stackingData = Object.values(groupBy(destinationArr['stacking_and_loading_vehicles'] || [], 'length')).map((one: any) => {
-              stackingSum += one.nums;
-              stackingTotalWeight += one.weight;
-              return {
-                ...one,
-                weight: one.weight.toFixed(3),
-                size: one.size / 1000,
-              };
-            });
-          }
-
-          // 计算冷床
-          let lcSum = 0;
-          let lcTotalWeight = 0;
-          let lcData: any = [];
-          if (destinationArr['lc']) {
-            lcData = Object.values(groupBy(destinationArr['lc'] || [], 'length')).map((one: any) => {
-              lcSum += one.nums;
-              lcTotalWeight += one.weight;
-              return {
-                ...one,
-                weight: one.weight.toFixed(3),
-                size: one.size / 1000,
-              };
-            });
-          }
-
-          typeList.value = [
-            {
-              title: '棒一',
-              titleColor: '#f50',
-              amount: hotSendSum || 0,
-              weight: hotSendTotalWeight ? hotSendTotalWeight.toFixed(3) : 0,
-              dtlList: hotsendData,
-            },
-            {
-              title: '热装',
-              titleColor: '#f50',
-              amount: hotChargeSum || 0,
-              weight: hotChargeTotalWeight ? hotChargeTotalWeight.toFixed(3) : 0,
-              dtlList: hotchargeData,
-            },
-            {
-              title: '堆垛',
-              titleColor: '#b8ceff',
-              amount: stackingSum || 0,
-              weight: stackingTotalWeight ? stackingTotalWeight.toFixed(3) : 0,
-              dtlList: stackingData,
-            },
-          ];
-
-          coldBed.value = [
-            {
-              title: '冷床',
-              titleColor: '#108ee9',
-              amount: lcSum || 0,
-              weight: lcTotalWeight ? lcTotalWeight.toFixed(3) : 0,
-              dtlList: lcData,
-            },
-          ];
-
-          getShiftInfo();
-        }
-      });
+      // getSteelPileBaseInfo({ ccmNo: props.ccmNo }).then((dtlRes) => {
+      //   // 按照目的地分组
+      //   if (dtlRes) {
+      //     const destinationArr = dtlRes.reduce((acc, cur) => {
+      //       const bt = cur.belongTable || 'lc';
+      //       acc[bt] = acc[bt] || [];
+      //       acc[bt].push(cur);
+      //       return acc;
+      //     }, {});
+
+      //     // roll_club_one 棒一
+      //     // roll_club_two 棒二
+      //     // roll_club_three 棒三
+      //     // roll_out_shipp 上若
+      //     // roll_height 高线
+      //     // stacking_and_loading_vehicles 堆垛
+      //     let hotsendData: any = [],
+      //       hotSendSum = 0,
+      //       hotSendTotalWeight = 0,
+      //       hotchargeData: any = [],
+      //       hotChargeSum = 0,
+      //       hotChargeTotalWeight = 0,
+      //       stackingData: any = [],
+      //       stackingSum = 0,
+      //       stackingTotalWeight = 0;
+      //     // 计算棒一
+      //     if (destinationArr['roll_club_one']) {
+      //       hotsendData = Object.values(groupBy(destinationArr['roll_club_one'] || [], 'length')).map((one: any) => {
+      //         hotSendSum += one.nums;
+      //         hotSendTotalWeight += one.weight;
+      //         return {
+      //           ...one,
+      //           weight: one.weight.toFixed(3),
+      //           size: one.size / 1000,
+      //         };
+      //       });
+      //     }
+
+      //     // 计算热装
+      //     if (destinationArr['roll_club_two'] || destinationArr['roll_club_three'] || destinationArr['roll_out_shipp']) {
+      //       const concatArr = [
+      //         ...(destinationArr['roll_club_two'] || []),
+      //         ...(destinationArr['roll_club_three'] || []),
+      //         ...(destinationArr['roll_out_shipp'] || []),
+      //       ];
+      //       hotchargeData = Object.values(groupBy(concatArr, 'length')).map((one: any) => {
+      //         hotChargeSum += one.nums;
+      //         hotChargeTotalWeight += one.weight;
+      //         return {
+      //           ...one,
+      //           weight: one.weight.toFixed(3),
+      //           size: one.size / 1000,
+      //         };
+      //       });
+      //     }
+
+      //     // 计算堆垛
+      //     if (destinationArr['stacking_and_loading_vehicles']) {
+      //       stackingData = Object.values(groupBy(destinationArr['stacking_and_loading_vehicles'] || [], 'length')).map((one: any) => {
+      //         stackingSum += one.nums;
+      //         stackingTotalWeight += one.weight;
+      //         return {
+      //           ...one,
+      //           weight: one.weight.toFixed(3),
+      //           size: one.size / 1000,
+      //         };
+      //       });
+      //     }
+
+      //     // 计算冷床
+      //     let lcSum = 0;
+      //     let lcTotalWeight = 0;
+      //     let lcData: any = [];
+      //     if (destinationArr['lc']) {
+      //       lcData = Object.values(groupBy(destinationArr['lc'] || [], 'length')).map((one: any) => {
+      //         lcSum += one.nums;
+      //         lcTotalWeight += one.weight;
+      //         return {
+      //           ...one,
+      //           weight: one.weight.toFixed(3),
+      //           size: one.size / 1000,
+      //         };
+      //       });
+      //     }
+
+      //     typeList.value = [
+      //       {
+      //         title: '棒一',
+      //         titleColor: '#f50',
+      //         amount: hotSendSum || 0,
+      //         weight: hotSendTotalWeight ? hotSendTotalWeight.toFixed(3) : 0,
+      //         dtlList: hotsendData,
+      //       },
+      //       {
+      //         title: '热装',
+      //         titleColor: '#f50',
+      //         amount: hotChargeSum || 0,
+      //         weight: hotChargeTotalWeight ? hotChargeTotalWeight.toFixed(3) : 0,
+      //         dtlList: hotchargeData,
+      //       },
+      //       {
+      //         title: '堆垛',
+      //         titleColor: '#b8ceff',
+      //         amount: stackingSum || 0,
+      //         weight: stackingTotalWeight ? stackingTotalWeight.toFixed(3) : 0,
+      //         dtlList: stackingData,
+      //       },
+      //     ];
+
+      //     coldBed.value = [
+      //       {
+      //         title: '冷床',
+      //         titleColor: '#108ee9',
+      //         amount: lcSum || 0,
+      //         weight: lcTotalWeight ? lcTotalWeight.toFixed(3) : 0,
+      //         dtlList: lcData,
+      //       },
+      //     ];
+
+      //   }
+      // });
+      getShiftInfo();
     } catch (error) {
     } finally {
       start();
     }
   };
 
-  const { start, stop } = useTimeoutFn(getInfo, 5000);
+  const { start, stop } = useTimeoutFn(getInfo, 5000, true);
 
   // 换炉
   const changeHeatLoading = ref(false);
@@ -343,6 +350,12 @@
       stop();
       getInfo();
     },
+    setTypeList: (data) => {
+      const { dtlList, allNums, allWeight } = data;
+      curAllNums.value = allNums;
+      curAllWeight.value = allWeight;
+      typeList.value = dtlList;
+    },
   });
 </script>
 <style lang="less" scoped>
@@ -412,7 +425,7 @@
 
     .type-title {
       display: inline-block;
-      width: 50px;
+      width: 66px;
     }
 
     .change-heat.is-disabled {

+ 2 - 2
src/views/billet/operator/components/heatList.vue

@@ -824,8 +824,8 @@
 
   const { start, stop } = useTimeoutFn(async () => {
     if (!props.changeShiftId) {
-      await reload();
-      start();
+      // await reload();
+      // start();
     }
   }, 10000);
 

+ 1671 - 0
src/views/billet/operator/components/orgData.vue

@@ -0,0 +1,1671 @@
+<template>
+  <a-spin :spinning="isSpinning" wrapperClassName="orgData-info-spin">
+    <div class="ticket next-ticket">
+      <div style="text-align: center; position: relative">
+        <div class="noprint" style="position: absolute">
+          <a-button type="primary" @click="addHeatNo">添加炉号</a-button>
+        </div>
+        <p style="font-size: 24px; font-weight: 800; display: inline-block; margin-bottom: 16px; line-height: 30px">
+          <span class="ccmno">{{ hostNumber }}</span> #机推钢室生产原始记录
+        </p>
+      </div>
+      <div class="flex ccmno-info" style="line-height: 24px">
+        <div class="flex-1"> 班组:<component :is="renderDictTag(shiftInfo.shiftGroup, 'lg_bz')" /> </div>
+        <div class="flex-1"> 班次:<component :is="renderDictTag(shiftInfo.shift, 'lg_bb')" /> </div>
+        <div class="flex-1 flex"
+          ><span> 定尺:</span><a-input v-model:value="mainSize" @blur="handleSizeBlur" style="flex: 1" :bordered="false" size="small" />
+        </div>
+        <div class="flex-1" style="text-align: center; font-size: 13px">
+          {{ dayjs(curTime).format('YYYY 年 MM 月 DD 日') }}
+        </div>
+        <div class="flex-1" style="text-align: right; font-size: 12px"> lg/R05 </div>
+      </div>
+      <a-table :columns="columns" size="small" :data-source="dataSource" bordered :pagination="false">
+        <template #summary>
+          <a-table-summary-row>
+            <a-table-summary-cell :col-span="remakeColSpan" style="text-align: center">备注</a-table-summary-cell>
+            <a-table-summary-cell :col-span="sizeColSpan" style="text-align: center"> 定尺 </a-table-summary-cell>
+            <a-table-summary-cell :col-span="flowColSpan" style="text-align: center"> 支数(支) </a-table-summary-cell>
+            <a-table-summary-cell :col-span="weightColSpan" style="text-align: center"> 产量(吨) </a-table-summary-cell>
+          </a-table-summary-row>
+          <a-table-summary-row class="summary-row-no-border">
+            <a-table-summary-cell :row-span="2" :col-span="remakeColSpan">
+              <div class="summary-cell-remark">
+                <a-textarea v-model:value="mainRemark" @blur="handleRemarkBlur" style="min-height: 160px" :bordered="false" />
+              </div>
+            </a-table-summary-cell>
+            <a-table-summary-cell :row-span="1" :col-span="1"> 热送 </a-table-summary-cell>
+            <a-table-summary-cell :row-span="1" :col-span="sizeColSpan - 1">
+              <div class="song-items flex" v-for="(item, index) in hotSendList" :key="index">
+                <div class="title">{{ index }}</div>
+                <div class="flex flex-col">
+                  <div class="song-item" v-for="ele in item">{{ ele.size }}</div>
+                </div>
+              </div>
+            </a-table-summary-cell>
+            <a-table-summary-cell :col-span="flowColSpan">
+              <div class="song-items flex" v-for="(item, index) in hotSendList" :key="index">
+                <div class="flex flex-col">
+                  <div class="song-item" v-for="ele in item">{{ ele.amount }}</div>
+                </div>
+              </div>
+            </a-table-summary-cell>
+            <a-table-summary-cell :col-span="weightColSpan">
+              <div class="song-items flex" v-for="(item, index) in hotSendList" :key="index">
+                <div class="flex flex-col">
+                  <div class="song-item" v-for="ele in item">{{ ele.weight ? ele.weight.toFixed(3) : '' }} t</div>
+                </div>
+              </div>
+            </a-table-summary-cell>
+          </a-table-summary-row>
+          <a-table-summary-row>
+            <a-table-summary-cell :row-span="1" :col-span="1"> 堆垛 </a-table-summary-cell>
+            <a-table-summary-cell :row-span="1" :col-span="sizeColSpan - 1">
+              <div class="song-items flex">
+                <div class="flex flex-col">
+                  <div class="song-item" v-for="ele in stackingList">{{ ele.size }}</div>
+                </div>
+              </div>
+            </a-table-summary-cell>
+            <a-table-summary-cell :col-span="flowColSpan">
+              <div class="song-items flex">
+                <div class="flex flex-col">
+                  <div class="song-item" v-for="ele in stackingList">{{ ele.amount }}</div>
+                </div>
+              </div>
+            </a-table-summary-cell>
+            <a-table-summary-cell :col-span="weightColSpan">
+              <div class="song-items flex">
+                <div class="flex flex-col">
+                  <div class="song-item" v-for="ele in stackingList">{{ ele.weight ? ele.weight.toFixed(3) : '' }} t</div>
+                </div>
+              </div>
+            </a-table-summary-cell>
+          </a-table-summary-row>
+        </template>
+      </a-table>
+    </div>
+  </a-spin>
+  <!-- 设置定尺数量的modal -->
+  <a-modal v-model:open="openSetSizeNumModal" title="设置定尺数量" centered width="500px" :zIndex="1100" @ok="confirmSetSizeNum">
+    <div style="padding: 60px 30px 30px; font-size: 16px" v-if="editSizeNumRecord && editSizeNumRecord.hotChargeLengthArr">
+      <div style="margin-bottom: 30px" v-for="(item, index) in editSizeNumRecord.hotChargeLengthArr" :key="index">
+        <a-input-number
+          size="large"
+          v-model:value="item.totalCount"
+          :min="0"
+          :step="4"
+          @change="
+            (value) => {
+              if (!value) {
+                item.totalCount = 0;
+              }
+              if (value % 4 !== 0) {
+                item.totalCount = value - (value % 4);
+              }
+            }
+          "
+          :controls="false"
+        >
+          <template #addonBefore>
+            <div :style="{ color: item.hotChargeBtype === '0' ? '#f50' : '#108ee9' }">
+              {{
+                headText[item.hotChargeDestination] +
+                ' ' +
+                Number(item.hotChargeLength) / 1000 +
+                'm ' +
+                ' ' +
+                (item.hotChargeBtype === '0' ? '热' : '冷')
+              }}
+            </div>
+          </template>
+        </a-input-number>
+      </div>
+      <div style="font-size: 16px; color: #f50">注:请输入4或4的倍数.</div>
+    </div>
+  </a-modal>
+
+  <!-- 新增炉号 -->
+  <a-modal v-model:open="openNewHeatNo" title="新增炉次" centered width="500px" :zIndex="1000" @ok="confirmAddHeatNo">
+    <div style="padding: 60px 30px 30px; font-size: 16px">
+      <a-input size="large" v-model:value="newHeatNo"></a-input>
+    </div>
+  </a-modal>
+</template>
+<script setup lang="ts">
+  import { ref, computed, h, onMounted } from 'vue';
+  import dayjs from 'dayjs';
+  import type { TableColumnsType } from 'ant-design-vue';
+  import { queryBilletRecordByCcmNo, editBilletRecord, addBilletNo, editOriginalProductRecord } from '../operator.api';
+  import { render } from '/@/utils/common/renderUtils';
+  import { isArray, isNumber } from '/@/utils/is';
+  import Icon from '/@/components/Icon';
+  import { Input, Select } from 'ant-design-vue';
+  import { throttle } from 'lodash-es';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { initDictOptions } from '/@/utils/dict';
+  import { useTimeoutFn } from '/@/hooks/core/useTimeout';
+
+  const emits = defineEmits(['statistics']);
+
+  const { createMessage } = useMessage();
+  const printKey = ref(dayjs().unix());
+
+  const props = defineProps({
+    openData: {
+      type: Object,
+      default: () => {},
+    },
+  });
+  // 渲染字典标签
+  const renderDictTag = (value: string, dictCode: string) => {
+    return render.renderDict(value, dictCode);
+  };
+  // 主机号
+  const hostNumber = ref('5');
+  const defaultColumns: TableColumnsType = [
+    {
+      title: '序号',
+      width: 40,
+      dataIndex: 'SerialNumber',
+      align: 'center',
+      key: 'SerialNumber',
+    },
+    {
+      title: '炉号',
+      dataIndex: 'heatNo',
+      // width: 80,
+      align: 'center',
+      key: 'heatNo',
+    },
+    {
+      title: '钢种',
+      // width: 80,
+      align: 'center',
+      dataIndex: 'brandNum',
+      key: 'brandNum',
+      customRender: ({ text }) => {
+        return render.renderDict(text, 'billet_spec');
+      },
+    },
+    {
+      title: () => {
+        return h('div', { style: { position: 'relative' } }, [
+          h('span', {}, '棒一'),
+          h(
+            'div',
+            {
+              style: {
+                cursor: 'pointer',
+                position: 'absolute',
+                right: '4px',
+                top: '1px',
+              },
+              class: 'noprint',
+              onClick: () => {
+                console.log('点击了');
+                const rollOnrColumn: any = columns.value.find((item: any) => item.dataIndex === 'rollOne');
+                let newSize: string | number = '';
+                rollOnrColumn.children.push({
+                  title: () => {
+                    return h(
+                      // Select,
+                      Input,
+                      {
+                        // options: sizeListOPtions.value,
+                        bordered: false,
+                        // dropdownStyle: {
+                        //   minWidth: '80px',
+                        // },
+                        defaultValue: '',
+                        style: {
+                          padding: 0,
+                          textAlign: 'center',
+                        },
+                        // onChange: (value) => {
+                        //   newSize = value;
+                        // },
+                        onBlur: throttle((e) => {
+                          if (e.target.value.trim() === '') {
+                            createMessage.error('请输入定尺');
+                            return;
+                          }
+                          const size = Number(e.target.value.trim());
+                          if (!isNumber(size)) {
+                            createMessage.error('请输入数字');
+                            return;
+                          }
+
+                          newSize = size <= 20 ? size * 1000 : size;
+                        }, 500),
+                      },
+                      ''
+                    );
+                  },
+                  dataIndex: 'newSize',
+                  key: 'newSize',
+                  align: 'center',
+                  // width: 100,
+                  customRender({ text, record }) {
+                    if (!record.heatNo) {
+                      return '';
+                    }
+                    return h(
+                      Input,
+                      { class: 'total-input', size: 'small', bordered: false, value: text, onBlur: (e) => handleSizeChange(e, record, newSize) },
+                      ''
+                    );
+                  },
+                });
+              },
+            },
+            h(Icon, { icon: 'ant-design:plus-square-outlined' }, '')
+          ),
+        ]);
+      },
+      width: 80,
+      align: 'center',
+      dataIndex: 'rollOne',
+      key: 'rollOne',
+      children: [],
+    },
+  ];
+
+  const totalColum: TableColumnsType = [
+    {
+      title: '合计',
+      dataIndex: 'total',
+      key: 'total',
+      align: 'center',
+      // width: 100,
+      customRender({ text, record }) {
+        if (!record.heatNo) {
+          return '';
+        }
+        const allCount = handleTotalSum(record.orgData);
+        return h(Input, { class: 'total-input', size: 'small', bordered: false, value: allCount, onBlur: (e) => handleTotalChange(e, record) }, '');
+      },
+    },
+  ];
+
+  const columns = ref<TableColumnsType>(defaultColumns);
+  const dataSource = ref<any[]>([]);
+  const shiftInfoTxt = ref(['', '']);
+  const shiftInfo = ref({ shift: '', shiftGroup: '' });
+  const curTime = ref(dayjs().format('YYYY-MM-DD'));
+  //表单赋值
+  const fetchQueryType = ref(1);
+  const fetchChangeShiftId = ref('');
+  // 定尺
+  const sizeListOPtions = ref([]);
+  const isSpinning = ref(false);
+  // 字段映射
+  const headText = {
+    rollClubTwoCount: '二',
+    rollClubThreeCount: '三',
+    rollClubShippCount: '上',
+    roll_club_two: '棒二',
+    roll_club_three: '棒三',
+    roll_out_shipp: '上若',
+  };
+  const changeLoading = (b) => {
+    isSpinning.value = b;
+  };
+
+  const { start, stop } = useTimeoutFn(() => {
+    getHeatList({
+      ccmNo: hostNumber.value,
+      queryType: fetchQueryType.value,
+      changeShiftId: fetchChangeShiftId.value,
+    });
+  }, 10000);
+  onMounted(() => {
+    initData(props.openData);
+  });
+  const initData = async (data) => {
+    const { ccmNo, shiftText, queryType, curShiftInfo, changeShiftId, time } = data;
+    printKey.value = dayjs().unix();
+
+    hostNumber.value = ccmNo;
+    fetchQueryType.value = queryType;
+    fetchChangeShiftId.value = changeShiftId;
+    shiftInfoTxt.value = shiftText.split('-');
+    shiftInfo.value = curShiftInfo;
+    if (time) {
+      curTime.value = time;
+    }
+
+    let newSip: any[] = [];
+    for (let index = 0; index < 22; index++) {
+      newSip.push({
+        SerialNumber: index + 1,
+        heatNo: '',
+        brandNum: '',
+        oneFlow: '',
+        twoFlow: '',
+        threeFlow: '',
+        fourFlow: '',
+        fiveFlow: '',
+        sixFlow: '',
+        sevenFlow: '',
+        eightFlow: '',
+        total: '',
+      });
+    }
+
+    dataSource.value = [...newSip];
+    getHeatList({
+      ccmNo,
+      queryType,
+      changeShiftId,
+    });
+
+    // 获取定尺啊
+    initDictOptions('lg_dcgg').then((dc) => {
+      sizeListOPtions.value = (dc || []).map((item) => {
+        return {
+          label: Number(item.value) / 1000,
+          value: item.value,
+        };
+      });
+    });
+  };
+
+  // 备注
+  const remakeColSpan = ref(8);
+  // 定尺
+  const sizeColSpan = ref(2);
+  // 支数
+  const flowColSpan = ref(2);
+  // 产量
+  const weightColSpan = ref(4);
+  // 热送统计
+  const hotSendList = ref<any>({});
+  // 堆垛统计
+  const stackingList = ref<any>([]);
+  // 定尺和备注
+  const mainOrgSize = ref('');
+  const mainSize = ref('');
+  const mainOrgRemark = ref('');
+  const mainRemark = ref('');
+  const getHeatList = async (params) => {
+    try {
+      stop();
+      changeLoading(true);
+      const { billetOriginalProductRecordList, content, sizeInfo } = await queryBilletRecordByCcmNo(params);
+      let newArr: any[] = [];
+      mainOrgSize.value = sizeInfo || '';
+      mainSize.value = sizeInfo || '';
+      mainRemark.value = content || '';
+      mainOrgRemark.value = content || '';
+      if (billetOriginalProductRecordList && Array.isArray(billetOriginalProductRecordList)) {
+        // 根据时间排序
+        newArr = billetOriginalProductRecordList.sort((a, b) => {
+          return dayjs(a.createTime).isBefore(dayjs(b.createTime)) ? -1 : 1;
+        });
+        // 棒一
+        const rollOneColumns: TableColumnsType = [];
+        const rollOneSize = {};
+        // 棒二
+        const rollTwoSize = {};
+        // 棒三
+        const rollThreeSize = {};
+        // 上若
+        const rollShippSize = {};
+        // 装车按热装和冷装分组
+        const rollChargeSizeType = {
+          '0': {},
+          '1': {},
+        };
+        // 堆垛
+        const stackingSize = {};
+
+        // 堆垛字段
+        let stackLengthColumn: any = {
+          title: () => {
+            return h('div', { style: { position: 'relative' } }, [
+              h('span', {}, '堆垛'),
+              h(
+                'div',
+                {
+                  style: {
+                    cursor: 'pointer',
+                    position: 'absolute',
+                    right: '4px',
+                    top: '1px',
+                  },
+                  class: 'noprint',
+                  onClick: () => {
+                    const rollOnrColumn: any = columns.value.find((item: any) => item.dataIndex === 'stackLength');
+                    let newSize: string | number = '';
+                    rollOnrColumn.children.push({
+                      title: () => {
+                        return h(
+                          // Select,
+                          Input,
+                          {
+                            //   options: sizeListOPtions.value,
+                            bordered: false,
+                            //   dropdownStyle: {
+                            //     minWidth: '80px',
+                            //   },
+                            style: {
+                              padding: '0px',
+                              textAlign: 'center',
+                            },
+                            defaultValue: ' ',
+                            // onChange: (value) => {
+                            //   newSize = value;
+                            // },
+                            onBlur: throttle((e) => {
+                              if (e.target.value.trim() === '') {
+                                createMessage.error('请输入定尺');
+                                return;
+                              }
+                              const size = Number(e.target.value.trim());
+                              if (!isNumber(size)) {
+                                createMessage.error('请输入数字');
+                                return;
+                              }
+
+                              newSize = size <= 20 ? size * 1000 : size;
+                            }, 500),
+                          },
+                          ''
+                        );
+                      },
+                      dataIndex: 'newSize',
+                      key: 'newSize',
+                      align: 'center',
+                      // width: 100,
+                      customRender({ text, record }) {
+                        if (!record.heatNo) {
+                          return '';
+                        }
+                        return h(
+                          Input,
+                          { class: 'total-input', size: 'small', bordered: false, value: text, onBlur: (e) => handleStackChange(e, record, newSize) },
+                          ''
+                        );
+                      },
+                    });
+                  },
+                },
+                h(Icon, { icon: 'ant-design:plus-square-outlined' }, '')
+              ),
+            ]);
+          },
+          dataIndex: 'stackLength',
+          key: 'stackLength',
+          // width: 100,
+          children: [],
+        };
+
+        const hotChargeColumns: any = {
+          // 棒二字段
+          roll_club_two: {
+            title: '棒二',
+            dataIndex: 'roll_club_two',
+            key: 'roll_club_two',
+            // width: 100,
+            children: [],
+          },
+          // 棒三字段
+          roll_club_three: {
+            title: '棒三',
+            dataIndex: 'roll_club_three',
+            key: 'roll_club_three',
+            // width: 100,
+            children: [],
+          },
+          // 上若字段
+          roll_out_shipp: {
+            title: '上若',
+            dataIndex: 'roll_out_shipp',
+            key: 'roll_out_shipp',
+            // width: 100,
+            children: [],
+          },
+        };
+
+        // 热装字段
+        let columnsHotCharge: any = {
+          roll_club_two: [],
+          roll_club_three: [],
+          roll_out_shipp: [],
+        };
+
+        dataSource.value = dataSource.value.map((item, index) => {
+          if (!newArr[index]) return item;
+          const { hotChargeLength, rollClubOneDetails, stackLength } = newArr[index];
+
+          // 棒一
+          let rollOneNum = '';
+          let rollOneSizesObj = {};
+          // if (hotSend) {
+          //   const obj = JSON.parse(hotSend);
+          //   rollOneNum = obj.hotSendTotalCount || '';
+          // }
+          if (rollClubOneDetails) {
+            const obj = JSON.parse(rollClubOneDetails);
+            rollOneNum = obj.directRollingTotalCount || '';
+            const lengthGroupCount = obj.lengthGroupCount;
+            if (lengthGroupCount) {
+              // 热送棒一的定尺
+              Object.keys(lengthGroupCount).forEach((key) => {
+                const column = key;
+                const columnKey = column + 'rollOneColumn';
+                const findIndex = rollOneColumns.findIndex((item: any) => item.dataIndex === columnKey);
+                if (findIndex === -1) {
+                  rollOneColumns.push({
+                    title: () => {
+                      return h('div', { class: 'rollOneColumnWrapper' }, [
+                        h(
+                          // Select,
+                          Input,
+                          {
+                            // options: sizeListOPtions.value,
+                            bordered: false,
+                            // dropdownStyle: {
+                            //   minWidth: '80px',
+                            // },
+                            style: {
+                              padding: '0px',
+                              textAlign: 'center',
+                            },
+                            defaultValue: Number(column) > 20 ? Number(column) / 1000 : column,
+                            // onChange: (value) => {
+                            //   switchSizehandler(value, column);
+                            // },
+                            onBlur: throttle((e) => {
+                              const value = Number(e.target.value) < 20 ? Number(e.target.value) * 1000 : Number(e.target.value);
+                              switchSizehandler(value, Number(column));
+                            }, 500),
+                          },
+                          ''
+                        ),
+                        h(
+                          'div',
+                          { class: 'noprint', onClick: () => deleteRollOneColumn(column) },
+                          h(Icon, { icon: 'ant-design:delete-outlined' }, '')
+                        ),
+                      ]);
+                    },
+                    dataIndex: columnKey,
+                    key: columnKey,
+                    align: 'center',
+                    width: 80,
+                    customRender({ text, record }) {
+                      if (!record.heatNo) {
+                        return '';
+                      }
+                      return h(
+                        Input,
+                        { class: 'total-input', size: 'small', bordered: false, value: text, onBlur: (e) => handleSizeChange(e, record, column) },
+                        ''
+                      );
+                    },
+                  });
+                }
+
+                rollOneSizesObj[columnKey] = lengthGroupCount[key];
+
+                // 如果没有棒一的定尺
+                if (!rollOneSize[key]) {
+                  rollOneSize[key] = {
+                    size: Number(column) / 1000 + 'm',
+                    amount: lengthGroupCount[key],
+                    weight: lengthGroupCount[key] * (Number(column) / 1000) * 0.2265,
+                  };
+                } else {
+                  rollOneSize[key].amount += lengthGroupCount[key];
+                  rollOneSize[key].weight += lengthGroupCount[key] * (Number(column) / 1000) * 0.2265;
+                }
+              });
+            }
+          }
+
+          // 热装
+          let sizeArr = {};
+          if (hotChargeLength) {
+            // "[{\"hotChargeLength\":\"11820\",\"hotChargeDestination\":\"roll_club_three\",\"totalWeight\":\"74.9624\",\"hotChargeBtype\":\"0\",\"totalCount\":28}]"
+            const hotChargeArr = JSON.parse(hotChargeLength);
+            hotChargeArr.forEach((k) => {
+              const sizeFormat = Number(k.hotChargeLength) / 1000;
+              const dataKey = sizeFormat + k.hotChargeDestination + k.hotChargeBtype;
+              sizeArr[dataKey] = k.totalCount;
+              // 热送统计
+              // 棒二
+              if (k.hotChargeDestination === 'roll_club_two' && k.totalCount > 0) {
+                // 添加定尺
+                columnsHotCharge.roll_club_two.push(sizeFormat);
+
+                if (!rollTwoSize[k.hotChargeLength]) {
+                  rollTwoSize[k.hotChargeLength] = {
+                    type: k.hotChargeBtype,
+                    size: Number(k.hotChargeLength) / 1000 + 'm',
+                    amount: k.totalCount,
+                    weight: k.totalCount * (Number(k.hotChargeLength) / 1000) * 0.2265,
+                  };
+                } else {
+                  rollTwoSize[k.hotChargeLength].amount += k.totalCount;
+                  rollTwoSize[k.hotChargeLength].weight += k.totalCount * (Number(k.hotChargeLength) / 1000) * 0.2265;
+                }
+              }
+              // 棒三
+              if (k.hotChargeDestination === 'roll_club_three' && k.totalCount > 0) {
+                // 添加定尺
+                columnsHotCharge.roll_club_three.push(sizeFormat);
+
+                if (!rollThreeSize[k.hotChargeLength]) {
+                  rollThreeSize[k.hotChargeLength] = {
+                    type: k.hotChargeBtype,
+                    size: Number(k.hotChargeLength) / 1000 + 'm',
+                    amount: k.totalCount,
+                    weight: k.totalCount * (Number(k.hotChargeLength) / 1000) * 0.2265,
+                  };
+                } else {
+                  rollThreeSize[k.hotChargeLength].amount += k.totalCount;
+                  rollThreeSize[k.hotChargeLength].weight += k.totalCount * (Number(k.hotChargeLength) / 1000) * 0.2265;
+                }
+              }
+              // 上若
+              if (k.hotChargeDestination === 'roll_out_shipp' && k.totalCount > 0) {
+                // 添加定尺
+                columnsHotCharge.roll_out_shipp.push(sizeFormat);
+
+                if (!rollShippSize[k.hotChargeLength]) {
+                  rollShippSize[k.hotChargeLength] = {
+                    type: k.hotChargeBtype,
+                    size: Number(k.hotChargeLength) / 1000 + 'm',
+                    amount: k.totalCount,
+                    weight: k.totalCount * (Number(k.hotChargeLength) / 1000) * 0.2265,
+                  };
+                } else {
+                  rollShippSize[k.hotChargeLength].amount += k.totalCount;
+                  rollShippSize[k.hotChargeLength].weight += k.totalCount * (Number(k.hotChargeLength) / 1000) * 0.2265;
+                }
+              }
+
+              // 热装按类型分组,分热装和冷装
+              if (!rollChargeSizeType[k.hotChargeBtype][k.hotChargeLength]) {
+                rollChargeSizeType[k.hotChargeBtype][k.hotChargeLength] = {
+                  size: sizeFormat + 'm',
+                  amount: k.totalCount,
+                  weight: k.totalCount * (Number(k.hotChargeLength) / 1000) * 0.2265,
+                };
+              } else {
+                rollChargeSizeType[k.hotChargeBtype][k.hotChargeLength].amount += k.totalCount;
+                rollChargeSizeType[k.hotChargeBtype][k.hotChargeLength].weight += k.totalCount * (Number(k.hotChargeLength) / 1000) * 0.2265;
+              }
+            });
+          }
+
+          // 堆垛
+          let stackSizeData = {};
+          if (stackLength) {
+            const stackLeghtObj = JSON.parse(stackLength);
+            stackLeghtObj.forEach((v) => {
+              const sSize = String(v.stackingLength);
+              const hasChild = stackLengthColumn.children.findIndex((ele) => ele.dataIndex === sSize + 'stackLength');
+              if (hasChild < 0) {
+                stackLengthColumn.children.push({
+                  title: () => {
+                    return h('div', { class: 'rollOneColumnWrapper' }, [
+                      h(
+                        // Select,
+                        Input,
+                        {
+                          // options: sizeListOPtions.value,
+                          bordered: false,
+                          // dropdownStyle: {
+                          //   minWidth: '80px',
+                          // },
+                          style: {
+                            padding: '0px',
+                            textAlign: 'center',
+                          },
+                          defaultValue: Number(sSize) > 20 ? Number(sSize) / 1000 : sSize,
+                          // onChange: (value) => {
+                          //   switchSizehandler(value, column);
+                          // },
+                          onBlur: throttle((e) => {
+                            const value = Number(e.target.value) < 20 ? Number(e.target.value) * 1000 : Number(e.target.value);
+                            switchStackhandler(value, Number(sSize));
+                          }, 500),
+                        },
+                        ''
+                      ),
+                      h('div', { class: 'noprint', onClick: () => deleteStackColumn(sSize) }, h(Icon, { icon: 'ant-design:delete-outlined' }, '')),
+                    ]);
+                  },
+                  dataIndex: sSize + 'stackLength',
+                  key: sSize + 'stackLength',
+                  width: 80,
+                  customRender({ text, record }) {
+                    if (!record.heatNo) {
+                      return '';
+                    }
+                    return h(
+                      Input,
+                      { class: 'total-input', size: 'small', bordered: false, value: text, onBlur: (e) => handleStackChange(e, record, sSize) },
+                      ''
+                    );
+                  },
+                });
+              }
+
+              stackSizeData[sSize + 'stackLength'] = v.stackingCount;
+
+              // 给堆垛添加致谢
+              if (!stackingSize[sSize]) {
+                stackingSize[sSize] = {
+                  size: Number(sSize) / 1000 + 'm',
+                  amount: v.stackingCount,
+                  weight: v.stackingCount * (Number(sSize) / 1000) * 0.2265,
+                };
+              } else {
+                stackingSize[sSize].amount += v.stackingCount;
+                stackingSize[sSize].weight += v.stackingCount * (Number(sSize) / 1000) * 0.2265;
+              }
+            });
+          }
+
+          return {
+            ...item,
+            heatNo: newArr[index].heatNo,
+            brandNum: newArr[index].grade,
+            oneFlow: newArr[index].oneStrandSum || '',
+            twoFlow: newArr[index].twoStrandSum || '',
+            threeFlow: newArr[index].threeStrandSum || '',
+            fourFlow: newArr[index].fourStrandSum || '',
+            fiveFlow: newArr[index].fiveStrandSum || '',
+            sixFlow: newArr[index].sixStrandSum || '',
+            sevenFlow: newArr[index].sevenStrandSum || '',
+            eightFlow: newArr[index].eightStrandSum || '',
+            total: newArr[index].amount || '',
+            rollOneOld: rollOneNum,
+            ...sizeArr,
+            ...rollOneSizesObj,
+            ...stackSizeData,
+            orgData: newArr[index],
+          };
+        });
+
+        let otherColumnsNums = 0;
+        const otherColumns = Object.keys(columnsHotCharge)
+          .filter((item) => columnsHotCharge[item].length)
+          .map((item) => {
+            const hotChargeSizeArr = [...new Set(columnsHotCharge[item])];
+            const niubiGls: any[] = [];
+            hotChargeSizeArr.forEach((ele) => {
+              niubiGls.push(
+                {
+                  hotChargeLength: Number(ele) * 1000,
+                  hotChargeDestination: item,
+                  totalWeight: 0,
+                  hotChargeBtype: '0',
+                  totalCount: 0,
+                },
+                {
+                  hotChargeLength: Number(ele) * 1000,
+                  hotChargeDestination: item,
+                  totalWeight: 0,
+                  hotChargeBtype: '1',
+                  totalCount: 0,
+                }
+              );
+            });
+            const childSizesColumn = hotChargeSizeArr.map((childItem) => {
+              return {
+                title: childItem,
+                dataIndex: `${item}.${childItem}`,
+                key: `${item}.${childItem}`,
+                width: 80,
+                align: 'center',
+                customRender: ({ record }) => {
+                  const hotKey = childItem + item + '0';
+                  const coldKey = childItem + item + '1';
+                  let sizeArr: any = [];
+                  if (record[hotKey] || record[coldKey]) {
+                    sizeArr = [h('div', { class: 'line' }, ''), h('div', { class: 'size-st-item' }, record[hotKey] || '~')];
+                    sizeArr.push(h('div', { class: ' size-st-num' }, record[coldKey] || '~'));
+                  }
+
+                  return h(
+                    'div',
+                    {
+                      class: 'size-st-wrapper',
+                      onClick: () => {
+                        // if (!record[hotKey] && !record[coldKey]) return;
+                        const { orgData } = record;
+                        if (!orgData) return;
+                        const { hotChargeLength } = orgData;
+
+                        const hotChargeInfoArr = hotChargeLength ? JSON.parse(hotChargeLength) : [];
+
+                        const itemsHotArr = niubiGls.map((v) => {
+                          const hasVal = hotChargeInfoArr.find((j) => j.hotChargeLength == v.hotChargeLength && j.hotChargeBtype == v.hotChargeBtype);
+                          return {
+                            ...v,
+                            totalCount: hasVal ? hasVal.totalCount : 0,
+                          };
+                        });
+
+                        editSizeNumRecord.value = {
+                          ...orgData,
+                          hotChargeLengthArr: itemsHotArr,
+                        };
+                        openSetSizeNumModal.value = true;
+                      },
+                    },
+                    sizeArr
+                  );
+                },
+              };
+            });
+            otherColumnsNums = otherColumnsNums + (childSizesColumn.length ? childSizesColumn.length : 1);
+            return {
+              ...hotChargeColumns[item],
+              children: childSizesColumn,
+            };
+          });
+
+        columns.value = [...defaultColumns, ...otherColumns, ...[stackLengthColumn], ...totalColum];
+        const rollOneIndex = defaultColumns.findIndex((ele: any) => ele.dataIndex === 'rollOne');
+        (columns.value[rollOneIndex] as any).children = rollOneColumns.length ? rollOneColumns : [];
+
+        // 计算列,合并
+        const allSpan =
+          4 +
+          (rollOneColumns.length ? rollOneColumns.length : 1) +
+          otherColumnsNums +
+          (stackLengthColumn.children.length ? stackLengthColumn.children.length : 1);
+        remakeColSpan.value = Math.ceil(allSpan / 3);
+        const nnColSpan = Math.ceil((allSpan - remakeColSpan.value) / 2);
+        const newNNColSpan = nnColSpan % 2 === 0 ? nnColSpan : nnColSpan + 1;
+        sizeColSpan.value = newNNColSpan / 2 > 4 ? newNNColSpan / 2 : 4;
+        flowColSpan.value = newNNColSpan - sizeColSpan.value;
+        weightColSpan.value = allSpan - remakeColSpan.value - newNNColSpan;
+
+        let allWeight = 0;
+        // 热送统计
+        if (Object.values(rollOneSize).length) {
+          hotSendList.value['一'] = Object.values(rollOneSize);
+          hotSendList.value['一'].forEach((ele) => (allWeight += ele.weight));
+        }
+        if (Object.values(rollTwoSize).length) {
+          hotSendList.value['二'] = Object.values(rollTwoSize);
+          hotSendList.value['二'].forEach((ele) => (allWeight += ele.weight));
+        }
+        if (Object.values(rollThreeSize).length) {
+          hotSendList.value['三'] = Object.values(rollThreeSize);
+          hotSendList.value['三'].forEach((ele) => (allWeight += ele.weight));
+        }
+        if (Object.values(rollShippSize).length) {
+          hotSendList.value['上'] = Object.values(rollShippSize);
+          hotSendList.value['上'].forEach((ele) => (allWeight += ele.weight));
+        }
+        if (Object.values(stackingSize)) {
+          stackingList.value = Object.values(stackingSize);
+          stackingList.value.forEach((ele) => (allWeight += ele.weight));
+        }
+
+        emits('statistics', {
+          chargeList: rollChargeSizeType,
+          stackingList: stackingList.value,
+          hotSendList: hotSendList.value['一'],
+        });
+        mainRemark.value = `合计:${allWeight.toFixed(3)} t`;
+      }
+      start();
+      changeLoading(false);
+    } catch (error) {
+      start();
+      changeLoading(false);
+      console.log(error);
+    }
+  };
+
+  const openJSModal = ref(false);
+  const xiShu = ref(0.2265);
+  const sizeNum = ref();
+  const weightNum = ref();
+  // 重量计算按钮
+  const weightCalc = computed(() => {
+    const w = Number(weightNum.value);
+    const x = Number(xiShu.value);
+    const s = Number(sizeNum.value);
+    if (isNumber(w) && isNumber(x) && isNumber(s)) {
+      const r = w * x * s;
+
+      return !isNaN(r) ? r.toFixed(6) : '';
+    }
+    return '';
+  });
+
+  // 修改合计
+  const handleTotalChange = throttle((e: any, record) => {
+    const val = Number(e.target.value);
+    if (!isNumber(val) || val < 0) {
+      createMessage.error('请输入大于0数字');
+      return;
+    }
+    const { orgData } = record;
+    if (Number(orgData.amount) != val) {
+      handleEdit({
+        ...orgData,
+        amount: val,
+      });
+    }
+  }, 800);
+
+  // 编辑
+  const handleEdit = async (record) => {
+    try {
+      changeLoading(true);
+
+      await editBilletRecord(record);
+
+      await getHeatList({
+        ccmNo: hostNumber.value,
+        queryType: fetchQueryType.value,
+        changeShiftId: fetchChangeShiftId.value,
+      });
+      changeLoading(false);
+    } catch (error) {
+      changeLoading(false);
+      console.log(error);
+    }
+  };
+
+  // 修改棒一定尺数量
+  const handleSizeChange = throttle((e: any, record, size) => {
+    if (!size) {
+      createMessage.error('请选择定尺');
+      return;
+    }
+    const val = Number(e.target.value);
+    if (!isNumber(val) || val < 0) {
+      createMessage.error('请输入大于或等于0的数字');
+      return;
+    }
+
+    const { orgData } = record;
+    const { rollClubOneDetails } = orgData;
+    let obj = {
+      lengthGroupCount: {},
+      directRollingTotalWeight: 0,
+      directRollingTotalCount: 0,
+    };
+    if (rollClubOneDetails) {
+      obj = JSON.parse(rollClubOneDetails);
+    }
+
+    const lengthGroupCount = obj.lengthGroupCount;
+    if (
+      lengthGroupCount &&
+      ((Object.hasOwn(lengthGroupCount, size) && (val === 0 || lengthGroupCount[size] !== val)) ||
+        (!Object.hasOwn(lengthGroupCount, size) && val > 0))
+    ) {
+      if (val <= 0) {
+        delete obj.lengthGroupCount[size];
+      } else {
+        obj.lengthGroupCount[size] = val;
+      }
+
+      const params = {
+        ...orgData,
+        rollClubOneDetails: JSON.stringify(obj),
+      };
+      const amount = handleTotalSum(params);
+      handleEdit({
+        ...params,
+        amount,
+      });
+    }
+  }, 800);
+
+  // 计算总数
+  const handleTotalSum = (record) => {
+    const { rollClubOneDetails, stackLength, hotChargeLength } = record;
+    let allCount = 0;
+    if (rollClubOneDetails) {
+      const sendObj = JSON.parse(rollClubOneDetails);
+      if (sendObj.lengthGroupCount) {
+        Object.keys(sendObj.lengthGroupCount).forEach((key) => {
+          allCount += sendObj.lengthGroupCount[key];
+        });
+      }
+    }
+
+    if (stackLength) {
+      const stackObj = JSON.parse(stackLength);
+      if (isArray(stackObj)) {
+        stackObj.forEach((item) => {
+          allCount += item.stackingCount;
+        });
+      }
+    }
+
+    if (hotChargeLength) {
+      const chargeObj = JSON.parse(hotChargeLength);
+      if (isArray(chargeObj)) {
+        chargeObj.forEach((item) => {
+          allCount += item.totalCount;
+        });
+      }
+    }
+
+    return allCount;
+  };
+
+  // 修改堆垛定尺数量
+  const handleStackChange = throttle((e: any, record, size) => {
+    if (e.target.value.trim() === '') return;
+    if (!size) {
+      createMessage.error('请选择定尺');
+      return;
+    }
+    const val = Number(e.target.value);
+    if (!isNumber(val)) {
+      createMessage.error('请输入大于等于0的数字');
+      return;
+    }
+
+    const { orgData } = record;
+    const { stackLength } = orgData;
+    let obj: any[] = [];
+    if (stackLength) {
+      obj = JSON.parse(stackLength);
+    }
+
+    const lengthGroupCount = obj.findIndex((v) => v.stackingLength == size);
+
+    // 计算补的数量是不是4的倍数
+    let stackInfo: any = null;
+    const buCount = lengthGroupCount > -1 ? val - obj[lengthGroupCount].stackingCount : val;
+    if (buCount && buCount > 0) {
+      if (buCount % 4 !== 0) {
+        createMessage.error('补数量必须是4的倍数');
+        return;
+      }
+      stackInfo = buCount + '-' + size + '-10';
+    } else {
+      stackInfo = null;
+    }
+
+    if (lengthGroupCount === -1) {
+      obj.push({
+        stackingCount: val,
+        stackingLength: size,
+        stackingWeight: val * (Number(size) / 1000) * 0.2265,
+      });
+    } else {
+      if (obj[lengthGroupCount].stackingCount === val) return;
+      obj[lengthGroupCount].stackingCount = val;
+      obj[lengthGroupCount].stackingWeight = val * (Number(size) / 1000) * 0.2265;
+    }
+
+    const params = {
+      ...orgData,
+      stackLength: JSON.stringify(obj),
+      stackInfo,
+    };
+    const amount = handleTotalSum(params);
+    handleEdit({
+      ...params,
+      amount,
+    });
+  }, 800);
+
+  // 编辑切换定尺
+  const switchSizehandler = async (val, oldSize) => {
+    try {
+      if (val == oldSize) return;
+      changeLoading(true);
+      const fetchArr: any[] = [];
+      dataSource.value.forEach((item) => {
+        if (item.heatNo && item.orgData) {
+          const { rollClubOneDetails } = item.orgData;
+          if (rollClubOneDetails) {
+            const obj = JSON.parse(rollClubOneDetails);
+            if (obj && obj.lengthGroupCount) {
+              const lengthGroupCount = obj.lengthGroupCount;
+
+              if (lengthGroupCount[oldSize]) {
+                obj.lengthGroupCount[val] = lengthGroupCount[oldSize] + (lengthGroupCount[val] ? lengthGroupCount[val] : 0);
+                delete obj.lengthGroupCount[oldSize];
+
+                // 请求push了
+                fetchArr.push(
+                  editBilletRecord({
+                    ...item.orgData,
+                    rollClubOneDetails: JSON.stringify(obj),
+                  })
+                );
+              }
+            }
+          }
+        }
+      });
+
+      if (fetchArr.length > 0) {
+        await Promise.all(fetchArr);
+
+        await getHeatList({
+          ccmNo: hostNumber.value,
+          queryType: fetchQueryType.value,
+          changeShiftId: fetchChangeShiftId.value,
+        });
+
+        changeLoading(false);
+      }
+    } catch (error) {
+      changeLoading(false);
+      console.log(error);
+    }
+  };
+
+  // 堆垛编辑定尺
+  const switchStackhandler = async (val, oldSize) => {
+    try {
+      if (val === oldSize) return;
+      changeLoading(true);
+      const fetchArr: any[] = [];
+      dataSource.value.forEach((item) => {
+        if (item.heatNo && item.orgData) {
+          const { stackLength } = item.orgData;
+          if (stackLength) {
+            let obj = stackLength ? JSON.parse(stackLength) : [];
+            const oldSizeIndex = obj.findIndex((k) => k.stackingLength === oldSize);
+            if (oldSizeIndex > -1) {
+              const newSizeIndex = obj.findIndex((k) => k.stackingLength === Number(val));
+              if (newSizeIndex > -1) {
+                obj[newSizeIndex].stackingCount += obj[oldSizeIndex].stackingCount;
+                obj = obj.filter((j) => j.stackingLength !== oldSize);
+              } else {
+                obj[oldSizeIndex].stackingLength = Number(val);
+              }
+
+              // 请求push了
+              fetchArr.push(
+                editBilletRecord({
+                  ...item.orgData,
+                  stackLength: JSON.stringify(obj),
+                })
+              );
+            }
+          }
+        }
+      });
+
+      if (fetchArr.length > 0) {
+        await Promise.all(fetchArr);
+
+        await getHeatList({
+          ccmNo: hostNumber.value,
+          queryType: fetchQueryType.value,
+          changeShiftId: fetchChangeShiftId.value,
+        });
+
+        changeLoading(false);
+      }
+    } catch (error) {
+      changeLoading(false);
+      console.log(error);
+    }
+  };
+
+  // 删除定尺
+  const deleteRollOneColumn = async (size) => {
+    try {
+      changeLoading(true);
+      const fetchArr: any[] = [];
+      dataSource.value.forEach((item) => {
+        if (item.heatNo && item.orgData) {
+          const { rollClubOneDetails } = item.orgData;
+          if (rollClubOneDetails) {
+            const obj = JSON.parse(rollClubOneDetails);
+            if (obj && obj.lengthGroupCount) {
+              const lengthGroupCount = obj.lengthGroupCount;
+
+              if (lengthGroupCount[size]) {
+                delete obj.lengthGroupCount[size];
+
+                // 请求push了
+                const params = {
+                  ...item.orgData,
+                  rollClubOneDetails: JSON.stringify(obj),
+                };
+
+                const amount = handleTotalSum(params);
+                fetchArr.push(
+                  editBilletRecord({
+                    ...params,
+                    amount,
+                  })
+                );
+              }
+            }
+          }
+        }
+      });
+
+      if (fetchArr.length > 0) {
+        await Promise.all(fetchArr);
+
+        await getHeatList({
+          ccmNo: hostNumber.value,
+          queryType: fetchQueryType.value,
+          changeShiftId: fetchChangeShiftId.value,
+        });
+
+        changeLoading(false);
+      }
+    } catch (error) {
+      changeLoading(false);
+      console.log(error);
+    }
+  };
+
+  // 删除堆垛定尺
+  const deleteStackColumn = async (size) => {
+    try {
+      changeLoading(true);
+      const fetchArr: any[] = [];
+      dataSource.value.forEach((item) => {
+        if (item.heatNo && item.orgData) {
+          const { stackLength } = item.orgData;
+          if (stackLength) {
+            const obj = JSON.parse(stackLength);
+            const hasStackItem = obj.findIndex((n) => n.stackingLength == size);
+            if (hasStackItem > -1) {
+              const lengthGroupCount = obj.filter((m) => m.stackingLength != size);
+
+              // 请求push了
+              const params = {
+                ...item.orgData,
+                stackLength: JSON.stringify(lengthGroupCount),
+              };
+
+              const amount = handleTotalSum(params);
+              fetchArr.push(
+                editBilletRecord({
+                  ...params,
+                  amount,
+                })
+              );
+            }
+          }
+        }
+      });
+
+      if (fetchArr.length > 0) {
+        await Promise.all(fetchArr);
+
+        await getHeatList({
+          ccmNo: hostNumber.value,
+          queryType: fetchQueryType.value,
+          changeShiftId: fetchChangeShiftId.value,
+        });
+      }
+      changeLoading(false);
+    } catch (error) {
+      changeLoading(false);
+      console.log(error);
+    }
+  };
+
+  // 编辑目的地定尺数量
+  const openSetSizeNumModal = ref(false);
+  const editSizeNumRecord = ref<any>({});
+
+  const confirmSetSizeNum = async () => {
+    try {
+      changeLoading(true);
+      const { hotChargeLengthArr } = editSizeNumRecord.value;
+      if (!hotChargeLengthArr.length) {
+        return;
+      }
+
+      const arr = hotChargeLengthArr
+        .filter((ele) => ele.totalCount)
+        .map((k) => {
+          return {
+            ...k,
+            totalWeight: (k.totalCount * (Number(k.hotChargeLength) / 1000) * 0.2265).toFixed(4),
+          };
+        });
+
+      editSizeNumRecord.value.hotChargeLength = arr.length ? JSON.stringify(arr) : null;
+
+      await editBilletRecord({
+        ...editSizeNumRecord.value,
+      });
+      openSetSizeNumModal.value = false;
+
+      await getHeatList({
+        ccmNo: hostNumber.value,
+        queryType: fetchQueryType.value,
+        changeShiftId: fetchChangeShiftId.value,
+      });
+      changeLoading(false);
+    } catch (e) {
+      changeLoading(false);
+      console.log(e);
+    }
+  };
+
+  // 确定修改定尺
+  const handleSizeBlur = throttle((e) => {
+    if (mainOrgSize.value.trim() === e.target.value.trim()) return;
+    handleEditShiftInfo({
+      id: fetchChangeShiftId.value,
+      sizeInfo: e.target.value,
+    });
+  }, 500);
+
+  // 修改备注
+  const handleRemarkBlur = throttle((e) => {
+    if (mainOrgRemark.value.trim() === e.target.value.trim()) return;
+    handleEditShiftInfo({
+      id: fetchChangeShiftId.value,
+      content: e.target.value,
+    });
+  }, 500);
+
+  // 编辑定尺和备注
+  const handleEditShiftInfo = async (params) => {
+    try {
+      changeLoading(true);
+      await editOriginalProductRecord(params);
+
+      await getHeatList({
+        ccmNo: hostNumber.value,
+        queryType: fetchQueryType.value,
+        changeShiftId: fetchChangeShiftId.value,
+      });
+      changeLoading(false);
+    } catch (e) {
+      console.log(e);
+      changeLoading(false);
+    }
+  };
+
+  // 添加炉次
+  const newHeatNo = ref('');
+  const openNewHeatNo = ref(false);
+  const addHeatNo = () => {
+    newHeatNo.value = '';
+    openNewHeatNo.value = true;
+  };
+  const confirmAddHeatNo = async () => {
+    try {
+      if (!newHeatNo.value) {
+        createMessage.error('请输入炉次号');
+        return;
+      }
+
+      changeLoading(true);
+      await addBilletNo({
+        ccmNo: hostNumber.value,
+        heatNo: newHeatNo.value,
+      });
+      openNewHeatNo.value = false;
+
+      await getHeatList({
+        ccmNo: hostNumber.value,
+        queryType: fetchQueryType.value,
+        changeShiftId: fetchChangeShiftId.value,
+      });
+      changeLoading(false);
+    } catch (e) {
+      console.log(e);
+      changeLoading(false);
+    }
+  };
+</script>
+<style lang="less" scoped>
+  .orgData-info-spin {
+    height: 100%;
+    overflow: auto;
+    padding: 6px;
+    background: #01396c;
+    color: rgba(255, 255, 255, 0.8);
+    border-radius: 6px;
+  }
+
+  .ticket {
+    max-width: 1400px;
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+
+    .ccmno-info {
+      font-family: 'Kingsoft_Cloud_Font';
+
+      .ant-input {
+        color: rgba(255, 255, 255, 0.8);
+      }
+    }
+    .ccmno {
+      display: inline-block;
+      width: 60px;
+      border-bottom: 1px solid rgb(218, 218, 218);
+      text-align: center;
+    }
+
+    .size-items-title {
+      font-size: 12px;
+      line-height: 32px;
+      border-bottom: 1px solid #bfbfbf;
+      padding-left: 10px;
+      min-width: 100px;
+    }
+
+    .size-num-title {
+      font-size: 12px;
+      line-height: 32px;
+      padding-left: 10px;
+    }
+
+    .size-items-content {
+      height: 32px;
+      text-align: center;
+      line-height: 32px;
+    }
+
+    .size-items-remark {
+      width: 100%;
+      min-height: 90px;
+      flex-wrap: wrap;
+      font-family: 'Kingsoft_Cloud_Font';
+      align-content: flex-start;
+
+      .size-remark-item {
+        width: 50%;
+        height: 30px;
+        color: #000;
+      }
+
+      .size-remark-size {
+        display: inline-block;
+        width: 80px;
+      }
+
+      .size-remark-num {
+        display: inline-block;
+        width: 80px;
+        padding: 0 40px 0 0;
+        font-size: 12px;
+      }
+    }
+
+    .two-num-wrapper {
+      position: absolute;
+      left: 0;
+      top: 0;
+      width: 100%;
+      height: 100%;
+      z-index: 10;
+      display: flex;
+      flex-direction: column;
+      justify-content: center;
+      align-items: flex-end;
+      padding-right: 6px;
+    }
+
+    .s-txt {
+      font-family: 'Kingsoft_Cloud_Font';
+    }
+
+    .ant-table-wrapper {
+      flex: 1;
+
+      :deep(.ant-spin-nested-loading) {
+        min-height: 100%;
+
+        .ant-table {
+          border-top: 1px solid rgba(184, 184, 184, 0.6);
+
+          > .ant-table-container {
+            border-inline-start: 1px solid rgba(184, 184, 184, 0.6);
+          }
+
+          .ant-table-content > table > thead > tr > th,
+          .ant-table-tbody > tr > td,
+          .ant-table-summary > tr > td {
+            padding: 2px;
+            border-inline-end: 1px solid rgba(184, 184, 184, 0.6);
+            border-bottom: 1px solid rgba(184, 184, 184, 0.6) !important;
+            text-align: center;
+            position: relative;
+            background: #01396c;
+            color: rgba(255, 255, 255, 0.8);
+          }
+
+          .size-st-wrapper {
+            position: absolute;
+            top: 1px;
+            left: 1px;
+            right: 1px;
+            bottom: 1px;
+            font-weight: 600;
+            cursor: pointer;
+            overflow: hidden;
+
+            .line {
+              // content: '';
+              // position: absolute;
+              // top: 0;
+              // left: 0;
+              // width: 100%; /* 等于长方形宽度 */
+              // height: 100%; /* 等于长方形高度 */
+
+              // /* 创建斜线:线性渐变从左上到右下 */
+              // background: linear-gradient(
+              //   to bottom right,
+              //   transparent 0%,
+              //   transparent calc(50% - 0.5px),
+              //   /* 斜线上方透明 */ rgba(0, 0, 0, 0.6) calc(50% - 0.5px),
+              //   /* 斜线颜色 */ rgba(0, 0, 0, 0.6) calc(50% + 0.5px),
+              //   /* 斜线厚度 */ transparent calc(50% + 0.5px) /* 斜线下方透明 */
+              // );
+              position: absolute;
+              left: -5px;
+              top: 50%;
+              width: 110%;
+              border-bottom: 1px solid rgba(231, 230, 230, 0.6);
+              transform: rotate(165deg);
+            }
+
+            .size-st-item {
+              position: absolute;
+              top: -4px;
+              left: 2px;
+              color: #f50;
+            }
+          }
+          .size-st-num {
+            color: #108ee9;
+            cursor: pointer;
+            position: absolute;
+            right: 1px;
+            bottom: -4px;
+          }
+
+          // 自定义啊
+          .total-input {
+            width: 100%;
+            padding: 0;
+            text-align: center;
+            cursor: pointer;
+          }
+
+          .ant-select {
+            width: 100%;
+
+            .ant-select-selector {
+              padding: 0;
+
+              .ant-select-selection-item,
+              .ant-select-selection-placeholder {
+                padding-inline-end: 0;
+              }
+            }
+            .ant-select-arrow {
+              display: none;
+            }
+          }
+
+          .rollOneColumnWrapper {
+            position: relative;
+            width: 100%;
+            height: 100%;
+
+            .noprint {
+              position: absolute;
+              left: 0;
+              top: 0;
+              display: none;
+              color: #f50;
+              cursor: pointer;
+            }
+
+            &:hover {
+              .noprint {
+                display: block;
+              }
+            }
+          }
+
+          .ant-input {
+            color: rgba(255, 255, 255, 0.8);
+          }
+        }
+      }
+
+      .summary-row-no-border {
+        td:first-child {
+          border-bottom: none !important;
+        }
+
+        .song-items {
+          width: 100%;
+          height: 100%;
+          align-items: flex-start;
+          justify-content: flex-start;
+
+          .title {
+            margin-right: 10px;
+          }
+        }
+      }
+
+      .summary-cell-remark {
+        min-height: 70px;
+      }
+    }
+  }
+</style>

+ 2 - 1
src/views/billet/operator/components/printBilletSampleCard.vue

@@ -244,6 +244,7 @@
 
   //表单赋值
   const [registerModal, { changeOkLoading }] = useModalInner(async (data) => {
+    console.log('11111111111111111', data);
     const { ccmNo, shiftText, queryType, curShiftInfo, changeShiftId } = data;
     hostNumber.value = ccmNo;
     shiftInfoTxt.value = shiftText.replace('-', '/');
@@ -268,7 +269,7 @@
       let newArr: any[] = [];
       if (res && Array.isArray(res)) {
         const ln = res.length;
-        for (let i = ln - 1; i >= 0; i--) {
+        for (let i = 0; i < ln; i++) {
           const item = res[i];
           const lengthObj: Record<string, any> = item.lengthCountMap;
           const sizeArr: string[] = Object.keys(lengthObj);

+ 162 - 49
src/views/billet/operator/components/printOriginalRecords.vue

@@ -17,8 +17,25 @@
     >
       <div class="ticket next-ticket">
         <div style="text-align: center; position: relative">
-          <div class="noprint" style="position: absolute">
-            <a-button type="primary" @click="addHeatNo">添加炉号</a-button>
+          <div class="noprint" style="position: absolute; z-index: 100">
+            <a-button v-if="!isConfirmOrgData && !isEditAbled" type="primary" @click="addHeatNo">添加炉号</a-button>
+            <a-button
+              v-if="isConfirmOrgData"
+              type="primary"
+              @click="
+                () => {
+                  closeModal();
+                  openModal(true, {
+                    ccmNo: hostNumber,
+                    queryType: '2',
+                    shiftText: shiftInfoTxt.join('-'),
+                    curShiftInfo: shiftInfo,
+                    changeShiftId: fetchChangeShiftId,
+                  });
+                }
+              "
+              >送样卡</a-button
+            >
           </div>
           <p style="font-size: 24px; font-weight: 800; display: inline-block; margin-bottom: 16px; line-height: 30px">
             <span class="ccmno">{{ hostNumber }}</span> #机推钢室生产原始记录
@@ -103,10 +120,13 @@
           </template>
         </a-table>
       </div>
+
+      <div style="position: absolute; top: 0; left: 0; width: 100%; height: 100%" v-if="isConfirmOrgData || isEditAbled"> </div>
     </section>
 
     <template #appendFooter>
-      <a-button @click="openJSModal = true"> 重量计算 </a-button>
+      <a-button @click="openJSModal = true" v-if="!isConfirmOrgData && !isEditAbled"> 重量计算 </a-button>
+      <a-button type="primary" v-if="isConfirmOrgData && !isEditAbled" @click="handlerConfirmOrgData"> 确认无误 </a-button>
     </template>
   </BasicModal>
   <a-modal
@@ -154,9 +174,6 @@
         <a-input-number
           size="large"
           v-model:value="item.totalCount"
-          :addon-before="
-            headText[item.hotChargeDestination] + ' ' + Number(item.hotChargeLength) / 1000 + 'm ' + ' ' + (item.hotChargeBtype === '0' ? '热' : '冷')
-          "
           :min="0"
           :step="4"
           @change="
@@ -170,7 +187,20 @@
             }
           "
           :controls="false"
-        ></a-input-number>
+        >
+          <template #addonBefore>
+            <div :style="{ color: item.hotChargeBtype === '0' ? '#f50' : '#108ee9' }">
+              {{
+                headText[item.hotChargeDestination] +
+                ' ' +
+                Number(item.hotChargeLength) / 1000 +
+                'm ' +
+                ' ' +
+                (item.hotChargeBtype === '0' ? '热' : '冷')
+              }}
+            </div>
+          </template>
+        </a-input-number>
       </div>
       <div style="font-size: 16px; color: #f50">注:请输入4或4的倍数.</div>
     </div>
@@ -182,6 +212,9 @@
       <a-input size="large" v-model:value="newHeatNo"></a-input>
     </div>
   </a-modal>
+
+  <!-- 打印钢坯送样卡 -->
+  <print-billet-sample-card @register="registerPrintModal" />
 </template>
 <script lang="ts" setup>
   import { ref, computed, h } from 'vue';
@@ -197,9 +230,15 @@
   import { throttle } from 'lodash-es';
   import { useMessage } from '/@/hooks/web/useMessage';
   import { initDictOptions } from '/@/utils/dict';
+  import printBilletSampleCard from './printBilletSampleCard.vue';
+  import { useModal } from '/@/components/Modal';
+
+  // 注册打印送样卡modal
+  const [registerPrintModal, { openModal }] = useModal();
 
   const { createMessage } = useMessage();
   const printKey = ref(dayjs().unix());
+  const isEditAbled = ref(false); // 是否可编辑
   // 渲染字典标签
   const renderDictTag = (value: string, dictCode: string) => {
     return render.renderDict(value, dictCode);
@@ -217,13 +256,13 @@
     {
       title: '炉号',
       dataIndex: 'heatNo',
-      width: 80,
+      // width: 80,
       align: 'center',
       key: 'heatNo',
     },
     {
       title: '钢种',
-      width: 80,
+      // width: 80,
       align: 'center',
       dataIndex: 'brandNum',
       key: 'brandNum',
@@ -369,7 +408,7 @@
                   dataIndex: 'newSize',
                   key: 'newSize',
                   align: 'center',
-                  width: 100,
+                  // width: 100,
                   customRender({ text, record }) {
                     if (!record.heatNo) {
                       return '';
@@ -387,7 +426,7 @@
           ),
         ]);
       },
-      width: 100,
+      // width: 100,
       align: 'center',
       dataIndex: 'rollOne',
       key: 'rollOne',
@@ -401,7 +440,7 @@
       dataIndex: 'total',
       key: 'total',
       align: 'center',
-      width: 100,
+      // width: 100,
       customRender({ text, record }) {
         if (!record.heatNo) {
           return '';
@@ -417,13 +456,15 @@
   const shiftInfoTxt = ref(['', '']);
   const shiftInfo = ref({ shift: '', shiftGroup: '' });
   const curTime = ref(dayjs().format('YYYY-MM-DD'));
+  // 确认上一个班次的原始数据
+  const isConfirmOrgData = ref(false);
   //表单赋值
   const fetchQueryType = ref(1);
   const fetchChangeShiftId = ref('');
   // 定尺
   const sizeListOPtions = ref([]);
-  const [registerModal, { changeOkLoading, changeLoading }] = useModalInner(async (data) => {
-    const { ccmNo, shiftText, queryType, curShiftInfo, changeShiftId, time } = data;
+  const [registerModal, { changeOkLoading, changeLoading, closeModal }] = useModalInner(async (data) => {
+    const { ccmNo, shiftText, queryType, curShiftInfo, changeShiftId, time, confirmOrgData } = data;
     printKey.value = dayjs().unix();
 
     hostNumber.value = ccmNo;
@@ -431,6 +472,7 @@
     fetchChangeShiftId.value = changeShiftId;
     shiftInfoTxt.value = shiftText.split('-');
     shiftInfo.value = curShiftInfo;
+    isConfirmOrgData.value = !!confirmOrgData;
     if (time) {
       curTime.value = time;
     }
@@ -501,12 +543,13 @@
   const getHeatList = async (params) => {
     try {
       changeLoading(true);
-      const { billetOriginalProductRecordList, content, sizeInfo } = await queryBilletRecordByCcmNo(params);
+      const { billetOriginalProductRecordList, content, sizeInfo, confirmStatus } = await queryBilletRecordByCcmNo(params);
       let newArr: any[] = [];
       mainOrgSize.value = sizeInfo || '';
       mainSize.value = sizeInfo || '';
       mainRemark.value = content || '';
       mainOrgRemark.value = content || '';
+      isEditAbled.value = confirmStatus === 2;
       if (billetOriginalProductRecordList && Array.isArray(billetOriginalProductRecordList)) {
         // 根据时间排序
         newArr = billetOriginalProductRecordList.sort((a, b) => {
@@ -581,7 +624,7 @@
                       dataIndex: 'newSize',
                       key: 'newSize',
                       align: 'center',
-                      width: 100,
+                      // width: 100,
                       customRender({ text, record }) {
                         if (!record.heatNo) {
                           return '';
@@ -601,7 +644,7 @@
           },
           dataIndex: 'stackLength',
           key: 'stackLength',
-          width: 100,
+          // width: 100,
           children: [],
         };
 
@@ -611,7 +654,7 @@
             title: '棒二',
             dataIndex: 'roll_club_two',
             key: 'roll_club_two',
-            width: 100,
+            // width: 100,
             children: [],
           },
           // 棒三字段
@@ -619,7 +662,7 @@
             title: '棒三',
             dataIndex: 'roll_club_three',
             key: 'roll_club_three',
-            width: 100,
+            // width: 100,
             children: [],
           },
           // 上若字段
@@ -627,7 +670,7 @@
             title: '上若',
             dataIndex: 'roll_out_shipp',
             key: 'roll_out_shipp',
-            width: 100,
+            // width: 100,
             children: [],
           },
         };
@@ -885,7 +928,27 @@
         const otherColumns = Object.keys(columnsHotCharge)
           .filter((item) => columnsHotCharge[item].length)
           .map((item) => {
-            const childSizesColumn = [...new Set(columnsHotCharge[item])].map((childItem) => {
+            const hotChargeSizeArr = [...new Set(columnsHotCharge[item])];
+            const niubiGls: any[] = [];
+            hotChargeSizeArr.forEach((ele) => {
+              niubiGls.push(
+                {
+                  hotChargeLength: Number(ele) * 1000,
+                  hotChargeDestination: item,
+                  totalWeight: 0,
+                  hotChargeBtype: '0',
+                  totalCount: 0,
+                },
+                {
+                  hotChargeLength: Number(ele) * 1000,
+                  hotChargeDestination: item,
+                  totalWeight: 0,
+                  hotChargeBtype: '1',
+                  totalCount: 0,
+                }
+              );
+            });
+            const childSizesColumn = hotChargeSizeArr.map((childItem) => {
               return {
                 title: childItem,
                 dataIndex: `${item}.${childItem}`,
@@ -895,23 +958,35 @@
                 customRender: ({ record }) => {
                   const hotKey = childItem + item + '0';
                   const coldKey = childItem + item + '1';
-                  if (!record[hotKey] && !record[coldKey]) return '';
-                  const sizeArr = [h('div', { class: 'line' }, ''), h('div', { class: 'size-st-item' }, record[hotKey] || '~')];
+                  let sizeArr: any = [];
+                  if (record[hotKey] || record[coldKey]) {
+                    sizeArr = [h('div', { class: 'line' }, ''), h('div', { class: 'size-st-item' }, record[hotKey] || '~')];
+                    sizeArr.push(h('div', { class: ' size-st-num' }, record[coldKey] || '~'));
+                  }
 
-                  sizeArr.push(h('div', { class: ' size-st-num' }, record[coldKey] || '~'));
                   return h(
                     'div',
                     {
                       class: 'size-st-wrapper',
                       onClick: () => {
-                        if (!record[hotKey] && !record[coldKey]) return;
-
+                        // if (!record[hotKey] && !record[coldKey]) return;
                         const { orgData } = record;
-                        if (!orgData || !orgData.hotChargeLength) return;
+                        if (!orgData) return;
                         const { hotChargeLength } = orgData;
+
+                        const hotChargeInfoArr = hotChargeLength ? JSON.parse(hotChargeLength) : [];
+
+                        const itemsHotArr = niubiGls.map((v) => {
+                          const hasVal = hotChargeInfoArr.find((j) => j.hotChargeLength == v.hotChargeLength && j.hotChargeBtype == v.hotChargeBtype);
+                          return {
+                            ...v,
+                            totalCount: hasVal ? hasVal.totalCount : 0,
+                          };
+                        });
+
                         editSizeNumRecord.value = {
                           ...orgData,
-                          hotChargeLengthArr: JSON.parse(hotChargeLength),
+                          hotChargeLengthArr: itemsHotArr,
                         };
                         openSetSizeNumModal.value = true;
                       },
@@ -921,7 +996,7 @@
                 },
               };
             });
-            otherColumnsNums += childSizesColumn.length;
+            otherColumnsNums = otherColumnsNums + (childSizesColumn.length ? childSizesColumn.length : 1);
             return {
               ...hotChargeColumns[item],
               children: childSizesColumn,
@@ -931,7 +1006,13 @@
         columns.value = [...defaultColumns, ...otherColumns, ...[stackLengthColumn], ...totalColum];
         const rollOneIndex = defaultColumns.findIndex((ele: any) => ele.dataIndex === 'rollOne');
         (columns.value[rollOneIndex] as any).children = rollOneColumns.length ? rollOneColumns : [];
-        const allSpan = 4 + rollOneColumns.length + otherColumnsNums + stackLengthColumn.children.length;
+
+        // 计算列,合并
+        const allSpan =
+          4 +
+          (rollOneColumns.length ? rollOneColumns.length : 1) +
+          otherColumnsNums +
+          (stackLengthColumn.children.length ? stackLengthColumn.children.length : 1);
         remakeColSpan.value = Math.ceil(allSpan / 3);
         const nnColSpan = Math.ceil((allSpan - remakeColSpan.value) / 2);
         const newNNColSpan = nnColSpan % 2 === 0 ? nnColSpan : nnColSpan + 1;
@@ -939,22 +1020,30 @@
         flowColSpan.value = newNNColSpan - sizeColSpan.value;
         weightColSpan.value = allSpan - remakeColSpan.value - newNNColSpan;
 
+        let allWeight = 0;
         // 热送统计
         if (Object.values(rollOneSize).length) {
           hotSendList.value['一'] = Object.values(rollOneSize);
+          hotSendList.value['一'].forEach((ele) => (allWeight += ele.weight));
         }
         if (Object.values(rollTwoSize).length) {
           hotSendList.value['二'] = Object.values(rollTwoSize);
+          hotSendList.value['二'].forEach((ele) => (allWeight += ele.weight));
         }
         if (Object.values(rollThreeSize).length) {
           hotSendList.value['三'] = Object.values(rollThreeSize);
+          hotSendList.value['三'].forEach((ele) => (allWeight += ele.weight));
         }
         if (Object.values(rollShippSize).length) {
           hotSendList.value['上'] = Object.values(rollShippSize);
+          hotSendList.value['上'].forEach((ele) => (allWeight += ele.weight));
         }
         if (Object.values(stackingSize)) {
           stackingList.value = Object.values(stackingSize);
+          stackingList.value.forEach((ele) => (allWeight += ele.weight));
         }
+
+        mainRemark.value = `合计:${allWeight.toFixed(3)} t`;
       }
       changeLoading(false);
     } catch (error) {
@@ -983,12 +1072,12 @@
   // 修改合计
   const handleTotalChange = throttle((e: any, record) => {
     const val = Number(e.target.value);
-    if (!isNumber(val) || val <= 0) {
-      createMessage.error('请输入数字');
+    if (!isNumber(val) || val < 0) {
+      createMessage.error('请输入大于0数字');
       return;
     }
-    if (record.total !== val) {
-      const { orgData } = record;
+    const { orgData } = record;
+    if (Number(orgData.amount) != val) {
       handleEdit({
         ...orgData,
         amount: val,
@@ -1410,6 +1499,22 @@
     });
   }, 500);
 
+  // 确认上一个班次的原始数据
+  const handlerConfirmOrgData = async () => {
+    try {
+      changeLoading(true);
+      await handleEditShiftInfo({
+        id: fetchChangeShiftId.value,
+        confirmStatus: 2,
+      });
+      closeModal();
+      changeLoading(false);
+    } catch (e) {
+      console.log(e);
+      changeLoading(false);
+    }
+  };
+
   // 编辑定尺和备注
   const handleEditShiftInfo = async (params) => {
     try {
@@ -1447,6 +1552,7 @@
         ccmNo: hostNumber.value,
         heatNo: newHeatNo.value,
       });
+      openNewHeatNo.value = false;
 
       await getHeatList({
         ccmNo: hostNumber.value,
@@ -1583,24 +1689,31 @@
             bottom: 1px;
             font-weight: 600;
             cursor: pointer;
+            overflow: hidden;
 
             .line {
-              content: '';
+              // content: '';
+              // position: absolute;
+              // top: 0;
+              // left: 0;
+              // width: 100%; /* 等于长方形宽度 */
+              // height: 100%; /* 等于长方形高度 */
+
+              // /* 创建斜线:线性渐变从左上到右下 */
+              // background: linear-gradient(
+              //   to bottom right,
+              //   transparent 0%,
+              //   transparent calc(50% - 0.5px),
+              //   /* 斜线上方透明 */ rgba(0, 0, 0, 0.6) calc(50% - 0.5px),
+              //   /* 斜线颜色 */ rgba(0, 0, 0, 0.6) calc(50% + 0.5px),
+              //   /* 斜线厚度 */ transparent calc(50% + 0.5px) /* 斜线下方透明 */
+              // );
               position: absolute;
-              top: 0;
-              left: 0;
-              width: 100%; /* 等于长方形宽度 */
-              height: 100%; /* 等于长方形高度 */
-
-              /* 创建斜线:线性渐变从左上到右下 */
-              background: linear-gradient(
-                to bottom right,
-                transparent 0%,
-                transparent calc(50% - 0.5px),
-                /* 斜线上方透明 */ rgba(0, 0, 0, 0.6) calc(50% - 0.5px),
-                /* 斜线颜色 */ rgba(0, 0, 0, 0.6) calc(50% + 0.5px),
-                /* 斜线厚度 */ transparent calc(50% + 0.5px) /* 斜线下方透明 */
-              );
+              left: -5px;
+              top: 50%;
+              width: 110%;
+              border-bottom: 1px solid rgba(0, 0, 0, 0.6);
+              transform: rotate(165deg);
             }
 
             .size-st-item {

+ 5 - 0
src/views/billet/operator/components/useOrgData.ts

@@ -0,0 +1,5 @@
+export function useOrgData(options?: any) {
+  const {} = options ?? {};
+
+  return {};
+}

+ 123 - 5
src/views/billet/operator/index.vue

@@ -13,11 +13,21 @@
             type="primary"
             style="margin-right: 20px"
             size="large"
+            danger
             @click="
-              () => openPrintOriginalRecordsModal(true, { ccmNo, queryType: '1', shiftText, curShiftInfo, changeShiftId: curShiftInfo.changeShiftId })
+              () =>
+                openPrintOriginalRecordsModal(true, {
+                  ccmNo,
+                  queryType: '2',
+                  shiftText,
+                  curShiftInfo: curShiftInfo.lastShiftInfo ? curShiftInfo.lastShiftInfo : curShiftInfo,
+                  changeShiftId: curShiftInfo.lastShiftInfo ? curShiftInfo.lastShiftInfo.id : '',
+                  time: curShiftInfo.lastShiftInfo ? curShiftInfo.lastShiftInfo.changeShiftTime : '',
+                  confirmOrgData: true,
+                })
             "
           >
-            原始记录
+            {{ lastShiftText }} 确认记录
           </a-button>
           <a-button type="primary" size="large" @click="() => openModal(true, { ccmNo, queryType: '1', shiftText, curShiftInfo })"> 送样卡 </a-button>
         </div>
@@ -35,7 +45,7 @@
         <head-top @onShiftChange="curShiftChange" ref="headTopRef" @lengthChange="(v, auto) => ((lengthList = v), (cuttolength = auto))" />
         <div class="operator-content-wrapper flex">
           <div class="operator-content-left">
-            <heat-list
+            <!-- <heat-list
               ref="heatListRef"
               v-if="curShiftInfo.shift && curShiftInfo.shiftGroup"
               :ccmNo="ccmNo"
@@ -44,6 +54,18 @@
               :cuttolength="cuttolength"
               @changeLengthSuccess="() => headTopRef && headTopRef.reload()"
               :curShiftInfo="curShiftInfo"
+            /> -->
+            <org-data
+              ref="heatListRef"
+              v-if="curShiftInfo.shift && curShiftInfo.shiftGroup"
+              :openData="{
+                ccmNo,
+                queryType: '1',
+                shiftText,
+                curShiftInfo,
+                changeShiftId: curShiftInfo.changeShiftId,
+              }"
+              @statistics="handleStatistics"
             />
           </div>
           <div class="operator-content-right">
@@ -87,7 +109,8 @@
   import { useTimeoutFn } from '/@/hooks/core/useTimeout';
   import headTop from './components/headTop.vue';
   import car from './components/car.vue';
-  import heatList from './components/heatList.vue';
+  // import heatList from './components/heatList.vue';
+  import orgData from './components/orgData.vue';
   import { getMachineNum, getMachineDict } from '../hotDelivery/common.data';
   import { changeShift } from '../hotDelivery/hotDelivery.api';
   import { useMessage } from '/@/hooks/web/useMessage';
@@ -110,10 +133,12 @@
   const heatListRef = ref();
   // 班次信息
   const shiftText = ref('');
-  const curShiftInfo = ref({
+  const lastShiftText = ref('');
+  const curShiftInfo = ref<any>({
     shift: undefined,
     shiftGroup: undefined,
     changeShiftId: undefined,
+    lastShiftInfo: null,
   });
   // 时钟
   const clockObj = ref({
@@ -146,9 +171,102 @@
       const { shift, shiftGroup } = shiftInfo;
       shiftText.value = `${getMachineDict(shift, 'lg_bb')} - ${getMachineDict(shiftGroup, 'lg_bz')}`;
     }
+    if (shiftInfo.lastShiftInfo) {
+      const { shift, shiftGroup } = shiftInfo.lastShiftInfo;
+      lastShiftText.value = `${getMachineDict(shift, 'lg_bb')} - ${getMachineDict(shiftGroup, 'lg_bz')}`;
+    }
     curShiftInfo.value = shiftInfo;
   };
 
+  let defaultDtlList: any = [
+    { title: '棒一', titleColor: '#f50', amount: 0, weight: 0, dtlList: [] },
+    { title: '冷装', titleColor: '#108ee9', amount: 0, weight: 0, dtlList: [] },
+    { title: '热装', titleColor: '#f50', amount: 0, weight: 0, dtlList: [] },
+    { title: '堆垛', titleColor: '#b8ceff', amount: 0, weight: 0, dtlList: [] },
+  ];
+  // 统计改变
+  const handleStatistics = (data) => {
+    const { stackingList, hotSendList, chargeList } = data;
+
+    // 总支数
+    let allNums = 0;
+    // 总重量
+    let allWeight = 0;
+
+    let oneTotal = 0;
+    let oneWeight = 0;
+    let oneDtlList = hotSendList.map((item) => {
+      allNums += item.amount;
+      allWeight += item.weight;
+      oneTotal += item.amount;
+      oneWeight += item.weight;
+      return {
+        ...item,
+        nums: item.amount,
+      };
+    });
+    defaultDtlList[0].amount = oneTotal;
+    defaultDtlList[0].weight = oneWeight;
+    defaultDtlList[0].dtlList = oneDtlList;
+
+    let clodChargeTotal = 0;
+    let clodChargeWeight = 0;
+    let clodChargeDtlList = Object.keys(chargeList['1']).map((k) => {
+      const item = chargeList['1'][k];
+      clodChargeTotal += item.amount;
+      clodChargeWeight += item.weight;
+      allNums += item.amount;
+      allWeight += item.weight;
+      return {
+        ...item,
+        nums: item.amount,
+      };
+    });
+    defaultDtlList[1].amount = clodChargeTotal;
+    defaultDtlList[1].weight = clodChargeWeight;
+    defaultDtlList[1].dtlList = clodChargeDtlList;
+
+    let hotChargeTotal = 0;
+    let hotChargeWeight = 0;
+    let hotChargeDtlList = Object.keys(chargeList['0']).map((k) => {
+      const item = chargeList['0'][k];
+      hotChargeTotal += item.amount;
+      hotChargeWeight += item.weight;
+      allNums += item.amount;
+      allWeight += item.weight;
+      return {
+        ...item,
+        nums: item.amount,
+      };
+    });
+    defaultDtlList[2].amount = hotChargeTotal;
+    defaultDtlList[2].weight = hotChargeWeight;
+    defaultDtlList[2].dtlList = hotChargeDtlList;
+
+    let stackTotal = 0;
+    let stackWeight = 0;
+    const stackList = stackingList.map((item) => {
+      stackTotal += item.amount;
+      stackWeight += item.weight;
+      allNums += item.amount;
+      allWeight += item.weight;
+      return {
+        ...item,
+        nums: item.amount,
+      };
+    });
+    defaultDtlList[3].amount = stackTotal;
+    defaultDtlList[3].weight = stackWeight;
+    defaultDtlList[3].dtlList = stackList;
+
+    headTopRef.value &&
+      headTopRef.value.setTypeList({
+        dtlList: defaultDtlList,
+        allNums,
+        allWeight,
+      });
+  };
+
   // 交班
   const newShiftGroup = ref('');
   const openJiaobanModal = ref(false);

+ 7 - 0
src/views/billet/operator/operator.api.ts

@@ -38,6 +38,8 @@ enum Api {
   addHeatNo = '/billet/billetOriginalProductRecord/add',
   // 编辑原始数据定尺和备注
   editOriginalProductRecord = '/billetHotsend/billetHotsendChangeShift/editOriginalProductRecord',
+  // 获取堆垛信息
+  queryBilletStackInfoByCcmNo = '/billet/billetOriginalProductRecord/queryBilletStackInfoByCcmNo',
 }
 
 // 炉次信息
@@ -132,3 +134,8 @@ export const addBilletNo = (params: any) => {
 export const editOriginalProductRecord = (params: any) => {
   return defHttp.post({ url: Api.editOriginalProductRecord, params });
 };
+
+// 获取堆垛信息
+export const getStackInfoByCcmNo = (params: any) => {
+  return defHttp.get({ url: Api.queryBilletStackInfoByCcmNo, params });
+};