loulijun2021
2024-05-06 fcac164d607958b8271e70b010376ab52a843ce1
src/views/kanbanManager/zhkb.vue
@@ -1,29 +1,26 @@
<template>
  <div>
    <div class="kb_dashboard">
      <!--    星空背景-->
      <div ref="starsRef" class="stars">
        <div v-for="(item, index) in starsCount" :key="index" class="star" />
      </div>
      <div class="kb_backgroundCustom" />
      <div class="kb_header">
        <div class="flex_c_c kb_header_text">
          <div id="topBarLeft" style="width:600px;height:100%" />
          车间综合数字化看板
          <div id="topBarRight" style="width:600px;height:100%;transform:rotate(180deg);" />
        <div class="kb_headTime" style="top: 35px;left:  20px">
          <span>浙江正清和日用制品有限公司</span>
        </div>
        <div class="kb_headTime" style="left: 85px">
          <span>浙江新凯迪数字科技股份有限公司</span>
        <div class="kb_headTime kb_header_text" style="top: 35px;" :style="{left:ShopArr[0]==='202'?'780px':'800px'}">
          <span>{{ title }}数字化看板</span>
        </div>
        <div class="kb_headTime">
        <div class="kb_headTime" style="top: 35px;right:  25px">
          <span>{{ headTime }}</span>
        </div>
      </div>
      <div style="display: flex;justify-content: space-between;padding:0 20px 20px 20px">
      <div style="display: flex;justify-content: space-between;padding:0 20px 20px 20px;">
        <!--       左边-->
        <div style="width: 1400px ;height: 969px;" class="flex_c_b">
        <div style="width: 1400px ;height: 950px;z-index: 2;margin-top:50px;justify-content:flex-start" class="flex_c_b">
          <div>
            <div class="smallTitle">
              <svg-icon icon-class="cxjg" class="svg_class" />
@@ -57,8 +54,8 @@
                      </div>
                      <div class="content02Parent">
                        <div class="content02">
                          <div class="content02_1 ">任务</div>
                          <div class="content02_2 borderTop ">{{ parseFloat(it.planqty) }}</div>
                          <div class="content02_1 ">开工</div>
                          <div class="content02_2 borderTop ">{{ parseFloat(it.startqty) }}</div>
                        </div>
                        <div class="content02">
                          <div class="content02_1 ">合格</div>
@@ -102,12 +99,12 @@
            </div>
          </div>
          <div>
          <div style="margin-top: 20px;">
            <div class="smallTitle">
              <svg-icon icon-class="cxmc" class="svg_class" />
              产线加工任务
            </div>
            <div class="lineContent horn">
            <div class="lineContent horn" style="height: 400px;">
              <el-table
                ref="tableDataLeftBottomRef"
                :data="tableDataLeftBottom"
@@ -115,7 +112,7 @@
                style="width: 100%;"
                :header-cell-style="headerCellStyle"
                :cell-style="cellStyle"
                height="428"
                height="390"
              >
                <el-table-column
                  prop="RowNum"
@@ -146,7 +143,7 @@
                <el-table-column
                  prop="saleOrderCode"
                  label="销售订单号"
                  width="170"
                  width="160"
                >
                  <template slot-scope="{row}">
                    <div v-if="row.saleOrderCode">{{ row.saleOrderCode }}</div>
@@ -156,7 +153,7 @@
                <el-table-column
                  prop="wo_code"
                  label="加工单号"
                  width="190"
                  width="200"
                />
                <el-table-column
                  prop="partname"
@@ -171,21 +168,21 @@
                <el-table-column
                  prop="plan_qty"
                  label="任务数量"
                  width="105"
                  width="106"
                />
                <el-table-column
                  prop="good_qty"
                  label="完工数量"
                  width="105"
                  width="106"
                />
                <el-table-column
                  prop="ng_qty"
                  label="不良数量"
                  width="105"
                  width="106"
                />
                <el-table-column
                  label="完成率"
                  width="105"
                  width="106"
                >
                  <template slot-scope="{row}">
                    <div>{{ parseFloat((row.good_qty * 100 / row.plan_qty).toFixed(2)) }}%</div>
@@ -215,7 +212,7 @@
          </div>
        </div>
        <!--        右边-->
        <div style="width: 450px;height: 969px;" class="flex_c_b">
        <div style="width: 450px;height: 950px;z-index: 2;margin-top:50px;justify-content:flex-start" class="flex_c_b">
          <div>
            <div class="smallTitle">
              <svg-icon icon-class="drwg" class="svg_class" />
