zhuzhuanzhuan
2023-10-12 36ca71eaff11519ef34eb6e4fb192f24bf3bf47c
新增大屏车间管理页面并基本实现基础功能(除车间删除与批量删除与查询)
已添加3个文件
已修改7个文件
1169 ■■■■ 文件已修改
src/api/mdc.js 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/WorkshopSignage.vue 249 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mdc/base/modules/StatisticalAnalysis/StatisticalAnalysisMain.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mdc/base/modules/alarmAnalysis/alarmAnalysisMain.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mdc/base/modules/openRateFractionAnalysis/openRateFractionAnalysisMain.vue 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mdc/base/modules/openRateTrendAnalysis/openRateTrendAnalysisMain.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/WorkshopSignageManagement.vue 495 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/modules/SelectDeviceModal.vue 256 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/modules/UserModal.vue 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/modules/WorkshopModal.vue 134 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/mdc.js
@@ -3,5 +3,26 @@
export default {
//  -------------------------------------驱动参数管理页面----------------------------------------
//  èŽ·å–æŽ§åˆ¶ç³»ç»Ÿç±»åž‹
  getDriveTypeApi:()=>getAction('/mdc/mdcDriveTypeParamConfig/getDriveParamOptions')
  getDriveTypeApi: () => getAction('/mdc/mdcDriveTypeParamConfig/getDriveParamOptions'),
  // -------------------------------------车间看板页面----------------------------------------
  // æ ¹æ®è½¦é—´id查询设备列表
  getDeviceListByWorkshopIdApi: params => getAction('/mdc/mdcWorkshopInfo/workshopEquipmentList', params),
  // æ ¹æ®è½¦é—´id查询车间详细信息
  getWorkshopDetailByWorkshopIdApi: id => getAction('/mdc/mdcWorkshopInfo/queryById', { id }),
  // æŸ¥è¯¢è½¦é—´åˆ—表
  getWorkshopListApi: params => getAction('/mdc/mdcWorkshopInfo/list', params),
  // æ–°å¢žè½¦é—´ä¿¡æ¯
  addWorkshopApi: params => postAction('/mdc/mdcWorkshopInfo/add', params),
  // ç¼–辑车间信息
  editWorkshopApi: params => putAction('/mdc/mdcWorkshopInfo/edit', params),
  // åˆ é™¤å•个车间信息
  deleteSingleWorkshopApi: id => deleteAction('/mdc/mdcWorkshopInfo/delete', { id }),
  // æ‰¹é‡åˆ é™¤è½¦é—´ä¿¡æ¯
  deleteBatchWorkshopApi: ids => deleteAction('/mdc/mdcWorkshopInfo/deleteBatch', { ids }),
  // æ–°å¢žå¤§å±è½¦é—´å’Œè®¾å¤‡å…³ç³»
  addDeviceInWorkshopApi: params => postAction('/mdc/mdcWorkshopInfo/addWorkshopEquipment', params),
  // åˆ é™¤å•个大屏车间和设备关系
  deleteSingleDeviceInWorkshopApi: params => deleteAction('/mdc/mdcWorkshopInfo/deleteWorkshopEquipment', params),
  // æ‰¹é‡åˆ é™¤å¤§å±è½¦é—´å’Œè®¾å¤‡å…³ç³»
  deleteBatchDeviceInWorkshopApi: params => deleteAction('/mdc/mdcWorkshopInfo/deleteWorkshopEquipmentBatch', params)
}
src/views/WorkshopSignage.vue
@@ -3,43 +3,25 @@
    <header class="page-header">
      {{getWorkshopName}}
      <div class="header-right">
        <a-button type="primary" icon="save" size="large" @click="saveDevicePositionByApi">保存位置</a-button>
        <a-button type="primary" icon="save" size="large" @click="saveDevicePositionAndSizeByApi"
                  v-has="'home:saveDevicePositionAndSize'">保存位置
        </a-button>
      </div>
    </header>
    <dv-border-box-8 class="content-container">
      <!--<div v-for="item in deviceList" :key="item.equipmentId" class="single-device"-->
      <!--:style="{top:item.top+'px',left:item.left+'px',height:'135px',width:'175px'}" @mousedown="handleMouseDown"-->
      <!--:id="item.equipmentId">-->
      <!--<div class="device-status">-->
      <!--<img v-if="item.status==0" src="@/assets/yellow.png" draggable="false">-->
      <!--<img v-if="item.status==1" src="@/assets/red.png" draggable="false">-->
      <!--<img v-if="item.status==2" src="@/assets/gray.png" draggable="false">-->
      <!--<img v-if="item.status==3" src="@/assets/green.png" draggable="false">-->
      <!--<img :src="item.equipmentImageUrl" draggable="false">-->
      <!--</div>-->
      <!--<div class="device-id">{{item.equipmentId}}</div>-->
      <!--&lt;!&ndash;<div draggable="false" class="device-info">&ndash;&gt;-->
      <!--&lt;!&ndash;<div v-if="item.status==0" class="status-square" style="background-color: gray"></div>&ndash;&gt;-->
      <!--&lt;!&ndash;<div v-if="item.status==1" class="status-square" style="background-color: red"></div>&ndash;&gt;-->
      <!--&lt;!&ndash;<div v-if="item.status==2" class="status-square" style="background-color: green"></div>&ndash;&gt;-->
      <!--&lt;!&ndash;<div v-if="item.status==3" class="status-square" style="background-color: yellow"></div>&ndash;&gt;-->
      <!--&lt;!&ndash;<div class="device-id">{{item.equipmentId}}</div>&ndash;&gt;-->
      <!--&lt;!&ndash;</div>&ndash;&gt;-->
      <!--&lt;!&ndash;</div>&ndash;&gt;-->
      <!--</div>-->
      <VueDragResize v-for="(item,index) in deviceList" :key="item.equipmentId" :w="item.vw"
                     :h="item.vh" :x="item.left" :y="item.top"
                     v-on:resizing="resize($event,index)"
                     v-on:dragging="resize($event,index)"
                     :parentLimitation="true"
                     :minw="175"
                     :minh="135"
                     :minw="100"
                     :minh="100"
                     :id="item.equipmentId"
                     :stickSize="6"
      >
        <div class="single-device"
             :style="{width: + item.vw+ 'px',height:+item.vh+'px'}">
             :style="{width:  item.vw+ 'px',height:item.vh+'px'}">
          <div class="device-status">
            <div v-if="item.status==0"
                 :style="{backgroundImage:`url(${require('@/assets/yellow.png')})`}" class="status-image"></div>
