src/views/mdc/base/modules/WorkshopSignage/DeviceDragLayout.vue
@@ -1,7 +1,5 @@
<template>
  <div>
    <div class="guideline guidelineX" :style="{top:guidelineXTop+'px',display:showGuideline}"></div>
    <div class="guideline guidelineY" :style="{left:guidelineYLeft+'px',display:showGuideline}"></div>
    <VueDragResize
      v-for="(item, index) in deviceList"
      :key="item.equipmentId"
@@ -14,136 +12,229 @@
      :parentLimitation="true"
      :parentH="1065"
      :parentW="1500"
      :minw="70"
      :minh="70"
      :isDraggable="true"
      :isResizable="true"
      :minw="50"
      :minh="50"
      :isDraggable="isSwitchChecked"
      :isResizable="isSwitchChecked"
      :stickSize="6"
      @deactivated="showGuideline = 'none'"
      @deactivated="isShowGuideline = false"
    >
      <div class="single-device" :style="{ width: item.vw + 'px', height: item.vh + 'px' }">
        <div class="device-status">
          <div
            v-if="item.equipmentStatus == 2 || item.equipmentStatus == 1"
            :style="{ backgroundImage: `url(${require('@/assets/yellow.png')})` }"
            class="status-image"
          ></div>
          <div
            v-if="item.equipmentStatus == 22"
            :style="{ backgroundImage: `url(${require('@/assets/red.png')})` }"
            class="status-image"
          ></div>
          <div
            v-if="item.equipmentStatus == 0"
            :style="{ backgroundImage: `url(${require('@/assets/gray.png')})` }"
            class="status-image"
          ></div>
          <div
            v-if="item.equipmentStatus == 3"
            :style="{ backgroundImage: `url(${require('@/assets/green.png')})` }"
            class="status-image"
          ></div>
          <div
            :style="{ backgroundImage: `url(${getImgView(item.equipmentImage) || require('@/assets/default.png')})` }"
            :style="{ backgroundImage: `url(${getImgView(item.equipmentImage) || require('@/assets/WorskhopSignage/default.png')})` }"
            class="device-image"
          ></div>
          >
            <div
              :style="{ backgroundImage: `url(${getCurrentDeviceStatusImage(item.oporation)})` }"
              class="status-image"
            ></div>
          </div>
        </div>
        <div
          :style="{ color:workshopDetails.equipmentIdColor?workshopDetails.equipmentIdColor:'#fff',marginTop:'10px' }">
          {{ item.equipmentId }}
        </div>
        <div :style="{backgroundColor:item.equipmentStatus!==0?'#f00':'rgba(0,0,0,.4)'}">{{ item.equipmentId }}</div>
      </div>
    </VueDragResize>
    <template v-if="isShowGuideline">
      <div class="guideline guidelineX" :style="{top:guidelineXTop+'px'}"></div>
      <div class="guideline guidelineY" :style="{left:guidelineYLeft+'px'}"></div>
    </template>
    <a-form layout="inline" v-has="'isCanDragAndResize'">
      <a-form-item label="功能开关">
        <a-switch checked-children="开" un-checked-children="关" v-model="isSwitchChecked" @change="handleSwitchChange"
                  :disabled="isHasResizeOrDragDevice"/>
      </a-form-item>
      <a-form-item label="保存坐标">
        <a-button type="primary" icon="save" @click="saveDevicePositionAndSizeByApi"
                  :disabled="!isHasResizeOrDragDevice">保存
        </a-button>
      </a-form-item>
    </a-form>
  </div>
