cuilei
2025-06-24 a22a69946912221dab4d32987dda6c4c8ba3c5d8
Merge remote-tracking branch 'origin/master'
已添加2个文件
已修改22个文件
3069 ■■■■■ 文件已修改
src/api/dnc.js 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dnc/base/modules/DeviceStructure/DeviceStructureMainTop.vue 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dnc/base/modules/DeviceStructure/Document/HasReceivedDocumentAssignModal.vue 543 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dnc/base/modules/DeviceStructure/Document/HasReceivedDocumentTableList.vue 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dnc/base/modules/ProductStructure/Document/NcDocumentAssignModal.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dnc/base/modules/ProductStructure/Document/NcDocumentTableList.vue 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dnc/base/modules/ProductStructure/GuideCardBatch/GuideCardBatchForm.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dnc/base/modules/ProductStructure/GuideCardBatch/GuideCardBatchList.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dnc/common/TableContextMenu.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/flowable/workflow/FlowTodo.vue 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/flowable/workflow/assignEquipmentFileStream/AssignEquipmentFileStreamHandle.vue 392 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mdc/base/DeliveryGroupUtilizationRateChart.vue 504 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mdc/base/DeviceParamThresholdManagement.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mdc/base/GroupEquipmentUtilizationRateChart.vue 444 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mdc/base/GroupUtilizationRateChart.vue 442 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mdc/base/GroupUtilizationRateCompareChart.vue 345 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mdc/base/modules/DeviceLog/LogInfo.vue 159 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mdc/base/modules/PartsMatchingManagement/PartsMatchingForm.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mdc/base/modules/TorqueconfigurationList/TorqueconfigurationList.vue 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mdc/base/modules/TorqueconfigurationList/TorqueconfigurationModal.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mdc/base/modules/comparativeAnalysis/ComparativeAnalysisMain.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mdc/base/modules/deviceCalendar/DeviceCalendarList.vue 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mdc/base/modules/deviceCalendar/DeviceCalendarModel.vue 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mdc/base/modules/efficiencyReport/EfficiencyList.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/dnc.js
@@ -28,13 +28,13 @@
  // æŒ‡æ´¾æ–‡æ¡£åˆ°è®¾å¤‡
  assignDocumentToDeviceApi: params => postAction('/nc/activit/assign/file/apply', params),
  // æå–刀具
  extractToolsApi: ({ docId,attributionType, attributionId}) => getAction(`/nc/cutter/extractCutterInfo/${docId}/${attributionType}/${attributionId}`),
  extractToolsApi: ({ docId, attributionType, attributionId }) => getAction(`/nc/cutter/extractCutterInfo/${docId}/${attributionType}/${attributionId}`),
  // å‘送刀具系统
  sendToolsApi: ({ docId,attributionType, attributionId}) => getAction(`/nc/cutter/sendCutterInfo/${docId}/${attributionType}/${attributionId}`),
  sendToolsApi: ({ docId, attributionType, attributionId }) => getAction(`/nc/cutter/sendCutterInfo/${docId}/${attributionType}/${attributionId}`),
  // ä¸‹è½½æ–‡æ¡£
  downloadDocumentApi: ({ docId, docName }) => requestGetDownLoad(`/nc/doc/download/${docId}`, docName),
  // åˆ é™¤æ–‡æ¡£
  deleteDocumentApi: ({ docId,attributionType, attributionId}) => deleteAction(`/nc/doc/delete/${docId}/${attributionType}/${attributionId}`),
  deleteDocumentApi: ({ docId, attributionType, attributionId }) => deleteAction(`/nc/doc/delete/${docId}/${attributionType}/${attributionId}`),
  // æ–‡æ¡£å‡ºåº“
  documentOutboundApi: ({ docId, docName }) => requestGetDownLoad(`/nc/doc/pull/${docId}`, docName),
  // æ–‡æ¡£å–消出库
@@ -85,6 +85,10 @@
  //-------------------------设备结构树------------------------------------------------
  // èŽ·å–è®¾å¤‡æ ‘
  getDeviceTreeDataApi: () => getAction('/nc/device/queryTreeListByProduction'),
  // èŽ·å–äº§å“ç»“æž„æ ‘å®Œæ•´å±‚çº§åˆ°NC文件
  getAllProductTreeDataApi: () => getAction('/nc/product/getAllTree'),
  // æŒ‡æ´¾åˆ°äº§å“
  assignNcToProductApi: params => postAction('/dncFlow/assignEquipmentFileStream/savaFlow', params),
  // åˆ é™¤æ–‡æ¡£
  deleteDeviceRelativeDocumentApi: ({ docId, attributionId }) => deleteAction(`doc/relative/delete/device/${docId}/${attributionId}`),
  // èŽ·å–æœ‰æƒé™çš„ç”¨æˆ·åˆ—è¡¨
src/views/dnc/base/modules/DeviceStructure/DeviceStructureMainTop.vue
@@ -47,7 +47,7 @@
      currentRightClickedTableRowInfo: {},
      hasLoadedDataTabKeyArray: [],
      url:{
        submitProccess:'/dncFlow/dispatchFile/submitProccess'
      }
    }
  },