@@ -236,14 +233,14 @@
                  label="序号"
                  width="60"
                />
                <el-table-column
                  prop="linename"
                  width="125"
                  label="产线"
                />
                <!--                <el-table-column-->
                <!--                  prop="linename"-->
                <!--                  width="125"-->
                <!--                  label="产线"-->
                <!--                />-->
                <el-table-column
                  prop="partname"
                  width="160"
                  width="260"
                  label="产品"
                >
                  <template slot-scope="{row}">
@@ -254,7 +251,7 @@
                <el-table-column
                  prop="good_qty"
                  label="数量"
                  width="90"
                  width="115"
                >
                  <template slot-scope="{row}">
                    <div>{{ parseFloat(row.good_qty) }}</div>
@@ -264,12 +261,12 @@
            </div>
          </div>
          <div>
          <div style="margin-top: 20px;">
            <div class="smallTitle">
              <svg-icon icon-class="top5" class="svg_class" />
              一周不良Top5
            </div>
            <div class="lineContent horn">
            <div class="lineContent horn" style="height: 400px;">
              <div id="bar01" class="flex_c_c" style="width: 100%;height:100%" />
            </div>
@@ -306,35 +303,50 @@
      lineContent3: [],
      ShopArr: [], // 车间编码数组
      starsCount: 800, // 星星数量
      distance: 900 // 间距
      codeArr: [
        { code: '202', name: '机加工车间' },
        { code: '205', name: '包装车间' },
        { code: '204', name: '喷涂车间' },
        { code: '203', name: '抛光车间' },
        // { code: '001', name: '压铸车间' }
        { code: '201', name: '压铸车间' }
      ],
      title: '车间综合'
    }
  },
  created() {
    setInterval(this.getNowTime, 1000)
    // this.getShopSearch()
    let code = ''
    if (window.location.hash.indexOf('?') !== -1) {
      code = window.location.hash.split('?')[1].split('=')[1]
      this.title = this.codeArr.find(i => i.code === code).name
      this.ShopArr = [code]
    }
    // 两小时看板刷新一次
    setInterval(() => {
      window.location.reload()
    }, 1000 * 60 * 60 * 10)
    }, 1000 * 60 * 120)
  },
  mounted() {
    // 监听网络是否在线
    window.addEventListener('online', this.updateOnlineStatus)
    window.addEventListener('offline', this.updateOnlineStatus)
    this.updateOnlineStatus({ type: this.onLine ? 'online' : 'offline', isFirst: true })
    this.getTopBar()
    this.getShopSearch()
    this.setStarsRef()
    this.getAllApi()
  },
  beforeDestroy() {
    window.removeEventListener('online', this.updateOnlineStatus)
    window.removeEventListener('offline', this.updateOnlineStatus)
  },
  methods: {
    getAllApi() {
      this.getShopSearchLine()
      this.getLineSearchTopRightData()
      this.getLeftBottomData()
      this.getEcharts()
    },
    // 更新网络状态
    updateOnlineStatus(e) {
      if (e.isFirst) {
@@ -357,50 +369,155 @@
        }
      }
    },
    setStarsRef() {
      const starNodes = Array.from(this.$refs.starsRef.children)
      starNodes.forEach(item => {
        const speed = 0.2 + Math.random() * 1
        const thisDistance = this.distance + Math.random() * 300
        item.style.transformOrigin = `0 0 ${thisDistance}px`
        item.style.transform = `
        translate3d(0,0,-${thisDistance}px)
        rotateY(${Math.random() * 360}deg)
        rotateX(${Math.random() * -50}deg)
        scale(${speed},${speed})`
      })
    },
    // 获取车间编码
    async getShopSearch() {
      const res1 = await ShopSearch()
      if (res1.code === '200') {
        this.ShopArr = []
        res1.data.forEach(item => {
          this.ShopArr.push(item.org_code)
        })
    // async getShopSearch() {
    //   const res1 = await ShopSearch()
    //   if (res1.code === '200') {
    //     this.ShopArr = []
    //     res1.data.forEach(item => {
    //       this.ShopArr.push(item.org_code)
    //     })
    //
    //     if (this.ShopArr.length > 0) {
    //       this.getShopSearchLine()
    //       this.getLineSearchTopRightData()
    //       this.getLeftBottomData()
    //       this.getEcharts()
    //     }
    //   }
    //   if (this.ShopArr.length > 0) {
    //     setInterval(() => {
    //       this.ShopSearchTask = ShopSearch().then(res1 => {
    //         if (res1.code === '200') {
    //           this.ShopArr = []
    //           res1.data.forEach(item => {
    //             this.ShopArr.push(item.org_code)
    //           })
    //         }
    //       })
    //     }, 1000 * 60)
    //   }
    // },
    // 产线加工中任务
    getShopSearchLine() {
      let length, count
      LineSearchTopLeftData({ shopcode: this.ShopArr.join(',') }).then(res => {
        this.lineContent = res.data // 调用接口返回的数据
        this.number1 = this.lineContent.length // 产线加工中任务  单数
        if (this.ShopArr.length > 0) {
          this.getShopSearchLine()
          this.getRightRightData()
          this.getLeftBottomData()
          this.getEcharts()
        }
      }
      if (this.ShopArr.length > 0) {
        setInterval(() => {
          this.ShopSearchTask = ShopSearch().then(res1 => {
            if (res1.code === '200') {
              this.ShopArr = []
              res1.data.forEach(item => {
                this.ShopArr.push(item.org_code)
        const newData = []
        if (this.lineContent.length > 0) {
          this.lineContent.forEach(item => {
            if (item.children.length > 5) {
              newData.push({
                workcode: item.workcode,
                partname: item.partname,
                partnumber: item.partnumber,
                partspec: item.partspec,
                qty: item.qty,
                saleordercode: item.saleordercode,
                uom: item.uom,
                children: item.children.slice(0, 5)
              })
              newData.push({
                workcode: item.workcode,
                partname: item.partname,
                partnumber: item.partnumber,
                partspec: item.partspec,
                qty: item.qty,
                saleordercode: item.saleordercode,
                uom: item.uom,
                children: item.children.slice(5)
              })
            } else {
              newData.push({
                workcode: item.workcode,
                partname: item.partname,
                partnumber: item.partnumber,
                partspec: item.partspec,
                qty: item.qty,
                saleordercode: item.saleordercode,
                uom: item.uom,
                children: item.children
              })
            }
          })
        }, 1000 * 60)
      }
          // console.log(newData.length, 9777)
        }
        this.lineContent = newData
        length = this.lineContent.length
        count = Math.ceil(length / 3) // 需要轮播的组数   3个为一组
        this.lineContent3 = this.lineContent.slice(0, 3)
      })
      let start = 0
      this.ShopSearchLineTask = setInterval(() => {
        if (Math.floor(start / 3) === count && count !== 0) {
          start = 0
          LineSearchTopLeftData({ shopcode: this.ShopArr.join(',') }).then(res => {
            this.lineContent = res.data // 调用接口返回的数据
            this.number1 = this.lineContent.length // 产线加工中任务  单数
            const newData = []
            if (this.lineContent.length > 0) {
              this.lineContent.forEach(item => {
                if (item.children.length > 5) {
                  newData.push({
                    workcode: item.workcode,
                    partname: item.partname,
                    partnumber: item.partnumber,
                    partspec: item.partspec,
                    qty: item.qty,
                    saleordercode: item.saleordercode,
                    uom: item.uom,
                    children: item.children.slice(0, 5)
                  }
                  )
                  newData.push({
                    workcode: item.workcode,
                    partname: item.partname,
                    partnumber: item.partnumber,
                    partspec: item.partspec,
                    qty: item.qty,
                    saleordercode: item.saleordercode,
                    uom: item.uom,
                    children: item.children.slice(5)
                  })
                } else {
                  newData.push({
                    workcode: item.workcode,
                    partname: item.partname,
                    partnumber: item.partnumber,
                    partspec: item.partspec,
                    qty: item.qty,
                    saleordercode: item.saleordercode,
                    uom: item.uom,
                    children: item.children
                  })
                }
              })
            }
            this.lineContent = newData
            length = this.lineContent.length
            count = Math.ceil(length / 3) // 需要轮播的组数   3个为一组
            this.lineContent3 = this.lineContent.slice(0, 3)
          })
        } else if (count === 0) {
          clearInterval(this.ShopSearchLineTask)
          this.getShopSearchLine()
        }
        this.lineContent3 = this.lineContent.slice(start, start + 3)
        start = start + 3
      }, 1000 * 10)
    },
    // 产线加工中任务
    getShopSearchLine() {
    // 产线加工中任务(备份  原先的方法)
    getShopSearchLineBack() {
      let length, count
      LineSearchTopLeftData({ shopcode: this.ShopArr.join(',') }).then(res => {
        this.lineContent = res.data
@@ -432,54 +549,96 @@
    },
    // 获取右上数据 当日完工产品数量排行
    getRightRightData() {
      let startValue = 0 // 初始值
      const scale = 10// 刻度
    getLineSearchTopRightData() {
      LineSearchTopRightData({ shopcode: this.ShopArr.join(',') }).then(res => {
        this.tableDataRightTopTemp = res.data
        this.tableDataRightTop = this.tableDataRightTopTemp.slice(startValue, startValue + scale)
        const loop = Math.floor(this.tableDataRightTopTemp.length / scale)// 需要循环的次数
        let nowLoop = 0// 当前循环的次数
        const timer = setInterval(() => {
          startValue = startValue + scale
          this.tableDataRightTop = this.tableDataRightTopTemp.slice(startValue, startValue + scale)
          if (nowLoop === loop) {
            clearInterval(timer)
            this.getRightRightData()
          }
          nowLoop++
        }, 1000 * 10)
        this.tableDataRightTop = res.data
        // const divData = this.$refs.tableDataRightTopRef.bodyWrapper
        //
        // const temp = setInterval(() => {
        //   divData.scrollTop += 1
        //
        //   if (divData.clientHeight + divData.scrollTop === divData.scrollHeight) {
        //     divData.scrollTop = 0
        //     LineSearchTopRightData({ shopcode: this.ShopArr.join(',') }).then(res => {
        //       this.tableDataRightTop = res.data
        //
        //       if (this.tableDataRightTop.length > 9) {
        //         clearInterval(temp)
        //         this.getLineSearchTopRightData()
        //       }
        //     })
        //   }
        // }, this.tableDataRightTop.length <= 9 ? 1000 * 15 : 300)
      })
      // let startValue = 0 // 初始值
      // const scale = 10// 刻度
      //
      // LineSearchTopRightData({ shopcode: this.ShopArr.join(',') }).then(res => {
      //   this.tableDataRightTopTemp = res.data
      //
      //   this.tableDataRightTop = this.tableDataRightTopTemp.slice(startValue, startValue + scale)
      //
      //   const loop = Math.floor(this.tableDataRightTopTemp.length / scale)// 需要循环的次数
      //   let nowLoop = 0// 当前循环的次数
      //
      //   const timer = setInterval(() => {
      //     startValue = startValue + scale
      //     this.tableDataRightTop = this.tableDataRightTopTemp.slice(startValue, startValue + scale)
      //     if (nowLoop === loop) {
      //       clearInterval(timer)
      //       this.getLineSearchTopRightData()
      //     }
      //
      //     nowLoop++
      //   }, 1000 * 10)
      // })
    },
    // 产线加工任务  左下数据
    getLeftBottomData() {
      let startValue = 0 // 初始值
      const scale = 10// 刻度
      LineSearchBottomLeftData({ shopcode: this.ShopArr.join(',') }).then(res => {
        this.tableDataLeftBottomTemp = res.data
        this.tableDataLeftBottom = this.tableDataLeftBottomTemp.slice(startValue, startValue + scale)
        this.tableDataLeftBottom = res.data
        const loop = Math.floor(this.tableDataLeftBottomTemp.length / scale)// 需要循环的次数
        let nowLoop = 0// 当前循环的次数
        const divData = this.$refs.tableDataLeftBottomRef.bodyWrapper
        this.TableDataRollTask = setInterval(() => {
          // 元素自增距离顶部1像素
          divData.scrollTop += 1
          if (divData.clientHeight + divData.scrollTop === divData.scrollHeight) {
            divData.scrollTop = 0
            LineSearchBottomLeftData({ shopcode: this.ShopArr.join(',') }).then(res => {
              this.tableDataLeftBottom = res.data
        const timer = setInterval(() => {
          startValue = startValue + scale
          this.tableDataLeftBottom = this.tableDataLeftBottomTemp.slice(startValue, startValue + scale)
          nowLoop++ // 放在这里可以了,就等待零点几秒
          if (nowLoop === loop) {
            clearInterval(timer)
            this.getLeftBottomData()
              if (this.tableDataLeftBottom.length > 9) {
                clearInterval(this.TableDataRollTask)
                this.getLeftBottomData()
              }
            })
          }
          // nowLoop++ //之前放在这里逻辑不对,相差了一次的循环,相当于多等待了10秒
        }, 1000 * 10)
        }, this.tableDataLeftBottom.length <= 9 ? 1000 * 15 : 200)
      })
      // let startValue = 0 // 初始值
      // const scale = 10// 刻度
      //
      // LineSearchBottomLeftData({ shopcode: this.ShopArr.join(',') }).then(res => {
      //   this.tableDataLeftBottomTemp = res.data
      //   this.tableDataLeftBottom = this.tableDataLeftBottomTemp.slice(startValue, startValue + scale)
      //
      //   const loop = Math.floor(this.tableDataLeftBottomTemp.length / scale)// 需要循环的次数
      //   let nowLoop = 0// 当前循环的次数
      //
      //   const timer = setInterval(() => {
      //     startValue = startValue + scale
      //     this.tableDataLeftBottom = this.tableDataLeftBottomTemp.slice(startValue, startValue + scale)
      //     nowLoop++ // 放在这里可以了,就等待零点几秒
      //     if (nowLoop === loop) {
      //       clearInterval(timer)
      //       this.getLeftBottomData()
      //     }
      //
      //     // nowLoop++ //之前放在这里逻辑不对,相差了一次的循环,相当于多等待了10秒
      //   }, 1000 * 10)
      // })
    },
    getEcharts() {
@@ -499,11 +658,6 @@
        })
      }, 1000 * 10)
    },
    // 获取topEcharts
    getTopBar() {
      loadEcharts('topBarLeft', kbTop())
      loadEcharts('topBarRight', kbTop())
    },
    // 获取当前时间
    getNowTime() {
      const dt = new Date()
@@ -522,7 +676,7 @@
    },
    headerCellStyle() {
      return {
        backgroundColor: '#000',
        backgroundColor: 'transparent ',
        padding: '10px 0',
        textAlign: 'center',
        color: '#07acc2',
@@ -534,8 +688,8 @@
      return {
        padding: '7px 0',
        textAlign: 'center',
        backgroundColor: '#000',
        color: '#fff',
        backgroundColor: 'transparent ',
        color: '#c7e7ff',
        border: 'none',
        fontSize: '18px'
      }
@@ -549,8 +703,14 @@
$main_color: #09d8f2;
$color01: #00FFFF;
::v-deep .el-table th,
::v-deep .el-table tr,
::v-deep .el-table td {
  background-color: transparent;
}
.tableData {
  background: #000;
  background: transparent;
}
.el-table::before {
@@ -594,7 +754,7 @@
      .content01 {
        height: 30px;
        width: 100%;
        border-bottom: 1px solid $main_color;
        //border-bottom: 1px solid $main_color;
        display: flex;
        align-items: center;
        justify-content: center;
@@ -602,7 +762,7 @@
      .content02Parent {
        display: flex;
border-top: 1px solid $main_color;
        .content02 {
          width: 60px;
          border-right: 1px solid $main_color;
@@ -661,39 +821,8 @@
  border-radius: 50%;
}
</style>
<!--星空-->
<style lang="css" scoped>
@keyframes rotate {
  0% {
    transform: perspective(400px) rotateZ(20deg) rotateX(-40deg) rotateY(0);
  }
  100% {
    transform: perspective(400px) rotateZ(20deg) rotateX(-40deg) rotateY(-360deg);
  }
}
.stars {
  transform: perspective(500px);
  transform-style: preserve-3d;
  position: absolute;
  perspective-origin: 50% 100%;
  left: 45%;
  animation: rotate 90s infinite linear;
  bottom: 0;
  z-index: 102;
}
.star {
  width: 2px;
  height: 2px;
  /*background: #f7f7b6;*/
  background: #8edffc;
  position: absolute;
  left: 0;
  top: 0;
  backface-visibility: hidden;
  z-index: 102;
::v-deep .el-table__body-wrapper::-webkit-scrollbar {
  /* width: 0;宽度为0暗藏 */
  width: 0;
}
</style>