Browse Source

6号机推钢室

zhangafei 2 weeks ago
parent
commit
14b7384c14

+ 4 - 4
.env.development

@@ -7,15 +7,15 @@ VITE_PUBLIC_PATH = /
 # 跨域代理,您可以配置多个 ,请注意,没有换行符
 # VITE_PROXY = [["/jeecgboot","http://192.168.1.53:9999"],["/upload","http://localhost:3300/upload"]]
 # VITE_PROXY = [["/jeecgboot","http://192.168.1.6:9999"],["/upload","http://localhost:3300/upload"]]
-# VITE_PROXY = [["/jeecgboot","http://192.168.0.119:9999"],["/upload","http://localhost:3300/upload"]]
-VITE_PROXY = [["/jeecgboot","http://123.57.213.14:9898"],["/upload","http://localhost:3300/upload"]]
+VITE_PROXY = [["/jeecgboot","http://192.168.0.119:9999"],["/upload","http://localhost:3300/upload"]]
+# VITE_PROXY = [["/jeecgboot","http://123.57.213.14:9898"],["/upload","http://localhost:3300/upload"]]
 
 #后台接口全路径地址(必填)
 # VITE_GLOB_DOMAIN_URL=http://localhost:9999
 # VITE_GLOB_DOMAIN_URL=http://192.168.1.6:9999
 # VITE_GLOB_DOMAIN_URL=http://192.168.1.53:9999
-# VITE_GLOB_DOMAIN_URL=http://192.168.0.119:9999
-VITE_GLOB_DOMAIN_URL=http://123.57.213.14:9898
+VITE_GLOB_DOMAIN_URL=http://192.168.0.119:9999
+# VITE_GLOB_DOMAIN_URL=http://123.57.213.14:9898
 
 
 

+ 12 - 0
src/views/billet/Dashboard/dashboard.api.ts

@@ -56,12 +56,15 @@ enum Api {
   // 棒一
   rollClubOneList = '/rollClubOne/rollClubOneList',
   confirmRecord = '/billet/billetOriginalProductRecord/confirmRecord',
+  // 高线
+  rollHeightList = '/rollHeight/rollHeightList',
   // 棒线工作台统计
   rollClubStatistics = '/billet/billetOriginalProductRecord/queryBilletStatisticsDetailByCcmNo',
   // 导出
   exportOneXlsUrl = '/rollClubOne/exportOneXls', // 棒一
   exportThreeXlsUrl = '/rollClubThreeDetails/exportThreeXls', // 棒三
   exportOutXlsUrl = '/rollOutShippDetails/exportOutXls', // 上若
+  exportHeightXlsUrl = '/rollHeight/exportHeightXls',
   // 撤销
   backStorageBill = '/storageBillPrint/storageBillPrint/withdrawPrint',
 }
@@ -70,6 +73,10 @@ export const exportOneExcel = () => {
   return Api.exportOneXlsUrl;
 };
 
+export const exportHeightExcel = () => {
+  return Api.exportHeightXlsUrl;
+};
+
 export const exportThreeExcel = () => {
   return Api.exportThreeXlsUrl;
 };
@@ -250,6 +257,11 @@ export const getRollClubOneList = (params: any) => {
   return defHttp.get({ url: Api.rollClubOneList, params }, { joinParamsToUrl: true });
 };
 
