干燥机配套车间生产管理系统/云平台前端
baoshiwei
2023-06-07 34ff338ff4d6575f9a25457286b3a5aad6b8823b
src/views/dry/monitor/WorkShop.vue
@@ -1,8 +1,7 @@
<template>
   <div class="workshop">
      <div class="eqp-row">
         <div v-for="(item, index) in eqps" :key="index">
            <div class="eqp-card">
         <div class="eqp-card" v-for="(item, index) in eqps" :key="index">
               <div class="eqp-content">
                  <div class="chart">
                        <div>
@@ -10,78 +9,84 @@
                           <div style=""> 
                              <div>加热</div>
                              <div></div> 
                           <span class="info-text">36</span> 分钟
                           <span class="info-text">{{ realTime.get(item.id)?.dryTime | 0 }}</span> 分钟
                           </div>
                     
                           <div style=" padding: 0 10px;width: 200px;height: 40px;">
                        <div style="padding: 0 10px; width: 200px; height: 40px">
                              <div style="padding-top: 10px">
                                    <Progress
                                       :stroke-color="{
                                          from: '#108ee9',
                                          to: '#87d068',
                                       }"
                                       :percent="55.9"
                                 :percent="realTime.get(item.id)?.percent"
                                       status="active"
                                       :show-info="false">
                                 </Progress>
                                 :show-info="false"
                              />
                              </div>
                           </div>
                        
                           <div>
                              <div>预计 </div> 
                              <div><span class="info-text">90</span>  分钟
                           <div
                              ><span class="info-text">{{ (realTime.get(item.id)?.dryTime + realTime.get(item.id)?.remain) | 0 }}</span> 分钟
                              </div>   
                           </div>
                     </div>
                     <div style="height:50px; text-align: left; padding-left: 25px; display: flex;">
                     <div style="height: 50px; text-align: left; padding-left: 25px; display: flex">
                        <div class="herbInfo">
                           <div>药材:<span class="info-text">当归</span></div>
                           <div>投料:<span class="info-text">16</span> 筐</div>
                           <div
                              >药材:<span class="info-text">{{ realTime.get(item.id)?.herbName }}</span></div
                           >
                           <div
                              >投料:<span class="info-text">{{ realTime.get(item.id)?.feed | 0 }}</span> 筐</div
                           >
                        </div>
                        <div class="herbInfo">
                           <div>原始重量:<span class="info-text">160</span> Kg</div>
                           <div>实时重量:<span class="info-text">70</span> Kg</div>
                           <div
                              >原始重量:<span class="info-text">{{ realTime.get(item.id)?.originWeight | 0 }}</span> Kg</div
                           >
                           <div
                              >实时重量:<span class="info-text">{{ realTime.get(item.id)?.yield | 0 }}</span> Kg</div
                           >
                        </div>
                     </div>
                  </div>
                     
                     <div class="eqpStatus">
                        <div > <span class="info-text">运行</span>  </div>
                     <div> <span class="info-text">翻料</span> </div>
                     </div>
                  </div>
                  <!-- <div :id="'chartDom' + item.id" class="chart"> </div> -->
                  <div class="info">
                     <div class="leftInfo">
                     <div style="width: 120px">
                        <div style="height: 1px; font-size: 10px; text-align: center; margin-top: 10px; margin-bottom: -10px"
                           >初始:{{ realTime.get(item.id)?.initial }}%</div
                        >
                        <div :id="'moisture' + item.id" style="width: 110px; height: 187px"></div>
                        <div style="height: 1px; font-size: 10px; text-align: center; margin-top: -25px">目标:{{ realTime.get(item.id)?.target }}%</div>
                        <div style="width: 110px; text-align: center; margin-top: 23px">含水率</div>
                     </div>
                        <!-- <div class="herbName"> 当归 </div> -->
                        <div class="eqpName">{{ item.name }}</div>
                     <div style="flex: 1" @click="gotoEqp(item.id)"
                        ><div class="eqpName">{{ item.name }}</div></div
                     >
                     </div>
                     <div class="rightInfo">
                        <div style="width: 120px" >
                           <div style="    height: 1px;
    font-size: 10px;
    text-align: center;
    margin-top: 10px;
    margin-bottom: -10px; ">初始:{{ (mois[0] * 100).toFixed(2) }}%</div>
                           <div :id="'moisture' + item.id" style="width: 110px; height: 187px"></div>
                           <div style="height: 1px;
    font-size: 10px;
    text-align: center;
    margin-top: -25px;">目标:{{ (mois[2] * 100).toFixed(2) }}%</div>
                           <div style="    width: 110px;
    text-align: center;
    margin-top: 23px;">含水率</div>
                        </div>
                        <div class="tempChart"   style="pointer-events: none; cursor: none;"  :id="'tempDom' + item.id">
                           <a-slider v-model:value="tempValue"
                            :min="0" range :max="100" :marks="marks" vertical />
                            <div>热风:<span class="info-text">{{ tempValue[0] }}</span> °C</div>
                        </div>
                     <div class="tempChart" style="pointer-events: none; cursor: none" :id="'tempDom' + item.id">
                        <a-slider
                           v-if="realTime.get(item.id)"
                           v-model:value="realTime.get(item.id).tempValue"
                           :min="0"
                           range
                           :max="100"
                           :marks="marks"
                           vertical
                        />
                        <div
                           >热风:<span class="info-text">{{ realTime.get(item.id)?.windTemp | 0 }}</span> °C</div
                        >
                     </div>
                  </div>
               </div>