@@ -50,21 +32,20 @@
            <div v-if="item.status==3" :style="{backgroundImage:`url(${require('@/assets/green.png')})`}"
                 class="status-image"></div>
            <div
              :style="{backgroundImage:`url(${item.equipmentImageUrl})`}"
              class="device-image"></div>
              :style="{backgroundImage:`url(${item.equipmentImageUrl})`}" class="device-image"></div>
          </div>
          <div class="device-id" :style="{fontSize: item.fontSize+'px'}">
            {{item.equipmentId}}
          </div>
          <!--<div draggable="false" class="device-info">-->
          <!--<div v-if="item.status==0" class="status-square" style="background-color: gray"></div>-->
          <!--<div v-if="item.status==1" class="status-square" style="background-color: red"></div>-->
          <!--<div v-if="item.status==2" class="status-square" style="background-color: green"></div>-->
          <!--<div v-if="item.status==3" class="status-square" style="background-color: yellow"></div>-->
          <!--<div class="device-id">{{item.equipmentId}}</div>-->
          <!--</div>-->
        </div>
      </VueDragResize>
      <div class="device-status-info">
        <div v-for="item in deviceStatusList" :key="item.value" class="single-status-info">
          <div>{{item.label}}</div>
          <div class="status-square" :style="{backgroundColor:item.color}"></div>
          <div>{{getDeviceNumberByStatus(item.value)}}</div>
        </div>
      </div>
    </dv-border-box-8>
  </dv-full-screen-container>