</template>
<script>
  export default {
    name: 'DeviceDragLayout',
    components: {},
    props: {
      deviceList: {
        type: Array
      }
import signageApi from '@/api/signage'
import VueDragResize from 'vue-drag-resize'
export default {
  name: 'DeviceDragLayout',
  components: {
    VueDragResize
  },
  props: {
    currentProductionId: {
      type: String
    },
    data() {
      return {
        showGuideline: 'none',
        guidelineXTop: 0,
        guidelineYLeft: 0
      }
    getImgView: {
      type: Function
    },
    methods: {
      /**
       * 设备拖拽或缩放时触发事件
       * @param newRect 拖拽或缩放后的尺寸及距离
       * @param index 拖拽设备在数组中的下标
       */
      resize(newRect, index) {
        this.showGuideline = 'block'
        this.deviceList[index].vw = newRect.width
        this.deviceList[index].vh = newRect.height
        this.deviceList[index].coordinateTop = newRect.top
        this.deviceList[index].coordinateLeft = newRect.left
        this.guidelineXTop = newRect.top + newRect.height / 2
        this.guidelineYLeft = newRect.left + newRect.width / 2
    equipmentStatusList: {
      type: Array
    }
  },
  data() {
    return {
      deviceList: [],
      isShowGuideline: false,
      guidelineXTop: 0,
      guidelineYLeft: 0,
      isSwitchChecked: false,
      isHasResizeOrDragDevice: false
    }
  },
  created() {
    if (!this.currentProductionId) return
    this.getDeviceListByApi()
  },
  methods: {
    // 通过车间Id调用接口获取设备信息列表
    getDeviceListByApi() {
      const that = this
      signageApi.getDeviceListInWorkshopSignagePageApi(that.currentProductionId)
        .then((res) => {
          if (res.success && res.result && res.result.length > 0) that.deviceList = res.result
        })
    },
    handleSwitchChange(checked) {
      console.log('checked--------', checked)
      this.$emit('handleTimeIntervalForShortOpen', checked)
    },
    /**
     * 设备拖拽或缩放时触发事件
     * @param newRect 拖拽或缩放后的尺寸及距离
     * @param index 拖拽设备在数组中的下标
     */
    resize(newRect, index) {
      this.isShowGuideline = true
      // 当设备缩放或拖拽后禁用switch组件并开放保存按钮功能(避免无效请求)
      if (!this.isHasResizeOrDragDevice) {
        if (this.deviceList[index].vw !== newRect.width || this.deviceList[index].vh !== newRect.height || this.deviceList[index].coordinateTop !== newRect.top || this.deviceList[index].coordinateLeft !== newRect.left) {
          this.isHasResizeOrDragDevice = true
        }
      }
      // this.isHasResizeOrDragDevice = true
      this.deviceList[index].vw = newRect.width
      this.deviceList[index].vh = newRect.height
      this.deviceList[index].coordinateTop = newRect.top
      this.deviceList[index].coordinateLeft = newRect.left
      this.guidelineXTop = newRect.top + newRect.height / 2
      this.guidelineYLeft = newRect.left + newRect.width / 2
    },
    // 点击保存按钮调用接口保存拖拽后的位置与设备图标尺寸
    saveDevicePositionAndSizeByApi() {
      const that = this
      signageApi.saveDevicePositionAndSizeApi(that.deviceList)
        .then((res) => {
          if (!res.success) return
          that.$notification.success({
            message: '消息',
            description: res.message
          })
          that.isSwitchChecked = that.isHasResizeOrDragDevice = false
          that.getDeviceListByApi(that.currentProductionId)
        })
    },
    /**
     * 获取当前设备状态图片
     * @param oporation 状态码
     * @returns {any} 设备状态图片资源
     */
    getCurrentDeviceStatusImage(oporation) {
      const currentStatus = this.equipmentStatusList.find(item => item.value.includes(oporation))
      return currentStatus.statusImage
    }
  }
}
</script>
<style scoped lang="less">
  .single-device {
    position: absolute;
    border: 1px solid transparent;
    padding: 10px;
.single-device {
  position: absolute;
  border: 1px solid transparent;
  //padding: 10px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  cursor: default;
  &:active {
    border: 1px solid #1890ff;
  }
  .device-status {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: space-between;
    cursor: default;
    -webkit-align-items: flex-end;
    -moz-align-items: flex-end;
    -ms-align-items: flex-end;
    &:active {
      border: 1px solid #1890ff;
    }
    .device-status {
    .device-image {
      background-size: 100% 100%;
      background-repeat: no-repeat;
      width: 100%;
      height: 100%;
      display: flex;
      -webkit-align-items: flex-end;
      -moz-align-items: flex-end;
      -ms-align-items: flex-end;
      position: relative;
      margin-bottom: 2px;
      .status-image {
        position: absolute;
        top: 25%;
        left: 25%;
        background-size: 100% 100%;
        background-repeat: no-repeat;
        width: 10px;
        height: 80%;
        margin-right: 5px;
      }
      .device-image {
        background-size: 100% 100%;
        background-repeat: no-repeat;
        width: 100%;
        height: 100%;
        width: 50%;
        height: 50%;
      }
    }
  }
  .guideline {
    position: absolute;
    border: 1px dashed #ccc;
  & > div:last-child {
    color: #fff;
    font-weight: bold;
    font-size: 0.6vw;
  }
}
.guideline {
  position: absolute;
  border: 1px dashed rgba(255,255,255,.7);
}
.guidelineX {
  width: 9999px;
  left: 0;
}
.guidelineY {
  top: 0;
  height: 9999px;
}
form {
  position: absolute;
  right: 0;
  bottom: 0.5%;
  /deep/.ant-form-item-label > label{
    color: #fff;
  }
  .guidelineX {
    width: 9999px;
    left: 0;
  .ant-switch {
    background-color: #999;
  }
  .guidelineY {
    top: 0;
    height: 9999px;
  .ant-switch-checked {
    background-color: #1890FF;
  }
}
</style>