Переглянути джерело

增加堆垛可以修改位置;
调整工作台历史班次

zhangafei 1 місяць тому
батько
коміт
58df6ded75

+ 2 - 2
.env.development

@@ -6,13 +6,13 @@ VITE_PUBLIC_PATH = /
 
 # 跨域代理,您可以配置多个 ,请注意,没有换行符
 # VITE_PROXY = [["/jeecgboot","http://192.168.0.105:9999"],["/upload","http://localhost:3300/upload"]]
-VITE_PROXY = [["/jeecgboot","http://192.168.0.119:9999"],["/upload","http://localhost:3300/upload"]]
+VITE_PROXY = [["/jeecgboot","http://192.168.1.32:9999"],["/upload","http://localhost:3300/upload"]]
 
 #后台接口全路径地址(必填)
 # VITE_GLOB_DOMAIN_URL=http://localhost:9999
 # VITE_GLOB_DOMAIN_URL=http://192.168.0.105:8080/jeecg-boot
 # VITE_GLOB_DOMAIN_URL=http://192.168.6.24:8080/jeecg-boot
-VITE_GLOB_DOMAIN_URL=http://192.168.0.119:9999
+VITE_GLOB_DOMAIN_URL=http://192.168.1.32:9999
 
 
 

+ 42 - 15
src/views/billet/Dashboard/components/HistoricalSchedule.vue

@@ -39,7 +39,13 @@
       </template>
       <template #dateCellRender="{ current }">
         <div class="events-wrapper">
-          <div class="events-item" v-for="item in getListData(current)" :key="item.content" @click.stop="handleLookShift(item)">
+          <div
+            class="events-item"
+            v-for="item in getListData(current)"
+            :title="item.createTime + ' ~ ' + (item.changeShiftTime ? item.changeShiftTime : '此刻')"
+            :key="item.content"
+            @click.stop="handleLookShift(item)"
+          >
             <a-badge :status="item.badgeType" :text="item.shiftName" />
           </div>
         </div>
@@ -51,7 +57,9 @@
   import { onMounted, ref } from 'vue';
   import dayjs, { Dayjs } from 'dayjs';
   import { getChangeShiftList, getTeamShift } from '../dashboard.api';
+  import isBetween from 'dayjs/plugin/isBetween';
 