@@ -92,17 +97,22 @@
</template>
<script setup lang="ts">
   import { onMounted, ref } from 'vue'
   import { onMounted, ref, onUnmounted } from 'vue'
   import { Progress } from 'ant-design-vue'
   import * as echarts from 'echarts'
   import 'echarts-liquidfill'
   import { listAll } from '../api/DryEquipment.api'
   import { dryEquipment } from '../dataDefine/DryEquipment.data'
   import { router } from '/@/router'
   import { defHttp } from '/@/utils/http/axios'
   import { useUserStore } from '/@/store/modules/user'
   const eqps = ref([] as dryEquipment[])
   const mois = ref([0.3939,0.2112,0.11])
   const mois = ref([0, 0, 0])
   const userStore = useUserStore()
   const Timer = ref()
   const tempValue = ref(<Record<number, number>>([70, 100]))
   const realTime = ref(new Map())
   const marks = ref<Record<number, any>>({
      0: '0°C',
@@ -212,7 +222,8 @@
         .then((result) => {
            console.log(`output->result`, result)
            eqps.value = result
            setTimeout(initCharts, 1000)
            setTimeout(initCharts, 500)
            updateRealTime()
         })
         .catch((err) => {
            console.log(`output->err`, err)
@@ -310,7 +321,6 @@
//                   }
//                },
//                // {yAxis: 0},
//                // {yAxis: 100}
//             ]
@@ -320,8 +330,8 @@
//   ]
// };
const option = {
    series: [{
            series: [
               {
        type: 'liquidFill',
            radius: '100%',
            //waveAnimation: false,
@@ -329,42 +339,99 @@
        animationDuration: 5,
        //animationDurationUpdate: 0,
        data: mois.value,
            shape: 'path://M828.817,706.209C828.817,881.725,686.98,1024,512,1024c-174.98,0-316.817-142.275-316.817-317.791C195.183,530.74,512,0,512,0s316.817,530.74,316.817,706.209z',
                  shape:
                     'path://M828.817,706.209C828.817,881.725,686.98,1024,512,1024c-174.98,0-316.817-142.275-316.817-317.791C195.183,530.74,512,0,512,0s316.817,530.74,316.817,706.209z',
            outline: {
            show: false
                     show: false,
        },
            label: {
                     formatter: function () {
                        //console.log(`output->params`,params,mois.value)
               
               formatter: function(params) {
                  console.log(`output->params`,params,mois.value)
                  return ''
                        return (
                           '' +
                  // +'初始'+(mois.value[0]*100).toFixed(2) + '%\n\n\n' 
                  + (mois.value[1]*100).toFixed(2) + '%'
                           (mois.value[1] * 100).toFixed(2) +
                           '%'
                  // + '\n\n\n目标'+(mois.value[2]*100).toFixed(2) + '%'
                  ;
                        )
               },
               fontSize: 10,
               position: ['50%',(100-mois.value[1]*100).toFixed(2) + '%'],
                     //position: ['50%',(100-mois.value[1]*100).toFixed(2) + '%'],
                  },
               },
            ],
            }
    }]
};
          option && myChart.setOption(option)
          moistureCharts.set(item.id, myChart)
       })
    }
   function gotoEqp(id: string) {
      router.push('/dashboard/eqp/' + id)
   }
   function updateRealTime() {
      console.log(`output->定时刷新数据`)
      eqps.value.forEach((item) => {
         queryRealTime(item)
      })
   }
   function queryRealTime(eqp: dryEquipment) {
      let tenantId = userStore.getTenant
      let eqpCode = eqp.code
      let queryRealTimeUrl = '/dry/real/getRealTimeData'
      defHttp.get({ url: queryRealTimeUrl, params: { tenantid: tenantId, machineid: eqpCode } }).then((res) => {
         console.log(`output->res`, res)
         if (res && res.trendVo) {
            res.tempValue = [res.windTemp, 100]
            res.percent = ((res.dryTime / res.et) * 100).toFixed(2)
            res.mois = [
               (res.trendVo.moisture / 100).toFixed(2),
               (res.trendVo.moisture / 100 / 1.5).toFixed(2),
               (res.trendVo.moisture / 100 / 3).toFixed(2),
            ]
            moistureCharts.get(eqp.id)?.setOption({
               series: [
                  {
                     data: res.mois,
                     label: {
                        formatter: function () {
                           return res.trendVo.moisture + '%'
                        },
                        fontSize: 10,
                        //position: ['50%',(100- res.trendVo.moisture)+ '%'],
                     },
                  },
               ],
            })
         } else {
            res = {
               tempValue: [0, 100],
               percent: 0,
               mois: [],
            }
         }
         realTime.value.set(eqp.id, res)
      })
   }
   listAllEqp()
   // DOM挂载完成后渲染图表
   onMounted(() => {})
   onMounted(() => {
      Timer.value = setInterval(updateRealTime, 3000)
   })
   onUnmounted(() => {
      clearInterval(Timer.value)
      Timer.value = null
   })
</script>
<style>
<style scoped>
   .workshop {
   }
   .eqp-row {
@@ -376,6 +443,8 @@
      width: 566px;
      height: 400px;
      padding: 6px 6px;
      flex-grow: 0;
      flex-shrink: 0;
   }
   .eqp-content {
@@ -384,7 +453,7 @@
      background-image: url('../../../assets/images/dry/ganzaoji-x.png');
      background-repeat: no-repeat;
      background-size: 60% 60%;
      background-position: 10px 150px;
      background-position: 105px 150px;
      border-radius: 8px;
   }
@@ -395,30 +464,31 @@
      display: flex;
      text-align: center;
   }
   .progress {
   :deep() .progress {
      padding:25px 25px;
      width: 360px;
      display: flex;
   }
   .ant-progress-bg {
   :deep() .ant-progress-bg {
      height: 25px !important;
   }
   .eqpStatus {
      width:170px;
      background-position: 0 -10px;
      background-image: url('../../../assets/images/dry/ganzaoji.gif');
      background-size: 100% 100%;
      background-position: 0 0px;
      background-image: url('../../../assets/images/dry/refeng2.gif');
      background-size: 180px;
      background-repeat: no-repeat;
      display: inline-flex;
      flex-direction: column-reverse;
      padding: 15px;
   }
   .info {
      display: flex;
   }
   .leftInfo {
      width: 335px;
      width: 445px;
      display: flex;
      /* background: gray; */
   }
   .rightInfo {
@@ -445,16 +515,16 @@
   }
   .eqpName {
      margin-top: 68px;
      margin-left: 174px;
      margin-left: 150px;
      width: 95px;
      font-weight: bold;
      text-align: center;
      background-color: white;
      height: 22px;
   }
   .tempChart {
      padding-top: 10px;
      height: 150px;
      width: 100px;
@@ -463,11 +533,11 @@
   .herbInfo {
   width: 160px;
   }
   .ant-slider-mark-text {
   :deep() .ant-slider-mark-text {
      padding-left: 15px;
      font-size: 10px;
   }
   .ant-slider-mark-text::before {
   :deep() .ant-slider-mark-text::before {
      content: '';
      display: block;
      width: 6px;
@@ -478,30 +548,30 @@
      top: 10px;
      left: 0px;
   }
   .ant-slider-rail {
   :deep() .ant-slider-rail {
      width: 6px !important;
      border-radius: 6px 6px 0 0;
      background: linear-gradient(to top, #ce0000 0%, #ce0000 40%, #ce0000 75%, rgb(160, 160, 160) 100%);
   }
   .ant-slider-track {
   :deep() .ant-slider-track {
      background: rgb(175, 175, 175);
      height: 20px;
      width: 6px !important;
      border-radius: 6px 6px 0 0;
   }
   .ant-slider-track:hover {
   :deep() .ant-slider-track:hover {
   }
   .ant-slider-handle {
   :deep() .ant-slider-handle {
      display: none;
   }
   .ant-slider-dot {
   :deep() .ant-slider-dot {
      display: none;
   }
   .ant-slider-step {
   :deep() .ant-slider-step {
      width: 10px !important;
   }
   .ant-slider-step > :first-child {
   :deep() .ant-slider-step > :first-child {
      display: block !important;
      width: 22px !important;
      height: 22px !important;