+// 得到高线
+export const getRollHeightList = (params: any) => {
+  return defHttp.get({ url: Api.rollHeightList, params }, { joinParamsToUrl: true });
+};
+
 // 确认
 export const confirmRollClubOne = (params: any) => {
   return defHttp.put({ url: Api.confirmRecord, params }, { joinParamsToUrl: true });

+ 32 - 0
src/views/billet/Dashboard/dashboard.data.ts

@@ -0,0 +1,32 @@
+export const Colors = [
+  '#FF3300', // 1. 熔炉核心红
+  '#0066FF', // 2. 淬火液蓝
+  '#FF4500', // 3. 钢坯初热
+  '#0088FF', // 4. 水淬深蓝
+  '#FF6A00', // 5. 锻造火花
+  '#00AAFF', // 6. 冷却斑点
+  '#FF8000', // 7. 钢水表面
+  '#00CCFF', // 8. 蒸汽淡蓝
+  '#FFAA00', // 9. 白炽金属
+  '#00FFFF', // 10. 极致冷光
+  '#FF0000', // 11. 纯熔岩红
+  '#33CCFF', // 12. 淬火雾气
+  '#FF5500', // 13. 高温氧化红
+  '#66BBFF', // 14. 钢锭冷光
+  '#FF9500', // 15. 金属反光
+  '#99AAFF', // 16. 蓝紫干涉
+  '#FF2A1A', // 17. 热渣红
+  '#4D8AFF', // 18. 深冷钢蓝
+  '#FF4D4D', // 19. 飞溅铁花
+  '#5A7BFF', // 20. 氧化蓝膜
+  '#FF0066', // 21. 淬火紫红
+  '#6A6BFF', // 22. 蓝紫过渡
+  '#FF1A00', // 23. 氧化初层
+  '#0077EE', // 24. 冷却池蓝
+  '#FF9900', // 25. 退火橙
+  '#00BBEE', // 26. 淬火青
+  '#FF6600', // 27. 熔融金属
+  '#33AAFF', // 28. 冷轧钢蓝
+  '#FF2200', // 29. 炉口红光
+  '#0088CC', // 30. 最终冷却
+];

+ 34 - 22
src/views/billet/Dashboard/rollingOne.vue

@@ -39,7 +39,7 @@
                     <div>明细:</div>
                     <div class="dtl flex-1 flex flex-wrap">
                       <div class="flex-dlt-item flex" v-for="ele in item.statisticsDetailsList">
-                        <div class="flex dtl-item bt-line" :style="{ color: sizeColor[ele.size] }">
+                        <div class="flex dtl-item bt-line font-weight" :style="{ color: sizeColor[ele.size] }">
                           <span class="nums">{{ ele.size }}:&nbsp;&nbsp;&nbsp;{{ ele.nums }} 支</span>
                         </div>
                         <div class="flex dtl-item">
@@ -95,7 +95,7 @@
                 <a-descriptions-item class="ticket-info-item" label="规格尺寸">
                   <!-- <a-select v-model:value="sizeValue" :options="sizeOptions" @change="getStartEnd" style="width: 100%" :bordered="false"></a-select> -->
                   <div
-                    class="line"
+                    class="line font-weight"
                     :class="[item.sizeValue !== ele.value ? 'noprint' : 'selected']"
                     :style="{ cursor: 'pointer', color: sizeColor[ele.size] }"
                     v-for="ele in item.sizeObj"
@@ -112,7 +112,7 @@
                 <a-descriptions-item class="ticket-info-item" label="合格支数">
                   <!-- {{ sizeValue && rollOneInfo.size[sizeValue] ? rollOneInfo.size[sizeValue] : '' }} -->
                   <div
-                    class="line"
+                    class="line font-weight"
                     :class="[item.sizeValue !== ele.value ? 'noprint' : 'selected']"
                     :style="{ cursor: 'pointer', color: sizeColor[ele.size] }"
                     v-for="ele in item.sizeObj"
@@ -185,7 +185,14 @@
 </template>
 <script setup lang="ts">
   import { onMounted, ref } from 'vue';
-  import { getRollClubOneList, confirmRollClubOne, getrollClubStatistics, exportOneExcel } from './dashboard.api';
+  import {
+    getRollClubOneList,
+    confirmRollClubOne,
+    getrollClubStatistics,
+    exportOneExcel,
+    getRollHeightList,
+    exportHeightExcel,
+  } from './dashboard.api';
   import dayjs, { Dayjs } from 'dayjs';
   import { useForm, BasicForm, FormSchema } from '/@/components/Form';
   import { Empty } from 'ant-design-vue';
@@ -194,9 +201,9 @@
   import { Pagination as APagination } from 'ant-design-vue';
   import { useUserStore } from '/@/store/modules/user';
   import { list } from '../ShiftPerformance/ShiftPerformance.api';
-  import { getTeamShift } from '../Dashboard/dashboard.api';
+  import { getTeamShift } from './dashboard.api';
   import { useMethods } from '/@/hooks/system/useMethods';
-  import { Colors } from '/@/utils/dict/DictColors';
+  import { Colors } from './dashboard.data';
 
   // 导入导出方法
   const { handleExportXlsx } = useMethods();
@@ -357,22 +364,20 @@
   // 获取列表
   const loading = ref(false);
   const destinationTxt = {
-    '3': '棒三',
-    '4': '上若',
+    '1': '棒一',
+    '5': '高线',
   };
   const getList = async () => {
     try {
       const values = getFieldsValue();
       let params: any = Object.assign({}, values, { destination: destinationTxt[machineNum] });
-      if (!values.ccmNo) {
-        values.ccmNo = '5';
-      }
+      values.ccmNo = machineNum == '1' ? '5' : '6';
       loading.value = true;
 
       if (!values.arrivalTime) {
         params = Object.assign({}, values, {
           // arrivalTime: dateObj.value.format('YYYY-MM-DD 00:00:00'),
-          // destination: destinationTxt[machineNum],
+          destination: destinationTxt[machineNum],
         });
       }
 
@@ -383,17 +388,18 @@
       }
 
       loading.value = true;
-      const res = await getRollClubOneList({ pageNo: currentPage.value, pageSize: pageLimit.value, ...params, changeShiftId });
+      const fetchFn = machineNum == '1' ? getRollClubOneList : getRollHeightList;
+      const res = await fetchFn({ pageNo: currentPage.value, pageSize: pageLimit.value, ...params, changeShiftId });
 
       totalPage.value = res.total;
       currentPage.value = res.current;
       threeList.value = (res.records || []).map((item) => {
         const {
           heatNoDetails,
-          storageCenterHeatNoInvoicing: { rollClubOneDetails },
+          storageCenterHeatNoInvoicing: { rollClubOneDetails, rollHeightDetails },
         } = item;
 
-        const { sizeDetails, confirmTime, id, brandNum } = rollClubOneDetails;
+        const { sizeDetails, confirmTime, id, brandNum } = rollClubOneDetails ? rollClubOneDetails : rollHeightDetails;
 
         const sizeObj = {};
         sizeDetails.forEach((item) => {
@@ -445,7 +451,7 @@
   const getStatistics = async () => {
     try {
       const values = getFieldsValue();
-      let params: any = Object.assign({}, values, { queryType: '1', ccmNo: '5' });
+      let params: any = Object.assign({}, values, { queryType: '1', ccmNo: machineNum == '1' ? '5' : '6' });
       // 班次
       let changeShiftId = undefined;
       if (currentShift.value !== -1) {
@@ -462,7 +468,7 @@
       let statisticsDetailsList5: any[] = [];
 
       res.billetStatisticList.forEach((element, index) => {
-        sizeColor.value[element.size] = Colors[index] ? Colors[index][0] : '#f50';
+        sizeColor.value[element.size] = Colors[index] ? Colors[index] : '#f50';
         statisticsDetailsList5.push({ ...element, nums: element.amountTotal, blankOutput: element.blankOutput.toFixed(4) });
         totalObj[5].blankOutput += element.blankOutput;
         totalObj[5].nums += element.amountTotal;
@@ -493,7 +499,6 @@
 
   // 获取班次信息
   const getShiftInfo = async (pageSize: number = 3, date?: Dayjs) => {
-    const formVals = getFieldsValue();
     try {
       if (date && !date.isValid()) {
         shiftPerformanceColumns.value = [];
@@ -505,7 +510,7 @@
       const createTime_begin = date ? date.subtract(1, 'day').format('YYYY-MM-DD 23:55:00') : undefined;
       const createTime_end = date ? date.add(1, 'day').format('YYYY-MM-DD 00:05:00') : undefined;
       const res = await list({
-        ccmNo: formVals.ccmNo || '5',
+        ccmNo: machineNum == '1' ? '5' : '6',
         pageNo: 1,
         pageSize: pageSize,
         column: 'createTime',
@@ -539,12 +544,12 @@
   // 导出
   const onExportXls = () => {
     const values = getFieldsValue();
-    let params = Object.assign({}, values, { ccmNo: '5' });
+    let params = Object.assign({}, values, { ccmNo: machineNum == '1' ? '5' : '6' });
     if (currentShift.value >= 0) {
       params = {
         changeShiftId: shiftPerformanceColumns.value[currentShift.value].id,
         queryDate: values.queryDate,
-        ccmNo: '5',
+        ccmNo: machineNum == '1' ? '5' : '6',
       };
     }
 
@@ -553,7 +558,10 @@
       .map((key) => {
         return `${key}=${params[key]}`;
       });
-    return handleExportXlsx('棒一数据', exportOneExcel() + (queryParams.length > 0 ? '?' + queryParams.join('&') : ''));
+
+    const exportExlUrl = machineNum == '1' ? exportOneExcel() : exportHeightExcel();
+    const exportExlTitle = machineNum == '1' ? '棒一数据' : '高线数据';
+    return handleExportXlsx(exportExlTitle, exportExlUrl + (queryParams.length > 0 ? '?' + queryParams.join('&') : ''));
   };
 
   onMounted(() => {
@@ -758,5 +766,9 @@
         transform: translateX(-30px);
       }
     }
+
+    .font-weight {
+      font-weight: 700;
+    }
   }
 </style>

+ 18 - 4
src/views/billet/Dashboard/rollingThree.vue

@@ -10,7 +10,7 @@
                 handleReSubmit();
               }
             "
-            dict="lg_zj"
+            :options="getZjOptions"
           />
         </template>
 
@@ -84,7 +84,8 @@
         <a-row :gutter="[16, 8]">
           <a-col class="gutter-row" v-for="item in threeList" :key="item.id">
             <div class="ticket next-ticket" :class="{ disabled: !!item.confirmTime, 'back-disabled': item.withdrawStatus === 1 }">
-              <div class="ticket-op-w flex" v-if="!isAuth">
+              <!-- 如果是棒三 就只有 gp 账号 和bangsan3 账号 有权限编辑 -->
+              <div class="ticket-op-w flex" v-if="machineNum != '3' || (isAuthGpAndBangsan && machineNum == '3')">
                 <div class="ticket-op flex-1">
                   <a-button
                     :disabled="!!item.confirmTime || item.withdrawStatus === 1"
@@ -210,7 +211,7 @@
   </a-modal>
 </template>
 <script setup lang="ts">
-  import { onMounted, ref } from 'vue';
+  import { computed, onMounted, ref } from 'vue';
   import {
     getStorageBillPrintList,
     saveStorageBillPrint,
@@ -243,10 +244,23 @@
   const { createMessage } = useMessage();
 
   const isAuth = userStore.userInfo && userStore.userInfo.username === '5';
+  const isAuthGpAndBangsan = userStore.userInfo && (userStore.userInfo.username === 'gp' || userStore.userInfo.username === 'bangsan3');
 
   const threeList = ref<any[]>([]);
   const machineNum = getMachineNum(true) || '3';
 
+  const getZjOptions = computed(() => {
+    // { label: '5#机', value: '5' },
+    // { label: '6#机', value: '6' },
+    let zjOptions = machineDicts['lg_zj'];
+    const userInfo = userStore.userInfo;
+    if (userInfo && ['5', '6'].includes(userInfo.username)) {
+      zjOptions = machineDicts['lg_zj'].filter((item) => item.value == userInfo.username) || [];
+    }
+    console.log('zjOptions', zjOptions);
+    return zjOptions;
+  });
+
   // 注册打印modal
   const [registerPrintModal, { openModal: openPrintModal }] = useModal();
   // 渲染字典标签
@@ -263,7 +277,7 @@
       field: 'ccmNo',
       label: '铸机',
       component: 'Input',
-      defaultValue: '5',
+      defaultValue: userStore.userInfo && userStore.userInfo.username == '6' ? '6' : '5',
       componentProps: {
         dictCode: 'lg_zj',
       },

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

@@ -1,10 +1,10 @@
 <template>
   <a-spin :spinning="isSpinning" wrapperClassName="car-info-spin">
     <div type="card">
-      <div :key="item" v-for="item in carPosition[ccmNo]">
+      <div :key="item" style="margin-bottom: 20px" v-for="item in carPosition[ccmNo]">
         <div class="car-wei" :class="`car-wei-${item}`">
           <span class="num">{{ '车位' + item }}</span>
-          <!-- <a-button size="large" type="primary" style="font-size: 18px; margin-left: 6px">创建装运单</a-button> -->
+          <a-button size="large" type="primary" style="font-size: 18px; margin-left: 6px" @click="createChargeBill(item)">创建装运单</a-button>
         </div>
         <div class="car-info-wrapper">
           <div class="licensePlate"
@@ -55,56 +55,102 @@
         <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-tabs
+      v-model:activeKey="stackActiveKey"
+      @change="
+        (v) => {
+          const index = stackList.findIndex((item) => item.id == v);
+          stackInfo = stackList[index];
+          getStackInfoList(v);
+        }
+      "
+    >
+      <a-tab-pane :key="item.id" :tab="item.typeName" v-for="item in stackList">
+        <div
+          v-if="stackingObj[stackActiveKey] && stackingObj[stackActiveKey].length"
+          class="stacking-wrapper selected-divider flex flex-wrap"
+          id="operatorCC-stacking-wrapper"
         >
-          堆垛装车
-        </a-button>
-        <a-button style="background-color: #f5f5f5; color: #838383" v-else disabled>堆垛装车</a-button>
-      </div> -->
-    </div>
-    <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
+            class="selected-divider-row flex flex-col"
+            :id="`stackLayer${pitem.heatNo}`"
+            v-for="pitem in stackingObj[stackActiveKey]"
+            :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>
-      </div>
-    </div>
+        <a-empty v-else />
+      </a-tab-pane>
+
+      <template #rightExtra>
+        <!-- <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> -->
+        <a-button size="large" type="primary" style="font-size: 18px" @click="refresh(2)"> 刷新 </a-button>
+      </template>
+    </a-tabs>
   </a-spin>
   <!-- 打印 -->
   <printModal @register="registerPrintModal" />
+  <!-- 快速创建装运单 -->
+  <a-modal
+    v-model:open="openCreateChargeBill"
+    title="创建装运单"
+    centered
+    width="400px"
+    ok-text="确认"
+    :okButtonProps="{ loading: okLoading }"
+    cancel-text="取消"
+    @ok="confirmCreateChargeBill"
+    @cancel="
+      () => {
+        openCreateChargeBill = false;
+      }
+    "
+  >
+    <div class="flex justify-center items-center" v-if="createChargeBillPositionNum == 2" style="margin: 20px 0">
+      <div>选择铸机:</div>
+      <JSearchSelect type="list" style="width: 277px" v-model:value="createChargeBillCcmNo" dict="lg_zj" placeholder="请选择" allowClear />
+    </div>
+    <div class="flex justify-center items-center" style="margin: 20px 0">
+      <div>选择车辆:</div>
+      <JSearchSelect type="list" style="width: 277px" v-model:value="createChargeBillCar" dict="lg_car" placeholder="请选择" allowClear />
+    </div>
+  </a-modal>
 </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 { 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';
-  import { getStackInfoByCcmNo } from '../operator.api';
+  import { getStackInfoByCcmNo, quickCreateStorageBill } from '../operator.api';
+  import JSearchSelect from '/@/components/Form/src/jeecg/components/JSearchSelect.vue';
 
   // 注册打印modal
   const [registerPrintModal, { openModal: openPrintModal }] = useModal();
@@ -133,10 +179,12 @@
   const printCarInfoRefs = { infoRef1, infoRef2, infoRef3, infoRef4 };
 
   // 5号机堆垛
-  const stackingList = ref<any[]>([]);
   const stackingObj = ref<any>({});
   const stackInfo = ref<any>({});
 
+  const stackActiveKey = ref('10');
+  const stackList = ref<any[]>([]);
+
   // 车位1车辆信息
   // id: '',
   // licensePlate: '',
@@ -155,6 +203,15 @@
     info4: {},
   });
 
+  // 获取堆垛信息
+  const getStackInfo = async () => {
+    const machineConfig = await getMachineConfig(props.ccmNo)[MachineConfigType.STACKING];
+
+    stackInfo.value = machineConfig[0];
+    stackActiveKey.value = machineConfig[0].id;
+    stackList.value = machineConfig;
+  };
+
   const getInfo = async (type?: number | undefined) => {
     // 获取车位1车辆信息
     try {
@@ -176,9 +233,9 @@
 
         await Promise.all(fetchArr).then((res) => {
           if (Array.isArray(res)) {
-            res.forEach((item, index) => {
+            res.forEach((item) => {
               if (item.records[0]) {
-                vehicleInfo.value[`info${index + 1}`] = {
+                vehicleInfo.value[`info${item.records[0].positionNum}`] = {
                   ...item.records[0],
                   oldLicensePlate: item.records[0].licensePlate,
                   oldTypeConfigId: item.records[0].typeConfigId === '1024' ? undefined : item.records[0].typeConfigId,
@@ -188,20 +245,17 @@
                 };
               }
             });
-            setTimeout(() => {
-              printCarInfoRefs[`infoRef${activeKey.value}`] &&
-                printCarInfoRefs[`infoRef${activeKey.value}`].value &&
-                printCarInfoRefs[`infoRef${activeKey.value}`].value[0].getTableList();
-            }, 50);
+            // 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);
+        await getStackInfoList(stackActiveKey.value);
       }
     } catch (error) {
       console.log(error);
@@ -217,7 +271,8 @@
   // 获取当前堆垛信息
   const getStackInfoList = async (typeConfigId) => {
     const stackingInfo = await getStackInfoByCcmNo({ ccmNo: props.ccmNo, typeConfigId });
-    stackingList.value = stackingInfo || [];
+    // stackingList.value = stackingInfo || [];
+    stackingObj.value[typeConfigId] = stackingInfo || [];
   };
 
   // 修改类型
@@ -286,7 +341,6 @@
       },
       onOk: () => {
         let params = { ...vehicleInfo.value[`info${carPositon}`] };
-        console.log('11111111111111111111', params);
         if (type === 'destination') {
           const curDestination = destinationOptions[props.ccmNo].find((item) => item.value === value);
           params.destination = curDestination.label;
@@ -429,13 +483,53 @@
     return true;
   };
 
+  // 创建装车单
+  const openCreateChargeBill = ref(false);
+  const createChargeBillCcmNo = ref(props.ccmNo);
+  const createChargeBillPositionNum = ref(1);
+  const createChargeBillCar = ref(undefined);
+  const okLoading = ref(false);
+  const createChargeBill = async (pn) => {
+    openCreateChargeBill.value = true;
+    createChargeBillPositionNum.value = pn;
+    createChargeBillCcmNo.value = props.ccmNo;
+    createChargeBillCar.value = undefined;
+  };
+  const confirmCreateChargeBill = async () => {
+    try {
+      if (createChargeBillPositionNum.value == 2 && !createChargeBillCcmNo.value) {
+        createMessage.error('请选择铸机号!');
+        return;
+      }
+
+      if (!createChargeBillCar.value) {
+        createMessage.error('请选择车辆!');
+        return;
+      }
+
+      okLoading.value = true;
+      await quickCreateStorageBill({
+        ccmNo: createChargeBillCcmNo.value,
+        licensePlate: createChargeBillCar.value,
+        positionNum: createChargeBillPositionNum.value,
+      });
+
+      refresh(1);
+      openCreateChargeBill.value = false;
+      okLoading.value = false;
+    } catch (error) {
+      okLoading.value = false;
+    }
+  };
+
   // 刷新
-  const refresh = (type) => {
+  const refresh = (type?: number) => {
     stop();
     getInfo(type);
   };
 
   onMounted(() => {
+    getStackInfo();
     getInfo();
   });
 
@@ -484,6 +578,9 @@
       :deep(.ant-tabs-tab) {
         font-size: 16px;
         background: #01396c;
+        margin-left: 6px;
+        padding: 8px 12px;
+        border-radius: 6px 6px 0 0;
 
         &.ant-tabs-tab-active {
           background: #0085ff;
@@ -497,7 +594,6 @@
 
     .car-wei {
       height: 58px;
-      margin-top: 20px;
       font-size: 20px;
       color: #fff;
 
@@ -583,6 +679,8 @@
       border-radius: 2px;
       border: 1px solid #001966;
       padding: 6px;
+      margin-top: 0;
+      margin-bottom: 10px;
     }
 
     &.selected-divider .selected-divider-row .stacking-list-row {

+ 1 - 1
src/views/billet/operator/components/headTop.vue

@@ -289,7 +289,7 @@
     }
   };
 
-  const { start, stop } = useTimeoutFn(getInfo, 5000, true);
+  const { start, stop } = useTimeoutFn(getInfo, 5000);
 
   // 换炉
   const changeHeatLoading = ref(false);

+ 149 - 97
src/views/billet/operator/components/orgData.vue

@@ -144,7 +144,13 @@
 
   <!-- 新增炉号 -->
   <a-modal v-model:open="openNewHeatNo" title="新增炉次" centered width="500px" :zIndex="1000" @ok="confirmAddHeatNo">
-    <div style="padding: 60px 30px 30px; font-size: 16px">
+    <div style="padding: 30px; font-size: 16px">
+      <div class="flex" style="margin-bottom: 30px">
+        <span style="color: #f50; padding: 0 20px 0 0"> 添加</span>
+        <a-select class="flex-1" v-model:value="nextHeatNo" allowClear :options="getAddHeatNo" />
+        <span style="color: #f50; padding: 0 0 0 20px"> 之前</span>
+      </div>
+
       <a-input size="large" v-model:value="newHeatNo"></a-input>
     </div>
   </a-modal>
@@ -162,6 +168,7 @@
   import { useMessage } from '/@/hooks/web/useMessage';
   import { initDictOptions } from '/@/utils/dict';
   import { useTimeoutFn } from '/@/hooks/core/useTimeout';
+  import { getMachineConfig, MachineConfigType } from '../../hotDelivery/common.data';
 
   const emits = defineEmits(['statistics']);
 
@@ -191,13 +198,13 @@
     {
       title: '炉号',
       dataIndex: 'heatNo',
-      // width: 80,
+      width: 100,
       align: 'center',
       key: 'heatNo',
     },
     {
       title: '钢种',
-      // width: 80,
+      width: 80,
       align: 'center',
       dataIndex: 'brandNum',
       key: 'brandNum',
@@ -208,7 +215,7 @@
     {
       title: () => {
         return h('div', { style: { position: 'relative' } }, [
-          h('span', {}, '棒一'),
+          h('span', {}, props.openData && props.openData.ccmNo == '6' ? '高线' : '棒一'),
           h(
             'div',
             {
@@ -262,7 +269,7 @@
                   dataIndex: 'newSize',
                   key: 'newSize',
                   align: 'center',
-                  // width: 100,
+                  width: 100,
                   customRender({ text, record }) {
                     if (!record.heatNo) {
                       return '';
@@ -294,7 +301,7 @@
       dataIndex: 'total',
       key: 'total',
       align: 'center',
-      // width: 100,
+      width: 80,
       customRender({ text, record }) {
         if (!record.heatNo) {
           return '';
@@ -315,6 +322,15 @@
   const fetchChangeShiftId = ref('');
   // 定尺
   const sizeListOPtions = ref([]);
+
+  // 堆垛
+  const stackList = ref<any[]>([]);
+  // 获取堆垛信息
+  const getStackInfo = async (ccmNo) => {
+    const machineConfig = await getMachineConfig(ccmNo)[MachineConfigType.STACKING];
+    stackList.value = machineConfig;
+  };
+
   const isSpinning = ref(false);
   // 字段映射
   const headText = {
@@ -341,6 +357,7 @@
   }, 60000);
   onMounted(() => {
     initData(props.openData);
+    getStackInfo(props.openData.ccmNo);
   });
 
   let newSip: any[] = [];
@@ -462,85 +479,93 @@
         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',
+        let stackLengthColumn: any[] = stackList.value.map((stack) => {
+          return {
+            title: () => {
+              return h('div', { style: { position: 'relative' } }, [
+                h('span', {}, stack.typeName),
+                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' + stack.id);
+                      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),
                             },
-                            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) },
-                          ''
-                        );
-                      },
-                    });
+                            ''
+                          );
+                        },
+                        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, stack.id),
+                            },
+                            ''
+                          );
+                        },
+                      });
+                    },
                   },
-                },
-                h(Icon, { icon: 'ant-design:plus-square-outlined' }, '')
-              ),
-            ]);
-          },
-          dataIndex: 'stackLength',
-          key: 'stackLength',
-          width: 120,
-          children: [],
-        };
+                  h(Icon, { icon: 'ant-design:plus-square-outlined' }, '')
+                ),
+              ]);
+            },
+            dataIndex: 'stackLength' + stack.id,
+            key: 'stackLength' + stack.id,
+            width: 120,
+            children: [],
+          };
+        });
 
         const hotChargeColumns: any = {
           // 棒二字段
@@ -789,10 +814,15 @@
           if (stackLength) {
             const stackLeghtObj = JSON.parse(stackLength);
             stackLeghtObj.forEach((v) => {
+              // 初始化堆垛的定尺key
               const sSize = String(v.stackingLength);
-              const hasChild = stackLengthColumn.children.findIndex((ele) => ele.dataIndex === sSize + 'stackLength');
+              const stackKey = sSize + 'stackLength' + v.stackingBhtcId;
+              // 查找某一个堆垛 dataIndex='stackLength' + stackingBhtcId
+              const index = stackLengthColumn.findIndex((ele) => ele.dataIndex == 'stackLength' + v.stackingBhtcId);
+              const curStackChild = stackLengthColumn[index === -1 ? 0 : index].children;
+              const hasChild = curStackChild.findIndex((ele) => ele.dataIndex === stackKey);
               if (hasChild < 0) {
-                stackLengthColumn.children.push({
+                curStackChild.push({
                   title: () => {
                     return h('div', { class: 'rollOneColumnWrapper' }, [
                       h(
@@ -822,8 +852,8 @@
                       h('div', { class: 'noprint', onClick: () => deleteStackColumn(sSize) }, h(Icon, { icon: 'ant-design:delete-outlined' }, '')),
                     ]);
                   },
-                  dataIndex: sSize + 'stackLength',
-                  key: sSize + 'stackLength',
+                  dataIndex: stackKey,
+                  key: stackKey,
                   width: 80,
                   customRender({ text, record }) {
                     if (!record.heatNo) {
@@ -831,14 +861,20 @@
                     }
                     return h(
                       Input,
-                      { class: 'total-input', size: 'small', bordered: false, value: text, onBlur: (e) => handleStackChange(e, record, sSize) },
+                      {
+                        class: 'total-input',
+                        size: 'small',
+                        bordered: false,
+                        value: text,
+                        onBlur: (e) => handleStackChange(e, record, sSize, v.stackingBhtcId),
+                      },
                       ''
                     );
                   },
                 });
               }
 
-              stackSizeData[sSize + 'stackLength'] = v.stackingCount;
+              stackSizeData[stackKey] = v.stackingCount;
 
               // 给堆垛添加致谢
               if (!stackingSize[sSize]) {
@@ -954,16 +990,16 @@
             };
           });
 
-        columns.value = [...defaultColumns, ...otherColumns, ...[stackLengthColumn], ...totalColum];
+        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 stackColNums = stackLengthColumn.reduce((pre: any, cur: any) => {
+          return pre + (cur.children && cur.children.length ? cur.children.length : 1);
+        }, 0);
         // 计算列,合并
-        const allSpan =
-          4 +
-          (rollOneColumns.length ? rollOneColumns.length : 1) +
-          otherColumnsNums +
-          (stackLengthColumn.children.length ? stackLengthColumn.children.length : 1);
+        const allSpan = 4 + (rollOneColumns.length ? rollOneColumns.length : 1) + otherColumnsNums + stackColNums;
         remakeColSpan.value = Math.ceil(allSpan / 3);
         const nnColSpan = Math.ceil((allSpan - remakeColSpan.value) / 2);
         const newNNColSpan = nnColSpan % 2 === 0 ? nnColSpan : nnColSpan + 1;
@@ -1160,7 +1196,7 @@
   };
 
   // 修改堆垛定尺数量
-  const handleStackChange = throttle((e: any, record, size) => {
+  const handleStackChange = throttle((e: any, record, size, stackingId) => {
     if (e.target.value.trim() === '') return;
     if (!size) {
       createMessage.error('请选择定尺');
@@ -1179,7 +1215,7 @@
       obj = JSON.parse(stackLength);
     }
 
-    const lengthGroupCount = obj.findIndex((v) => v.stackingLength == size);
+    const lengthGroupCount = obj.findIndex((v) => v.stackingLength == size && v.stackingBhtcId == stackingId);
 
     // 计算补的数量是不是4的倍数
     let stackInfo: any = null;
@@ -1199,6 +1235,7 @@
         stackingCount: val,
         stackingLength: size,
         stackingWeight: val * (Number(size) / 1000) * 0.2265,
+        stackingBhtcId: stackingId,
       });
     } else {
       if (obj[lengthGroupCount].stackingCount === val) return;
@@ -1494,11 +1531,24 @@
 
   // 添加炉次
   const newHeatNo = ref('');
+  const nextHeatNo = ref(undefined);
   const openNewHeatNo = ref(false);
   const addHeatNo = () => {
     newHeatNo.value = '';
     openNewHeatNo.value = true;
   };
+
+  const getAddHeatNo = computed(() => {
+    return dataSource.value
+      .filter((o) => o.heatNo)
+      .map((t) => {
+        return {
+          label: t.SerialNumber + ' - ' + t.heatNo,
+          value: t.heatNo,
+        };
+      });
+  });
+
   const confirmAddHeatNo = async () => {
     try {
       if (!newHeatNo.value) {
@@ -1510,6 +1560,8 @@
       await addBilletNo({
         ccmNo: hostNumber.value,
         heatNo: newHeatNo.value,
+        changeShiftId: fetchChangeShiftId.value,
+        nextHeatNo: nextHeatNo.value,
       });
       openNewHeatNo.value = false;
 

+ 176 - 110
src/views/billet/operator/components/printOriginalRecords.vue

@@ -224,7 +224,13 @@
 
   <!-- 新增炉号 -->
   <a-modal v-model:open="openNewHeatNo" title="新增炉次" centered width="500px" :zIndex="1000" @ok="confirmAddHeatNo">
-    <div style="padding: 60px 30px 30px; font-size: 16px">
+    <div style="padding: 30px; font-size: 16px">
+      <div class="flex" style="margin-bottom: 30px">
+        <span style="color: #f50; padding: 0 20px 0 0"> 添加</span>
+        <a-select class="flex-1" v-model:value="nextHeatNo" allowClear :options="getAddHeatNo" />
+        <span style="color: #f50; padding: 0 0 0 20px"> 之前</span>
+      </div>
+
       <a-input size="large" v-model:value="newHeatNo"></a-input>
     </div>
   </a-modal>
@@ -248,6 +254,7 @@
   import { initDictOptions } from '/@/utils/dict';
   import printBilletSampleCard from './printBilletSampleCard.vue';
   import { useModal } from '/@/components/Modal';
+  import { getMachineConfig, MachineConfigType } from '../../hotDelivery/common.data';
 
   // 注册打印送样卡modal
   const [registerPrintModal, { openModal }] = useModal();
@@ -370,7 +377,7 @@
     {
       title: () => {
         return h('div', { style: { position: 'relative' } }, [
-          h('span', {}, '棒一'),
+          h('span', {}, hostNumber.value == '5' ? '棒一' : '高线'),
           h(
             'div',
             {
@@ -382,7 +389,6 @@
               },
               class: 'noprint',
               onClick: () => {
-                console.log('点击了');
                 const rollOnrColumn: any = columns.value.find((item: any) => item.dataIndex === 'rollOne');
                 let newSize: string | number = '';
                 rollOnrColumn.children.push({
@@ -479,22 +485,18 @@
   const fetchChangeShiftId = ref('');
   // 定尺
   const sizeListOPtions = ref([]);
-  const [registerModal, { changeOkLoading, changeLoading, closeModal }] = useModalInner(async (data) => {
-    const { ccmNo, shiftText, queryType, curShiftInfo, changeShiftId, time, confirmOrgData } = data;
-    printKey.value = dayjs().unix();
 
-    hostNumber.value = ccmNo;
-    fetchQueryType.value = queryType;
-    fetchChangeShiftId.value = changeShiftId;
-    shiftInfoTxt.value = shiftText.split('-');
-    shiftInfo.value = curShiftInfo;
-    isConfirmOrgData.value = confirmOrgData === true;
-    if (time) {
-      curTime.value = time;
-    }
+  // 堆垛
+  const stackList = ref<any[]>([]);
+  // 获取堆垛信息
+  const getStackInfo = async (ccmNo) => {
+    const machineConfig = await getMachineConfig(ccmNo)[MachineConfigType.STACKING];
+    stackList.value = machineConfig;
+  };
 
+  const getTotalRows = (num = 22) => {
     let newSip: any[] = [];
-    for (let index = 0; index < 22; index++) {
+    for (let index = 0; index < num; index++) {
       newSip.push({
         SerialNumber: index + 1,
         heatNo: '',
@@ -511,7 +513,27 @@
       });
     }
 
-    dataSource.value = [...newSip];
+    return newSip;
+  };
+
+  const [registerModal, { changeOkLoading, changeLoading, closeModal }] = useModalInner(async (data) => {
+    const { ccmNo, shiftText, queryType, curShiftInfo, changeShiftId, time, confirmOrgData } = data;
+    printKey.value = dayjs().unix();
+
+    // 获取堆垛信息
+    getStackInfo(ccmNo);
+
+    hostNumber.value = ccmNo;
+    fetchQueryType.value = queryType;
+    fetchChangeShiftId.value = changeShiftId;
+    shiftInfoTxt.value = shiftText.split('-');
+    shiftInfo.value = curShiftInfo;
+    isConfirmOrgData.value = confirmOrgData === true;
+    if (time) {
+      curTime.value = time;
+    }
+
+    dataSource.value = getTotalRows();
     getHeatList({
       ccmNo,
       queryType,
@@ -590,85 +612,93 @@
         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',
+        let stackLengthColumn: any[] = stackList.value.map((stack) => {
+          return {
+            title: () => {
+              return h('div', { style: { position: 'relative' } }, [
+                h('span', {}, stack.typeName),
+                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' + stack.id);
+                      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),
                             },
-                            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) },
-                          ''
-                        );
-                      },
-                    });
+                            ''
+                          );
+                        },
+                        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, stack.id),
+                            },
+                            ''
+                          );
+                        },
+                      });
+                    },
                   },
-                },
-                h(Icon, { icon: 'ant-design:plus-square-outlined' }, '')
-              ),
-            ]);
-          },
-          dataIndex: 'stackLength',
-          key: 'stackLength',
-          width: 120,
-          children: [],
-        };
+                  h(Icon, { icon: 'ant-design:plus-square-outlined' }, '')
+                ),
+              ]);
+            },
+            dataIndex: 'stackLength' + stack.id,
+            key: 'stackLength' + stack.id,
+            width: 120,
+            children: [],
+          };
+        });
 
         const hotChargeColumns: any = {
           // 棒二字段
@@ -704,7 +734,8 @@
           roll_out_shipp: [],
         };
 
-        dataSource.value = dataSource.value.map((item, index) => {
+        const totalRows = getTotalRows();
+        dataSource.value = totalRows.map((item, index) => {
           if (!newArr[index]) return item;
           const { hotChargeLength, rollClubOneDetails, stackLength } = newArr[index];
 
@@ -902,10 +933,15 @@
           if (stackLength) {
             const stackLeghtObj = JSON.parse(stackLength);
             stackLeghtObj.forEach((v) => {
+              // 初始化堆垛的定尺key
               const sSize = String(v.stackingLength);
-              const hasChild = stackLengthColumn.children.findIndex((ele) => ele.dataIndex === sSize + 'stackLength');
+              const stackKey = sSize + 'stackLength' + v.stackingBhtcId;
+              // 查找某一个堆垛 dataIndex='stackLength' + stackingBhtcId
+              const index = stackLengthColumn.findIndex((ele) => ele.dataIndex == 'stackLength' + v.stackingBhtcId);
+              const curStackChild = stackLengthColumn[index === -1 ? 0 : index].children;
+              const hasChild = curStackChild.findIndex((ele) => ele.dataIndex === stackKey);
               if (hasChild < 0) {
-                stackLengthColumn.children.push({
+                curStackChild.push({
                   title: () => {
                     return h('div', { class: 'rollOneColumnWrapper' }, [
                       h(
@@ -935,8 +971,8 @@
                       h('div', { class: 'noprint', onClick: () => deleteStackColumn(sSize) }, h(Icon, { icon: 'ant-design:delete-outlined' }, '')),
                     ]);
                   },
-                  dataIndex: sSize + 'stackLength',
-                  key: sSize + 'stackLength',
+                  dataIndex: stackKey,
+                  key: stackKey,
                   width: 100,
                   customRender({ text, record }) {
                     if (!record.heatNo) {
@@ -944,14 +980,20 @@
                     }
                     return h(
                       Input,
-                      { class: 'total-input', size: 'small', bordered: false, value: text, onBlur: (e) => handleStackChange(e, record, sSize) },
+                      {
+                        class: 'total-input',
+                        size: 'small',
+                        bordered: false,
+                        value: text,
+                        onBlur: (e) => handleStackChange(e, record, sSize, v.stackingBhtcId),
+                      },
                       ''
                     );
                   },
                 });
               }
 
-              stackSizeData[sSize + 'stackLength'] = v.stackingCount;
+              stackSizeData[stackKey] = v.stackingCount;
 
               // 给堆垛添加致谢
               if (!stackingSize[sSize]) {
@@ -1067,22 +1109,30 @@
             };
           });
 
-        columns.value = [...defaultColumns, ...otherColumns, ...[stackLengthColumn], ...totalColum];
+        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 stackColNums = stackLengthColumn.reduce((pre: any, cur: any) => {
+          return pre + (cur.children && cur.children.length ? cur.children.length : 1);
+        }, 0);
         // 计算列,合并
-        const allSpan =
-          4 +
-          (rollOneColumns.length ? rollOneColumns.length : 1) +
-          otherColumnsNums +
-          (stackLengthColumn.children.length ? stackLengthColumn.children.length : 1);
+        const allSpan = 4 + (rollOneColumns.length ? rollOneColumns.length : 1) + otherColumnsNums + stackColNums;
         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 ? 4 : newNNColSpan / 2;
         flowColSpan.value = newNNColSpan - sizeColSpan.value;
         weightColSpan.value = allSpan - remakeColSpan.value - newNNColSpan;
+        // console.log('列宽计算结果allSpan', allSpan);
+        // console.log('列宽计算结果stackColNums', stackColNums);
+        // console.log('列宽计算结果remakeColSpan.value', remakeColSpan.value);
+        // console.log('列宽计算结果nnColSpan', nnColSpan);
+        // console.log('列宽计算结果newNNColSpan', newNNColSpan);
+        // console.log('列宽计算结果sizeColSpan.value', sizeColSpan.value);
+        // console.log('列宽计算结果flowColSpan.value', flowColSpan.value);
+        // console.log('列宽计算结果weightColSpan.value', weightColSpan.value);
 
         let allWeight = 0;
         // 热送统计
@@ -1155,7 +1205,8 @@
       return;
     }
     const { orgData } = record;
-    if (Number(orgData.amount) != val) {
+    const allCount = handleTotalSum(orgData);
+    if (Number(orgData.amount) != val && allCount != val) {
       handleEdit({
         ...orgData,
         amount: val,
@@ -1264,7 +1315,7 @@
   };
 
   // 修改堆垛定尺数量
-  const handleStackChange = throttle((e: any, record, size) => {
+  const handleStackChange = throttle((e: any, record, size, stackingId) => {
     if (e.target.value.trim() === '') return;
     if (!size) {
       createMessage.error('请选择定尺');
@@ -1283,7 +1334,7 @@
       obj = JSON.parse(stackLength);
     }
 
-    const lengthGroupCount = obj.findIndex((v) => v.stackingLength == size);
+    const lengthGroupCount = obj.findIndex((v) => v.stackingLength == size && v.stackingBhtcId == stackingId);
 
     // 计算补的数量是不是4的倍数
     let stackInfo: any = null;
@@ -1303,6 +1354,7 @@
         stackingCount: val,
         stackingLength: size,
         stackingWeight: val * (Number(size) / 1000) * 0.2265,
+        stackingBhtcId: stackingId,
       });
     } else {
       if (obj[lengthGroupCount].stackingCount === val) return;
@@ -1614,11 +1666,23 @@
 
   // 添加炉次
   const newHeatNo = ref('');
+  const nextHeatNo = ref(undefined);
   const openNewHeatNo = ref(false);
   const addHeatNo = () => {
     newHeatNo.value = '';
     openNewHeatNo.value = true;
   };
+
+  const getAddHeatNo = computed(() => {
+    return dataSource.value
+      .filter((o) => o.heatNo)
+      .map((t) => {
+        return {
+          label: t.SerialNumber + ' - ' + t.heatNo,
+          value: t.heatNo,
+        };
+      });
+  });
   const confirmAddHeatNo = async () => {
     try {
       if (!newHeatNo.value) {
@@ -1630,6 +1694,8 @@
       await addBilletNo({
         ccmNo: hostNumber.value,
         heatNo: newHeatNo.value,
+        changeShiftId: fetchChangeShiftId.value,
+        nextHeatNo: nextHeatNo.value,
       });
       openNewHeatNo.value = false;
 

+ 6 - 1
src/views/billet/operator/index.vue

@@ -42,7 +42,12 @@
         </div>
       </a-layout-header>
       <a-layout-content class="operator-content">
-        <head-top @onShiftChange="curShiftChange" ref="headTopRef" @lengthChange="(v, auto) => ((lengthList = v), (cuttolength = auto))" />
+        <head-top
+          @onShiftChange="curShiftChange"
+          :ccmNo="ccmNo"
+          ref="headTopRef"
+          @lengthChange="(v, auto) => ((lengthList = v), (cuttolength = auto))"
+        />
         <div class="operator-content-wrapper flex">
           <div class="operator-content-left">
             <!-- <heat-list

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

@@ -40,6 +40,8 @@ enum Api {
   editOriginalProductRecord = '/billetHotsend/billetHotsendChangeShift/editOriginalProductRecord',
   // 获取堆垛信息
   queryBilletStackInfoByCcmNo = '/billet/billetOriginalProductRecord/queryBilletStackInfoByCcmNo',
+  // 快速创建装运单
+  quickCreateStorageBill = '/billet/billetOriginalProductRecord/addStorageBill',
 }
 
 // 炉次信息
@@ -139,3 +141,8 @@ export const editOriginalProductRecord = (params: any) => {
 export const getStackInfoByCcmNo = (params: any) => {
   return defHttp.get({ url: Api.queryBilletStackInfoByCcmNo, params });
 };
+
+// 快速创建装运单
+export const quickCreateStorageBill = (params: any) => {
+  return defHttp.put({ url: Api.quickCreateStorageBill, params }, { joinParamsToUrl: true });
+};

+ 2 - 1
src/views/billet/quality/index.vue

@@ -362,6 +362,7 @@
           ...(records[index] || {}),
           dayLength: dayLengthArr[index] || '',
           workLength: workLengthArr[index] || '',
+          deliveryTimeDate: dayjs(item.deliveryTime),
         };
       });
       setColumns(oldColumns);
@@ -493,7 +494,7 @@
   };
 
   onMounted(() => {
-    getShiftInfo(3, dayjs('2025-07-07'));
+    getShiftInfo(3, dayjs());
   });
 </script>
 <style lang="less" scoped>

+ 4 - 2
src/views/billet/quality/quality.data.ts

@@ -31,11 +31,13 @@ export const getTableColumns = ({ onTimeChange, onClickRemark, onBrandNumChange
     width: 120,
     align: 'center',
     customRender({ text, record }) {
+      console.log('2222222222222', record);
+      console.log('1111111111111', text, record.deliveryTimeDate.format('YYYY-MM-DD HH:mm:ss'));
       if (!record.heatNo) return '';
       return h(DatePicker, {
         bordered: false,
         showTime: true,
-        defaultValue: dayjs(text),
+        defaultValue: record.deliveryTimeDate,
         onChange(date) {
           onTimeChange && onTimeChange(date, record);
         },
@@ -149,7 +151,7 @@ export const getFormSchemas = ({ onDateChange }) => {
       label: '班次日期',
       field: 'queryDate',
       component: 'DatePicker',
-      defaultValue: dayjs('2025-07-07'),
+      defaultValue: dayjs(),
       componentProps: {
         valueFormat: 'YYYY-MM-DD',
         onChange: (v) => {