+  dayjs.extend(isBetween);
   const props = defineProps({
     ccmNo: {
       type: String,
@@ -104,6 +112,15 @@
       return;
     }
     oldDate.value = date.format('YYYY-MM');
+
+    // 处理选择的月份的天数
+    const daysInMonth = date.daysInMonth();
+    let dayObj: any = {};
+    for (let i = 1; i <= daysInMonth; i++) {
+      const dateStr = `${date.format('YYYY-MM')}-${i.toString().padStart(2, '0')}`;
+      dayObj[dateStr] = [];
+    }
+
     loading.value = true;
     getChangeShiftList({
       ccmNo: props.ccmNo,
@@ -111,20 +128,30 @@
     })
       .then((res) => {
         if (Array.isArray(res)) {
-          // 对数组按createTime进行分组
-          const groupedData = res.reduce((acc, cur) => {
-            const createTime = cur.createTime.split(' ')[0];
-            if (!acc[createTime]) {
-              acc[createTime] = [];
-            }
-            acc[createTime].push({
-              ...cur,
-              shiftName: getTeamShift(cur.shift, cur.shiftGroup, 1),
-            });
-            return acc;
-          }, {});
-
-          dateEvents.value = groupedData;
+          Object.keys(dayObj).forEach((key) => {
+            const curDate = dayjs(key);
+            const createTimeBegin = curDate.subtract(1, 'day').format('YYYY-MM-DD 23:50:00');
+            const createTimeEnd = curDate.add(1, 'day').format('YYYY-MM-DD 00:10:00');
+            const curDayArr = res
+              .filter(
+                (item) =>
+                  dayjs(item.createTime).isBetween(createTimeBegin, createTimeEnd) &&
+                  (!item.changeShiftTime || dayjs(item.changeShiftTime).isBetween(createTimeBegin, createTimeEnd))
+              )
+              .sort((a, b) => {
+                return dayjs(a.createTime).unix() - dayjs(b.createTime).unix();
+              })
+              .map((item) => {
+                return {
+                  ...item,
+                  shiftName: getTeamShift(item.shift, item.shiftGroup, 1),
+                };
+              });
+
+            dayObj[key] = curDayArr;
+          });
+
+          dateEvents.value = dayObj;
         }
       })
       .finally(() => {

+ 3 - 1
src/views/billet/Dashboard/components/WorkbenchHeader.vue

@@ -2,7 +2,9 @@
   <div class="workbench-header">
     <div class="workbench-header-top">
       <div class="workbench-header-top-title">
-        当班信息:<span class="txt">{{ getShiftInfo }}{{ duty ? `(${duty.createTime.split(' ')[0]})` : '' }}</span>
+        当班信息:<span class="txt"
+          >{{ getShiftInfo }}{{ duty ? `(${duty.createTime} ~ ${duty.changeShiftTime ? duty.changeShiftTime : '此刻'})` : '' }}</span
+        >
         <a-button v-if="duty" type="primary" size="small" class="back-shift" @click="() => $emit('change-shift', null)">当前班次</a-button>
       </div>
     </div>

+ 5 - 0
src/views/billet/hotDelivery/hotDelivery.api.ts

@@ -55,6 +55,8 @@ enum Api {
   queryCarHasStackBillet = '/stackingDownLog/stackingDownLog/queryByStorageBillId',
   // 导出接口
   exportXls = '/billetHotsendBase/billetHotsendBase/exportExcel',
+  // 堆垛更换位置
+  stackLocationChange = '/billet/stackingAndLoadingVehicles/stackLocationChange',
 }
 
 /**
@@ -165,3 +167,6 @@ export const addBilletHotsendInfo = (params) => defHttp.post({ url: Api.addBille
 
 // 查询车辆是否装运过堆垛信息
 export const getCarHasStackBillet = (params) => defHttp.get({ url: Api.queryCarHasStackBillet, params }, { joinParamsToUrl: true });
+
+// 堆垛更换位置
+export const stackLocationChange = (params) => defHttp.post({ url: Api.stackLocationChange, params });

+ 8 - 1
src/views/billet/shippingBill/components/detailsModal.vue

@@ -161,14 +161,21 @@
           acc.push({
             ...cur,
             billetNos: [cur.billetNo],
+            sizeList: cur.size ? [cur.size] : cur.length ? [cur.length] : [],
           });
         } else {
           acc[index].billetNos.push(cur.billetNo);
+          acc[index].sizeList.push(cur.size || cur.length);
         }
         return acc;
       }, []);
 
-      tableData.value = newArr;
+      tableData.value = newArr.map((ele) => {
+        return {
+          ...ele,
+          size: ele.sizeList.filter((item, index) => ele.sizeList.indexOf(item) === index).join(',\n\r') + ',',
+        };
+      });
     } catch (error) {
       console.log(error);
     } finally {

+ 2 - 1
src/views/billet/shippingBill/components/editForm.vue

@@ -56,7 +56,7 @@
         <a-col :span="12">
           <a-form-item label="定尺">
             <!-- <a-input v-model:value="model.size" placeholder="请输入" allowClear @input="(val) => formatFloatData(val, 'size')" /> -->
-            <JSearchSelect type="list" v-model:value="model.size" dict="lg_dcgg" placeholder="请选择" allowClear />
+            <JSelectMultiple type="list" v-model:value="model.size" dictCode="lg_dcgg" placeholder="请选择" allowClear />
           </a-form-item>
         </a-col>
         <a-col :span="12">
@@ -125,6 +125,7 @@
   import { ref } from 'vue';
   import { defHttp } from '/@/utils/http/axios';
   import JSearchSelect from '/@/components/Form/src/jeecg/components/JSearchSelect.vue';
+  import JSelectMultiple from '/@/components/Form/src/jeecg/components/JSelectMultiple.vue';
   // import { dictOptions } from '../shippingBill.data';
   import { queryBilletNameList } from '../../hotDelivery/hotDelivery.api';
   import { carPosition5, carPosition6 } from '../shippingBill.data';

+ 7 - 1
src/views/billet/shippingBill/components/printModal.vue

@@ -37,7 +37,7 @@
             <div v-for="item in headDtl" :key="item.id">{{ item.heatNo }} - {{ item.billetNos.length }}</div>
           </a-descriptions-item>
           <a-descriptions-item style="border: 1px solid #bfbfbf; font-size: 12px; padding: 4px; text-align: center; height: 36px" label="规格">
-            170 / {{ info.size }}
+            170 / {{ sizeInfo.join(',') }}
           </a-descriptions-item>
           <a-descriptions-item style="border: 1px solid #bfbfbf; font-size: 12px; padding: 4px; text-align: center; height: 36px" label="名称">
             方坯
@@ -77,6 +77,7 @@
   const info = ref<any>({});
   const headDtl = ref<any[]>([]);
   const weight = ref<number>(0);
+  const sizeInfo = ref<string[]>([]);
   //表单赋值
   const [registerModal, { changeLoading, changeOkLoading }] = useModalInner(async (data) => {
     const { record } = data;
@@ -118,6 +119,7 @@
       }
       let allWeight = 0;
 
+      let sizeArr: string[] = [];
       // 数据结果按组批号分组
       newArr = newArr.reduce((acc, cur) => {
         const index = acc.findIndex((item) => cur.heatNo && item.heatNo === cur.heatNo);
@@ -133,11 +135,15 @@
         if (cur.blankOutput) {
           allWeight += Number(cur.blankOutput);
         }
+        if (sizeArr.indexOf(cur.size) === -1) {
+          sizeArr.push(cur.size);
+        }
         return acc;
       }, []);
 
       headDtl.value = newArr;
       weight.value = allWeight;
+      sizeInfo.value = sizeArr;
     } catch (error) {
       console.log(error);
     } finally {

+ 193 - 0
src/views/billet/stackingManage/components/changePosition.vue

@@ -0,0 +1,193 @@
+<template>
+  <basic-modal
+    v-bind="$attrs"
+    @register="registerModal"
+    destroyOnClose
+    :title="modalTitle"
+    :height="900"
+    width="1400px"
+    ok-text="保存"
+    @ok="handleSubmit"
+    :ok-button-props="{ disabled: !curLayerSelectedAddress }"
+    @cancel="handleCancel"
+  >
+    <div class="stacking-modal">
+      <a-spin :spinning="isSpinning">
+        <div class="selected-divider">
+          <a-segmented v-model:value="activeKey" :options="stackingList" />
+          <a-row class="selected-divider-row" :gutter="[30, 20]">
+            <a-col :span="8" v-for="item in getSelectedData" class="p-stack-col">
+              <div class="weizhi">{{ item.address }}</div>
+              <a-row
+                justify="start"
+                class="stacking-list-row"
+                :class="{ 'selected-row': curLayerSelectedAddress === item.id }"
+                @click="handleStackClick(item)"
+              >
+                <a-col class="stack-col" :class="{ 'hemp-texture': !!item.steelBillet[0] }" :span="6">{{ item.steelBillet[0] || '' }}</a-col>
+                <a-col class="stack-col" :class="{ 'hemp-texture': !!item.steelBillet[1] }" :span="6">{{ item.steelBillet[1] || '' }}</a-col>
+                <a-col class="stack-col" :class="{ 'hemp-texture': !!item.steelBillet[2] }" :span="6">{{ item.steelBillet[2] || '' }}</a-col>
+                <a-col class="stack-col" :class="{ 'hemp-texture': !!item.steelBillet[3] }" :span="6">{{ item.steelBillet[3] || '' }}</a-col>
+              </a-row>
+            </a-col>
+          </a-row>
+          <div class="single-billet-wrap selected-divider-row" v-if="singleBillet == '1'">
+            <a-row justify="start" class="single-billet-row stacking-list-row">
+              <a-col class="stack-col hemp-texture" v-for="item in singleSelectBillers" :span="6">
+                {{ item.billetNo || '' }}
+              </a-col>
+            </a-row>
+          </div>
+        </div>
+      </a-spin>
+    </div>
+  </basic-modal>
+</template>
+
+<script lang="ts" setup>
+  import { computed, ref } from 'vue';
+  import { BasicModal, useModalInner } from '/@/components/Modal';
+  import { getStackInfo, stackLocationChange } from '/@/views/billet/hotDelivery/hotDelivery.api';
+  import ASegmented from 'ant-design-vue/es/segmented/src/segmented';
+  import { useMessage } from '/@/hooks/web/useMessage';
+
+  const { createMessage } = useMessage();
+
+  // Emits声明
+  const emit = defineEmits(['register', 'success']);
+  const modalTitle = ref('');
+  const record = ref<Record<string, any>>({});
+  // 当前铸机线信息
+  const activeKey = ref('1');
+  const stackingList = ref<any[]>([]);
+  const stackingInfoList = ref<Record<string, any>>({});
+  // 定尺
+  // 获取堆垛容器加载
+  const isSpinning = ref(false);
+  // 是否是单支钢坯进行棒线操作
+  const singleBillet = ref('4');
+  const singleSelectBillers = ref<any[]>([]);
+
+  //表单赋值
+  const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
+    try {
+      const { basicInfo } = data;
+      record.value = basicInfo;
+      modalTitle.value = `${basicInfo.layer}层${basicInfo.address}位置 - 更换位置`;
+
+      // 获取当前堆垛信息
+      getStackInfoList();
+    } catch (error) {
+      console.log(error);
+    }
+  });
+
+  // 获取当前堆垛信息
+  const getStackInfoList = async () => {
+    isSpinning.value = true;
+    const stackingInfo = await getStackInfo({ typeConfigId: record.value.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(',') : [] });
+      });
+    }
+    stackingInfoList.value = layerObj;
+    stackingList.value = Object.keys(layerObj)
+      .sort((a, b) => Number(a) - Number(b))
+      .map((item) => ({ label: `第${item}层`, value: item }));
+
+    const canShowLayer = stackingList.value.filter((item) => layerObj[item.value].some((item) => !!item.billetNos));
+    if (canShowLayer.length) {
+      activeKey.value = canShowLayer[canShowLayer.length - 1].value;
+    }
+    isSpinning.value = false;
+  };
+
+  // 返回选中的表格数据
+  const getSelectedData = computed(() => {
+    const key = activeKey.value;
+    const newData = stackingInfoList.value[key] ? stackingInfoList.value[key].sort((a, b) => Number(b.address) - Number(a.address)) : [];
+    return newData;
+  });
+
+  // 选中当前层的位置
+  const curLayerSelectedAddress = ref<string | number>('');
+  const handleStackClick = (item) => {
+    if (item.steelBillet.length || item.billetNos) return;
+
+    curLayerSelectedAddress.value = curLayerSelectedAddress.value === item.id ? '' : item.id;
+  };
+
+  const handleCancel = () => {
+    curLayerSelectedAddress.value = '';
+    closeModal();
+  };
+
+  //表单提交事件
+  async function handleSubmit() {
+    try {
+      if (!curLayerSelectedAddress.value) {
+        createMessage.warning('请选择位置');
+        return;
+      }
+      const params = {
+        stackId: record.value.id,
+        locationChangeId: curLayerSelectedAddress.value,
+      };
+      setModalProps({ confirmLoading: true });
+      //提交表单
+      await stackLocationChange(params);
+      //关闭弹窗
+      handleCancel();
+    } catch (e) {
+      console.log(e);
+    } finally {
+      setModalProps({ confirmLoading: false });
+      //刷新列表
+      emit('success');
+    }
+  }
+</script>
+
+<style lang="less" scoped>
+  @import '/@/views/billet/hotDelivery/components/metal.less';
+  .stacking-modal {
+    position: relative;
+
+    .group-zhishu {
+      margin-bottom: 20px;
+      margin-left: 20px;
+    }
+
+    .single-billet-wrap {
+      position: absolute;
+      top: -30px;
+      left: 0;
+      right: 0;
+      bottom: 0;
+      z-index: 10;
+      background: rgba(51, 51, 51, 0.45);
+      display: flex;
+      justify-content: center;
+      align-items: center;
+
+      .single-billet-row {
+        width: 30%;
+        height: 80px;
+        background: rgba(255, 255, 255, 0.8);
+        padding: 20px;
+
+        .delete {
+          position: absolute;
+          right: 2px;
+          top: -10px;
+          color: red;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+</style>

+ 12 - 0
src/views/billet/stackingManage/index.vue

@@ -71,6 +71,7 @@
                 <template #overlay v-if="item.billetNos">
                   <a-menu @click="menuClick($event, item)" style="min-width: 100px">
                     <a-menu-item key="1" style="background-color: #f56c6c; color: #fff; text-align: center">判废</a-menu-item>
+                    <a-menu-item key="2" style="background-color: #b7eb8f; color: #000; text-align: center; margin-top: 8px">更换位置</a-menu-item>
                   </a-menu>
                 </template>
               </a-dropdown>
@@ -84,6 +85,8 @@
     <stacking @register="registerStackingModal" :machine="machine" @success="handleSuccess" :machineConfigType="MachineConfigType.STACKING" />
     <!-- 堆垛判废 -->
     <wastes @register="registerWastesModal" :machine="machine" @success="handleSuccess" />
+    <!-- 堆垛位置更换 -->
+    <changePosition @register="registerChangePositionModal" :machine="machine" @success="handleSuccess" />
   </div>
 </template>
 <script setup lang="ts" name="stackManage">
@@ -95,6 +98,7 @@
   import { useModal } from '/@/components/Modal';
   import stacking from './components/stacking.vue';
   import wastes from './components/wastes.vue';
+  import changePosition from './components/changePosition.vue';
 
   const { createConfirm } = useMessage();
 
@@ -114,6 +118,8 @@
   const [registerStackingModal, { openModal: openStackingModal }] = useModal();
   // 堆垛判废
   const [registerWastesModal, { openModal: openWastesModal }] = useModal();
+  // 堆垛位置更换
+  const [registerChangePositionModal, { openModal: openChangePositionModal }] = useModal();
 
   // 根据铸机号获取配置信息
   const getMachineConfig = async (machineNum) => {
@@ -209,6 +215,12 @@
 
       return;
     }
+    if (e.key === '2') {
+      openChangePositionModal(true, {
+        basicInfo: info,
+      });
+      return;
+    }
   };
 
   const handleSuccess = () => {