</template>
@@ -78,31 +59,26 @@
    },
    data() {
      return {
        mouseX: 0, // é¼ æ ‡åœ¨å…ƒç´ å†…çš„X坐标
        mouseY: 0, // é¼ æ ‡åœ¨å…ƒç´ å†…çš„Y坐标,
        dragging: false, //是否在拖拽中
        elementId: '',// è¢«æ‹–拽元素的id属性值
        elementWidth: '',
        elementHeight: '',
        // è®¾å¤‡ä¿¡æ¯åˆ—表
        deviceList: [
          {
            equipmentId: '123213213123232',
            equipmentImageUrl: require('@/assets/8.png'),
            top: 200,
            left: 100,
            vw: 175,
            vh: 135,
            fontSize: 20,
            status: 1
            equipmentId: '123213213123232',// è®¾å¤‡ID
            equipmentImageUrl: require('@/assets/8.png'), // è®¾å¤‡å›¾ç‰‡
            top: 200, // æ‹–拽元素距盒子顶距离
            left: 100, // æ‹–拽元素距盒子左侧距离
            vw: 100,  // ç¼©æ”¾å…ƒç´ å®½åº¦
            vh: 100, // ç¼©æ”¾å…ƒç´ é«˜åº¦
            fontSize: 12, // ç¼©æ”¾å…ƒç´ å­—体大小
            status: 1 // è®¾å¤‡çŠ¶æ€ 0:待机 1:报警 2:关机 3:运行
          },
          {
            equipmentId: '512346789561232',
            equipmentImageUrl: require('@/assets/8.png'),
            top: 500,
            left: 753,
            vw: 175,
            vh: 135,
            fontSize: 20,
            vw: 100,
            vh: 100,
            fontSize: 12,
            status: 0
          },
          {
@@ -110,9 +86,9 @@
            equipmentImageUrl: require('@/assets/8.png'),
            top: 300,
            left: 860,
            vw: 175,
            vh: 135,
            fontSize: 20,
            vw: 100,
            vh: 100,
            fontSize: 12,
            status: 2
          },
          {
@@ -120,9 +96,9 @@
            equipmentImageUrl: require('@/assets/8.png'),
            top: 100,
            left: 380,
            vw: 175,
            vh: 135,
            fontSize: 20,
            vw: 100,
            vh: 100,
            fontSize: 12,
            status: 3
          },
          {
@@ -130,10 +106,33 @@
            equipmentImageUrl: require('@/assets/8.png'),
            top: 200,
            left: 1500,
            vw: 175,
            vh: 135,
            fontSize: 20,
            vw: 100,
            vh: 100,
            fontSize: 12,
            status: 2
          }
        ],
        // è®¾å¤‡çŠ¶æ€æŒ‡ç¤ºç¯åˆ—è¡¨
        deviceStatusList: [
          {
            label: '关机',
            value: 2,
            color: '#A8A8A8'
          },
          {
            label: '待机',
            value: 0,
            color: '#FFFF00'
          },
          {
            label: '运行',
            value: 3,
            color: '#00EE00'
          },
          {
            label: '报警',
            value: 1,
            color: '#FF0000'
          }
        ]
      }
@@ -156,74 +155,16 @@
    },
    methods: {
      /**
       * é€šè¿‡è½¦é—´Id调用接口获取设备列表
       * é€šè¿‡è½¦é—´Id调用接口获取设备信息列表
       * @param workshopId è½¦é—´Id
       */
      getDeviceListByApi(workshopId) {
        console.log('车间Id', workshopId)
      },
      /**
       * æ‹–拽对象鼠标按键按下事件
       * @param event
       * ç‚¹å‡»ä¿å­˜æŒ‰é’®è°ƒç”¨æŽ¥å£ä¿å­˜æ‹–拽后的位置与设备图标尺寸
       */
      handleMouseDown(event) {
        this.dragging = true
        this.mouseX = event.clientX
        this.mouseY = event.clientY
        this.elementId = event.currentTarget.id
        this.top = event.currentTarget.offsetTop
        this.left = event.currentTarget.offsetLeft
        document.addEventListener('mousemove', this.handleMouseMove)
        document.addEventListener('mouseup', this.handleMouseUp)
        this.elementWidth = +event.currentTarget.style.width.replace('px', '')
        this.elementHeight = +event.currentTarget.style.height.replace('px', '')
      },
      /**
       * æ–‡æ¡£å¯¹è±¡é¼ æ ‡ç§»åŠ¨äº‹ä»¶
       * @param event
       */
      handleMouseMove(event) {
        if (this.dragging) {
          // x方向鼠标偏移量
          const deltaX = event.clientX - this.mouseX
          // y方向鼠标偏移量
          const deltaY = event.clientY - this.mouseY
          this.left += deltaX
          this.top += deltaY
          this.deviceList.forEach(item => {
            if (item.equipmentId === this.elementId) {
              item.top = this.top
              item.left = this.left
              // é™åˆ¶æ‹–拽超出区域(缩放浏览器窗口后距四周距离出现问题)
              if (item.top < 0) {
                item.top = 0
              } else if (item.top + this.elementHeight + 80 > window.innerHeight) {
                item.top = window.innerHeight - this.elementHeight
              }
              if (item.left < 0) {
                item.left = 0
              } else if (item.left + this.elementWidth > window.innerWidth) {
                item.left = window.innerWidth - this.elementWidth
              }
            }
          })
          this.mouseX = event.clientX
          this.mouseY = event.clientY
        }
      },
      /**
       * æ–‡æ¡£å¯¹è±¡é¼ æ ‡æŒ‰é”®å¼¹èµ·äº‹ä»¶
       * @param event
       */
      handleMouseUp(event) {
        this.dragging = false
        document.removeEventListener('mousemove', this.handleMouseMove)
        document.removeEventListener('mouseup', this.handleMouseUp)
      },
      /**
       * ç‚¹å‡»ä¿å­˜æŒ‰é’®è°ƒç”¨æŽ¥å£ä¿å­˜æ‹–拽后的位置
       */
      saveDevicePositionByApi() {
      saveDevicePositionAndSizeByApi() {
        console.log('保存位置')
      },
      /**
@@ -233,15 +174,27 @@
       */
      resize(newRect, index) {
        console.log('newRect', newRect)
        if (newRect.width > 200) {
        if (newRect.width > 100) {
          if (newRect.width / newRect.height < 2) {
          this.deviceList[index].fontSize = newRect.width / 10
        } else {
          this.deviceList[index].fontSize = 20
            this.deviceList[index].fontSize = newRect.height / 5
        }
        this.deviceList[index].top = newRect.top
        this.deviceList[index].left = newRect.left
        } else {
          this.deviceList[index].fontSize = 12
        }
        this.deviceList[index].vw = newRect.width
        this.deviceList[index].vh = newRect.height
        this.deviceList[index].top = newRect.top
        this.deviceList[index].left = newRect.left
      },
      /**
       * æ ¹æ®è®¾å¤‡çŠ¶æ€å€¼èŽ·å–å¯¹åº”è®¾å¤‡æ•°é‡
       * @param value è®¾å¤‡çŠ¶æ€å€¼
       * @returns {number} è®¾å¤‡æ•°é‡
       */
      getDeviceNumberByStatus(value) {
        return this.deviceList.filter(item => item.status === value).length
      }
    },
    mounted() {
@@ -267,6 +220,7 @@
      font-size: 50px;
      text-align: center;
      position: relative;
      .header-right {
        position: absolute;
        right: 200px;
@@ -276,6 +230,31 @@
    .content-container {
      position: relative;
      .device-status-info {
        width: 400px;
        position: absolute;
        top: 5px;
        right: 5px;
        display: flex;
        align-items: center;
        justify-content: space-between;
        .single-status-info {
          width: 60px;
          display: flex;
          align-items: center;
          justify-content: space-between;
          .status-square {
            width: 14px;
            height: 14px;
            border: 1px solid #fff;
            border-radius: 2px;
          }
        }
      }
      .single-device {
        position: absolute;
        border: 1px solid transparent;
@@ -285,20 +264,24 @@
        align-items: center;
        justify-content: space-between;
        cursor: default;
        &:active {
          border: 1px solid #1890ff;
        }
        .device-status {
          width: 100%;
          height: 100%;
          display: flex;
          justify-content: space-between;
          .status-image {
            background-size: 100% 100%;
            background-repeat: no-repeat;
            width: 45px;
            margin-right: 10px;
          }
          .device-image {
            background-size: 100% 100%;
            background-repeat: no-repeat;
@@ -306,22 +289,8 @@
            height: 100%;
          }
        }
        .device-id {
          /*font-size: 20px;*/
        }
        /*.device-info {*/
        /*width: 100%;*/
        /*display: flex;*/
        /*align-items: center;*/
        /*justify-content: space-between;*/
        /*.status-square {*/
        /*width: 14px;*/
        /*height: 14px;*/
        /*border: 1px solid #fff;*/
        /*border-radius: 2px;*/
        /*}*/
        /*}*/
      }
    }
  }
</style>
src/views/mdc/base/modules/StatisticalAnalysis/StatisticalAnalysisMain.vue
@@ -384,7 +384,6 @@
            name: '运行效率',
            type: 'pie',
            radius: '70%',
            center: ['55%', '55%'],
            itemStyle: {
              normal: {
                color: function (params) {
src/views/mdc/base/modules/alarmAnalysis/alarmAnalysisMain.vue
@@ -369,7 +369,6 @@
          series: [{
            type: 'pie',
            radius: '60%',
            center: ['55%', '55%'],
            itemStyle: {
              normal: {
                /*color: function (params) {
src/views/mdc/base/modules/openRateFractionAnalysis/openRateFractionAnalysisMain.vue
@@ -326,7 +326,7 @@
        let openRateTrendAnalysisChart = this.$echarts.init(document.getElementById('openRateTrendChart'), 'macarons')
        let openRateTrendChartOptions = {
          title: {
            text: '利用率走势分析',
            text: '利用率分段分析',
            x: 'center',
            textStyle: {
              fontSize: 18,
@@ -422,6 +422,7 @@
  .dataContent .mathData td {
    padding: 10px;
    /*display: none;*/
    cursor: pointer;
  }
  .dataContent .mathData:hover td {
src/views/mdc/base/modules/openRateTrendAnalysis/openRateTrendAnalysisMain.vue
@@ -428,6 +428,7 @@
  .dataContent .mathData td {
    padding: 10px;
    /*display: none;*/
    cursor: pointer;
  }
  .dataContent .mathData:hover td {
src/views/system/WorkshopSignageManagement.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,495 @@
<template>
  <a-row :gutter="10">
    <a-col :md="leftColMd" :sm="24" style="margin-bottom: 20px">
      <a-card :bordered="false">
        <!-- æŸ¥è¯¢åŒºåŸŸ -->
        <div class="table-page-search-wrapper">
          <!-- æœç´¢åŒºåŸŸ -->
          <a-form layout="inline" @keyup.enter.native="searchQuery">
            <a-row :gutter="24">
              <a-col :md="12" :sm="8">
                <a-form-item label="车间名称" :labelCol="{span: 5}" :wrapperCol="{span: 18, offset: 1}">
                  <a-input placeholder="" v-model="queryParam.roleName"></a-input>
                </a-form-item>
              </a-col>
              <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
            <a-col :md="12" :sm="24">
               <a-button type="primary" @click="searchQuery" icon="search" style="margin-left: 21px">查询</a-button>
              <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
            </a-col>
          </span>
            </a-row>
          </a-form>
        </div>
        <!-- æ“ä½œæŒ‰é’®åŒºåŸŸ -->
        <div class="table-operator" style="margin: 5px 0 10px 2px">
          <a-button @click="handleAdd" type="primary" icon="plus">新建车间</a-button>
        </div>
        <div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
          <i class="anticon anticon-info-circle ant-alert-icon">
          </i> å·²é€‰æ‹© <a><b>{{ selectedRowKeys1.length }}</b></a>项
          <a style="margin-left: 24px" @click="onClearSelected1">清空</a>
        </div>
        <div style="margin-top: 15px">
          <a-table
            style="height:500px"
            ref="table"
            size="middle"
            bordered
            rowKey="id"
            :columns="columns"
            :dataSource="dataSource"
            :pagination="ipagination"
            :loading="loading"
            :rowSelection="{selectedRowKeys: selectedRowKeys1, onChange: onSelectChange1, type:'radio'}"
            @change="handleTableChange">
            <template slot="backgroundImage" slot-scope="text,record">
              <img :src="getImgView(record.backgroundImage)" width="50" height="50">
            </template>
            <span slot="action" slot-scope="text, record">
            <a @click="handleOpen(record)">车间</a>
            <a-divider type="vertical"/>
            <a-dropdown>
              <a class="ant-dropdown-link">
                æ›´å¤š <a-icon type="down"/>
              </a>
              <a-menu slot="overlay">
                <a-menu-item>
                  <a @click="handleEdit(record)">编辑</a>
                </a-menu-item>
                <a-menu-item>
                  <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete1(record.id)">
                    <a>删除</a>
                  </a-popconfirm>
                </a-menu-item>
              </a-menu>
            </a-dropdown>
        </span>
          </a-table>
        </div>
      </a-card>
    </a-col>
    <a-col :md="rightColMd" :sm="24" v-if="this.rightcolval == 1">
      <a-card :bordered="false">
        <div style="text-align: right;">
          <a-icon type="close-circle" @click="hideUserList"/>
        </div>
        <!-- æŸ¥è¯¢åŒºåŸŸ -->
        <div class="table-page-search-wrapper">
          <a-form layout="inline">
            <a-row :gutter="24">
              <a-col :md="12" :sm="12">
                <a-form-item label="设备编码">
                  <a-input placeholder="" v-model="queryParam2.equipmentId"></a-input>
                </a-form-item>
              </a-col>
              <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
            <a-col :md="9" :sm="24">
             <a-button type="primary" @click="searchQuery2" icon="search" style="margin-left: 21px">查询</a-button>
              <a-button type="primary" @click="searchReset2" icon="reload" style="margin-left: 8px">重置</a-button>
            </a-col>
          </span>
            </a-row>
          </a-form>
        </div>
        <!-- æ“ä½œæŒ‰é’®åŒºåŸŸ -->
        <div class="table-operator" :md="24" :sm="24">
          <a-button @click="handleAddDeviceInWorkshop" type="primary" icon="plus" style="margin-top: 16px">已有设备
          </a-button>
          <a-dropdown v-if="selectedRowKeys2.length > 0">
            <a-menu slot="overlay">
              <a-menu-item key="1" @click="batchDel2">
                <a-icon type="delete"/>
                åˆ é™¤
              </a-menu-item>
            </a-menu>
            <a-button style="margin-left: 8px"> æ‰¹é‡æ“ä½œ
              <a-icon type="down"/>
            </a-button>
          </a-dropdown>
        </div>
        <!-- table区域-begin -->
        <div>
          <div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
            <i class="anticon anticon-info-circle ant-alert-icon"></i> å·²é€‰æ‹© <a style="font-weight: 600">{{
            selectedRowKeys2.length }}</a>项
            <a style="margin-left: 24px" @click="onClearSelected2">清空</a>
          </div>
          <a-table
            style="height:500px"
            ref="table2"
            bordered
            size="middle"
            rowKey="equipmentId"
            :columns="columns2"
            :dataSource="dataSource2"
            :pagination="ipagination2"
            :loading="loading2"
            :rowSelection="{selectedRowKeys: selectedRowKeys2, onChange: onSelectChange2}"
            @change="handleTableChange2">
            <span slot="action" slot-scope="text, record">
          <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete2(record.equipmentId)">
                  <a>删除</a>
          </a-popconfirm>
        </span>
          </a-table>
        </div>
      </a-card>
    </a-col>
    <!-- è¡¨å•区域 -->
    <workshop-modal ref="modalForm" @ok="modalFormOk"></workshop-modal> <!--新增车间-->
    <select-device-modal ref="selectUserModal" @selectFinished="selectOK"></select-device-modal> <!--已有设备-->
  </a-row>
</template>
<script>
  import { JeecgListMixin } from '@/mixins/JeecgListMixin'
  import { deleteAction, postAction, getAction } from '@/api/manage'
  import SelectDeviceModal from './modules/SelectDeviceModal'
  import WorkshopModal from './modules/WorkshopModal'
  import { filterObj } from '@/utils/util'
  import moment from 'moment'
  export default {
    name: 'WorkshopSignageManagement',
    mixins: [JeecgListMixin],
    components: {
      SelectDeviceModal,
      WorkshopModal,
      moment
    },
    data() {
      return {
        model1: {},
        model2: {},
        currentRoleId: '',
        currentWorkshopId: '',
        queryParam1: {},
        queryParam2: {},
        dataSource1: [],
        dataSource2: [],
        ipagination1: {
          current: 1,
          pageSize: 10,
          pageSizeOptions: ['10', '20', '30'],
          showTotal: (total, range) => {
            return range[0] + '-' + range[1] + ' å…±' + total + '条'
          },
          showQuickJumper: true,
          showSizeChanger: true,
          total: 0
        },
        ipagination2: {
          current: 1,
          pageSize: 10,
          pageSizeOptions: ['10', '20', '30'],
          showTotal: (total, range) => {
            return range[0] + '-' + range[1] + ' å…±' + total + '条'
          },
          showQuickJumper: true,
          showSizeChanger: true,
          total: 0
        },
        isorter1: {
          column: 'createTime',
          order: 'desc'
        },
        isorter2: {
          column: 'createTime',
          order: 'desc'
        },
        filters1: {},
        filters2: {},
        loading1: false,
        loading2: false,
        selectedRowKeys1: [],
        selectedRowKeys2: [],
        selectionRows1: [],
        selectionRows2: [],
        test: {},
        rightcolval: 0,
        columns: [
          {
            title: '车间名称',
            align: 'center',
            dataIndex: 'workshopName'
          },
          {
            title: '车间背景图',
            dataIndex: 'backgroundImage',
            align: 'center',
            scopedSlots: { customRender: 'backgroundImage' }
          },
          {
            title: '操作',
            dataIndex: 'action',
            align: 'center',
            scopedSlots: { customRender: 'action' }
          }
        ],
        columns2: [
          {
            title: '设备编码',
            align: 'center',
            dataIndex: 'equipmentId',
            width: 120
          },
          {
            title: '设备名称',
            align: 'center',
            width: 100,
            dataIndex: 'equipmentName'
          },
          {
            title: '设备类型',
            align: 'center',
            width: 80,
            dataIndex: 'equipmentType'
          },
          {
            title: '操作',
            dataIndex: 'action',
            scopedSlots: { customRender: 'action' },
            align: 'center',
            width: 120
          }],
        // é«˜çº§æŸ¥è¯¢å‚æ•°
        superQueryParams2: '',
        // é«˜çº§æŸ¥è¯¢æ‹¼æŽ¥æ¡ä»¶
        superQueryMatchType2: 'and',
        url: {
          list: '/mdc/mdcWorkshopInfo/list',
          delete: '/sys/role/delete',
          list2: '/mdc/mdcWorkshopInfo/workshopEquipmentList',
          addDeviceInWorkshop: '/mdc/mdcWorkshopInfo/addWorkshopEquipment',
          delete2: '/mdc/mdcWorkshopInfo/deleteWorkshopEquipment',
          deleteBatch2: '/mdc/mdcWorkshopInfo/deleteWorkshopEquipmentBatch'
        }
      }
    },
    computed: {
      leftColMd() {
        return this.selectedRowKeys1.length === 0 ? 24 : 12
      },
      rightColMd() {
        return this.selectedRowKeys1.length === 0 ? 0 : 12
      }
    },
    methods: {
      onSelectChange2(selectedRowKeys, selectionRows) {
        this.selectedRowKeys2 = selectedRowKeys
        this.selectionRows2 = selectionRows
      },
      onClearSelected2() {
        this.selectedRowKeys2 = []
        this.selectionRows2 = []
      },
      onClearSelected1() {
        this.selectedRowKeys1 = []
        this.selectionRows1 = []
      },
      onSelectChange1(selectedRowKeys, selectionRows) {
        this.rightcolval = 1
        this.selectedRowKeys1 = selectedRowKeys
        this.selectionRows1 = selectionRows
        this.model1 = Object.assign({}, selectionRows[0])
        this.currentWorkshopId = selectedRowKeys[0]
        this.loadData2()
      },
      getQueryParams2() {
        //获取查询条件
        let sqp = {}
        if (this.superQueryParams2) {
          sqp['superQueryParams'] = encodeURI(this.superQueryParams2)
          sqp['superQueryMatchType'] = this.superQueryMatchType2
        }
        var param = Object.assign(sqp, this.queryParam2, this.isorter2, this.filters2)
        param.field = this.getQueryField2()
        param.pageNo = this.ipagination2.current
        param.pageSize = this.ipagination2.pageSize
        return filterObj(param)
      },
      getQueryField2() {
        //TODO å­—段权限控制
        var str = 'id,'
        this.columns2.forEach(function(value) {
          str += ',' + value.dataIndex
        })
        return str
      },
      modalFormOk2() {
        // æ–°å¢ž/修改 æˆåŠŸæ—¶ï¼Œé‡è½½åˆ—è¡¨
        this.loadData2()
      },
      loadData2(arg) {
        if (!this.url.list2) {
          this.$message.error('请设置url.list2属性!')
          return
        }
        //加载数据 è‹¥ä¼ å…¥å‚æ•°1则加载第一页的内容
        if (arg === 1) {
          this.ipagination2.current = 1
        }
        if (this.currentWorkshopId === '') return
        let params = this.getQueryParams2()//查询条件
        params.workshopId = this.currentWorkshopId
        this.loading2 = true
        getAction(this.url.list2, params).then((res) => {
          if (res.success) {
            this.dataSource2 = res.result.records
            this.ipagination2.total = res.result.total
          }
          this.loading2 = false
        })
      },
      handleDelete1: function(id) {
        this.handleDelete(id)
        this.dataSource2 = []
        this.currentRoleId = ''
      },
      /**
       * ç‚¹å‡»è®¾å¤‡è¡¨æ ¼ä¸­çš„删除按钮后触发删除单个车间与设备的关系
       * @param equipmentId å½“前行的设备编号
       */
      handleDelete2: function(equipmentId) {
        if (!this.url.delete2) {
          this.$message.error('请设置url.delete2属性!')
          return
        }
        var that = this
        deleteAction(that.url.delete2, { workshopId: this.currentWorkshopId, equipmentId }).then((res) => {
          if (res.success) {
            that.$message.success(res.message)
            that.loadData2()
          } else {
            that.$message.warning(res.message)
          }
        })
      },
      /**
       * æ‰¹é‡åˆ é™¤è½¦é—´ä¸Žè®¾å¤‡çš„关系
       */
      batchDel2: function() {
        if (!this.url.deleteBatch2) {
          this.$message.error('请设置url.deleteBatch2属性!')
          return
        }
        if (this.selectedRowKeys2.length <= 0) {
          // this.$message.warning('请选择一条记录!')
          this.$notification.warning({
            message: '消息',
            description: '请选择一条记录'
          })
          return
        } else {
          var ids = ''
          for (var a = 0; a < this.selectedRowKeys2.length; a++) {
            ids += this.selectedRowKeys2[a] + ','
          }
          var that = this
          this.$confirm({
            title: '确认删除',
            content: '是否删除选中数据?',
            onOk: function() {
              deleteAction(that.url.deleteBatch2, {
                workshopId: that.currentWorkshopId,
                equipmentIds: ids
              }).then((res) => {
                if (res.success) {
                  that.$message.success(res.message)
                  that.loadData2()
                  that.onClearSelected()
                } else {
                  that.$message.warning(res.message)
                }
              })
            }
          })
        }
      },
      /**
       * é€‰æ‹©å·²æœ‰è®¾å¤‡åŽç‚¹å‡»ç¡®å®šæ—¶è§¦å‘
       * @param data å·²é€‰æ‹©çš„设备
       */
      selectOK(data) {
        let params = {}
        params.workshopId = this.currentWorkshopId
        params.equipmentIdList = []
        for (var a = 0; a < data.length; a++) {
          params.equipmentIdList.push(data[a])
        }
        console.log(params)
        postAction(this.url.addDeviceInWorkshop, params).then((res) => {
          if (res.success) {
            this.loadData2()
            this.$message.success(res.message)
          } else {
            this.$message.warning(res.message)
          }
        })
      },
      /**
       * ç‚¹å‡»å·²æœ‰è®¾å¤‡æŒ‰é’®è§¦å‘
       */
      handleAddDeviceInWorkshop() {
        if (this.currentWorkshopId == '') {
          this.$message.error('请选择一个车间!')
        } else {
          this.$refs.selectUserModal.visible = true
          this.$refs.selectUserModal.selectedRowKeys = []
          this.$refs.selectUserModal.selectedRows = []
        }
      },
      /**
       * ç‚¹å‡»å½“前行车间选项后触发事件
       * @param record å½“前行数据
       */
      handleOpen(record) {
        this.rightcolval = 1
        this.selectedRowKeys1 = [record.id]
        this.model1 = Object.assign({}, record)
        this.currentWorkshopId = record.id
        this.onClearSelected2()
        this.loadData2()
      },
      searchQuery2() {
        this.loadData2(1)
      },
      searchReset2() {
        this.queryParam2 = {}
        this.loadData2(1)
      },
      handleTableChange2(pagination, filters, sorter) {
        //分页、排序、筛选变化时触发
        //TODO ç­›é€‰
        if (Object.keys(sorter).length > 0) {
          this.isorter2.column = sorter.field
          this.isorter2.order = 'ascend' == sorter.order ? 'asc' : 'desc'
        }
        this.ipagination2 = pagination
        this.loadData2()
      },
      hideUserList() {
        //this.rightcolval = 0
        this.selectedRowKeys1 = []
      }
    }
  }
</script>
<style scoped>
  /** Button按钮间距 */
  .ant-btn {
    margin-left: 8px
  }
</style>
src/views/system/modules/SelectDeviceModal.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,256 @@
<template>
  <div>
    <a-modal
      centered
      :title="title"
      :width="1000"
      :visible="visible"
      @ok="handleOk"
      @cancel="handleCancel"
      cancelText="关闭">
      <!-- æŸ¥è¯¢åŒºåŸŸ -->
      <div class="table-page-search-wrapper">
        <a-form layout="inline" @keyup.enter.native="searchQuery">
          <a-row :gutter="24">
            <a-col :span="10">
              <a-form-item label="设备名称">
                <a-input placeholder="请输入设备名称" v-model="queryParam.equipmentName"></a-input>
              </a-form-item>
            </a-col>
            <a-col :span="8">
                    <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
                      <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
                      <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
                    </span>
            </a-col>
          </a-row>
        </a-form>
      </div>
      <!-- table区域-begin -->
      <div>
        <a-table
          size="small"
          bordered
          rowKey="equipmentId"
          :columns="columns1"
          :dataSource="dataSource1"
          :pagination="ipagination"
          :loading="loading"
          :scroll="{ y: 240 }"
          :rowSelection="{selectedRowKeys: selectedRowKeys,onSelectAll:onSelectAll,onSelect:onSelect,onChange: onSelectChange}"
          @change="handleTableChange">
        </a-table>
      </div>
      <!-- table区域-end -->
    </a-modal>
  </div>
</template>
<script>
  import { filterObj } from '@/utils/util'
  import { getAction } from '@/api/manage'
  export default {
    name: 'SelectDeviceModal',
    data() {
      return {
        title: '添加已有设备',
        names: [],
        visible: false,
        placement: 'right',
        description: '',
        // æŸ¥è¯¢æ¡ä»¶
        queryParam: {},
        // è¡¨å¤´
        columns1: [
          {
            title: '#',
            dataIndex: '',
            key: 'rowIndex',
            width: 50,
            align: 'center',
            customRender: function(t, r, index) {
              return parseInt(index) + 1
            }
          },
          {
            title: '设备编号',
            align: 'center',
            width: 100,
            dataIndex: 'equipmentId'
          },
          {
            title: '设备名称',
            align: 'center',
            width: 100,
            dataIndex: 'equipmentName'
          },
          {
            title: '设备类型',
            align: 'center',
            width: 100,
            dataIndex: 'equipmentType'
          },
          {
            title: '驱动类型',
            align: 'center',
            width: 100,
            dataIndex: 'driveType'
          }
        ],
        //数据集
        dataSource1: [],
        dataSource2: [],
        // åˆ†é¡µå‚æ•°
        ipagination: {
          current: 1,
          pageSize: 10,
          pageSizeOptions: ['10', '20', '30'],
          showTotal: (total, range) => {
            return range[0] + '-' + range[1] + ' å…±' + total + '条'
          },
          showQuickJumper: true,
          showSizeChanger: true,
          total: 0
        },
        loading: false,
        selectedRowKeys: [],
        selectedRows: [],
        url: {
          list: '/mdc/mdcEquipment/list'
        }
      }
    },
    created() {
      this.loadData()
    },
    methods: {
      searchQuery() {
        this.loadData(1)
      },
      searchReset() {
        this.queryParam = {}
        this.loadData(1)
      },
      handleCancel() {
        this.visible = false
      },
      handleOk() {
        this.dataSource2 = this.selectedRowKeys
        console.log('data---------' + this.dataSource2)
        if (this.dataSource2.length > 0) {
          this.$emit('selectFinished', this.dataSource2)
        }
        this.visible = false
      },
      add() {
        this.visible = true
      },
      loadData(arg) {
        //加载数据 è‹¥ä¼ å…¥å‚æ•°1则加载第一页的内容
        if (arg === 1) {
          this.ipagination.current = 1
        }
        var params = this.getQueryParams()//查询条件
        getAction(this.url.list, params).then((res) => {
          if (res.success) {
            this.dataSource1 = res.result.records
            this.ipagination.total = res.result.total
          }
        })
      },
      getQueryParams() {
        var param = Object.assign({}, this.queryParam, this.isorter)
        param.field = this.getQueryField()
        param.pageNo = this.ipagination.current
        param.pageSize = this.ipagination.pageSize
        return filterObj(param)
      },
      getQueryField() {
        //TODO å­—段权限控制
      },
      onSelectAll(selected, selectedRows, changeRows) {
        if (selected === true) {
          for (var a = 0; a < changeRows.length; a++) {
            this.dataSource2.push(changeRows[a])
          }
        } else {
          for (var b = 0; b < changeRows.length; b++) {
            this.dataSource2.splice(this.dataSource2.indexOf(changeRows[b]), 1)
          }
        }
        // console.log(selected, selectedRows, changeRows);
      },
      onSelect(record, selected) {
        console.log(this.selectedRowKeys)
        if (selected === true) {
          this.dataSource2.push(record)
        } else {
          var index = this.dataSource2.indexOf(record)
          //console.log();
          if (index >= 0) {
            this.dataSource2.splice(this.dataSource2.indexOf(record), 1)
          }
        }
      },
      onSelectChange(selectedRowKeys, selectedRows) {
        console.log('selectedRowKeys', selectedRowKeys)
        this.selectedRowKeys = selectedRowKeys
        this.selectionRows = selectedRows
      },
      onClearSelected() {
        this.selectedRowKeys = []
        this.selectionRows = []
      },
      handleDelete: function(record) {
        this.dataSource2.splice(this.dataSource2.indexOf(record), 1)
      },
      handleTableChange(pagination, filters, sorter) {
        //分页、排序、筛选变化时触发
        console.log(sorter)
        //TODO ç­›é€‰
        if (Object.keys(sorter).length > 0) {
          this.isorter.column = sorter.field
          this.isorter.order = 'ascend' == sorter.order ? 'asc' : 'desc'
        }
        this.ipagination = pagination
        this.loadData()
      }
    }
  }
</script>
<style lang="less" scoped>
  .ant-card-body .table-operator {
    margin-bottom: 18px;
  }
  .ant-table-tbody .ant-table-row td {
    padding-top: 15px;
    padding-bottom: 15px;
  }
  .anty-row-operator button {
    margin: 0 5px
  }
  .ant-btn-danger {
    background-color: #ffffff
  }
  .ant-modal-cust-warp {
    height: 100%
  }
  .ant-modal-cust-warp .ant-modal-body {
    height: calc(100% - 110px) !important;
    overflow-y: auto
  }
  .ant-modal-cust-warp .ant-modal-content {
    height: 90% !important;
    overflow-y: hidden
  }
</style>
src/views/system/modules/UserModal.vue
@@ -238,9 +238,9 @@
        //根据屏幕宽度自适应抽屉宽度
        this.resetScreenSize();
        that.userId = record.id;
        that.model = Object.assign({},{selectedroles:'',selecteddeparts:''}, record);
        that.model = Object.assign({},{selectedroles:'',selectedProduction:''}, record);
        //身份为上级显示负责部门,否则不显示
        if(this.model.userIdentity==2){
          this.departIdShow=true;
@@ -252,7 +252,7 @@
          that.getUserRoles(record.id);
          that.getUserDeparts(record.id);
        }
        console.log('that.model=',that.model)
        console.log('that.model',that.model)
      },
      isDisabledAuth(code){
        return disabledAuthFilter(code);
@@ -366,8 +366,6 @@
          return c;
        })
      },
      refresh () {
        this.userId=""
src/views/system/modules/WorkshopModal.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,134 @@
<template>
  <a-modal
    :title="title"
    :width="800"
    :visible="visible"
    :confirmLoading="confirmLoading"
    @ok="handleOk"
    @cancel="handleCancel"
    cancelText="关闭"
    wrapClassName="ant-modal-cust-warp"
    style="top:5%;height: 85%;overflow-y: hidden">
    <a-spin :spinning="confirmLoading">
      <a-form-model ref="form" v-bind="layout" :model="model" :rules="validatorRules">
        <a-form-model-item label="车间编号" required prop="id">
          <a-input v-model="model.id" :disabled="isEdit" placeholder="请输入车间编号"/>
        </a-form-model-item>
        <a-form-model-item label="车间名称" required prop="workshopName">
          <a-input v-model="model.workshopName" placeholder="请输入车间名称"/>
        </a-form-model-item>
        <a-form-model-item label="车间背景图" required prop="backgroundImage">
          <j-image-upload class="avatar-uploader" text="上传" v-model="model.backgroundImage"></j-image-upload>
        </a-form-model-item>
      </a-form-model>
    </a-spin>
  </a-modal>
</template>
<script>
  import api from '@/api/mdc'
  export default {
    name: 'WorkshopModal',
    data() {
      return {
        title: '操作',
        visible: false,
        isEdit: false,
        model: {},
        layout: {
          labelCol: { span: 3 },
          wrapperCol: { span: 14 }
        },
        confirmLoading: false,
        validatorRules: {
          workshopName: [
            { required: true, message: '请输入车间名称!' },
            { min: 2, max: 30, message: '长度在 2 åˆ° 30 ä¸ªå­—符', trigger: 'blur' }
          ],
          id: [
            { required: true, message: '请输入车间编号!' },
            { min: 0, max: 64, message: '长度不超过 64 ä¸ªå­—符', trigger: 'blur' },
            { validator: this.validateRoleCode }
          ],
          backgroundImage:[
            { required: true, message: '请上传车间背景图!' }
          ]
        }
      }
    },
    created() {
      //备份model原始值
      this.modelDefault = JSON.parse(JSON.stringify(this.model))
    },
    methods: {
      add() {
        this.edit(this.modelDefault)
      },
      edit(record) {
        this.model = Object.assign({}, record)
        this.visible = true
        //编辑页面禁止修改角色编码
        if (this.model.id) {
          this.isEdit = true
        } else {
          this.isEdit = false
        }
      },
      close() {
        this.$refs.form.clearValidate()
        this.$emit('close')
        this.visible = false
      },
      handleOk() {
        const that = this
        // è§¦å‘表单验证
        this.$refs.form.validate(valid => {
          if (valid) {
            console.log('触发')
            that.confirmLoading = true
            let obj
            if (!this.isEdit) {
              console.log('触发新增')
              obj = api.addWorkshopApi(this.model)
            } else {
              console.log('触发修改')
              obj = api.editWorkshopApi(this.model)
            }
            obj.then((res) => {
              if (res.success) {
                that.$message.success(res.message)
                that.$emit('ok')
              } else {
                that.$message.warning(res.message)
              }
            }).finally(() => {
              that.confirmLoading = false
              that.close()
            })
          } else {
            return false
          }
        })
      },
      handleCancel() {
        this.close()
      },
      validateRoleCode(rule, value, callback) {
        if (/[\u4E00-\u9FA5]/g.test(value)) {
          callback('车间编号不可输入汉字!')
        } else {
          callback()
        }
      }
    }
  }
</script>
<style scoped>
  .avatar-uploader > .ant-upload {
    width: 104px;
    height: 104px;
  }
</style>