瀏覽代碼

换炉操作;
堆垛换位置

zhangafei 3 周之前
父節點
當前提交
2542d01779

二進制
src/assets/images/billetHome/operator-head-bg.png


+ 88 - 7
src/views/billet/operator/components/car.vue

@@ -18,7 +18,13 @@
             <a-button
               type="primary"
               v-if="vehicleInfo['info' + item] && vehicleInfo['info' + item].id"
-              @click="() => openPrintModal(true, { record: vehicleInfo['info' + item] })"
+              @click="
+                () =>
+                  openPrintModal(true, {
+                    record: vehicleInfo['info' + item],
+                    typeConfigId: !vehicleInfo['info' + item].typeConfigId ? '1024' : vehicleInfo['info' + item].typeConfigId,
+                  })
+              "
               >打印</a-button
             >
           </div>
@@ -38,7 +44,7 @@
       </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">
+    <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>
@@ -73,7 +79,14 @@
           @click="handleStackClick(item)"
           :class="{ 'selected-row': selectedAddressId.includes(item.id) }"
         >
-          <div class="stack-col" :class="{ 'hemp-texture': !!item.steelBillet.length }">{{ item.heatNo }}</div>
+          <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>
@@ -86,7 +99,7 @@
   import printCarInfo from './printCarInfo.vue';
   import { useTimeoutFn } from '/@/hooks/core/useTimeout';
   import { list, edit } from '../../shippingBill/shippingBill.api';
-  import { getStackInfo, stackLoadSave } from '../../hotDelivery/hotDelivery.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';
@@ -109,8 +122,7 @@
 
   const activeKey = ref(1);
   const carPosition = {
-    // '5': [1, 2],
-    '5': [1],
+    '5': [1, 2],
     '6': [2, 3, 4],
   };
   // 车辆信息