@@ -166,47 +166,6 @@
                  description: res.message
                })
              }
            })
            .finally(() => {
              that.$destroyAll()
            })
        },
        onCancel: () => {
          that.$destroyAll()
        }
      })
    },
    handleAppoint(){
      const that = this
      const { docId, param, attributionId,attributionType,publishFileId } = this.currentRightClickedTableRowInfo
      that.$confirm({
        title: '提示',
        content: `确认定型吗?`,
        okText: '确认',
        cancelText: '取消',
        onOk: () => {
          let dispatchFile = {
            'docId':docId,
            'attributionId':attributionId,
            'attributionType':attributionType,
            'fileId':publishFileId
          }
          postAction(this.url.submitProccess,dispatchFile)
            .then(res => {
              if (res.success) {
                this.$message.success('流程发起成功')
              } else {
                that.$notification.error({
                  message: '消息',
                  description: res.message
                })
              }
            })
            .catch(err => {
              that.$notification.error({
                message: '消息',
                description: err.message
              })
            })
            .finally(() => {
              that.$destroyAll()
src/views/dnc/base/modules/DeviceStructure/Document/HasReceivedDocumentAssignModal.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,543 @@
<template>
  <j-modal width="85%" :title="title" :visible="visible" @cancel="handleCancel" :maskClosable="false" centered
           @ok="handleAssignDocumentToDevice" :confirmLoading="confirmLoading">
    <div class="tabs-container">
      <div style="width: 72%">
        <a-tabs>
          <a-tab-pane tab="文档列表">
            <div class="table-page-search-wrapper">
              <a-form layout="inline" @keyup.enter.native="searchQuery">
                <a-row :gutter="24">
                  <a-col :md="7" :sm="7">
                    <a-form-item label="文件名称">
                      <a-input placeholder="请输入文件名称" v-model="queryParam.docName" allow-clear></a-input>
                    </a-form-item>
                  </a-col>
                  <a-col :md="9" :sm="9">
                    <a-form-item label="上传时间">
                      <a-range-picker v-model="date" value-format="YYYY-MM-DD"
                                      @change="handleDateChange" allow-clear></a-range-picker>
                    </a-form-item>
                  </a-col>
                  <a-col :md="4" :sm="4">
                    <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
                  </a-col>
                </a-row>
              </a-form>
            </div>
            <a-table :columns="columns" :data-source="dataSource" bordered :pagination="false" :loading="loading"
                     :rowSelection="{selectedRowKeys: selectedRowKeys,selectedRows:selectionRows, onChange: onSelectChange,type:'radio'}"
                     @change="handleTableChange" :customRow="customRow"
                     :scroll="{y:456}" :size="size" rowKey="docId">
              <!-- å­—符串超长截取省略号显示-->
              <span slot="docName" slot-scope="text">
                <j-ellipsis :value="text"/>
              </span>
            </a-table>
          </a-tab-pane>
        </a-tabs>
      </div>
      <div style="width: 26%">
        <a-tabs>
          <a-tab-pane tab="设备列表">
            <a-spin :spinning="spinning">
              <div style="display: flex;flex-direction: column;">
                <div style="display: flex">
                  <a-input placeholder="输入关键字进行搜索" allowClear v-model="searchInput"
                           @change="handleSearchInputChange"/>
                  <a-button type="primary" @click="isExpandAllTreeNode=!isExpandAllTreeNode" style="margin: 0 8px">
                    å±•å¼€/折叠
                  </a-button>
                </div>
                <!--产品结构树-->
                <div style="overflow:auto;margin-top: 10px;height: 400px">
                  <a-tree blockNode checkable :checkedKeys="checkedKeys" :expandedKeys.sync="expandedKeys"
                          :autoExpandParent="autoExpandParent" @select="handleTreeNodeSelect" checkStrictly
                          :treeData="treeDataSource" @check="handleTreeNodeCheck" @expand="handleTreeNodeExpand">
                    <template slot="title" slot-scope="{ label, parentId, entity, key:treeKey,type}">
                      <a-tooltip :title="label" v-if="type==99">
                          <span v-if="label.indexOf(searchValue) > -1">
                      {{ label.substr(0, label.indexOf(searchValue)) }}
                      <span class="replaceSearch">{{searchValue}}</span>
                      {{ label.substr(label.indexOf(searchValue) + searchValue.length) }}
                    </span>
                        <span v-else>{{ label }}</span>
                      </a-tooltip>
                      <template v-else>
                         <span v-if="label.indexOf(searchValue) > -1">
                      {{ label.substr(0, label.indexOf(searchValue)) }}
                      <span class="replaceSearch">{{searchValue}}</span>
                      {{ label.substr(label.indexOf(searchValue) + searchValue.length) }}
                    </span>
                        <span v-else>{{ label }}</span>
                      </template>
                    </template>
                  </a-tree>
                </div>
                <a-form-model ref="form" :rules="validateRules" :model="queryParam">
                  <a-form-model-item label="指派原因" prop="applyReason">
                    <a-textarea placeholder="请输入指派原因" v-model="queryParam.applyReason" rows="3" style="resize: none"/>
                  </a-form-model-item>
                </a-form-model>
              </div>
            </a-spin>
          </a-tab-pane>
        </a-tabs>
      </div>
    </div>
  </j-modal>
</template>
<script>
  import { getAction } from '@/api/manage'
  import dncApi from '@/api/dnc'
  import { JeecgListMixin } from '@/mixins/JeecgListMixin'
  export default {
    name: 'HasReceivedDocumentAssignModal',
    components: {},
    mixins: [JeecgListMixin],
    props: {
      currentDocumentInfo: {
        type: Object
      },
      currentTreeNodeInfo: {
        type: Object
      },
      size: {
        type: String
      }
    },
    data() {
      return {
        disableMixinCreated: true,
        visible: false,
        title: '',
        columns: [
          {
            title: '序号',
            dataIndex: 'rowIndex',
            key: 'rowIndex',
            width: 65,
            align: 'center',
            customRender: function(t, r, index) {
              return parseInt(index) + 1
            }
          },
          {
            title: '文件名称',
            dataIndex: 'docName',
            key: 'docName',
            align: 'center',
            scopedSlots: { customRender: 'docName' },
            sorter: true
          },
          { title: '设备编号', dataIndex: 'docCode', align: 'center' },
          {
            title: '出库状态',
            dataIndex: 'pullStatus_dictText',
            key: 'pullStatus',
            align: 'center',
            filters: [
              { text: '未出库', value: 1 },
              { text: '已出库', value: 2 }
            ]
          },
          {
            title: '状  æ€',
            dataIndex: 'docDispatchStatus_dictText',
            key: 'docDispatchStatus',
            align: 'center',
            filters: [
              { text: '编制', value: 1 },
              { text: '校对', value: 2 },
              { text: '批准', value: 3 },
              { text: '试切', value: 4 },
              { text: '定型', value: 5 }
            ]
          },
          {
            title: '创建时间',
            dataIndex: 'createTime',
            align: 'center',
            width: 200,
            sorter: true
          }
        ],
        validateRules: {
          applyReason: [
            { required: true, message: '请输入指派原因' }
          ]
        },
        searchValue: '',
        searchInput: '',
        spinning: false,
        treeDataSource: [],
        allTreeKeys: [],
        checkedKeys: [],
        expandedKeys: [],
        autoExpandParent: true,
        isExpandAllTreeNode: false,
        confirmLoading: false,
        date: [],
        url: {
          list: '/nc/doc/find/list'
        }
      }
    },
    watch: {
      visible: {
        handler(value) {
          if (value) {
            this.resetData()
            this.loadData()
            this.getDocumentAssignDeviceTreeByApi()
          }
        }
      },
      isExpandAllTreeNode: {
        handler(value) {
          if (value) this.expandedKeys = this.allTreeKeys
          else this.expandedKeys = []
        }
      }
    },
    created() {
      this.$bus.$on('treeMenuItemMethodTrigger', this.triggerCorrespondingMethod)
    },
    beforeDestroy() {
      this.$bus.$off('treeMenuItemMethodTrigger', this.triggerCorrespondingMethod)
    },
    methods: {
      // è®¾å¤‡æ ‘右键菜单指派到产品弹窗
      handleDeviceRecAssign() {
        this.visible = true
      },
      // èŽ·å–å½“å‰å·¥åºæˆ–å·¥æ­¥å¯¹åº”æ–‡æ¡£åˆ—è¡¨
      loadData() {
        this.dataSource = []
        if (!this.url.list) {
          this.$message.error('请设置url.list属性!')
          return
        }
        var params = this.getQueryParams()//查询条件
        if (!params) return false
        let paramType, paramId
        if (this.currentTreeNodeInfo) {
          const { key, type } = this.currentTreeNodeInfo
          paramType = type
          paramId = key
        } else if (this.currentDocumentInfo) {
          const { attributionType, attributionId } = this.currentDocumentInfo
          paramType = attributionType
          paramId = attributionId
        }
        params.attributionType = paramType
        params.attributionId = paramId
        params.docClassCode = 'REC'
        this.loading = true
        getAction(this.url.list, params)
          .then((res) => {
            if (res.success) this.dataSource = res.result
            else this.$message.warning(res.message)
          }).finally(() => {
          this.loading = false
        })
      },
      /**
       * è‡ªå®šä¹‰è¡¨æ ¼è¡Œ
       * @param record è¡¨æ ¼è¡Œè®°å½•
       */
      customRow(record) {
        return {
          style: {
            cursor: 'pointer'
          },
          on: {
            click: () => {
              this.onSelectChange([record.docId], [record])
            }
          }
        }
      },
      // èŽ·å–DNC产品树
      getDocumentAssignDeviceTreeByApi() {
        this.spinning = true
        this.treeDataSource = []
        dncApi.getAllProductTreeDataApi()
          .then(res => {
            if (res.success) {
              this.dataList = []
              this.allTreeKeys = []
              this.treeDataSource = res.result
              console.log('treeDataSource', res.result)
              this.generateList(this.treeDataSource)
              this.expandedKeys = [this.treeDataSource[0].id]
            } else {
              this.$message.warn(res.message)
            }
          })
          .finally(() => {
            this.spinning = false
          })
      },
      // æ—¶é—´é€‰æ‹©å™¨é€‰æ‹©å®ŒæˆåŽè§¦å‘
      handleDateChange(value) {
        this.queryParam.startTime = value[0]
        this.queryParam.endTime = value[1]
      },
      /**
       * è¡¨æ ¼åˆ†é¡µã€æŽ’序改变、筛选时触发
       * @param pagination åˆ†é¡µå™¨é€‰é¡¹
       * @param filters ç­›é€‰é€‰é¡¹
       * @param sorter æŽ’序选项
       */
      handleTableChange(pagination, filters, sorter) {
        if (sorter.order) {
          this.isorter.column = sorter.field
          this.isorter.order = sorter.order === 'ascend' ? 'asc' : 'desc'
        } else {
          this.isorter.column = 'createTime'
          this.isorter.order = 'desc'
        }
        for (let key in filters) {
          this.filters[key] = filters[key].join(',')
        }
        this.loadData()
      },
      // æŒ‡æ´¾åˆ°äº§å“çª—口点击确定指派设备后触发
      handleAssignDocumentToDevice() {
        const { checkedKeys, selectionRows, selectedRowKeys, $confirm, $notification, queryParam: { applyReason }, $destroyAll, handleCancel } = this
        if (checkedKeys.length === 0 || selectedRowKeys.length === 0) {
          $notification.warning({
            message: '消息',
            description: '请选择设备或文档'
          })
          return
        }
        const that = this
        this.$refs.form.validate(valid => {
          if (valid) {
            const { docId, attributionId, publishFileId } = selectionRows[0]
            const params = {
              docId: checkedKeys[0],
              equipmentDocId: docId,
              equipmentId: attributionId,
              equipmentFileId: publishFileId,
              applyReason
            }
            $confirm({
              title: '提示',
              content: `确认提交吗?`,
              okText: '确认',
              cancelText: '取消',
              onOk: () => {
                that.confirmLoading = true
                dncApi.assignNcToProductApi(params)
                  .then(res => {
                    if (res.success) {
                      handleCancel()
                      $notification.success({
                        message: '消息',
                        description: res.message
                      })
                    } else {
                      $notification.error({
                        message: '消息',
                        description: res.message
                      })
                    }
                  })
                  .finally(() => {
                    $destroyAll()
                    that.confirmLoading = false
                  })
              },
              onCancel: () => {
                $destroyAll()
              }
            })
          } else {
            return false
          }
        })
      },
      /* è¾“入查询内容变化时触发 */
      handleSearchInputChange() {
        let search = this.searchInput
        let expandedKeys = this.dataList
          .map(item => {
            if (item.title != null) {
              if (item.title.indexOf(search) > -1) {
                return this.getParentKey(item.key, this.treeDataSource)
              }
              return null
            }
          })
          .filter((item, i, self) => item && self.indexOf(item) === i)
        Object.assign(this, {
          expandedKeys,
          searchValue: search,
          autoExpandParent: true
        })
      },
      /**
       * æ ‘节点展开合并时触发
       * @param expandedKeys å±•开项key
       */
      handleTreeNodeExpand(expandedKeys) {
        this.expandedKeys = expandedKeys
        this.autoExpandParent = false
      },
      /**
       * æ ‘节点复选框选中时触发
       * @param selectedKeys é€‰ä¸­èŠ‚ç‚¹key
       * @param {node} node èŠ‚ç‚¹å¯¹è±¡
       */
      handleTreeNodeCheck(checkedObj, { node }) {
        console.log('checkedObj', checkedObj)
        console.log('node', node.dataRef)
        let record = node.dataRef
        if (record.type !== 99) return
        this.checkedKeys = checkedObj.checked.slice(-1)
      },
      /**
       * æ ‘节点选中时触发(模拟树节点复选框选中时的效果)
       * @param selectedKeys é€‰ä¸­èŠ‚ç‚¹key
       * @param {node} node èŠ‚ç‚¹å¯¹è±¡
       */
      handleTreeNodeSelect(selectedKeys, { node }) {
        node.$el.childNodes[1].click()
      },
      /**
       * é€’归获得输入项的父级key
       * @param key å­é¡¹key
       * @param tree å­é¡¹
       */
      getParentKey(key, tree) {
        let parentKey
        for (let i = 0; i < tree.length; i++) {
          const node = tree[i]
          if (node.children) {
            if (node.children.some(item => item.key === key)) {
              parentKey = node.key
            } else if (
              this.getParentKey(key, node.children)) {
              parentKey = this.getParentKey(key, node.children)
            }
          }
        }
        return parentKey
      },
      /**
       * é€’归获得所有树节点key
       * @param data è®¾å¤‡æ ‘数据
       */
      generateList(data) {
        for (let i = 0; i < data.length; i++) {
          data[i].key = data[i].id
          const node = data[i]
          const key = node.id
          const title = node.label
          this.dataList.push({ key, title })
          this.allTreeKeys.push(key)
          this.setTreeNodeIcon(node)
          if (node.children) this.generateList(node.children)
        }
      },
      /**
       * è®¾ç½®æ ‘节点图标
       * @param treeNode
       */
      setTreeNodeIcon(treeNode) {
        switch (+treeNode.type) {
          case 1:
            treeNode.slots = { icon: 'product' }
            break
          case 2:
            treeNode.slots = { icon: 'component' }
            break
          case 3:
            treeNode.slots = { icon: 'part' }
            break
          case 4:
            treeNode.slots = { icon: 'processSpecVersion' }
            break
          case 5:
            treeNode.slots = { icon: 'process' }
            break
          case 6:
            treeNode.slots = { icon: 'processStep' }
            break
          default:
        }
      },
      resetData() {
        this.searchInput = this.searchValue = ''
        this.expandedKeys = []
        this.selectedRowKeys = []
        this.selectionRows = {}
        this.checkedKeys = []
        this.filters = {}
        this.isorter = Object.assign({}, this.defaultSorter)
      },
      handleCancel() {
        this.visible = false
      },
      triggerCorrespondingMethod({ methodName, modalTitle }) {
        if (this[methodName]) {
          this[methodName]()
          this.title = modalTitle
        }
      }
    }
  }
</script>
<style scoped lang="less">
  /deep/ .ant-modal {
    .tabs-container {
      display: flex;
      justify-content: space-between;
      .replaceSearch {
        color: #40a9ff;
        font-weight: bold;
        background-color: rgb(204, 204, 204);
      }
    }
  }
  ::-webkit-scrollbar {
    width: 8px;
  }
</style>
src/views/dnc/base/modules/DeviceStructure/Document/HasReceivedDocumentTableList.vue
@@ -9,6 +9,9 @@
    </a-table>
    <DocumentModal ref="modalForm" @ok="modalFormOk"/>
    <has-received-document-assign-modal :size="size" ref="documentAssignModalRef"
                                        :currentDocumentInfo="currentRightClickedDocumentInfo"/>
  </div>
</template>
@@ -16,17 +19,18 @@
  import { getAction } from '@/api/manage'
  import { JeecgListMixin } from '@/mixins/JeecgListMixin'
  import DocumentModal from '../../../../common/DocumentModal.vue'
  import HasReceivedDocumentAssignModal from './HasReceivedDocumentAssignModal'
  export default {
    name: 'HasReceivedDocumentTableList',
    components: { DocumentModal },
    components: { HasReceivedDocumentAssignModal, DocumentModal },
    mixins: [JeecgListMixin],
    props: {
      currentTreeNodeInfo: {
        type: Object
      },
      currentTypeOfDevice:{
        type:Number
      currentTypeOfDevice: {
        type: Number
      },
      size: {
        type: String
@@ -51,7 +55,7 @@
            dataIndex: 'docName',
            key: 'docName',
            align: 'center',
            scopedSlots: {customRender: 'docName'},
            scopedSlots: { customRender: 'docName' },
            width: 300,
            sorter: true
          },
@@ -185,7 +189,12 @@
        this.$refs.modalForm.title = modalTitle
      },
      handleDocumentAssign(record, modalTitle) {
      /**
       * æŽ§åˆ¶æŒ‡æ´¾åˆ°äº§å“å¼¹çª—
       * @param record è¡¨æ ¼è¡Œä¿¡æ¯
       * @param modalTitle å¼¹çª—标题
       */
      handleDocumentRecAssign(record, modalTitle) {
        this.$refs.documentAssignModalRef.title = modalTitle
        this.$refs.documentAssignModalRef.visible = true
      },
src/views/dnc/base/modules/ProductStructure/Document/NcDocumentAssignModal.vue
@@ -56,7 +56,7 @@
                  </a-button>
                </div>
                <!--产品结构树-->
                <!--设备结构树-->
                <div style="overflow:auto;margin-top: 10px;height: 400px">
                  <a-tree blockNode checkable :checkedKeys="checkedKeys" :expandedKeys.sync="expandedKeys"
                          :autoExpandParent="autoExpandParent" @select="handleTreeNodeSelect"
@@ -436,7 +436,7 @@
    },
    resetData() {
      this.searchInput = ''
      this.searchInput = this.searchValue = ''
      this.expandedKeys = []
      this.selectedRowKeys = []
      this.selectionRows = {}
src/views/dnc/base/modules/ProductStructure/Document/NcDocumentTableList.vue
@@ -17,7 +17,7 @@
</template>
<script>
  import { getAction } from '@/api/manage'
import { getAction, postAction } from '@/api/manage'
  import { JeecgListMixin } from '@/mixins/JeecgListMixin'
  import DocumentModal from '../../../../common/DocumentModal'
  import NcDocumentAssignModal from './NcDocumentAssignModal'
@@ -96,7 +96,8 @@
        currentRightClickedDocumentInfo: {},
        currentClickedDocumentInfo: {},
        url: {
          list: '/nc/doc/find/page'
          list: '/nc/doc/find/page',
          submitProccess:'/dncFlow/dispatchFile/submitProccess'
        }
      }
    },
@@ -213,6 +214,48 @@
        this.$refs.documentAssignModalRef.visible = true
      },
      handleAppoint(record){
        const that = this
        console.log("sssss",record)
        that.$confirm({
          title: '提示',
          content: `确认定型吗?`,
          okText: '确认',
          cancelText: '取消',
          onOk: () => {
            let dispatchFile = {
              'docId':record.docId,
              'attributionId':record.attributionId,
              'attributionType':record.attributionType,
              'fileId':record.publishFileId
            }
            postAction(this.url.submitProccess,dispatchFile)
              .then(res => {
                if (res.success) {
                  this.$message.success('流程发起成功')
                } else {
                  that.$notification.error({
                    message: '消息',
                    description: res.message
                  })
                }
              })
              .catch(err => {
                that.$notification.error({
                  message: '消息',
                  description: err.message
                })
              })
              .finally(() => {
                that.$destroyAll()
              })
          },
          onCancel: () => {
            that.$destroyAll()
          }
        })
      },
      handleDocumentExtract(record) {
        const that = this
        const { docId, attributionId, attributionType } = record
src/views/dnc/base/modules/ProductStructure/GuideCardBatch/GuideCardBatchForm.vue
@@ -99,6 +99,11 @@
            </a-form-model-item>
          </a-col>
          <a-col :span="24">
            <a-form-model-item label="首检意见" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="inspectionOpinion">
              <a-textarea v-model="model.inspectionOpinion" rows="4" placeholder="请输入首检意见" />
            </a-form-model-item>
          </a-col>
          <a-col :span="24">
            <a-form-model-item label="审批人" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="approver">
              <a-input v-model="model.approver" placeholder="请输入审批人"  ></a-input>
            </a-form-model-item>
src/views/dnc/base/modules/ProductStructure/GuideCardBatch/GuideCardBatchList.vue
@@ -67,9 +67,9 @@
        <span slot="action" slot-scope="text, record">
          <a @click="handleEdit(record)">上传/修改信息</a>
          <a v-if="record.flowStatus === '0'" @click="handleEdit(record)">上传/修改信息</a>
          <a-divider type="vertical" />
          <a-divider v-if="record.flowStatus === '0'" type="vertical" />
          <a @click="handleOpenPrintGuideCardModal(record)">生成数控加工程序确认表</a>
@@ -325,6 +325,7 @@
              })
              .finally(() => {
                that.$destroyAll()
                this.loadData(1)
              })
          },
          onCancel: () => {
src/views/dnc/common/TableContextMenu.vue
@@ -42,10 +42,10 @@
        currentMenuLevel: '',
        defaultContextMenuList: {
          //设备类
          deviceCustomType:[
          deviceCustomType: [
            { label: '编辑设备类信息', code: 'type_edit', subMenu: [], icon: 'edit', isCommonMethod: false },
            { label: '删除', code: 'type_delete', subMenu: [], icon: 'delete', isCommonMethod: false },
            { label: '导入NC程序', code: 'type_nc_import', subMenu: [], icon: 'import', isCommonMethod: true },
            { label: '导入NC程序', code: 'type_nc_import', subMenu: [], icon: 'import', isCommonMethod: true }
          ],
          //NC文档
          NC: [
@@ -56,6 +56,7 @@
            { label: '下载', code: 'document_download', subMenu: [], icon: 'download', isCommonMethod: true },
            { label: '删除', code: 'document_delete', subMenu: [], icon: 'delete', isCommonMethod: true },
            { label: '批量删除', code: 'document_batch_remove', subMenu: [], icon: 'delete', isCommonMethod: true },
            { label: '定型', code: 'document_appoint', subMenu: [], icon: 'swap-right', isCommonMethod: true },
            {
              label: '生命周期',
              subMenu: [
@@ -96,7 +97,6 @@
            { label: '下载', code: 'document_download', subMenu: [], icon: 'download', isCommonMethod: true },
            { label: '删除', code: 'document_delete', subMenu: [], icon: 'delete', isCommonMethod: true },
            { label: '批量删除', code: 'document_batch_remove', subMenu: [], icon: 'delete', isCommonMethod: true },
            { label: '定型', code: 'document_appoint', subMenu: [], icon: 'swap-right', isCommonMethod: true },
            {
              label: '生命周期',
              subMenu: [
@@ -117,6 +117,7 @@
            { label: '下载', code: 'document_download', subMenu: [], icon: 'download', isCommonMethod: true },
            { label: '删除', code: 'document_delete', subMenu: [], icon: 'delete', isCommonMethod: true },
            { label: '批量删除', code: 'document_batch_remove', subMenu: [], icon: 'delete', isCommonMethod: true },
            { label: '指派到产品', code: 'document_rec_assign', subMenu: [], icon: 'cluster', isCommonMethod: false },
            {
              label: '生命周期',
              subMenu: [
src/views/flowable/workflow/FlowTodo.vue
@@ -280,6 +280,11 @@
      :selectShenpiData='selectGuideCardData'
      @searchReset='searchReset'
    ></guide-card-batch-handle>
    <AssignEquipmentFileStreamHandle
      ref='assignEquipmentFileStreamHandle'
      :selectShenpiData='selectEquipmentSealUpData'
      @searchReset='searchReset'
    ></AssignEquipmentFileStreamHandle>
  </a-card>
</template>
@@ -292,7 +297,6 @@
import WeekMaintenanceApprovalModal from '@views/flowable/workflow/weekMaintenance/WeekMaintenanceApprovalModal'
import RepairOrderApprovalModal from '@views/flowable/workflow/repairOrder/RepairOrderApprovalModal'
import InspectionOrderHandle from '@views/flowable/workflow/InspectionOrder/InspectionOrderHandle.vue'
import { getAction } from '@api/manage'
import InspectionOrderBatchHandle from './InspectionOrder/InspectionOrderBatchHandle'
import WeekMaintenanceBatchApprovalModal from './weekMaintenance/WeekMaintenanceBatchApprovalModal'
@@ -300,10 +304,10 @@
import DispatchFileHandle from '@views/flowable/workflow/dispatchFile/DispatchFileHandle.vue'
import DispatchFileBachHandleStyle from '@views/flowable/workflow/dispatchFile/DispatchFileBachHandleStyle#Drawer.vue'
import GuideCardBatchHandle from '@views/flowable/workflow/guideCardBatch/GuideCardBatchHandle.vue'
import AssignEquipmentFileStreamHandle from '@views/flowable/workflow/assignEquipmentFileStream/AssignEquipmentFileStreamHandle.vue'
import OutBoundOrderHandle from '@views/flowable/workflow/outBoundOrder/OutBoundOrderHandle.vue'
import EquipmentLeanOutApprovalModal from '@views/flowable/workflow/leanOut/EquipmentLeanOutApprovalModal.vue'
import SecondMaintenanceApprovalModal
  from '@views/flowable/workflow/secondMaintenance/SecondMaintenanceApprovalModal.vue'
import SecondMaintenanceApprovalModal from '@views/flowable/workflow/secondMaintenance/SecondMaintenanceApprovalModal.vue'
import ThirdMaintenanceApprovalModal from '@views/flowable/workflow/thirdMaintenance/ThirdMaintenanceApprovalModal.vue'
import EquipmentSealUpApprovalModal from '@views/flowable/workflow/sealUp/EquipmentSealUpApprovalModal.vue'
import EquipmentTransferApprovalModal from '@views/flowable/workflow/transfer/EquipmentTransferApprovalModal.vue'
@@ -339,7 +343,8 @@
    EquipmentScrapApprovalModal,
    SparePartApplyHandle,
    StandardizedProcessHandle,
    GuideCardBatchHandle
    GuideCardBatchHandle,
    AssignEquipmentFileStreamHandle
  },
  data() {
    return {
@@ -428,6 +433,8 @@
      selectInboundOrderData: {},
      selectSparePartApplyData: {},
      selectGuideCardData:{},
      selectEquipmentAssignProductData:{},
      selectEquipmentSealUpData:{},
      //业务信息ID
      dataId: undefined
    }
@@ -490,7 +497,7 @@
        case 'ggApproval':
          this.handDispatchFileDetial(item)
          break
        case 'standardized_approval':
        case 'ncFileSettingProcessApproval':
          this.handStandardizedDetial(item)
          break
        case 'sbdjApproval':
@@ -538,6 +545,9 @@
        case 'programConfirmApproval':
          this.handleGuideCardApproval(item)
          break
        case 'equipmentAssignProductApproval':
          this.handleEquipmentAssignProductApproval(item)
          break
        default:
          alert('没找到该流程')
      }
@@ -578,20 +588,20 @@
      let result = parts[0]
      return result
    },
    //DNC-指派NC程序至设备
    handDrDetial(item) {
      this.selectShenpiData = item
      this.$refs.modalFormApproval.clearTableSource()
      this.$refs.modalFormApproval.getAllApproveData(item)
    },
    //DNC-NC程序签派
    handDispatchFileDetial(item) {
      console.log('item----->', item)
      this.selectDispatchFileXqData = item
      this.$refs.modalFormDispatchFileXq.clearTableSource()
      this.$refs.modalFormDispatchFileXq.getAllApproveData(item)
    },
    //定型审批页面
    //DNC-定型审批页面
    handStandardizedDetial(item){
      this.selectDispatchFileXqData = item
      this.$refs.StandardizedProcessHandle.clearTableSource()
@@ -708,12 +718,20 @@
        this.$refs.sparePartApplyModal.getAllApproveData(item)
      }
    },
    //DNC-程序确认表流程
    handleGuideCardApproval(item) {
      console.log('item----->', item)
      this.selectGuideCardData = item
      this.$refs.guideCardBatchHandle.clearTableSource()
      this.$refs.guideCardBatchHandle.getAllApproveData(item)
    },
    //DNC-设备结构树指派产品结构树
    handleEquipmentAssignProductApproval(item){
      console.log('item----->', item)
      this.selectEquipmentSealUpData = item
      this.$refs.assignEquipmentFileStreamHandle.clearTableSource()
      this.$refs.assignEquipmentFileStreamHandle.getAllApproveData(item)
    }
  }
}
</script>
src/views/flowable/workflow/assignEquipmentFileStream/AssignEquipmentFileStreamHandle.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,392 @@
<!--
 Description: å·¥ä½œæµ-DNC-设备结构树指派产品结构树处理页面 List
 Author: ä½œè€… liuyh
 Date:   2025-02-27
-->
<template>
  <a-modal
    :title="title"
    :width="width"
    :visible="visible"
    :footer="null"
    @cancel="handCancel"
  >
    <a-card :bordered="false">
      <div>
        <b>{{ selectShenpiData.description }}</b>
        <br>
        <br>
        <a-tag color="blue">
          å½“前处理人 {{ selectShenpiData.assignee_dictText }}
        </a-tag>
        <a-tag color="blue">
          ä»»åŠ¡åˆ›å»ºæ—¶é—´ {{ selectShenpiData.createTime }}
        </a-tag>
        <br>
        <br>
        <button @click="fetchAndShowBmp" class="btn-custom">打开流程图</button>
        <div v-if="imageSrc">
          <img :src="imageSrc" alt="Fetched Image" />
        </div>
        <hr class="shallow-hr">
      </div>
      <div>
        <b>审签详情</b>
        <br>
        <a-form :form='form'>
          <a-spin :spinning="spinning">
            <a-tabs default-active-key='1' @change='callback'>
              <a-tab-pane key='1' tab='基本信息'>
                <a-form-model ref='form' :model='tableRowRecord' :rules='validatorRules'>
                  <a-row>
                    <a-col :span='span'>
                      <a-form-model-item label="设备编号" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="equipmentId_dictText">
                        <a-input :disabled='coldisabled' v-model="tableRowRecord.equipmentId_dictText" ></a-input>
                      </a-form-model-item>
                    </a-col>
                    <a-col :span='span'>
                      <a-form-model-item label="设备程序文件名" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="equipmentDocId_dictText">
                        <a-input :disabled='coldisabled' v-model="tableRowRecord.equipmentDocId_dictText"  ></a-input>
                      </a-form-model-item>
                    </a-col>
                  </a-row>
                  <a-row>
                    <a-col :span='span'>
                      <a-form-model-item label="产品名称" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="productId_dictText">
                        <a-input :disabled='coldisabled' v-model="tableRowRecord.productId_dictText" ></a-input>
                      </a-form-model-item>
                    </a-col>
                    <a-col :span='span'>
                      <a-form-model-item label="部件名称" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="componentId_dictText">
                        <a-input :disabled='coldisabled' v-model="tableRowRecord.componentId_dictText" ></a-input>
                      </a-form-model-item>
                    </a-col>
                  </a-row>
                  <a-row>
                    <a-col :span='span'>
                      <a-form-model-item label="零件名称" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="partsId_dictText">
                        <a-input :disabled='coldisabled' v-model="tableRowRecord.partsId_dictText"></a-input>
                      </a-form-model-item>
                    </a-col>
                    <a-col :span='span'>
                      <a-form-model-item label="工艺规程版本号" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="psvId_dictText">
                        <a-input :disabled='coldisabled' v-model="tableRowRecord.psvId_dictText"  ></a-input>
                      </a-form-model-item>
                    </a-col>
                  </a-row>
                  <a-row>
                    <a-col :span='span'>
                      <a-form-model-item label="工序名称" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="processId_dictText">
                        <a-input :disabled='coldisabled' v-model="tableRowRecord.processId_dictText"  ></a-input>
                      </a-form-model-item>
                    </a-col>
                    <a-col :span='span'>
                      <a-form-model-item label="工步名称" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="stepId_dictText">
                        <a-input :disabled='coldisabled' v-model="tableRowRecord.stepId_dictText"  ></a-input>
                      </a-form-model-item>
                    </a-col>
                  </a-row>
                  <a-row>
                    <a-col :span='span'>
                      <a-form-model-item label="数控系统类别" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="deviceTypeName">
                        <a-input :disabled='coldisabled' v-model="tableRowRecord.deviceTypeName" ></a-input>
                      </a-form-model-item>
                    </a-col>
                    <a-col :span='span'>
                      <a-form-model-item label="程序文件名称" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="docName">
                        <a-input :disabled='coldisabled' v-model="tableRowRecord.docName" ></a-input>
                      </a-form-model-item>
                    </a-col>
                  </a-row>
                </a-form-model>
              </a-tab-pane>
              <a-tab-pane key='2' tab='流程节点'>
                <a-card>
                  <a-timeline style="padding:0 1% 0 12%" >
                    <a-timeline-item color='white' v-for="(item,index1) in hitaskDataSource" :key="index1">
                      <div class="bottom">
                        <p>处理人:{{item.assignee_dictText}}</p>
                        <p v-if="index1 !==0">处理时长:{{item.duration}}</p>
                        <p v-if="item.name !== '提交申请'">处理类型:{{item.sequenceFlowName}}</p>
                        <p v-if="item.description != null">处理意见:{{item.description}}</p>
                        <div class="left_qiu"><span>{{item.taskName}}</span></div>
                      </div>
                    </a-timeline-item>
                  </a-timeline>
                </a-card>
              </a-tab-pane>
            </a-tabs>
          </a-spin>
        </a-form>
      </div>
      <div>
        <hr class="shallow-hr">
        <br>
        <b>审批详情</b>
        <br>
        <a-form-model ref="form" :model="approveData" :rules="validatorRules" slot="detail">
          <a-row>
            <a-col ::span='span' class="btxx">
              <a-form-model-item label="处理类型" :labelCol="labelCol" :wrapperCol="wrapperCol" prop='status'>
                <j-dict-select-tag type='list' v-model='assignFileStream.auditType' dictCode='nc_sq_handle_type' placeholder="请选择处理类型"  />
              </a-form-model-item >
            </a-col>
            <a-col :span="24" class="btxx">
              <a-form-model-item  label="处理意见" :labelCol="labelCol" :wrapperCol="wrapperCol">
                <a-textarea v-model="assignFileStream.approveContent" rows="4" placeholder="请输入处理意见"/>
              </a-form-model-item >
            </a-col>
          </a-row>
          <div class="table-operator" style="text-align: right;">
            <a-button  @click="handleQueXiaoTask" type="primary" icon="close">取消</a-button>
            <a-button @click="submitForm">提 äº¤</a-button>
          </div>
        </a-form-model>
      </div>
    </a-card>
  </a-modal>
</template>
<script>
import '@assets/less/TableExpand.less'
import { mixinDevice } from '@/utils/mixin'
import { getAction, deleteAction, postAction, downFile, httpAction } from '@api/manage'
export default {
  name: 'FlowShenPi',
  mixins: [mixinDevice],
  props: {
    selectShenpiData: {
      type: Object,
      required: true
    }
  },
  data() {
    return {
      form: this.$form.createForm(this),
      span: 12,
      span1: 8,
      coldisabled: true,
      spinning: false,
      tableRowRecord: {},
      assignFileStream:{},
      tableDataSource: [],
      usageDataSource: [],
      hitaskDataSource:[],
      bomForm: {},
      imageSrc: null,
      drawerVisible: true,
      labelCol: {
        xs: { span: 24 },
        sm: { span: 5 }
      },
      wrapperCol: {
        xs: { span: 30 },
        sm: { span: 16 }
      },
      validatorRules: {
        status: {
          rules: [
            { required: true, message: '请选择审批状态!'},
          ]
        },
      },
      approveData: {},
      flowData: {},
      title: '详情页面',
      width: 1000,
      visible: false,
      // è¡¨å¤´
      url: {
        queryBomDataById: '/dncFlow/assignEquipmentFileStream/selectVoById',
        diagramView: '/assign/flow/diagramView',
        queryHisTaskList:'/dncFlow/dispatchFile/queryHisTaskList',
        auditGuideCardBatch:"/dncFlow/assignEquipmentFileStream/audit",
      },
      dictOptions: {},
      superFieldList: [],
      workflowSource: []
    }
  },
  created() {
  },
  computed: {},
  methods: {
    callback() {
    },
    handCancel() {
      this.visible = false
    },
    clearTableSource() {
      this.tableDataSource = []
      this.usageDataSource = []
    },
    fetchAndShowBmp() {
      console.log('flowData----->', this.flowData)
      try {
        let parm = {
          processDefinitionId: this.flowData.processDefinitionId,
          processInstanceId:this.flowData.processInstanceId,
          TaskDefinitionKey:this.flowData.processDefinitionKey
        }
        downFile(this.url.diagramView,parm,'get').then((res=>{
          console.log('Pica------>',res)
          const urlObject = window.URL.createObjectURL(new Blob([res]))
          this.imageSrc = urlObject
        }))
      } catch (error) {
        console.error('Error fetching image blob:', error)
        alert('无法加载图片,请稍后再试。')
      }
    },
    handleQueXiaoTask(){
      this.visible = false
      this.routeReload()
    },
    submitForm () {
      const that = this;
      if (!that.assignFileStream.auditType==null || that.assignFileStream.auditType===undefined){
          this.$message.warning('请选择处理类型!')
          return false;
      }
      if (!that.assignFileStream.approveContent==null || that.assignFileStream.approveContent===undefined) {
        this.$message.warning('请输入处理意见!')
        return false;
      }
      if ((!that.selectShenpiData.inspectionOpinion==null || that.selectShenpiData.taskDefKey===undefined)&&that.selectShenpiData.taskDefKey==="proofread") {
        this.$message.warning('请输入首检意见!')
      }
      // è§¦å‘表单验证
      this.form.validateFields((err, values) => {
        if (!err) {
          that.confirmLoading = true;
          let url=this.url.auditGuideCardBatch
          let method = 'post';
          let flowTaskVo = {}
          flowTaskVo.comment =that.assignFileStream.approveContent;
          flowTaskVo.dataId = this.selectShenpiData.dataId
          flowTaskVo.taskId = this.selectShenpiData.id
          flowTaskVo.userId = this.selectShenpiData.assignee
          flowTaskVo.instanceId = this.selectShenpiData.procInstId
          flowTaskVo.values = this.selectShenpiData.variables
          flowTaskVo.inspectionOpinion=that.assignFileStream.inspectionOpinion
          flowTaskVo.auditType = that.assignFileStream.auditType
          console.log("表单提交数据",flowTaskVo)
          httpAction(url,flowTaskVo,method).then((res)=>{
            if(res.success){
              that.$message.success(res.message);
              that.visible = false
              //刷新表格
              that.$emit('searchReset')
            }else{
              that.$message.warning(res.message);
            }
          }).finally(() => {
            that.confirmLoading = false;
          })
        }
      })
    },
    getAllApproveData(item) {
      console.log('selectShenpiData----->', this.selectShenpiData)
      this.flowData = item
      let param = {
        'id': item.dataId
      }
      let parmhis={
        'procInstId': item.procInstId
      }
      getAction(this.url.queryHisTaskList,parmhis).then(res=>{
        this.hitaskDataSource=res.result
        getAction(this.url.queryBomDataById, param).then((res => {
          if (res.success) {
            this.tableRowRecord = res.result[0]
            console.log('this.tableRowRecord----->', this.tableRowRecord)
          }
        }))
      }).finally(
        this.visible = true,
        console.log('this.approveData---->', this.approveData)
      )
    }
  }
}
</script>
<style scoped>
.shallow-hr {
  border: 0;
  height: 1px; /* åˆ†ç•Œçº¿çš„高度 */
  background-color: rgba(0, 0, 0, 0.1); /* ä½¿ç”¨ RGBA é¢œè‰²ï¼Œå¹¶è®¾ç½®è¾ƒä½Žçš„透明度 */
  margin: 20px 0; /* åˆ†ç•Œçº¿ä¸Šä¸‹çš„外边距 */
}
.btn-custom {
  background-color: #4CAF50; /* ç»¿è‰²èƒŒæ™¯ */
  color: white; /* ç™½è‰²æ–‡å­— */
  border: none; /* æ— è¾¹æ¡† */
  padding: 5px 15px; /* å†…边距 */
  text-align: center; /* æ–‡å­—居中 */
  text-decoration: none; /* æ— ä¸‹åˆ’线 */
  display: inline-block; /* è¡Œå†…块元素 */
  font-size: 12px; /* å­—体大小 */
  margin: 4px 2px; /* å¤–边距 */
  cursor: pointer; /* é¼ æ ‡æ‚¬åœæ—¶æ˜¾ç¤ºæ‰‹åž‹ */
  border-radius: 4px; /* åœ†è§’边框 */
}
.bold-large-label {
  font-weight: bold;
  font-size: 20px; /* æˆ–你需要的任何大小 */
}
.left_qiu{
  position: absolute;
  left: -74px;
  top: 0;
  width:54px;
  border-radius: 50%;
  height:54px;
  font-size: 13px;
  margin: auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  background: #0099ff;
  transform: translate(0, 0);
}
/deep/ .ant-timeline-item-tail{
  left: -29px !important;
}
.left_qiu span{
  width: 3em;
  display: block;
  color: #fff;
  text-align: center;
}
.img{
  width: 75%;
}
.wrap{
  clear: both;
  width: 100%;
  display: flex;
  height: 50px;
  border: 1px solid #ccc;
  /* background-color: aqua; */
}
.box{
  width:21%;
  height:50px;
  border-right: 1px solid #ccc;
  line-height: 50px;
  /* background: red; */
  text-align:center;
  margin: auto;
}
@import '~@assets/less/common.less';
</style>
src/views/mdc/base/DeliveryGroupUtilizationRateChart.vue
@@ -28,7 +28,7 @@
          <a-col :md="8" :sm="8">
            <a-form-item label="配送小组">
              <a-select v-model="teamCodes" placeholder="请选择配送小组" mode="multiple" :maxTagCount="3"
              <a-select :value="teamCodes" placeholder="请选择配送小组" mode="multiple" :maxTagCount="3"
                        @change="handleDeliverGroupSelectChange" allowClear>
                <a-select-option v-for="item in deliveryGroupList" :key="item.key">{{ item.title }}</a-select-option>
              </a-select>
@@ -45,7 +45,6 @@
          <a-col :md="2" :sm="2">
            <a-space>
              <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
              <!--              <a-button type="primary" @click="searchReset" icon="reload">重置</a-button>-->
            </a-space>
          </a-col>
        </a-row>
@@ -57,271 +56,264 @@
</template>
<script>
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
import moment from 'moment/moment'
import mdcApi from '@api/mdc'
  import { JeecgListMixin } from '@/mixins/JeecgListMixin'
  import moment from 'moment/moment'
  import mdcApi from '@api/mdc'
export default {
  name: 'DeliveryGroupUtilizationRateChart',
  components: {},
  mixins: [JeecgListMixin],
  data() {
    return {
      disableMixinCreated: true,
      queryParam: {
        month: moment().subtract('1', 'month').format('YYYYMM')
      },
      productionIds: [],//班组
      teamCodes: [],//配送小组
      centerList: [],
      groupList: [],
      deliveryGroupList: []
    }
  },
  mounted() {
    window.addEventListener('resize', this.handleWindowResize)
    this.getCenterListByApi()
    this.handleWindowResize()
  },
  methods: {
    loadData() {
      this.chartContainer = this.$echarts.init(document.getElementById('chart-container'))
      this.initChart({})
      this.chartContainer.showLoading({
        text: '数据加载中 ...',
        color: '#0696e1', // åŠ è½½åŠ¨ç”»é¢œè‰²
        textColor: '#0696e1'
      })
      const that = this
      mdcApi.getDeliveryGroupChartDataApi(this.queryParam)
        .then(res => {
          if (res.success) {
            if (Object.keys(res.result).length === 0 || res.result.teamCodeList.length === 0) {
  export default {
    name: 'DeliveryGroupUtilizationRateChart',
    components: {},
    mixins: [JeecgListMixin],
    data() {
      return {
        disableMixinCreated: true,
        queryParam: {
          month: moment().subtract('1', 'month').format('YYYYMM')
        },
        productionIds: [],//班组
        teamCodes: [],//配送小组
        centerList: [],//中心列表
        groupList: [],//班组列表
        deliveryGroupList: []//配送小组列表
      }
    },
    mounted() {
      window.addEventListener('resize', this.handleWindowResize)
      this.getCenterListByApi()
      this.handleWindowResize()
    },
    methods: {
      loadData() {
        this.chartContainer = this.$echarts.init(document.getElementById('chart-container'))
        this.initChart({})
        this.chartContainer.showLoading({
          text: '数据加载中 ...',
          color: '#0696e1', // åŠ è½½åŠ¨ç”»é¢œè‰²
          textColor: '#0696e1'
        })
        const that = this
        mdcApi.getDeliveryGroupChartDataApi(this.queryParam)
          .then(res => {
            if (res.success) {
              if (Object.keys(res.result).length === 0 || res.result.teamCodeList.length === 0) {
                that.$notification.warning({
                  message: '消息',
                  description: '暂无数据'
                })
                // æ­¤å¤„未return是为保证图表数据能被清除并展示空图表
              }
              that.initChart(res.result)
            } else {
              that.$notification.warning({
                message: '消息',
                description: '暂无数据'
                description: res.message
              })
              // æ­¤å¤„未return是为保证图表数据能被清除并展示空图表
            }
            that.initChart(res.result)
          } else {
            that.$notification.warning({
              message: '消息',
              description: res.message
            })
          }
        })
        .catch(err => {
          that.$notification.error({
            message: '消息',
            description: err.message
          })
        })
    },
    /**
     * åˆå§‹åŒ–图表
     * @param chartDataObj æ•°æ®å¯¹è±¡ Object
     */
    initChart(chartDataObj) {
      const option = {
        title: {
          text: (this.queryParam.month.slice(-2) >= 10 ? this.queryParam.month.slice(-2) : this.queryParam.month.slice(-1)) + '月配送小组综合利用率',
          left: 'center',
          top: 0,
          textStyle: {
            fontSize: 22
          }
        },
        grid: {
          top: '12%',
          left: '1%',
          right: '1%',
          bottom: '8%',
          containLabel: true
        },
        legend: {
          top: '6%',
          right: 'center',
          itemGap: 20,
          data: ['24h综合利用率', '去除故障设备时间24h综合利用率', '班次利用率']
        },
        tooltip: {
          show: true,
          trigger: 'axis'
        },
        xAxis: {
          type: 'category',
          data: chartDataObj.teamCodeList ? chartDataObj.teamCodeList : []
          // data: ['李有为组', '丁红燕组', '唐东组', '朱小磊组', '张奇组', '宋宇坤组', '罗军组', '张双进组', '常振勇组', '葛应龙组', '赵广涛组', '于华亭组', '陈峻组', '王继峰组', '王晓明组', '陈林组', '吴吉平组']
        },
        yAxis: [
          {
            type: 'value',
            name: '利用率(%)',
            axisLine: {
              show: true
            },
            axisLabel: {
              formatter: '{value}%'
            }
          }
        ],
        series: [
          {
            type: 'bar',
            name: '24h综合利用率',
            // barWidth: '40%',
            // data: [85, 32, 23, 56, 24, 64, 34, 85, 32, 23, 56, 24, 85, 63, 74, 11, 58]
            data: chartDataObj.dataList ? chartDataObj.dataList.map(item => item.utilizationRate) : []
          },
          {
            type: 'bar',
            name: '去除故障设备时间24h综合利用率',
            // barWidth: '40%',
            // data: [24, 64, 34, 85, 32, 23, 56, 24, 85, 32, 23, 56, 24, 64, 34, 85, 54],
            data: chartDataObj.dataList ? chartDataObj.dataList.map(item => item.amendUtilizationRate) : []
          },
          {
            type: 'bar',
            name: '班次利用率',
            // barWidth: '40%',
            // data: [24, 64, 34, 85, 32, 23, 56, 24, 85, 32, 23, 56, 24, 64, 34, 85, 54],
            data: chartDataObj.dataList ? chartDataObj.dataList.map(item => item.shiftUtilizationRate) : []
          }
        ],
        dataZoom: [
          {
            type: 'slider',
            show: true,
            xAxisIndex: 0,
            startValue: 0,
            endValue: 19,
            // æ˜¯å¦æ˜¾ç¤ºdetail,即拖拽时候显示详细数值信息
            showDetail: false,
            // empty:当前数据窗口外的数据,被设置为空。
            // å³ä¸ä¼šå½±å“å…¶ä»–轴的数据范围
            filterMode: 'empty',
            // æŽ§åˆ¶æ‰‹æŸ„的尺寸
            // handleSize: 0,
            // æ˜¯å¦é”å®šé€‰æ‹©åŒºåŸŸï¼ˆæˆ–叫做数据窗口)的大小
            zoomLock: true,
            brushSelect: false
          },
          {
            // æ²¡æœ‰ä¸‹é¢è¿™å—的话,只能拖动滚动条,
            // é¼ æ ‡æ»šè½®åœ¨åŒºåŸŸå†…不能控制外部滚动条
            type: 'inside',
            show: true,
            // æŽ§åˆ¶å“ªä¸ªè½´ï¼Œå¦‚果是number表示控制一个轴,
            xAxisIndex: 0,
            // æ»šè½®æ˜¯å¦è§¦å‘缩放
            zoomOnMouseWheel: false,
            // é¼ æ ‡ç§»åŠ¨èƒ½å¦è§¦å‘å¹³ç§»
            moveOnMouseMove: true,
            // é¼ æ ‡æ»šè½®èƒ½å¦è§¦å‘平移
            moveOnMouseWheel: true
          }
        ]
      }
      this.chartContainer.setOption(option, true)
      this.chartContainer.hideLoading()
    },
    // èŽ·å–ä¸­å¿ƒåˆ—è¡¨
    getCenterListByApi() {
      const that = this
      mdcApi.getCenterOrGroupListApi()
        .then(res => {
          if (res.success) {
            that.centerList = res.result
            that.queryParam.productionId = res.result[0].value
            that.getGroupListByApi(res.result[0].value, true)
          }
        })
    },
    /**
     * èŽ·å–ç­ç»„åˆ—è¡¨
     * @param productionId ä¸­å¿ƒId
     * @param isInitLoad æ˜¯å¦ä¸ºåˆå§‹åŒ–加载
     */
    getGroupListByApi(productionId, isInitLoad = false) {
      const that = this
      mdcApi.getCenterOrGroupListApi(productionId)
        .then(res => {
          if (res.success) {
            that.groupList = res.result
            if (!isInitLoad) return
            that.handleGroupSelectChange([res.result[0].value])
            that.loadData()
          }
        })
    },
    /**
     * èŽ·å–é…é€å°ç»„åˆ—è¡¨
     * @param productionId ç­ç»„Id
     * @param isReduceSelectOption æ˜¯å¦å‡å°‘班组选中项
     */
    getDeliveryGroupListByApi(productionId, isReduceSelectOption = false) {
      const that = this
      mdcApi.getDeliveryGroupListApi(productionId)
        .then(res => {
          if (res.success) {
            that.deliveryGroupList = res.result
            if (!isReduceSelectOption) return
            that.teamCodes.forEach((key, keyIndex, self) => {
              // å¦‚果将唯一一组包含选中配送小组项的班组取消勾选后应将已勾选的配送小组一并取消勾选
              if (that.deliveryGroupList.findIndex(item => item.key === key) === -1) self.splice(keyIndex, 1)
          .catch(err => {
            that.$notification.error({
              message: '消息',
              description: err.message
            })
          }
        })
    },
          })
      },
    /**
     * ä¸­å¿ƒæ”¹å˜æ—¶è§¦å‘
     * @param value æ”¹å˜åŽçš„中心Id
     */
    handleCenterSelectChange(value) {
      if (this.productionIds.length > 0) {
      /**
       * åˆå§‹åŒ–图表
       * @param chartDataObj æ•°æ®å¯¹è±¡ Object
       */
      initChart(chartDataObj) {
        const option = {
          title: {
            text: (this.queryParam.month.slice(-2) >= 10 ? this.queryParam.month.slice(-2) : this.queryParam.month.slice(-1)) + '月配送小组综合利用率',
            left: 'center',
            top: 0,
            textStyle: {
              fontSize: 22
            }
          },
          grid: {
            top: '12%',
            left: '1%',
            right: '1%',
            bottom: '8%',
            containLabel: true
          },
          legend: {
            top: '6%',
            right: 'center',
            itemGap: 20,
            data: ['24h综合利用率', '去除故障设备时间24h综合利用率', '班次利用率']
          },
          tooltip: {
            show: true,
            trigger: 'axis'
          },
          xAxis: {
            type: 'category',
            data: chartDataObj.teamCodeList ? chartDataObj.teamCodeList : []
            // data: ['李有为组', '丁红燕组', '唐东组', '朱小磊组', '张奇组', '宋宇坤组', '罗军组', '张双进组', '常振勇组', '葛应龙组', '赵广涛组', '于华亭组', '陈峻组', '王继峰组', '王晓明组', '陈林组', '吴吉平组']
          },
          yAxis: [
            {
              type: 'value',
              name: '利用率(%)',
              axisLine: {
                show: true
              },
              axisLabel: {
                formatter: '{value}%'
              }
            }
          ],
          series: [
            {
              type: 'bar',
              name: '24h综合利用率',
              // barWidth: '40%',
              // data: [85, 32, 23, 56, 24, 64, 34, 85, 32, 23, 56, 24, 85, 63, 74, 11, 58]
              data: chartDataObj.dataList ? chartDataObj.dataList.map(item => item.utilizationRate) : []
            },
            {
              type: 'bar',
              name: '去除故障设备时间24h综合利用率',
              // barWidth: '40%',
              // data: [24, 64, 34, 85, 32, 23, 56, 24, 85, 32, 23, 56, 24, 64, 34, 85, 54],
              data: chartDataObj.dataList ? chartDataObj.dataList.map(item => item.amendUtilizationRate) : []
            },
            {
              type: 'bar',
              name: '班次利用率',
              // barWidth: '40%',
              // data: [24, 64, 34, 85, 32, 23, 56, 24, 85, 32, 23, 56, 24, 64, 34, 85, 54],
              data: chartDataObj.dataList ? chartDataObj.dataList.map(item => item.shiftUtilizationRate) : []
            }
          ],
          dataZoom: [
            {
              type: 'slider',
              show: true,
              xAxisIndex: 0,
              startValue: 0,
              endValue: 19,
              // æ˜¯å¦æ˜¾ç¤ºdetail,即拖拽时候显示详细数值信息
              showDetail: false,
              // empty:当前数据窗口外的数据,被设置为空。
              // å³ä¸ä¼šå½±å“å…¶ä»–轴的数据范围
              filterMode: 'empty',
              // æŽ§åˆ¶æ‰‹æŸ„的尺寸
              // handleSize: 0,
              // æ˜¯å¦é”å®šé€‰æ‹©åŒºåŸŸï¼ˆæˆ–叫做数据窗口)的大小
              zoomLock: true,
              brushSelect: false
            },
            {
              // æ²¡æœ‰ä¸‹é¢è¿™å—的话,只能拖动滚动条,
              // é¼ æ ‡æ»šè½®åœ¨åŒºåŸŸå†…不能控制外部滚动条
              type: 'inside',
              show: true,
              // æŽ§åˆ¶å“ªä¸ªè½´ï¼Œå¦‚果是number表示控制一个轴,
              xAxisIndex: 0,
              // æ»šè½®æ˜¯å¦è§¦å‘缩放
              zoomOnMouseWheel: false,
              // é¼ æ ‡ç§»åŠ¨èƒ½å¦è§¦å‘å¹³ç§»
              moveOnMouseMove: true,
              // é¼ æ ‡æ»šè½®èƒ½å¦è§¦å‘平移
              moveOnMouseWheel: true
            }
          ]
        }
        this.chartContainer.setOption(option, true)
        this.chartContainer.hideLoading()
      },
      // èŽ·å–ä¸­å¿ƒåˆ—è¡¨
      getCenterListByApi() {
        const that = this
        mdcApi.getCenterOrGroupListApi()
          .then(res => {
            if (res.success) {
              that.centerList = res.result
              that.queryParam.productionId = res.result[0].value
              that.getGroupListByApi(res.result[0].value, true)
            }
          })
      },
      /**
       * èŽ·å–ç­ç»„åˆ—è¡¨
       * @param productionId ä¸­å¿ƒId
       * @param isInitLoad æ˜¯å¦ä¸ºåˆå§‹åŒ–加载
       */
      getGroupListByApi(productionId, isInitLoad = false) {
        this.groupList = []
        this.productionIds = []
        delete this.queryParam.productionIds
      }
      if (this.teamCodes.length > 0) {
        const that = this
        mdcApi.getCenterOrGroupListApi(productionId)
          .then(res => {
            if (res.success) {
              that.groupList = res.result ? res.result : []
              that.handleGroupSelectChange(res.result && res.result.length > 0 && isInitLoad ? [res.result[0].value] : [])
              if (!isInitLoad) return
              that.loadData()
            }
          })
      },
      /**
       * èŽ·å–é…é€å°ç»„åˆ—è¡¨
       * @param productionId ç­ç»„Id
       * @param isReduceSelectOption æ˜¯å¦å‡å°‘班组选中项
       */
      getDeliveryGroupListByApi(productionId, isReduceSelectOption = false) {
        this.deliveryGroupList = []
        this.teamCodes = []
        delete this.queryParam.teamCodes
        const that = this
        mdcApi.getDeliveryGroupListApi(productionId)
          .then(res => {
            if (res.success) {
              that.deliveryGroupList = res.result ? res.result : []
              // ä»…减少勾选项时才进行下一步
              if (!isReduceSelectOption) return
              // ä¿ç•™æ”¹å˜åŽçš„配送小组列表中之前已勾选的配送小组
              const filterTeamCodes = that.teamCodes.filter(item => that.deliveryGroupList.map(item => item.key).includes(item))
              that.handleDeliverGroupSelectChange(filterTeamCodes)
            }
          })
      },
      /**
       * ä¸­å¿ƒæ”¹å˜æ—¶è§¦å‘
       * @param value æ”¹å˜åŽçš„中心Id
       */
      handleCenterSelectChange(value) {
        this.getGroupListByApi(value)
      },
      /**
       * ç­ç»„改变时触发
       * @param value æ”¹å˜åŽçš„班组Id
       */
      handleGroupSelectChange(value) {
        let isReduceSelectOption
        if (value.length > this.productionIds.length) isReduceSelectOption = false //增加勾选项
        else isReduceSelectOption = true // å‡å°‘勾选项
        this.productionIds = value
        this.queryParam.productionIds = value.join(',')
        this.getDeliveryGroupListByApi(value.join(','), isReduceSelectOption)
      },
      /**
       * é…é€å°ç»„发生改变时触发
       * @param value æ”¹å˜åŽçš„配送小组Id
       */
      handleDeliverGroupSelectChange(value) {
        this.teamCodes = value
        this.queryParam.teamCodes = value.join(',')
      },
      handleWindowResize() {
        if (this.chartContainer) this.chartContainer.resize()
      }
      this.getGroupListByApi(value)
    },
    /**
     * ç­ç»„改变时触发
     * @param value æ”¹å˜åŽçš„班组Id
     */
    handleGroupSelectChange(value) {
      let isReduceSelectOption
      if (value.length > this.productionIds.length) isReduceSelectOption = false //增加勾选项
      else isReduceSelectOption = true // å‡å°‘勾选项
      this.productionIds = value
      this.queryParam.productionIds = value.join(',')
      this.getDeliveryGroupListByApi(value.join(','), isReduceSelectOption)
    },
    /**
     * é…é€å°ç»„发生改变时触发
     * @param value æ”¹å˜åŽçš„配送小组Id
     */
    handleDeliverGroupSelectChange(value) {
      this.queryParam.teamCodes = value.join(',')
    },
    handleWindowResize() {
      if (this.chartContainer) this.chartContainer.resize()
    }
  }
}
</script>
src/views/mdc/base/DeviceParamThresholdManagement.vue
@@ -40,7 +40,7 @@
    <!-- æ“ä½œæŒ‰é’®åŒºåŸŸ -->
    <div class="table-operator" style="border-top: 5px">
      <a-button @click="handleAdd" type="primary" icon="plus">添加参数阈值</a-button>
      <a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
      <a-dropdown v-if="selectedRowKeys.length > 0">
        <a-menu slot="overlay" @click="handleMenuClick">
          <a-menu-item key="1">
src/views/mdc/base/GroupEquipmentUtilizationRateChart.vue
@@ -34,7 +34,6 @@
          <a-col :md="5" :sm="5">
            <a-space>
              <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
              <!--              <a-button type="primary" @click="searchReset" icon="reload">重置</a-button>-->
            </a-space>
          </a-col>
        </a-row>
@@ -46,246 +45,237 @@
</template>
<script>
import mdcApi from '@api/mdc'
import moment from 'moment'
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
  import mdcApi from '@api/mdc'
  import moment from 'moment'
  import { JeecgListMixin } from '@/mixins/JeecgListMixin'
export default {
  name: 'GroupEquipmentUtilizationRateChart',
  components: {},
  mixins: [JeecgListMixin],
  data() {
    return {
      disableMixinCreated: true,
      productionIds: [],//班组
      centerList: [],
      groupList: [],
      queryParam: {
        month: moment().subtract('1', 'month').format('YYYYMM')
  export default {
    name: 'GroupEquipmentUtilizationRateChart',
    components: {},
    mixins: [JeecgListMixin],
    data() {
      return {
        disableMixinCreated: true,
        productionIds: [],//班组
        centerList: [],
        groupList: [],
        queryParam: {
          month: moment().subtract('1', 'month').format('YYYYMM')
        }
      }
    }
  },
  mounted() {
    window.addEventListener('resize', this.handleWindowResize)
    this.handleWindowResize()
    this.getCenterListByApi()
  },
  methods: {
    loadData() {
      this.chartContainer = this.$echarts.init(document.getElementById('chart-container'))
      this.initChart({})
      this.chartContainer.showLoading({
        text: '数据加载中 ...',
        color: '#0696e1', // åŠ è½½åŠ¨ç”»é¢œè‰²
        textColor: '#0696e1'
      })
      const that = this
      mdcApi.getGroupEquipmentChartDataApi(this.queryParam)
        .then(res => {
          if (res.success) {
            if (Object.keys(res.result).length === 0 || res.result.equipmentNameList.length === 0) {
    },
    mounted() {
      window.addEventListener('resize', this.handleWindowResize)
      this.handleWindowResize()
      this.getCenterListByApi()
    },
    methods: {
      loadData() {
        this.chartContainer = this.$echarts.init(document.getElementById('chart-container'))
        this.initChart({})
        this.chartContainer.showLoading({
          text: '数据加载中 ...',
          color: '#0696e1', // åŠ è½½åŠ¨ç”»é¢œè‰²
          textColor: '#0696e1'
        })
        const that = this
        mdcApi.getGroupEquipmentChartDataApi(this.queryParam)
          .then(res => {
            if (res.success) {
              if (Object.keys(res.result).length === 0 || res.result.equipmentNameList.length === 0) {
                that.$notification.warning({
                  message: '消息',
                  description: '暂无数据'
                })
                // æ­¤å¤„未return是为保证图表数据能被清除并展示空图表
              }
              that.initChart(res.result)
            } else {
              that.$notification.warning({
                message: '消息',
                description: '暂无数据'
                description: res.message
              })
              // æ­¤å¤„未return是为保证图表数据能被清除并展示空图表
            }
            that.initChart(res.result)
          } else {
            that.$notification.warning({
              message: '消息',
              description: res.message
            })
          }
        })
        .catch(err => {
          that.$notification.error({
            message: '消息',
            description: err.message
          })
        })
    },
          .catch(err => {
            that.$notification.error({
              message: '消息',
              description: err.message
            })
          })
      },
    /**
     * åˆå§‹åŒ–图表
     * @param chartDataObj æ•°æ®å¯¹è±¡ Object
     */
    initChart(chartDataObj) {
      const option = {
        title: {
          text: '设备综合利用率(' + (this.queryParam.month.slice(-2) >= 10 ? this.queryParam.month.slice(-2) : this.queryParam.month.slice(-1)) + '月)',
          left: 'center',
          top: 0,
          textStyle: {
            fontSize: 22
          }
        },
        grid: {
          top: '12%',
          left: '1%',
          right: '1%',
          bottom: '8%',
          containLabel: true
        },
        legend: {
          top: '6%',
          right: 'center',
          itemGap: 20,
          data: ['24h综合利用率', '24h去除故障', '计划工作时间综合利用率']
        },
        tooltip: {
          show: true,
          trigger: 'axis'
        },
        xAxis: {
          type: 'category',
          // data: ['立加u1000-3', '五轴125P', '五坐标加工中心GS1000', 'Aè½´1000PLUS', '梧州80P_2', '雕刻机800TE', '四坐标立加104V', '立加u1000-4', '立加GX710_1', '三坐标立加1350', '卧加H5000-1', '立加u1000-2', '立加1000HS_1', '立加1160_1', '立加GX710_2', '立加u1000-3', '五轴125P', '五坐标加工中心GS1000', 'Aè½´1000PLUS', '梧州80P_2', '雕刻机800TE', '四坐标立加104V', '立加u1000-4', '立加GX710_1', '三坐标立加1350', '卧加H5000-1', '立加u1000-2', '立加1000HS_1', '立加1160_1', '立加GX710_2', '立加u1000-3', '五轴125P', '五坐标加工中心GS1000', 'Aè½´1000PLUS', '梧州80P_2', '雕刻机800TE', '四坐标立加104V'],
          data: chartDataObj.equipmentNameList ? chartDataObj.equipmentNameList : [],
          axisLabel: {
            interval: 0, // åæ ‡è½´åˆ»åº¦æ ‡ç­¾çš„æ˜¾ç¤ºé—´éš”,在类目轴中有效;默认会采用标签不重叠的策略间隔显示标签;可以设置成0强制显示所有标签;如果设置为1,表示『隔一个标签显示一个标签』,如果值为2,表示隔两个标签显示一个标签,以此类推。
            rotate: 45, // åˆ»åº¦æ ‡ç­¾æ—‹è½¬çš„角度,在类目轴的类目标签显示不下的时候可以通过旋转防止标签之间重叠;旋转的角度从-90度到90度
            inside: false, // åˆ»åº¦æ ‡ç­¾æ˜¯å¦æœå†…,默认朝外
            margin: 15, // åˆ»åº¦æ ‡ç­¾ä¸Žè½´çº¿ä¹‹é—´çš„距离
            fontSize: 14,
            color: '#000'
          }
        },
        yAxis: [
          {
            type: 'value',
            name: '利用率(%)',
            axisLine: {
              show: true
            },
            axisLabel: {
              formatter: '{value}%'
      /**
       * åˆå§‹åŒ–图表
       * @param chartDataObj æ•°æ®å¯¹è±¡ Object
       */
      initChart(chartDataObj) {
        const option = {
          title: {
            text: '设备综合利用率(' + (this.queryParam.month.slice(-2) >= 10 ? this.queryParam.month.slice(-2) : this.queryParam.month.slice(-1)) + '月)',
            left: 'center',
            top: 0,
            textStyle: {
              fontSize: 22
            }
          }
        ],
        series: [
          {
            type: 'bar',
            name: '24h综合利用率',
            // data: [53.28, 32.22, 23, 56, 24, 64, 34, 85, 32, 23, 56, 24, 85, 32, 23, 56, 24, 64, 34, 85, 32, 23, 56, 24, 23, 56, 24, 85, 32, 23, 56, 24, 85, 32, 85, 32, 23, 56, 24, 85, 32]
            data: chartDataObj.dataList ? chartDataObj.dataList.map(item => item.utilizationRate) : []
            // label: {
            //   show: true,
            //   position: 'top',
            //   formatter: '{c}%',
            //   avoidLabelOverlap: true
            // }
          },
          {
            type: 'bar',
            name: '24h去除故障',
            data: chartDataObj.dataList ? chartDataObj.dataList.map(item => item.amendUtilizationRate) : []
            // data: [53.28, 32.22, 23, 56, 24, 64, 34, 85, 32, 23, 56, 24, 85, 32, 23, 56, 24, 64, 34, 85, 32, 23, 56, 24, 23, 56, 24, 85, 32, 23, 56, 24, 85, 32, 85, 32, 23, 56, 24, 85, 32]
          grid: {
            top: '12%',
            left: '1%',
            right: '1%',
            bottom: '8%',
            containLabel: true
          },
          {
            type: 'bar',
            name: '计划工作时间综合利用率',
            data: chartDataObj.dataList ? chartDataObj.dataList.map(item => item.shiftUtilizationRate) : []
            // data: [63.25, 32.22, 23, 56, 24, 64, 34, 85, 32, 23, 56, 24, 85, 32, 23, 56, 24, 64, 34, 85, 32, 23, 56, 24, 85, 32, 23, 56, 24, 85, 32, 85, 32, 23, 56, 24, 85, 32]
          }
        ],
        dataZoom: [
          {
            type: 'slider',
          legend: {
            top: '6%',
            right: 'center',
            itemGap: 20,
            data: ['24h综合利用率', '24h去除故障', '计划工作时间综合利用率']
          },
          tooltip: {
            show: true,
            xAxisIndex: 0,
            startValue: 0,
            endValue: 19,
            // æ˜¯å¦æ˜¾ç¤ºdetail,即拖拽时候显示详细数值信息
            showDetail: false,
            // empty:当前数据窗口外的数据,被设置为空。
            // å³ä¸ä¼šå½±å“å…¶ä»–轴的数据范围
            filterMode: 'empty',
            // æŽ§åˆ¶æ‰‹æŸ„的尺寸
            // handleSize: 0,
            // æ˜¯å¦é”å®šé€‰æ‹©åŒºåŸŸï¼ˆæˆ–叫做数据窗口)的大小
            zoomLock: true,
            brushSelect: false
            trigger: 'axis'
          },
          {
            // æ²¡æœ‰ä¸‹é¢è¿™å—的话,只能拖动滚动条,
            // é¼ æ ‡æ»šè½®åœ¨åŒºåŸŸå†…不能控制外部滚动条
            type: 'inside',
            show: true,
            // æŽ§åˆ¶å“ªä¸ªè½´ï¼Œå¦‚果是number表示控制一个轴,
            xAxisIndex: 0,
            // æ»šè½®æ˜¯å¦è§¦å‘缩放
            zoomOnMouseWheel: false,
            // é¼ æ ‡ç§»åŠ¨èƒ½å¦è§¦å‘å¹³ç§»
            moveOnMouseMove: true,
            // é¼ æ ‡æ»šè½®èƒ½å¦è§¦å‘平移
            moveOnMouseWheel: true
          }
        ]
          xAxis: {
            type: 'category',
            // data: ['立加u1000-3', '五轴125P', '五坐标加工中心GS1000', 'Aè½´1000PLUS', '梧州80P_2', '雕刻机800TE', '四坐标立加104V', '立加u1000-4', '立加GX710_1', '三坐标立加1350', '卧加H5000-1', '立加u1000-2', '立加1000HS_1', '立加1160_1', '立加GX710_2', '立加u1000-3', '五轴125P', '五坐标加工中心GS1000', 'Aè½´1000PLUS', '梧州80P_2', '雕刻机800TE', '四坐标立加104V', '立加u1000-4', '立加GX710_1', '三坐标立加1350', '卧加H5000-1', '立加u1000-2', '立加1000HS_1', '立加1160_1', '立加GX710_2', '立加u1000-3', '五轴125P', '五坐标加工中心GS1000', 'Aè½´1000PLUS', '梧州80P_2', '雕刻机800TE', '四坐标立加104V'],
            data: chartDataObj.equipmentNameList ? chartDataObj.equipmentNameList : [],
            axisLabel: {
              interval: 0, // åæ ‡è½´åˆ»åº¦æ ‡ç­¾çš„æ˜¾ç¤ºé—´éš”,在类目轴中有效;默认会采用标签不重叠的策略间隔显示标签;可以设置成0强制显示所有标签;如果设置为1,表示『隔一个标签显示一个标签』,如果值为2,表示隔两个标签显示一个标签,以此类推。
              rotate: 45, // åˆ»åº¦æ ‡ç­¾æ—‹è½¬çš„角度,在类目轴的类目标签显示不下的时候可以通过旋转防止标签之间重叠;旋转的角度从-90度到90度
              inside: false, // åˆ»åº¦æ ‡ç­¾æ˜¯å¦æœå†…,默认朝外
              margin: 15, // åˆ»åº¦æ ‡ç­¾ä¸Žè½´çº¿ä¹‹é—´çš„距离
              fontSize: 14,
              color: '#000'
            }
          },
          yAxis: [
            {
              type: 'value',
              name: '利用率(%)',
              axisLine: {
                show: true
              },
              axisLabel: {
                formatter: '{value}%'
              }
            }
          ],
          series: [
            {
              type: 'bar',
              name: '24h综合利用率',
              // data: [53.28, 32.22, 23, 56, 24, 64, 34, 85, 32, 23, 56, 24, 85, 32, 23, 56, 24, 64, 34, 85, 32, 23, 56, 24, 23, 56, 24, 85, 32, 23, 56, 24, 85, 32, 85, 32, 23, 56, 24, 85, 32]
              data: chartDataObj.dataList ? chartDataObj.dataList.map(item => item.utilizationRate) : []
              // label: {
              //   show: true,
              //   position: 'top',
              //   formatter: '{c}%',
              //   avoidLabelOverlap: true
              // }
            },
            {
              type: 'bar',
              name: '24h去除故障',
              data: chartDataObj.dataList ? chartDataObj.dataList.map(item => item.amendUtilizationRate) : []
              // data: [53.28, 32.22, 23, 56, 24, 64, 34, 85, 32, 23, 56, 24, 85, 32, 23, 56, 24, 64, 34, 85, 32, 23, 56, 24, 23, 56, 24, 85, 32, 23, 56, 24, 85, 32, 85, 32, 23, 56, 24, 85, 32]
            },
            {
              type: 'bar',
              name: '计划工作时间综合利用率',
              data: chartDataObj.dataList ? chartDataObj.dataList.map(item => item.shiftUtilizationRate) : []
              // data: [63.25, 32.22, 23, 56, 24, 64, 34, 85, 32, 23, 56, 24, 85, 32, 23, 56, 24, 64, 34, 85, 32, 23, 56, 24, 85, 32, 23, 56, 24, 85, 32, 85, 32, 23, 56, 24, 85, 32]
            }
          ],
          dataZoom: [
            {
              type: 'slider',
              show: true,
              xAxisIndex: 0,
              startValue: 0,
              endValue: 19,
              // æ˜¯å¦æ˜¾ç¤ºdetail,即拖拽时候显示详细数值信息
              showDetail: false,
              // empty:当前数据窗口外的数据,被设置为空。
              // å³ä¸ä¼šå½±å“å…¶ä»–轴的数据范围
              filterMode: 'empty',
              // æŽ§åˆ¶æ‰‹æŸ„的尺寸
              // handleSize: 0,
              // æ˜¯å¦é”å®šé€‰æ‹©åŒºåŸŸï¼ˆæˆ–叫做数据窗口)的大小
              zoomLock: true,
              brushSelect: false
            },
            {
              // æ²¡æœ‰ä¸‹é¢è¿™å—的话,只能拖动滚动条,
              // é¼ æ ‡æ»šè½®åœ¨åŒºåŸŸå†…不能控制外部滚动条
              type: 'inside',
              show: true,
              // æŽ§åˆ¶å“ªä¸ªè½´ï¼Œå¦‚果是number表示控制一个轴,
              xAxisIndex: 0,
              // æ»šè½®æ˜¯å¦è§¦å‘缩放
              zoomOnMouseWheel: false,
              // é¼ æ ‡ç§»åŠ¨èƒ½å¦è§¦å‘å¹³ç§»
              moveOnMouseMove: true,
              // é¼ æ ‡æ»šè½®èƒ½å¦è§¦å‘平移
              moveOnMouseWheel: true
            }
          ]
        }
        this.chartContainer.setOption(option, true)
        this.chartContainer.hideLoading()
      },
      // èŽ·å–ä¸­å¿ƒåˆ—è¡¨
      getCenterListByApi() {
        const that = this
        mdcApi.getCenterOrGroupListApi()
          .then(res => {
            if (res.success) {
              that.centerList = res.result
              that.queryParam.productionId = res.result[0].value
              that.getGroupListByApi(res.result[0].value, true)
            }
          })
      },
      /**
       * èŽ·å–ç­ç»„åˆ—è¡¨
       * @param productionId ä¸­å¿ƒId
       * @param isInitLoad æ˜¯å¦ä¸ºåˆå§‹åŒ–加载
       */
      getGroupListByApi(productionId, isInitLoad = false) {
        const that = this
        mdcApi.getCenterOrGroupListApi(productionId)
          .then(res => {
            if (res.success) {
              that.groupList = res.result
              that.handleGroupSelectChange(res.result && res.result.length > 0 && isInitLoad ? [res.result[0].value] : [])
              if (!isInitLoad) return
              that.loadData()
            }
          })
      },
      /**
       * ä¸­å¿ƒæ”¹å˜æ—¶è§¦å‘
       * @param value æ”¹å˜åŽçš„中心Id
       */
      handleCenterSelectChange(value) {
        this.getGroupListByApi(value)
      },
      /**
       * ç­ç»„发生改变时触发
       * @param value æ”¹å˜åŽçš„班组Id
       */
      handleGroupSelectChange(value) {
        this.productionIds = value
        this.queryParam.productionIds = value.join(',')
      },
      handleWindowResize() {
        if (this.chartContainer) this.chartContainer.resize()
      }
      this.chartContainer.setOption(option, true)
      this.chartContainer.hideLoading()
    },
    // èŽ·å–ä¸­å¿ƒåˆ—è¡¨
    getCenterListByApi() {
      const that = this
      mdcApi.getCenterOrGroupListApi()
        .then(res => {
          if (res.success) {
            that.centerList = res.result
            that.queryParam.productionId = res.result[0].value
            that.getGroupListByApi(res.result[0].value, true)
          }
        })
    },
    /**
     * èŽ·å–ç­ç»„åˆ—è¡¨
     * @param productionId ä¸­å¿ƒId
     * @param isInitLoad æ˜¯å¦ä¸ºåˆå§‹åŒ–加载
     */
    getGroupListByApi(productionId, isInitLoad = false) {
      const that = this
      mdcApi.getCenterOrGroupListApi(productionId)
        .then(res => {
          if (res.success) {
            that.groupList = res.result
            if (!isInitLoad) return
            that.handleGroupSelectChange([res.result[0].value])
            that.loadData()
          }
        })
    },
    /**
     * ä¸­å¿ƒæ”¹å˜æ—¶è§¦å‘
     * @param value æ”¹å˜åŽçš„中心Id
     */
    handleCenterSelectChange(value) {
      if (this.productionIds.length > 0) {
        this.groupList = []
        this.productionIds = []
        delete this.queryParam.productionIds
      }
      this.getGroupListByApi(value)
    },
    /**
     * ç­ç»„发生改变时触发
     * @param value æ”¹å˜åŽçš„班组Id
     */
    handleGroupSelectChange(value) {
      this.productionIds = value
      if (value.length === 0) {
        delete this.queryParam.productionIds
        return
      }
      this.queryParam.productionIds = value.join(',')
    },
    handleWindowResize() {
      if (this.chartContainer) this.chartContainer.resize()
    }
  }
}
</script>
src/views/mdc/base/GroupUtilizationRateChart.vue
@@ -5,7 +5,7 @@
        <a-row :gutter="24">
          <a-col :md="3" :sm="3">
            <a-form-item label="中心">
              <a-select v-model="queryParam.productionId" placeholder="请选择中心">
              <a-select v-model="queryParam.productionId" placeholder="请选择中心" @change="handleCenterSelectChange">
                <a-select-option v-for="item in centerList" :key="item.key">
                  {{ item.title }}
                </a-select-option>
@@ -44,21 +44,9 @@
            </a-form-item>
          </a-col>
          <!--          <a-col :md="5" :sm="5">-->
          <!--            <a-form-item label="班次">-->
          <!--              <a-select v-model="queryParam.workTime" placeholder="请选择班次" mode="multiple" :maxTagCount="2">-->
          <!--                <a-select-option key="123">一班</a-select-option>-->
          <!--                <a-select-option key="234">二班</a-select-option>-->
          <!--                <a-select-option key="345">三班</a-select-option>-->
          <!--              </a-select>-->
          <!--            </a-form-item>-->
          <!--          </a-col>-->
          <a-col :md="2" :sm="2">
            <a-space>
              <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
              <!--              <a-button type="primary" @click="searchReset" icon="reload">重置</a-button>-->
            </a-space>
          </a-col>
        </a-row>
@@ -70,225 +58,237 @@
</template>
<script>
import mdcApi from '@api/mdc'
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
  import mdcApi from '@api/mdc'
  import { JeecgListMixin } from '@/mixins/JeecgListMixin'
export default {
  name: 'GroupUtilizationRateChart',
  components: {},
  mixins: [JeecgListMixin],
  data() {
    return {
      disableMixinCreated: true,
      queryParam: {},
      productionIds: [],//班组
      centerList: [],
      groupList: [],
      equipmentTypeList: [],
      shiftList: []
    }
  },
  mounted() {
    window.addEventListener('resize', this.handleWindowResize)
    this.handleWindowResize()
    this.getCenterListByApi()
    this.getEquipmentTypeListApi()
    this.getShiftListByApi()
  },
  methods: {
    // èŽ·å–æ•°æ®
    loadData() {
      this.chartContainer = this.$echarts.init(document.getElementById('chart-container'))
      this.initChart({})
      this.chartContainer.showLoading({
        text: '数据加载中 ...',
        color: '#0696e1', // åŠ è½½åŠ¨ç”»é¢œè‰²
        textColor: '#0696e1'
      })
      const that = this
      mdcApi.getGroupChartDataApi(this.queryParam)
        .then(res => {
          if (res.success) {
            if (!res.result.dataList || (res.result.dataList && res.result.dataList.length === 0)) {
              that.$notification.warning({
                message: '消息',
                description: '暂无数据'
              })
            }
            that.initChart(res.result)
          }
        })
  export default {
    name: 'GroupUtilizationRateChart',
    components: {},
    mixins: [JeecgListMixin],
    data() {
      return {
        disableMixinCreated: true,
        queryParam: {},
        productionIds: [],//班组
        centerList: [],
        groupList: [],
        equipmentTypeList: [],
        shiftList: []
      }
    },
    mounted() {
      window.addEventListener('resize', this.handleWindowResize)
      this.handleWindowResize()
      this.getCenterListByApi()
      this.getEquipmentTypeListApi()
      this.getShiftListByApi()
    },
    methods: {
      // èŽ·å–æ•°æ®
      loadData() {
        this.chartContainer = this.$echarts.init(document.getElementById('chart-container'))
        this.initChart({})
        this.chartContainer.showLoading({
          text: '数据加载中 ...',
          color: '#0696e1', // åŠ è½½åŠ¨ç”»é¢œè‰²
          textColor: '#0696e1'
        })
        const that = this
    /**
     * åˆå§‹åŒ–图表
     * @param dataList å›¾è¡¨æ•°æ®æº
     * @param dateList æ—¥æœŸåˆ—表
     * @param shiftSubList ç­æ¬¡æ ‡é¢˜åˆ—表
     * @param shiftDataList ç­æ¬¡æ•°æ®åˆ—表
     */
    initChart({ dataList, dateList, shiftSubList, shiftDataList }) {
      const defaultLegendData = ['24小时', '24小时(去除故障时间)', '班次', '累计运行时间(h)']
      const defaultSeries = [
        {
          type: 'line',
          name: '24小时',
          yAxisIndex: 0,
          data: dataList ? dataList.map(item => item.utilizationRate) : []
        },
        {
          type: 'line',
          name: '24小时(去除故障时间)',
          yAxisIndex: 0,
          data: dataList ? dataList.map(item => item.amendUtilizationRate) : []
        },
        {
          type: 'line',
          name: '班次',
          yAxisIndex: 0,
          data: dataList ? dataList.map(item => item.shiftUtilizationRate) : []
        },
        {
          type: 'bar',
          name: '累计运行时间(h)',
          yAxisIndex: 1,
          barWidth: '30%',
          data: dataList ? dataList.map(item => item.processLong) : []
        }
      ]
      const option = {
        title: {
          text: '设备综合利用率',
          left: 'center',
          top: 0,
          textStyle: {
            fontSize: 22
          }
        },
        grid: {
          top: '12%',
          left: '1%',
          right: '1%',
          bottom: '1%',
          containLabel: true
        },
        legend: {
          top: '6%',
          right: 'center',
          itemGap: 20,
          data: defaultLegendData
        },
        tooltip: {
          show: true,
          trigger: 'axis'
        },
        xAxis: {
          type: 'category',
          data: dateList ? dateList : []
        },
        yAxis: [
          {
            type: 'value',
            name: '利用率(%)',
            axisLine: {
              show: true
            },
            axisLabel: {
              formatter: '{value}%'
        mdcApi.getGroupChartDataApi(this.queryParam)
          .then(res => {
            if (res.success) {
              if (!res.result.dataList || (res.result.dataList && res.result.dataList.length === 0)) {
                that.$notification.warning({
                  message: '消息',
                  description: '暂无数据'
                })
              }
              that.initChart(res.result)
            }
          })
      },
      /**
       * åˆå§‹åŒ–图表
       * @param dataList å›¾è¡¨æ•°æ®æº
       * @param dateList æ—¥æœŸåˆ—表
       * @param shiftSubList ç­æ¬¡æ ‡é¢˜åˆ—表
       * @param shiftDataList ç­æ¬¡æ•°æ®åˆ—表
       */
      initChart({ dataList, dateList, shiftSubList, shiftDataList }) {
        const defaultLegendData = ['24小时', '24小时(去除故障时间)', '班次', '累计运行时间(h)']
        const defaultSeries = [
          {
            type: 'line',
            name: '24小时',
            yAxisIndex: 0,
            data: dataList ? dataList.map(item => item.utilizationRate) : []
          },
          {
            type: 'value',
            name: '运行时间(h)',
            axisLine: {
              show: true
            }
          }
        ],
        series: defaultSeries
      }
      if (shiftSubList) {
        option.legend.data = defaultLegendData.concat(shiftSubList)
        const newSeriesData = shiftDataList.map(item => {
          return {
            type: 'line',
            name: item.shiftSubName,
            name: '24小时(去除故障时间)',
            yAxisIndex: 0,
            data: item.dataList ? item.dataList.map(item => item.utilizationRate) : []
            data: dataList ? dataList.map(item => item.amendUtilizationRate) : []
          },
          {
            type: 'line',
            name: '班次',
            yAxisIndex: 0,
            data: dataList ? dataList.map(item => item.shiftUtilizationRate) : []
          },
          {
            type: 'bar',
            name: '累计运行时间(h)',
            yAxisIndex: 1,
            barWidth: '30%',
            data: dataList ? dataList.map(item => item.processLong) : []
          }
        })
        ]
        const option = {
          title: {
            text: '设备综合利用率',
            left: 'center',
            top: 0,
            textStyle: {
              fontSize: 22
            }
          },
          grid: {
            top: '12%',
            left: '1%',
            right: '1%',
            bottom: '1%',
            containLabel: true
          },
          legend: {
            top: '6%',
            right: 'center',
            itemGap: 20,
            data: defaultLegendData
          },
          tooltip: {
            show: true,
            trigger: 'axis'
          },
          xAxis: {
            type: 'category',
            data: dateList ? dateList : []
          },
          yAxis: [
            {
              type: 'value',
              name: '利用率(%)',
              axisLine: {
                show: true
              },
              axisLabel: {
                formatter: '{value}%'
              }
            },
            {
              type: 'value',
              name: '运行时间(h)',
              axisLine: {
                show: true
              }
            }
          ],
          series: defaultSeries
        }
        if (shiftSubList) {
          option.legend.data = defaultLegendData.concat(shiftSubList)
          const newSeriesData = shiftDataList.map(item => {
            return {
              type: 'line',
              name: item.shiftSubName,
              yAxisIndex: 0,
              data: item.dataList ? item.dataList.map(item => item.utilizationRate) : []
            }
          })
        option.series = defaultSeries.concat(newSeriesData)
          option.series = defaultSeries.concat(newSeriesData)
        }
        this.chartContainer.setOption(option, true)
        this.chartContainer.hideLoading()
      },
      // èŽ·å–ä¸­å¿ƒåˆ—è¡¨
      getCenterListByApi() {
        this.centerList = []
        const that = this
        mdcApi.getCenterOrGroupListApi()
          .then(res => {
            if (res.success) {
              that.centerList = res.result
              that.queryParam.productionId = res.result[0].value
              that.handleCenterSelectChange(res.result[0].value, { isInitLoad: true })
            }
          })
      },
      /**
       * èŽ·å–ç­ç»„åˆ—è¡¨
       * @param productionId ä¸­å¿ƒId
       */
      getGroupListByApi(productionId, isInitLoad) {
        this.groupList = []
        const that = this
        mdcApi.getCenterOrGroupListApi(productionId)
          .then(res => {
            if (res.success) {
              that.groupList = res.result
              that.handleGroupSelectChange(res.result && res.result.length > 0 && isInitLoad ? [res.result[0].value] : [])
              if (!isInitLoad) return
              that.loadData()
            }
          })
      },
      /**
       * ä¸­å¿ƒå‘生改变时触发
       * @param value æ”¹å˜åŽçš„值
       * @param isInitLoad æ˜¯å¦ä¸ºåˆå§‹åŒ–加载
       */
      handleCenterSelectChange(value, { isInitLoad }) {
        this.getGroupListByApi(value, isInitLoad)
      },
      /**
       * ç­ç»„发生改变时触发
       * @param value æ”¹å˜åŽçš„值
       */
      handleGroupSelectChange(value) {
        this.productionIds = value
        this.queryParam.productionIds = value.join(',')
      },
      // èŽ·å–è®¾å¤‡ç±»åž‹åˆ—è¡¨
      getEquipmentTypeListApi() {
        const that = this
        mdcApi.getEquipmentTypeListApi()
          .then(res => {
            if (res.success) {
              that.equipmentTypeList = res.result
            }
          })
      },
      // èŽ·å–ç­åˆ¶åˆ—è¡¨
      getShiftListByApi() {
        const that = this
        mdcApi.getShiftListApi()
          .then(res => {
            if (res.success) {
              that.shiftList = res.result
            }
          })
      },
      handleWindowResize() {
        if (this.chartContainer) this.chartContainer.resize()
      }
      this.chartContainer.setOption(option, true)
      this.chartContainer.hideLoading()
    },
    // èŽ·å–ä¸­å¿ƒåˆ—è¡¨
    getCenterListByApi() {
      const that = this
      mdcApi.getCenterOrGroupListApi()
        .then(res => {
          if (res.success) {
            that.centerList = res.result
            that.queryParam.productionId = res.result[0].value
            that.getGroupListByApi(res.result[0].value)
          }
        })
    },
    /**
     * èŽ·å–ç­ç»„åˆ—è¡¨
     * @param productionId ä¸­å¿ƒId
     */
    getGroupListByApi(productionId) {
      const that = this
      mdcApi.getCenterOrGroupListApi(productionId)
        .then(res => {
          if (res.success) {
            that.groupList = res.result
            that.handleGroupSelectChange([res.result[0].value])
            that.loadData()
          }
        })
    },
    /**
     * ç­ç»„发生改变时触发
     * @param value æ”¹å˜åŽçš„值
     */
    handleGroupSelectChange(value) {
      this.productionIds = value
      this.queryParam.productionIds = value.join(',')
    },
    // èŽ·å–è®¾å¤‡ç±»åž‹åˆ—è¡¨
    getEquipmentTypeListApi() {
      const that = this
      mdcApi.getEquipmentTypeListApi()
        .then(res => {
          if (res.success) {
            that.equipmentTypeList = res.result
          }
        })
    },
    // èŽ·å–ç­åˆ¶åˆ—è¡¨
    getShiftListByApi() {
      const that = this
      mdcApi.getShiftListApi()
        .then(res => {
          if (res.success) {
            that.shiftList = res.result
          }
        })
    },
    handleWindowResize() {
      if (this.chartContainer) this.chartContainer.resize()
    }
  }
}
</script>
src/views/mdc/base/GroupUtilizationRateCompareChart.vue
@@ -16,7 +16,6 @@
          <a-col :md="5" :sm="5">
            <a-space>
              <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
              <!--              <a-button type="primary" @click="searchReset" icon="reload">重置</a-button>-->
            </a-space>
          </a-col>
        </a-row>
@@ -32,186 +31,188 @@
</template>
<script>
import mdcApi from '@api/mdc'
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
  import mdcApi from '@api/mdc'
  import { JeecgListMixin } from '@/mixins/JeecgListMixin'
export default {
  name: 'GroupUtilizationRateCompareChart',
  components: {},
  mixins: [JeecgListMixin],
  data() {
    return {
      disableMixinCreated: true,
      centerList: [],
      chartsOptionList: [
        {
          position: 'left',
          title: '班组设备综合利用率(24h)',
          property: 'utilizationRateList'
        },
        {
          position: 'middle',
          title: '班组设备综合利用率(24h去除故障时间)',
          property: 'amendUtilizationRateList'
        },
        {
          position: 'right',
          title: '班组设备综合利用率(计划工作时间)',
          property: 'shiftUtilizationRateList'
        }
      ],
      leftChartContainer: null,
      middleChartContainer: null,
      rightChartContainer: null
    }
  },
  mounted() {
    window.addEventListener('resize', this.handleWindowResize)
    this.getCenterListByApi()
    this.handleWindowResize()
  },
  methods: {
    // èŽ·å–å›¾è¡¨æ•°æ®
    loadData() {
      const that = this
      this.chartsOptionList.forEach(item => {
        that.initChart(item.position)
        that.chartSetOption(item.position, item.title, [], [], false)
      })
      mdcApi.getGroupRateCompareChartDataApi(this.queryParam.productionId)
        .then(res => {
          if (res.success) {
            that.chartsOptionList.forEach(item => this.chartSetOption(item.position, item.title, res.result[item.property], res.result.dateList))
          } else {
            that.$notification.warning({
              message: '消息',
              description: res.message
            })
          }
        })
        .catch(err => {
          that.$notification.error({
            message: '消息',
            description: err.message
          })
        })
    },
    /**
     * åˆå§‹åŒ–图表
     * @param position å›¾è¡¨ä½ç½® String
     */
    initChart(position) {
      this[position + 'ChartContainer'] = this.$echarts.init(document.getElementById(`chart-container-${position}`))
      this[position + 'ChartContainer'].showLoading({
        text: '数据加载中 ...',
        color: '#0696e1', // åŠ è½½åŠ¨ç”»é¢œè‰²
        textColor: '#0696e1'
      })
    },
    /**
     * è®¾ç½®å›¾æ ‡é€‰é¡¹
     * @param position å›¾è¡¨ä½ç½® String
     * @param title å›¾è¡¨æ ‡é¢˜ String
     * @param dataList å›¾è¡¨æ•°æ®æº Array
     * @param dateList å›¾è¡¨æ¨ªåæ ‡æœˆä»½ Array
     * @param isHideLoading æ˜¯å¦å…³é—­åŠ è½½å›¾æ ‡ Boolean
     */
    chartSetOption(position, title, dataList, dateList, isHideLoading = true) {
      const option = {
        title: {
          text: title,
          left: 'center',
          top: 0,
          textStyle: {
            fontSize: 22
          }
        },
        grid: {
          top: '10%',
          left: '1%',
          right: '1%',
          bottom: '12%',
          containLabel: true
        },
        legend: {
          bottom: '3%',
          right: 'center',
          data: dataList.map(item => item.productionName)
        },
        tooltip: {
          show: true,
          trigger: 'axis'
        },
        xAxis: {
          type: 'category',
          data: dateList
        },
        yAxis: [
  export default {
    name: 'GroupUtilizationRateCompareChart',
    components: {},
    mixins: [JeecgListMixin],
    data() {
      return {
        disableMixinCreated: true,
        centerList: [],
        chartsOptionList: [
          {
            type: 'value',
            name: '利用率(%)',
            axisLine: {
              show: true
            },
            axisLabel: {
              formatter: '{value}%'
            }
            position: 'left',
            title: '班组设备综合利用率(24h)',
            property: 'utilizationRateList'
          },
          {
            position: 'middle',
            title: '班组设备综合利用率(24h去除故障时间)',
            property: 'amendUtilizationRateList'
          },
          {
            position: 'right',
            title: '班组设备综合利用率(计划工作时间)',
            property: 'shiftUtilizationRateList'
          }
        ],
        series: dataList.map(item => {
          return {
            type: 'line',
            name: item.productionName,
            data: item.dataList.map(item => item.utilizationRate)
          }
        })
        // series: [
        //   {
        //     type: 'line',
        //     name: '数铣一班',
        //     data: [85, 32, 23, 56, 24, 64]
        //   },
        //   {
        //     type: 'line',
        //     name: '数铣二班',
        //     data: [23, 42, 76, 54, 87, 34]
        //   },
        //   {
        //     type: 'line',
        //     name: '数铣三班',
        //     data: [10, 84, 21, 42, 53, 57]
        //   },
        //   {
        //     type: 'line',
        //     name: '数车班',
        //     data: [23, 32, 42, 35, 64, 53]
        //   }
        // ]
        leftChartContainer: null,
        middleChartContainer: null,
        rightChartContainer: null
      }
      this[position + 'ChartContainer'].setOption(option, true)
      if (isHideLoading) this[position + 'ChartContainer'].hideLoading()
    },
    // èŽ·å–ä¸­å¿ƒåˆ—è¡¨
    getCenterListByApi() {
      mdcApi.getCenterOrGroupListApi()
        .then(res => {
          if (res.success) {
            this.centerList = res.result
            this.queryParam.productionId = res.result[0].value
            this.loadData()
          }
    mounted() {
      window.addEventListener('resize', this.handleWindowResize)
      this.getCenterListByApi()
      this.handleWindowResize()
    },
    methods: {
      // èŽ·å–å›¾è¡¨æ•°æ®
      loadData() {
        const that = this
        this.chartsOptionList.forEach(item => {
          that.initChart(item.position)
          that.chartSetOption(item.position, item.title, [], [], false)
        })
    },
        mdcApi.getGroupRateCompareChartDataApi(this.queryParam.productionId)
          .then(res => {
            if (res.success) {
              that.chartsOptionList.forEach(item => this.chartSetOption(item.position, item.title, res.result[item.property], res.result.dateList))
            } else {
              that.$notification.warning({
                message: '消息',
                description: res.message
              })
            }
          })
          .catch(err => {
            that.$notification.error({
              message: '消息',
              description: err.message
            })
          })
      },
    handleWindowResize() {
      if (this.leftChartContainer) this.leftChartContainer.resize()
      if (this.middleChartContainer) this.middleChartContainer.resize()
      if (this.rightChartContainer) this.rightChartContainer.resize()
      /**
       * åˆå§‹åŒ–图表
       * @param position å›¾è¡¨ä½ç½® String
       */
      initChart(position) {
        this[position + 'ChartContainer'] = this.$echarts.init(document.getElementById(`chart-container-${position}`))
        this[position + 'ChartContainer'].showLoading({
          text: '数据加载中 ...',
          color: '#0696e1', // åŠ è½½åŠ¨ç”»é¢œè‰²
          textColor: '#0696e1'
        })
      },
      /**
       * è®¾ç½®å›¾æ ‡é€‰é¡¹
       * @param position å›¾è¡¨ä½ç½® String
       * @param title å›¾è¡¨æ ‡é¢˜ String
       * @param dataList å›¾è¡¨æ•°æ®æº Array
       * @param dateList å›¾è¡¨æ¨ªåæ ‡æœˆä»½ Array
       * @param isHideLoading æ˜¯å¦å…³é—­åŠ è½½å›¾æ ‡ Boolean
       */
      chartSetOption(position, title, dataList, dateList, isHideLoading = true) {
        const option = {
          title: {
            text: title,
            left: 'center',
            top: 0,
            textStyle: {
              fontSize: 22
            }
          },
          grid: {
            top: '10%',
            left: '1%',
            right: '1%',
            bottom: '12%',
            containLabel: true
          },
          legend: {
            bottom: '3%',
            right: 'center',
            data: dataList.map(item => item.productionName)
          },
          tooltip: {
            show: true,
            trigger: 'axis'
          },
          xAxis: {
            type: 'category',
            data: dateList
          },
          yAxis: [
            {
              type: 'value',
              name: '利用率(%)',
              axisLine: {
                show: true
              },
              axisLabel: {
                formatter: '{value}%'
              }
            }
          ],
          series: dataList.map(item => {
            return {
              type: 'line',
              name: item.productionName,
              data: item.dataList.map(item => item.utilizationRate)
            }
          })
          // series: [
          //   {
          //     type: 'line',
          //     name: '数铣一班',
          //     data: [85, 32, 23, 56, 24, 64]
          //   },
          //   {
          //     type: 'line',
          //     name: '数铣二班',
          //     data: [23, 42, 76, 54, 87, 34]
          //   },
          //   {
          //     type: 'line',
          //     name: '数铣三班',
          //     data: [10, 84, 21, 42, 53, 57]
          //   },
          //   {
          //     type: 'line',
          //     name: '数车班',
          //     data: [23, 32, 42, 35, 64, 53]
          //   }
          // ]
        }
        this[position + 'ChartContainer'].setOption(option, true)
        if (isHideLoading) this[position + 'ChartContainer'].hideLoading()
      },
      // èŽ·å–ä¸­å¿ƒåˆ—è¡¨
      getCenterListByApi() {
        this.centerList = []
        const that = this
        mdcApi.getCenterOrGroupListApi()
          .then(res => {
            if (res.success) {
              that.centerList = res.result
              that.$set(that.queryParam, 'productionId', res.result[0].value)
              that.loadData()
            }
          })
      },
      handleWindowResize() {
        if (this.leftChartContainer) this.leftChartContainer.resize()
        if (this.middleChartContainer) this.middleChartContainer.resize()
        if (this.rightChartContainer) this.rightChartContainer.resize()
      }
    }
  }
}
</script>
src/views/mdc/base/modules/DeviceLog/LogInfo.vue
@@ -31,87 +31,52 @@
    </div>
    <div>
      <table cellpadding="0" cellspacing="0" width="100%">
        <tr>
          <td>
            <table width="100%">
              <tr style="word-break: keep-all;">
                <td align="right"><a id="btnMdcLogWline" href="#">
                  <div style="padding-top: 15px;" @click="openWorkChart">
                    <img src="../../../../../assets/image/linechart.png" alt="">
                    <p>工作曲线</p>
                  </div>
                </a></td>
                <td width="100%" height="100%">
                  <table width="100%" height="100%" align="center" cellpadding="0" cellspacing="0">
                    <tr>
                      <td style="word-break: keep-all;" align="left">
                        <div
                          style="width: 100%;  height: 62px;border: 1px solid;border-color: #9d9d9d;position: relative;overflow: hidden">
                          <div class="mdcLogShowOne"
                               :style='{display: "inline-block",width:item.dateProportion,  height: "100%"}'
                               v-for="item in normal">
                            <span v-if="item.status == 0"
                                  :style='{display: "inline-block",width:item.dateProportion,  height: "100%", background: "#A8A8A8",position:"absolute",top:"0"}'></span>
                            <span v-if="item.status == 1"
                                  :style='{display: "inline-block",width:item.dateProportion,  height: "100%", background: "#fffc5c",position:"absolute",top:"0"}'></span>
                            <span v-if="item.status == 2"
                                  :style='{display: "inline-block",width:item.dateProportion,  height: "100%", background: "#fffc5c",position:"absolute",top:"0"}'></span>
                            <span v-if="item.status == 3"
                                  :style='{display: "inline-block",width:item.dateProportion,  height: "100%", background: "#19FE01",position:"absolute",top:"0"}'></span>
                            <span v-if="item.status == 23"
                                  :style='{display: "inline-block",width:item.dateProportion,  height: "100%", background: "#19FE01",position:"absolute",bottom:"0"}'></span>
                          </div>
                          <div v-if="item.status == 22" style="z-index: 999;"
                               :style='{display: "inline-block",left:item.left,width:item.dateProportion,  height: "100%",position:"absolute"}'
                               v-for="item in warning">
      <div class="equipment-status-container">
        <a href="#" @click="openWorkChart">
          <img src="@/assets/image/linechart.png" alt="">
          <div>工作曲线</div>
        </a>
        <div>
          <div :style='{display: "inline-block",width:item.dateProportion,  height: "100%"}' v-for="item in normal">
            <span v-if="item.status == 0"
                  :style='{display: "inline-block",width:item.dateProportion,  height: "100%", background: "#A8A8A8",position:"absolute",top:"0"}'></span>
            <span v-if="item.status == 1"
                  :style='{display: "inline-block",width:item.dateProportion,  height: "100%", background: "#fffc5c",position:"absolute",top:"0"}'></span>
            <span v-if="item.status == 2"
                  :style='{display: "inline-block",width:item.dateProportion,  height: "100%", background: "#fffc5c",position:"absolute",top:"0"}'></span>
            <span v-if="item.status == 3"
                  :style='{display: "inline-block",width:item.dateProportion,  height: "100%", background: "#19FE01",position:"absolute",top:"0"}'></span>
            <span v-if="item.status == 23"
                  :style='{display: "inline-block",width:item.dateProportion,  height: "100%", background: "#19FE01",position:"absolute",bottom:"0"}'></span>
          </div>
          <div v-if="item.status == 22"
               :style='{display: "inline-block",left:item.left,width:item.dateProportion,  height: "100%",position:"absolute"}'
               v-for="item in warning">
                            <span
                              :style='{display: "inline-block",width:"100%", left:0, height: "68%", background: "#FD0008",position:"absolute",bottom:"0"}'></span>
                          </div>
                          <div v-if="item.status == 25" style="z-index: 1000;"
                               :style='{display: "inline-block",left:item.left,width:item.dateProportion,  height: "100%",position:"absolute"}'
                               v-for="item in fault">
          </div>
          <div v-if="item.status == 25"
               :style='{display: "inline-block",left:item.left,width:item.dateProportion,  height: "100%",position:"absolute"}'
               v-for="item in fault">
                            <span
                              :style='{display: "inline-block",width:"100%", left:0, height: "50%", background: "#C11900",position:"absolute",bottom:"0"}'></span>
                          </div>
                        </div>
                      </td>
                    </tr>
                  </table>
                </td>
                <td align="left"><a id="btnMdcLogBar" href="#">
                  <div style="padding-top: 15px;" @click="openHistoryChart">
                    <img src="../../../../../assets/image/Histogram.png" alt="">
                    <p>历史记录</p>
                  </div>
                </a></td>
              </tr>
              <tr>
                <td align="right">0</td>
                <td width="100%">
                  <table width="100%;" cellpadding="0" cellspacing="0">
                    <tr align="right" style="word-break: keep-all;">
                      <td>02:00</td>
                      <td>04:00</td>
                      <td>06:00</td>
                      <td>08:00</td>
                      <td>10:00</td>
                      <td>12:00</td>
                      <td>14:00</td>
                      <td>16:00</td>
                      <td>18:00</td>
                      <td>20:00</td>
                      <td>22:00</td>
                      <td>24:00</td>
                    </tr>
                  </table>
                </td>
                <td></td>
              </tr>
            </table>
          </td>
        </tr>
      </table>
          </div>
        </div>
        <a href="#" @click="openHistoryChart">
          <img src="@/assets/image/Histogram.png" alt="">
          <div>历史记录</div>
        </a>
      </div>
      <div class="time-container">
        <div>0</div>
        <div>
          <div v-for="item in 12">{{('0'+item*2).slice(-2)}}:00</div>
        </div>
        <div></div>
      </div>
      <a-space class="date-change-container">
        <img @click="dataBefore" src="@/assets/image/left.png" alt="">
@@ -342,6 +307,46 @@
</script>
<style scoped="scoped" lang="less">
  @image-container-width: 58px;
  .equipment-status-container {
    display: flex;
    > a {
      display: inline-block;
      text-align: center;
      width: @image-container-width
    }
    > div {
      height: 62px;
      border: 1px solid #9d9d9d;
      position: relative;
      overflow: hidden;
      flex: 1
    }
  }
  .time-container {
    display: flex;
    align-items: center;
    > div:not(:nth-child(2)) {
      width: @image-container-width;
      text-align: right;
    }
    > div:nth-child(2) {
      width: calc(100% - @image-container-width * 2);
      display: flex;
      div {
        width: calc(100% / 12);
        text-align: right;
      }
    }
  }
  .date-change-container {
    display: flex;
    align-items: center;
src/views/mdc/base/modules/PartsMatchingManagement/PartsMatchingForm.vue
@@ -5,7 +5,7 @@
        <a-row>
          <a-col :span="24">
            <a-form-model-item label="设备组" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="equipmentIds">
              <a-input-search :readOnly="true" v-model="model.equipmentIds"
              <a-input-search :readOnly="true" v-model="model.equipmentIds" @click="deviceSearch"
                              @search="deviceSearch" :disabled="disableSelectDevice" enter-button
                              placeholder="请选择设备"></a-input-search>
            </a-form-model-item>
src/views/mdc/base/modules/TorqueconfigurationList/TorqueconfigurationList.vue
@@ -25,15 +25,6 @@
              <a-button type="primary" @click="searchReset" icon="reload">重置</a-button>
            </a-space>
          </a-col>
          <!--<a-col :md="2" :sm="3" :xs="3">-->
            <!--<a-button type="primary" @click="searchQuery" icon="search">查询</a-button>-->
          <!--</a-col>-->
          <!--<a-col :md="2" :sm="2" :xs="2">-->
            <!--<a-button type="primary" @click="searchReset" icon="reload">重置</a-button>-->
          <!--</a-col>-->
          <!--<a-col :lg="2" :md="3" :sm="3" :xs="3">-->
            <!--<a-button type="primary" @click="exportExcel" icon="download">导出</a-button>-->
          <!--</a-col>-->
        </a-row>
      </a-form>
    </div>
@@ -82,13 +73,8 @@
      </a-table>
    </div>
    <!-- table区域-end -->
    <!--<device-repair-model></device-repair-model>-->
    <torqueconfiguration-modal ref="modalForm" @ok="modalFormOk"></torqueconfiguration-modal>
    <torqueconfiguration-modaledit  ref="modalFormedit" @ok="modalFormOk">></torqueconfiguration-modaledit>
    <!--<device-repair-model-add  ref="modalFormadd" @ok="modalFormOk"></device-repair-model-add>-->
    <!--<device-repair-model-edit ref="modalFormedit" @ok="modalFormOk"></device-repair-model-edit>-->
    <!--<repair-model ref="repairModelFrom" @ok="modalFormOk"></repair-model>-->
  </div>
</template>
src/views/mdc/base/modules/TorqueconfigurationList/TorqueconfigurationModal.vue
@@ -7,7 +7,7 @@
          <a-col :span="12">
            <a-form-item label="设备组" :labelCol="labelCol" :wrapperCol="wrapperCol">
              <a-input-search :readOnly="true" v-decorator="['equipmentIds', validatorRules.equipmentIds]"
                              @search="deviceSearch" enter-button placeholder="请选择设备"/>
                              @search="deviceSearch" @click="deviceSearch" enter-button placeholder="请选择设备"/>
            </a-form-item>
          </a-col>
          <a-col :span="12">
src/views/mdc/base/modules/comparativeAnalysis/ComparativeAnalysisMain.vue
@@ -7,7 +7,7 @@
          <a-row :gutter="24">
            <a-col :md="5" :sm="5">
              <a-form-item label="设备">
                <a-input-search :readOnly="true" v-model="queryParam.equipmentId" @search="deviceSearch"
                <a-input-search :readOnly="true" v-model="queryParam.equipmentId" @search="deviceSearch" @click="deviceSearch"
                                placeholder='请选择设备'/>
              </a-form-item>
            </a-col>
src/views/mdc/base/modules/deviceCalendar/DeviceCalendarList.vue
@@ -16,17 +16,6 @@
                <a-button v-has="'user.disposition'" type="primary" @click="handleAdd" icon="plus">配置</a-button>
              </a-space>
            </a-col>
            <!--<a-col :md="2" :sm="2" :xs="2">-->
            <!--<a-button type="primary" @click="searchQuery" icon="search">查询</a-button>-->
            <!--</a-col>-->
            <!--<a-col :md="2" :sm="2">-->
            <!--&lt;!&ndash;//沈飞&ndash;&gt;-->
            <!--<a-button v-has="'user.disposition'" type="primary" @click="handleAdd" icon="plus">配置</a-button>-->
            <!--&lt;!&ndash;<a-button type="primary" @click="handleAdd" icon="plus">配置</a-button>&ndash;&gt;-->
            <!--</a-col>-->
          </a-row>
        </a-form>
      </div>
src/views/mdc/base/modules/deviceCalendar/DeviceCalendarModel.vue
@@ -10,7 +10,7 @@
            <a-col :span="24">
              <a-form-item label="设备组" :labelCol="labelColLong" :wrapperCol="wrapperColLong">
                <a-input-search :readOnly="true" v-decorator="['equipmentId', validatorRules.equipmentId]"
                                @search="deviceSearch" enter-button placeholder="请选择设备"/>
                                @search="deviceSearch" @click="deviceSearch" enter-button placeholder="请选择设备"/>
              </a-form-item>
            </a-col>
          </a-row>
@@ -341,35 +341,6 @@
</script>
<style scoped lang="less">
  /deep/ .ant-modal-close {
    color: #1191b0;
    font-size: 24px;
  }
  /deep/ .ant-modal-close-x {
    font-size: 24px;
  }
  .ant-btn {
    padding: 0 10px;
    margin-left: 3px;
  }
  .ant-form-item-control {
    line-height: 0px;
  }
  /** ä¸»è¡¨å•行间距 */
  .ant-form .ant-form-item {
    margin-bottom: 10px;
  }
  /** Tab页面行间距 */
  .ant-tabs-content .ant-form-item {
    margin-bottom: 0px;
  }
  /deep/ .mark1 {
    color: white !important;
    background-color: #1890ff !important;
src/views/mdc/base/modules/efficiencyReport/EfficiencyList.vue
@@ -189,7 +189,7 @@
                    {{tableHead.openRate | numFilter}}
                  </td>
                  <td :style="{background:tableHead.color }" v-if="checkedList.indexOf('gzl') > -1">
                    {{tableHead.faultRate | numFilter}}
                    {{tableHead.faultRate }}
                  </td>
                  <td :style="{background:tableHead.color }" v-if="checkedList.indexOf('kjsj') > -1">
                    {{tableHead.openLong | getFormattedTime}}