@@ -329,6 +341,50 @@
     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 handleStackClick = (v) => {
     const index = selectedAddressId.value.indexOf(v.id);
     if (index > -1) {
@@ -437,6 +493,23 @@
       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 {
@@ -465,12 +538,20 @@
     .change-type {
       position: absolute;
       right: 22px;
-      top: -40px;
+      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 {

+ 91 - 0
src/views/billet/operator/components/changeHeatModal.vue

@@ -0,0 +1,91 @@
+<template>
+  <BasicModal
+    title="换炉信息确认"
+    :width="670"
+    :height="500"
+    :body-style="{ padding: '20px' }"
+    v-bind="$attrs"
+    @register="registerModal"
+    @ok="handleOk"
+    okText="换炉"
+    cancelText="关闭"
+  >
+    <a-form ref="formRef" :model="changeHeatModel" :label-col="{ span: 3 }" :wrapper-col="{ span: 21 }">
+      <a-form-item label="铸机" name="ccmNo" :rules="[{ required: true, message: '请选择铸机号' }]">
+        <JSearchSelect placeholder="请选择" disabled v-model:value="changeHeatModel.ccmNo" dict="lg_zj" defaultValue="5" />
+      </a-form-item>
+      <a-form-item label="炉号" name="heatNo" :rules="[{ required: true, message: '请输入炉号' }]">
+        <a-input v-model:value="changeHeatModel.heatNo" placeholder="请输入炉号" allowClear />
+      </a-form-item>
+      <a-form-item label="钢水重量" name="netWeight">
+        <a-input-number style="width: 100%" v-model:value="changeHeatModel.netWeight" placeholder="请输入钢水重量" />
+      </a-form-item>
+      <a-form-item label="钢包号" name="ladleNo">
+        <a-input-number style="width: 100%" :min="1" :step="1" :precision="0" v-model:value="changeHeatModel.ladleNo" placeholder="请输入钢包号" />
+      </a-form-item>
+      <a-form-item label="钢种" name="grade">
+        <a-input v-model:value="changeHeatModel.grade" placeholder="请输入钢种" allowClear />
+      </a-form-item>
+      <a-form-item label="开浇时间" name="startPourTime" :rules="[{ required: true, message: '请选择开浇时间' }]">
+        <a-date-picker
+          format="YYYY-MM-DD HH:mm:ss"
+          showTime
+          style="width: 100%"
+          v-model:value="changeHeatModel.startPourTime"
+          placeholder="请选择开浇时间"
+        />
+      </a-form-item>
+      <a-form-item label="规格" name="spec">
+        <a-input v-model:value="changeHeatModel.spec" placeholder="请输入规格" allowClear />
+      </a-form-item>
+    </a-form>
+  </BasicModal>
+</template>
+
+<script lang="ts" setup>
+  import { ref } from 'vue';
+  import { BasicModal, useModalInner } from '/@/components/Modal';
+  import JSearchSelect from '/@/components/Form/src/jeecg/components/JSearchSelect.vue';
+  import { furnaceChange } from '../operator.api';
+  import dayjs from 'dayjs';
+
+  const emit = defineEmits(['register', 'success']);
+
+  const changeHeatModel = ref<Record<string, any>>({});
+  //表单赋值
+  const [registerModal, { closeModal, changeLoading, changeOkLoading }] = useModalInner(async (data) => {
+    try {
+      changeHeatModel.value = {
+        ...data.record,
+        startPourTime: data.record.startPourTime ? dayjs(data.record.startPourTime) : dayjs(),
+        grade: data.record.grade ? data.record.grade : '复合钒钢',
+        spec: data.record.spec ? data.record.spec : '棒二Φ18-Φ22',
+      };
+    } catch (error) {
+      console.log(error);
+    }
+  });
+
+  const formRef = ref();
+  async function handleOk() {
+    console.log('handleOk', formRef.value);
+    try {
+      const values = await formRef.value.validate();
+      changeLoading(true);
+      changeOkLoading(true);
+
+      await furnaceChange(values);
+
+      changeLoading(false);
+      changeOkLoading(false);
+      changeHeatModel.value = {};
+      closeModal();
+      emit('success');
+    } catch (error) {
+      changeLoading(false);
+      changeOkLoading(false);
+    }
+  }
+</script>
+
+<style lang="less" scoped></style>

+ 56 - 17
src/views/billet/operator/components/headTop.vue

@@ -1,6 +1,8 @@
 <template>
   <a-row class="head-top">
-    <a-col :span="3" class="head-no bg flex items-center justify-center"> 浇铸炉号:{{ info.billetHotsendChangeShift.heatNo }} </a-col>
+    <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-statistic title="支数" :value="info.currentCastingFurnaceAmount || 0" />
     </a-col>
@@ -8,7 +10,7 @@
       <a-statistic title="重量/t" :value="info.currentCastingFurnace ? info.currentCastingFurnace.toFixed(3) : 0" />
     </a-col>
     <a-col :span="1" class="flex items-center justify-center">
-      <a-button type="primary" class="change-heat" :disabled="true" @click="switchHeatNo">换炉</a-button>
+      <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">
@@ -50,21 +52,28 @@
   >
     <div class="flex justify-center items-center" style="margin: 20px 0">
       <div>选择牌号:</div>
-      <JSearchSelect type="list" style="width: 117px" v-model:value="newBrandNum" dict="billet_spec" placeholder="请选择" allowClear />
+      <JSearchSelect type="list" style="width: 277px" v-model:value="newBrandNum" dict="billet_spec" placeholder="请选择" allowClear />
     </div>
   </a-modal>
+  <!-- 切换炉号确认 -->
+  <changeHeatModal @register="registerChangeHeatModal" @ok="() => {}" />
 </template>
 <script setup lang="ts">
   import { ref, h, onMounted, onUnmounted } from 'vue';
   import AStatistic from 'ant-design-vue/lib/statistic/Statistic';
   import { getOnDutyInfo, getTeamShift, getOnDutyDetail } from '../../Dashboard/dashboard.api';
   import { useTimeoutFn } from '/@/hooks/core/useTimeout';
-  import { switchSteel, furnaceChange } from '../operator.api';
+  import { switchSteel, returnFurnaceChange } from '../operator.api';
   import { useMessage } from '/@/hooks/web/useMessage';
   import JSearchSelect from '/@/components/Form/src/jeecg/components/JSearchSelect.vue';
   import { render } from '/@/utils/common/renderUtils';
+  import changeHeatModal from './changeHeatModal.vue';
+  import { useModal } from '/@/components/Modal';
+
+  const { createMessage } = useMessage();
 
-  const { createConfirm, createMessage } = useMessage();
+  // 注册打印modal
+  const [registerChangeHeatModal, { openModal: openChangeHeatModal }] = useModal();
 
   const emits = defineEmits(['shiftChange']);
 
@@ -166,20 +175,24 @@
   const { start, stop } = useTimeoutFn(getInfo, 5000);
 
   // 换炉
+  const changeHeatLoading = ref(false);
   const switchHeatNo = async () => {
-    createConfirm({
-      iconType: 'warning',
-      title: '确认换炉',
-      width: '460px',
-      content: () => {
-        return h('div', { style: { fontSize: '16px' } }, [h('span', null, `是否换炉`), h('span', null, `?`)]);
-      },
-      onOk: () => {
-        return furnaceChange({ ccmNo: props.ccmNo, heatNo: info.value.billetHotsendChangeShift.heatNo }).then(() => {
-          getInfo();
+    try {
+      if (!info.value.billetHotsendChangeShift.heatNo) return;
+      changeHeatLoading.value = true;
+      const heatInfo = await returnFurnaceChange({
+        heatNo: Number(info.value.billetHotsendChangeShift.heatNo) + 1,
+      });
+
+      if (heatInfo) {
+        openChangeHeatModal(true, {
+          record: { ...heatInfo, ccmNo: heatInfo.ccmNo || props.ccmNo },
         });
-      },
-    });
+      }
+      changeHeatLoading.value = false;
+    } catch (error) {
+      changeHeatLoading.value = false;
+    }
   };
 
   // 切换牌号
@@ -284,5 +297,31 @@
       background: #d9d9d9;
       color: #8a8a8a;
     }
+
+    .ant-badge {
+      width: 12px;
+      height: 12px;
+      line-height: 12px;
+      margin-right: 8px;
+      margin-top: -7px;
+
+      :deep(.ant-badge-status-dot) {
+        width: 12px;
+        height: 12px;
+        color: #00fb6f;
+        background-color: #00fb6f;
+      }
+    }
+
+    @keyframes antStatusProcessing {
+      0% {
+        transform: scale(0.8);
+        opacity: 0.8;
+      }
+      100% {
+        transform: scale(2.4);
+        opacity: 0.2;
+      }
+    }
   }
 </style>

+ 12 - 1
src/views/billet/operator/components/heatList.vue

@@ -59,7 +59,7 @@
       },
       columns,
       showIndexColumn: false,
-      canResize: false,
+      canResize: true,
       striped: true,
       showTableSetting: false,
       pagination: false,
@@ -308,11 +308,22 @@
       .ant-table-thead > tr > th:nth-child(10),
       .ant-table-thead > tr > th:nth-child(11) {
         color: #f50;
+        padding: 0;
       }
 
       .ant-table-tbody {
         font-size: 15px;
         font-family: 'Kingsoft_Cloud_Font';
+
+        & > tr > td:nth-child(6),
+        & > tr > td:nth-child(7),
+        & > tr > td:nth-child(8),
+        & > tr > td:nth-child(9),
+        & > tr > td:nth-child(10),
+        & > tr > td:nth-child(11) {
+          padding: 0 8px;
+          position: relative;
+        }
       }
 
       .ant-table-footer {

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

@@ -137,7 +137,7 @@
         id,
         ccmNo,
         heatNo,
-        typeConfigId,
+        typeConfigId: !typeConfigId ? '1024' : typeConfigId,
       });
 
       let newArr: any[] = [];

+ 8 - 1
src/views/billet/operator/operator.api.ts

@@ -6,11 +6,13 @@ enum Api {
   // 切换牌号
   switchSteel = '/shiftConfiguration/shiftConfiguration/switchSteel',
   // 换炉
-  furnaceChange = '/sys/billetHotsendBase/billetHotsendBase/furnaceChange',
+  furnaceChange = '/billetHotsendBase/billetHotsendBase/furnaceChange',
   // 热装
   addHotCharge = '/billetHotsendBase/billetHotsendBase/addHotCharge',
   // 起垛
   stackingUpAdd = '/billet/stackingAndLoadingVehicles/stackingUpAdd',
+  // 换炉信息
+  returnFurnaceChange = '/billetHotsendBase/billetHotsendBase/returnFurnaceChange',
 }
 
 // 炉次信息
@@ -37,3 +39,8 @@ export const addHotCharge = (params: any) => {
 export const stackingUpAdd = (params: any) => {
   return defHttp.post({ url: Api.stackingUpAdd, params });
 };
+
+// 换炉信息
+export const returnFurnaceChange = (params: any) => {
+  return defHttp.post({ url: Api.returnFurnaceChange, params });
+};

+ 10 - 10
src/views/billet/operator/operator.data.ts

@@ -2,10 +2,10 @@ import { h } from 'vue';
 import { BasicColumn } from '/@/components/Table';
 import { render } from '/@/utils/common/renderUtils';
 
-const renderNum = (num, weight, backArr?: boolean) => {
-  let arr = [h('span', { style: { color: '#0085ff' } }, num)];
+const renderNum = (num, weight, backArr?: boolean, tag = 'div') => {
+  let arr = [h(tag, { style: { color: '#0085ff' } }, num)];
   if (weight !== null) {
-    arr.push(h('span', {}, '/' + weight.toFixed(2)));
+    arr.push(h(tag, {}, (tag === 'span' ? '/' : '') + weight.toFixed(2)));
   }
   if (backArr === true) {
     return arr;
@@ -20,8 +20,8 @@ const renderStrandCell = (num, lengthJsonStr) => {
       console.log('lengthJson', lengthJson);
       const lengthKeys = Object.keys(lengthJson);
       if (lengthKeys.length) {
-        return h('div', { style: { textAlign: 'left' } }, [
-          h('div', { style: { color: '#f50' } }, num),
+        return h('div', { style: { textAlign: 'left', padding: '20px 0 0' } }, [
+          h('div', { style: { color: '#f50', position: 'absolute', top: '0px' } }, num),
           ...lengthKeys.map((key) => {
             return h('div', {}, [h('span', {}, Number(key) / 1000 + ': '), h('span', { style: { color: '#0085ff' } }, lengthJson[key])]);
           }),
@@ -134,7 +134,7 @@ export const columns: BasicColumn[] = [
   {
     title: '棒一',
     align: 'center',
-    width: 100,
+    width: 75,
     dataIndex: 'directRolling',
     customRender({ record }) {
       const { hotSend, directRolling } = record;
@@ -156,7 +156,7 @@ export const columns: BasicColumn[] = [
   {
     title: '热装',
     align: 'center',
-    width: 100,
+    width: 75,
     dataIndex: 'hotCharge',
     customRender({ record }) {
       const { hotCharge } = record;
@@ -173,7 +173,7 @@ export const columns: BasicColumn[] = [
   {
     title: '堆垛',
     align: 'center',
-    width: 100,
+    width: 75,
     dataIndex: 'stacking',
     customRender({ record }) {
       const { stacking } = record;
@@ -200,7 +200,7 @@ export const columns: BasicColumn[] = [
           let lengthCC: any[] = [];
           Object.keys(obj).forEach((key) => {
             // lengthCC.push(h('div', {},  key + ' : ' + obj[key].lengthTotalCount + ' / ' + obj[key].lengthTotalWeight.toFixed(2)));
-            const lengthStlArr = renderNum(obj[key].lengthTotalCount, null, true) as any[];
+            const lengthStlArr = renderNum(obj[key].lengthTotalCount, null, true, 'span') as any[];
             lengthCC.push(h('div', {}, [h('span', {}, Number(key) / 1000 + ': '), ...lengthStlArr]));
           });
           return h('div', { style: { fontSize: '12px', textAlign: 'left' } }, lengthCC);
@@ -212,7 +212,7 @@ export const columns: BasicColumn[] = [
   {
     title: '总计',
     align: 'center',
-    width: 100,
+    width: 75,
     dataIndex: 'totalInfo',
     customRender({ record }) {
       try {

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

@@ -104,7 +104,7 @@
         id,
         ccmNo,
         heatNo,
-        typeConfigId,
+        typeConfigId: !typeConfigId ? '1024' : typeConfigId,
       });
 
       let newArr: any[] = [];