loulijun2021
2022-09-01 99a010f21d278498bafd248217c584e101db2d8f
1.自动扫码回车功能接入
已添加28个文件
已修改6个文件
7971 ■■■■■ 文件已修改
package.json 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Test/index.vue 246 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/TestLeft/index.vue 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/lib/v-gantt-chart/.babelrc 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/lib/v-gantt-chart/.gitignore 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/lib/v-gantt-chart/LICENSE 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/lib/v-gantt-chart/README.md 380 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/lib/v-gantt-chart/index.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/lib/v-gantt-chart/lib/assets/block.png 补丁 | 查看 | 原始文档 | blame | 历史
src/lib/v-gantt-chart/lib/components/blocks/index.vue 156 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/lib/v-gantt-chart/lib/components/dynamic-render.js 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/lib/v-gantt-chart/lib/components/left-bar/index.vue 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/lib/v-gantt-chart/lib/components/mark-line/current-time.vue 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/lib/v-gantt-chart/lib/components/mark-line/index.vue 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/lib/v-gantt-chart/lib/components/time-line/index.vue 162 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/lib/v-gantt-chart/lib/gantt.scss 176 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/lib/v-gantt-chart/lib/gantt.vue 550 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/lib/v-gantt-chart/lib/index.js 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/lib/v-gantt-chart/lib/utils/debounce.js 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/lib/v-gantt-chart/lib/utils/gtUtils.js 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/lib/v-gantt-chart/lib/utils/throttle.js 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/lib/v-gantt-chart/lib/utils/timeLineUtils.js 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/lib/v-gantt-chart/lib/utils/tool.js 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/lib/v-gantt-chart/package.json 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/lib/v-gantt-chart/test/gtUtils.test.js 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/lib/v-gantt-chart/test/timeblock.test.js 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/lib/v-gantt-chart/webpack.config.js 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/sbgl/byjl.vue 821 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/sbgl/djjl.vue 1858 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/sbgl/index1.js 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/scgl/gd.vue 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/scgl/sckbg.vue 132 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/scgl/sckbg_back.vue 2394 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/zlgl/gxjy.vue 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json
@@ -16,6 +16,7 @@
  "dependencies": {
    "axios": "0.18.1",
    "core-js": "3.6.5",
    "dayjs": "^1.11.5",
    "echarts": "^5.3.2",
    "element-ui": "2.13.2",
    "jquery": "^3.6.0",
src/components/Test/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,246 @@
<template>
  <el-popover placement="bottom"
              trigger="hover">
    <div slot="reference"
         class="plan"
         :style="{'margin-top':0.1*cellHeight+'px',}"
         @click="onClick"
    >
      <!-- <div class="runTime">
        <span>S:{{startToString}}</span>
        <span>E:{{endToString}}</span>
      </div> -->
      <div
        :class="{'hw':true,'SCHEDULEING' : item.type == 'schedule','H_SCHEDULE':item.type=='h_schedule','BM_SCHEDULE':item.type=='bm_schedule'}">
        <span v-show='item.type == "schedule"'>{{ item.number }}</span>
        <span v-show='item.type == "h_schedule"'>{{ item.number }}</span>
      </div>
      <!-- <div class="passenger"></div> -->
    </div>
    <div class="detail">
      <!-- <span>{{data.name}}</span> -->
      <ul v-if="item.type =='h_schedule' || item.type =='schedule'">
        <li>
          <span>工单编号:</span><span>{{ item.work_order }}</span>
        </li>
        <li>
          <span>产品名称:</span><span>{{ item.cl_name }}</span>
        </li>
        <li>
          <span>产品编码:</span><span>{{ item.cl_code }}</span>
        </li>
        <li>
          <span>生产数量:</span><span>{{ item.number }}{{ item.STATUS }}</span>
        </li>
        <li>
          <span>生产设备:</span><span>{{ item.id }}</span>
        </li>
        <li>
          <span>开始时间:</span><span>{{ item.start }}</span>
        </li>
        <li>
          <span>结束时间:</span><span>{{ item.end }}</span>
        </li>
      </ul>
      <ul v-if="item.type =='capacity'">
        <!-- <li>
          <span>产品:</span><span>{{item.cl_name}}</span>
        </li>
         <li>
          <span>数量:</span><span>{{item.number}}个</span>
        </li> -->
        <li>
          <span>生产设备:</span><span>{{ item.id }}</span>
        </li>
        <li>
          <span>开始时间:</span><span>{{ item.start }}</span>
        </li>
        <li>
          <span>结束时间:</span><span>{{ item.end }}</span>
        </li>
      </ul>
      <ul v-if="item.type =='bm_schedule'">
        <li>
          <span>维修时间:</span><span>{{ item.start }} ~ {{ item.end }}</span>
        </li>
      </ul>
    </div>
  </el-popover>
</template>
<script>
import dayjs from 'dayjs'
const NOW_PLAN = '#D5F8EA'
const FUTHER_PLAN = '#BFF2FE'
const PAST_PLAN = '#F2F2F2'
const CAPACITY = '#d1efed'
const H_SCHEDULE = '#ffc000'
const SCHEDULEING = '#14b6e7'
const BM_SCHEDULE = 'FFFF33'
export default {
  name: 'Test',
  props: {
    data: Object,
    item: Object,
    currentTime: dayjs,
    updateTimeLines: Function,
    cellHeight: Number,
    startTimeOfRenderArea: Number
  },
  data() {
    return {
      dayjs: dayjs
    }
  },
  computed: {
    statusColor() {
      let { item, currentTime } = this
      let start = dayjs(item.start)
      let end = dayjs(item.end)
      // if(item.type == 'capacity'){
      //   return CAPACITY
      // }else if(item.type == 'h_schedule'){
      //   return H_SCHEDULE
      // }else if(item.type == 'schedule'){
      //   return SCHEDULEING
      // }
      // if (start.isBefore(currentTime) && end.isAfter(currentTime)) {
      //   return NOW_PLAN; // NOW
      // } else if (end.isBefore(currentTime)) {
      //   return PAST_PLAN; // PAST
      // } else {
      //   return FUTHER_PLAN; // Future
      // }
    },
    startToString() {
      return dayjs(this.item.start).format('HH:mm')
    },
    endToString() {
      return dayjs(this.item.end).format('HH:mm')
    }
  },
  methods: {
    onClick() {
      this.updateTimeLines(this.item.start, this.item.end)
    }
  }
}
</script>
<style lang="scss" scoped>
.hw {
  height: 100%;
  width: 100%;
  position: relative;
  z-index: 0;
  // background:rgba(171, 245, 240 , 0.6);
  background: rgba(5, 185, 100, 0.1);
  text-align: center;
  border-radius: 5px;
}
.middle {
  flex: 1;
  text-align: center;
  padding-left: 5px;
}
.runTime {
  display: flex;
  flex-direction: column;
}
.plan {
  display: flex;
  align-items: center;
  box-sizing: border-box;
  height: 80%;
  // border: 1px solid #f0f0f0;
  border-radius: 5px;
  color: #333333;
  // padding-left: 5px;
  font-size: 0.8rem;
  // opacity: 0.8;
}
.capacity {
  background: rgb(209, 239, 237) !important
}
.detail {
  .header {
    text-align: center;
    font-size: 1rem;
  }
}
.detail ul {
  list-style: none;
  padding: 0px;
  li {
    span {
      // display: inline-block;
      width: 135px;
      color: #777;
      font-size: 0.8rem;
    }
    span:first-child {
      text-align: center;
    }
    span:last-child {
    }
  }
}
.CAPACITY {
  background: rgba(171, 245, 240, 0.6)
}
.H_SCHEDULE {
  background: #05b964;
  height: 70%;
  margin-left: 3px;
  border-radius: 5px;
  position: relative;
  z-index: 2;
  color: whitesmoke;
  font-size: 12px;
  line-height: 1.5
}
.SCHEDULEING {
  background: #ac96ff;
  height: 70%;
  margin-left: 3px;
  border-radius: 5px;
  position: relative;
  z-index: 2;
  color: whitesmoke;
  font-size: 12px;
  line-height: 1.5
}
.BM_SCHEDULE {
  background: #FFFF33;
  height: 70%;
  margin-left: 3px;
  border-radius: 5px;
  position: relative;
  z-index: 2;
  color: whitesmoke;
  font-size: 12px;
  line-height: 1.5
}
</style>
src/components/TestLeft/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,75 @@
<template>
  <!-- <div class="name" :style="{background:data.colorPair.light}"> -->
  <div>
    <div class="name">
      <!-- <div class="colorBar"  :style="{background:data.colorPair.dark}"/> -->
      <!-- <div class="type">{{data.type}}</div> -->
      <div class="carId"><input type="checkbox" id="label" v-model="ckeckVal" @change="click_box(data)">{{ data.name }}
      </div>
      <div class="speed">
        <el-tooltip class="item" effect="dark" content="查看" placement="top">
          <el-button type="text" size="mini" @click="look(data.id)">
            <i class="el-icon-document size i-color "></i>
          </el-button>
        </el-tooltip>
      </div>
    </div>
    <el-dialog title="查看" :visible.sync="showDialog" width="60%">
    </el-dialog>
  </div>
</template>
<script>
export default {
  name: 'TestLeft',
  data() {
    return {
      showDialog: false,
      ckeckVal: true
    }
  },
  props: {
    data: Object
  },
  methods: {
    look(id) {
      this.showDialog = true
      console.log(id)
    },
    click_box(data) {
      console.log(data)
      console.log(this.ckeckVal)
    }
  }
}
</script>
<style scoped>
.name {
  display: flex;
  box-sizing: border-box;
  overflow: hidden;
  height: 100%;
  width: 100%;
  padding: 0 5px 0 0;
  border-radius: 8px 0 0 8px;
  align-items: center;
}
.colorBar {
  width: 10px;
  height: 100%;
}
.carId {
  flex: 1;
}
.type {
  padding: 0 5px 0 0;
  font-size: 1.2rem;
}
</style>
src/lib/v-gantt-chart/.babelrc
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
{
  "presets": [
    ["env", {
      "modules": false
    }],
    "stage-3"
  ],
  "env": {
    "test": {
      "presets": [
        ["env"],
        "stage-3"
      ]
    }
  },
}
src/lib/v-gantt-chart/.gitignore
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
.DS_Store
node_modules
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw*
src/lib/v-gantt-chart/LICENSE
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2019 wuchouchou
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
src/lib/v-gantt-chart/README.md
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,380 @@
<p align="center"><img src="https://raw.githubusercontent.com/w1301625107/vue-gantt-chart/master/screenshot/icon.png" alt="logo" width="180"></p>
<h1 align="center">vue-gantt-chart</h1>
<p align="center">基于 Vue  å®žçŽ°çš„ gantt-like å›¾è¡¨ ,用于排班展示</p>
<p align="center"></p>
[![npm](https://img.shields.io/npm/v/v-gantt-chart.svg)](https://www.npmjs.com/package/v-gantt-chart)
![](https://img.shields.io/badge/license-MIT-000000.svg)
### [React版本](https://github.com/w1301625107/React-Gantt-chart)
### [Demo预览地址](https://w1301625107.github.io/Vue-Gantt-chart/dist/index)
## Feature
- è™šæ‹Ÿåˆ—表,快速渲染可视区域,支持大量数据渲染
- å¯å˜æ—¶é—´è½´ï¼Œ1 åˆ†é’Ÿï¼Œ2 åˆ†é’Ÿï¼Œ3 åˆ†é’Ÿï¼Œ4 åˆ†é’Ÿ~~~到一天
- å¯å˜å•元格
- æ ‡è®°çº¿
- æ”¯æŒè‡ªå®šä¹‰æè¿°å’Œå®¹å™¨å—
## Screenshot
![](https://raw.githubusercontent.com/w1301625107/vue-gantt-chart/master/screenshot/page1.png)
## Install
[![v-gantt-chart](https://nodei.co/npm/v-gantt-chart.png)](https://npmjs.org/package/v-gantt-chart)
``` bash
npm i v-gantt-chart --save
```
Include plugin in your `main.js` file.
```js
import Vue from 'vue'
import vGanttChart from 'v-gantt-chart';
Vue.use(vGanttChart});
```
## Use
### template code
```html
<template>
  <v-gantt-chart :startTime="startTime"
           :endTime="endTime"
           :datas="datas">
      <template v-slot:block="{data,item}">
        <!-- ä½ çš„容器块组件 -->
        <Test :data="data" :item="item"></Test>
      </template>
      <template v-slot:left="{data}">
        <!-- ä½ çš„行名组件 -->
        <TestLeft :data="data"></TestLeft>
      </template>
      <template v-slot:title>
        <!-- ä½ çš„表头组件 -->
        hola
      </template>
    </v-gantt-chart>
</template>
```
### script code
```js
import Test from "./test.vue"; //你自己的gantt条容器
import TestLeft from "./test-left.vue"; //你自己的行名称组件
import { mockDatas } from "@src/mock/index.js"; //伪造的数据
import dayjs from "dayjs" //时间库
export default {
  name: "App",
  components: { Test, TestLeft },
  data() {
    return {
      startTime: dayjs().toString(),//时间轴开始时间
      endTime: dayjs()
        .add(2, "d")
        .add(2, "h")
        .add(5, "s").toString(), //时间结束时间
      datas: mockDatas(100), // gantt数据
    };
  },
};
```
在**默认情况**下(即`customGenerateBlocks`为`false`)的渲染的数据需要**特殊格式** ï¼Œç›®å‰è¦æ±‚数组中每一个值均为对象,且有`gtAarry`对象数组这个属性(默认取`gtArray`,也可以自定义多个数组`key`值)
//数组中每一个对象需有两个属性,`start`和`end`(不提供的情况,偏移与宽度将为0),需为合法的时间字符串.例如
```js
[
  {
    id:'test', //非必须
    gtArray:[ //默认的需要渲染的数组的key
      {
        name:'test', //非必须
        start:'2019-01-11 18:18:18',
        end:'2019-01-11 18:18:18'
      }
    ],
    customKey:[ //自定义的需要渲染的数组的key
      {
        id:'test', //非必须
        start:'2019-01-11 18:18:18',
        end:'2019-01-11 18:18:18'
      }
    ]
  }
]
```
## Slot
```js
// å‡è®¾ä½ ä¼ å…¥çš„æ•°æ®ä¸º
[
  {
    id:'test',
    name:'sala',
    gtArray:[
      {
        name:'test',
        start:'2019-01-11 18:18:18',
        end:'2019-01-11 18:18:18'
        //...
      }
    ],
    //...
  }
  //...
]
```
### block å®¹å™¨å—slot
#### `customGenerateBlocks` ä¸ºfalse(默认值) çš„æƒ…况
```html
<template v-slot:block="{data,item}">
    <!-- ä½ çš„容器块组件 -->
    <Test :data="data" :item="item"></Test>
</template>
```
`data` ä¸º
```js
{
  id:'test',
  name:'sala',
  gtArray:[{...}],
  //...
}
```
`item` ä¸º
```js
{
  name:'test',
  start:'2019-01-11 18:18:18',
  end:'2019-01-11 18:18:18'
  //...
}
```
#### `customGenerateBlocks` ä¸ºtrue çš„æƒ…况
此时`arrayKeys`,`itemkey`将不在生效,如何渲染,渲染什么,将由你自己决定,下方是一个例子
```html
<template v-slot:block="{data,
                        getPositonOffset,
                        getWidthAbout2Times,
                        isInRenderingTimeRange}">
  <div class="myBlockContainer"
        v-for="item in data.gtArray"
        v-if="isInRenderingTimeRange(item.start)
              ||isInRenderingTimeRange(item.end)"
        :key="item.id"
        :style="{position:'absolute',
                left:getPositonOffset(item.start)+'px',
                width:getWidthAbout2Times(item.start,item.end)+'px'}">
    <Test :data="data"
          :item="item"></Test>
  </div>
</template>
```
 `data` ä¸º
```js
{
  id:'test',
  name:'sala',
  gtArray:[{...}],
  //...
}
```
`getPositonOffset(time:string):number `
定位函数,根据给定字符串形式的时间生成相对时间轴起点的的偏移值
`getWidthAbout2Times(start:string,end:string):number`
为宽度计算函数,根据给定字符串形式的时间计算两个时间差的宽度值
`isInRenderingTimeRange(time:string):boolean`
判定给定的时间是否在屏幕显示的时间轴范围之内
### left è¡Œåslot
```html
<template v-slot:left="{data}">
    <!-- ä½ çš„行名组件 -->
    <TestLeft :data="data"></TestLeft>
</template>
```
`data` ä¸º
```js
{
  id:'test',
  name:'sala',
  gtArray:[{...}],
  //...
}
```
### title æ ‡é¢˜slot
```html
<template v-slot:title>
    <!-- ä½ çš„表头组件 -->
    hola
</template>
````
## API
<style>
.param table th:first-of-type {
    width: 100px;
}
.param table th:nth-of-type(2) {
    width: 100px;
}
.param table th:nth-of-type(4) {
    width: 100px;
}
</style>
<div class="param">
### Param
| param            | required | type  | default | describe                                   |
| :-------------- | :------: | :-----: | :----: | :---- |
| startTime       |    âŒ     | string  |   å½“前时间   | æ—¶é—´è½´å¼€å§‹æ—¶é—´ï¼Œéœ€ä¸ºåˆæ³•的时间字符串,如:`2019-01-11 18:18:18`|
| endTime         |    âŒ     | string  |   å½“前时间   | æ—¶é—´è½´ç»“束时间,需为合法的时间字符串,如:`2019-01-11 18:18:18`|
| cellWidth       |    âŒ     | number  |   50   | æ—¶é—´åŒºé—´çš„宽度 |
| cellHeight      |    âŒ     | number  |   20   | æ—¶é—´åŒºé—´çš„高度 |
| titleHeight     |    âŒ     | number  |   40   | è¡¨å¤´çš„高度    |
| titleWidth      |    âŒ     | number  |  200   | è¡¨å¤´å’Œè¡Œçš„宽度 |
| scale           |    âŒ     | number  |   60   | æ—¶é—´è½´çš„刻度值。单位:分钟,允许值`[1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30, 60, 120,180,240,360, 720, 1440] `                                   |
| datas           |    âŒ     |  array  |   []   | åœ¨**默认情况**下(即`customGenerateBlocks`为`false`)的渲染的数据需要**特殊格式** ï¼Œç›®å‰è¦æ±‚数组中每一个值均为对象,且有gtAarry对象数组这个属性,gtArray中每一个对象需有两个属性,start和end(不提供的情况,偏移与宽度将为0),需为合法的时间字符串.例如```[{id:'test',gtArray:[{start:'2019-01-11 18:18:18',end:'2019-01-11 18:18:18'}]}] ``` å…¶ä»–不做限制。 |
| arrayKeys|    âŒ     | array  |   ["gtArray"]   | éœ€è¦æ¸²æŸ“的数组的key  |
| dataKey         |    âŒ     | string  |   --   | æ¸²æŸ“的每一行的key  |
| itemKey         |    âŒ     | string  |   --   | æ¸²æŸ“的每一个gantt容器的key  |
| showCurrentTime |    âŒ     | boolean | false  | æ˜¾ç¤ºå½“前时间,每秒钟更新  |
| timelines       |    âŒ     |  array  |   --   | æ˜¾ç¤ºæ ‡è®°æ—¶é—´ï¼Œæœ‰ç‰¹æ®Šæ ¼å¼ ``` [{time:'2019-01-11 18:18:18',color:'#00000'}]```                                                                      |
| scrollToTime    |    âŒ     | string  |   --   | æ»šåŠ¨åˆ°æŒ‡å®šçš„æ—¶é—´ï¼Œéœ€ä¸ºåˆæ³•çš„æ—¶é—´å­—ç¬¦ä¸²  |
| scrollToPostion |    âŒ     | object  |   --   | æ»šåŠ¨åˆ°æŒ‡å®šçš„ä½ç½® æ ¼å¼ä¸º``` {x:number,y:number}```  |
| hideHeader |    âŒ     | boolean  |   false   | éšè—æ—¶é—´è½´å’Œè¡¨å¤´ |
| hideXS |    âŒ     | boolean  |   false   | éšè—æ—¶é—´è½´å’Œè¡¨å¤´ |
| hideXScrollBar |    âŒ     | boolean  |   false   | éšè—æ¨ªå‘滚动轴 |
| hideYScrollBar |    âŒ     | boolean  |   false   | éšè—çºµå‘滚动轴 |
| customGenerateBlocks |    âŒ     | boolean  |   false | å¼€å¯è‡ªå®šä¹‰ç”Ÿæˆæ¸²æŸ“块,具体使用见说明 |
</div>
<style>
.event table th:first-of-type {
    width: 100px;
}
.event table th:nth-of-type(2) {
    width: 100px;
}
.event table th:nth-of-type(3) {
    width: 300px;
}
</style>
<div class="event">
### Event
| event | type | describle|
| :---  |:-----:|:---------|
| scrollLeft| number | X轴的滚动值|
| scrollTop | number | Y轴的滚动值|
</div>
## Next plan
- åŠ å¿«æ¸²æŸ“é€Ÿåº¦
## Run Demo
### æ³¨æ„é¡¹ç›®éœ€è¦ node çŽ¯å¢ƒ
```bash
#clone项目,进入项目根目录
#安装
npm i
# å¯åЍ
npm run serve
or
yarn serve
#打开浏览器地址栏输入localhost:8080即可
```
## Caution
IE éœ€è¦è‡ªå·±å¤„理一些ployfill
## Update
1.3.3
- ä¿®å¤æ—¶é—´è½´çš„æ—¥æœŸæ•°å­—在某些情况下撑开div,导致时间轴不准确的问题
1.3.2
- ä¿®æ­£æ»šåŠ¨çš„è§¦å‘å’Œæ»šåŠ¨èŒƒå›´é™åˆ¶çš„é—®é¢˜
1.3.1
- æ›¿æ¢moment ä¸ºdayjs
- ä¸ºstartTime,endTime,datas添加默认值
1.3.0
- ä¼˜åŒ–渲染速度
- ç›¸æ¯”之前的自定义渲染,添加一个新的slot,支持自定义的定位和渲染,更加的灵活
1.2.6
- ä¿®å¤å½“时间线宽度比渲染宽度小的情况下的部分白屏
- ä¿®å¤æ•°æ®åˆ·æ–°æ—¶ä¸é‡æ–°æ¸²æŸ“的问题
- ä¿®å¤æ»šåŠ¨æ¡é•¿åº¦è®¡ç®—é—®é¢˜å¯¼è‡´çš„æ—¶é—´çº¿éƒ¨åˆ†è¢«éšè—
- æ ·å¼å¾®è°ƒ
1.2.5
- ä¿®å¤cellheight,cellwidth å˜åŠ¨ä¸”ä¸æ»šåŠ¨æ—¶ï¼Œæ¸²æŸ“æ•°æ®èŒƒå›´ä¸æ­£å¸¸çš„é—®é¢˜
- ä¿®æ”¹æ ·å¼çš„变动处理
1.2.4
- ä¿®å¤æ»šåŠ¨æ—¶å‘ä¸Šæ»šåŠ¨æ—¶ä¼šç©ºç™½ä¸€è¡Œæ²¡æœ‰æ¸²æŸ“çš„é—®é¢˜
- ä¿®å¤å·¦ä¾§è¡ŒååŒºæ•°æ®è¿‡å°‘时,无法盖住其底下标记线的问题
1.2.3
- æ·»åŠ Resize Observer api  çš„polyfill
1.2.2
- é€šè¿‡Resize Observer api来监听div的变化,用以修复感知不到容器大小变化引起的渲染数量不正常的问题
1.2.1
- æ”¯æŒé€šè¿‡ç›‘听scrollLeft和scrollTop获取滚动值
- ä¿®å¤é¡µé¢ä¸­å­˜åœ¨2个甘特图滚动错误的问题
- ä¿®å¤æ²¡æœ‰start,end值可能引起的问题,当不存在start,end时偏移与宽度均为0值
1.2.0
- æ”¯æŒéšè—æ»šåŠ¨æ¡
- ä¿®å¤ä¸€æ¬¡æ»šåŠ¨è§¦å‘2次滚动事件的问题
- ä¿®å¤scrollToPosition æ— æ³•设置0值是问题
1.1.3
- æ·»åŠ é»˜è®¤slot
1.1.2
- æ”¯æŒéšè—è¡¨å¤´å’Œæ—¶é—´è½´åŠŸèƒ½
- æ”¯æŒè‡ªå®šä¹‰éœ€è¦æ¸²æŸ“的数组key
- ä¿®å¤æ¨ªçº¿æ»šåŠ¨è¶Šç•Œé—®é¢˜
#### License
_MIT_ Â©wuchouchou
src/lib/v-gantt-chart/index.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1 @@
module.exports = require('./lib')
src/lib/v-gantt-chart/lib/assets/block.png
src/lib/v-gantt-chart/lib/components/blocks/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,156 @@
<template>
  <div class="gantt-blocks"
       :style="{height:blockHeight+'px'}">
    <div class="gantt-block gantt-block-top-space"
         :style="{height:calTopSpace()+'px'}">
    </div>
    <div class="gantt-block"
         :style="blockStyle"
         v-for="(data,index) in showDatas"
         :key="dataKey?data[dataKey]:index">
      <template v-if="!customGenerateBlocks">
        <div class="gantt-block-item"
             v-for="(item,index) in concatArray(data)"
             v-if="isInRenderingTimeRange(item.start)||isInRenderingTimeRange(item.end)"
             :key="itemKey?item[itemKey]:index"
             :style="{left:getPosition(item)+'px',width:getWidth(item)+'px'}">
          <slot :data="data"
                :item="item">
            <div class="gantt-block-defaultBlock">need slot</div>
          </slot>
        </div>
      </template>
      <template v-else>
        <slot :data="data"
              :getPositonOffset="getPositonOffset"
              :getWidthAbout2Times="getWidthAbout2Times"
              :isInRenderingTimeRange="isInRenderingTimeRange">need slot</slot>
      </template>
    </div>
  </div>
</template>
<script>
import dr from "../dynamic-render.js";
import { isUndef, warn } from "../../utils/tool.js";
export default {
  name: "Blocks",
  mixins: [dr],
  props: {
    dataKey: String,
    itemKey: String,
    arrayKeys: {
      type: Array
    },
    scrollLeft: Number,
    cellWidth: {
      type: Number,
      required: true
    },
    scale: {
      type: Number,
      required: true
    },
    widthOfRenderAera: {
      type: Number,
      required: true
    },
    endTimeOfRenderArea: [Number, null],
    startTimeOfRenderArea: [Number, null],
    getPositonOffset: Function,
    getWidthAbout2Times: Function,
    customGenerateBlocks: Boolean
  },
  computed: {
    renderAarrys() {
      let { arrayKeys } = this;
      if (arrayKeys.length > 0) {
        return arrayKeys;
      }
      return ["gtArray"];
    },
    blockStyle() {
      return {
        backgroundSize: `${this.cellWidth}px ${this.cellHeight}px`,
        height: `${this.cellHeight}px`
      };
    }
  },
  methods: {
    /**
     * æ ¹æ®renderAarrys拼接需要渲染的数组
     *
     * @param {*} data
     * @returns {[]} è¯¥data中所有需要渲染的数据
     */
    concatArray(data) {
      return this.renderAarrys.reduce((prev, curr) => {
        if (Array.isArray(data[curr])) {
          return prev.concat(data[curr]);
        } else {
          return prev;
        }
      }, []);
    },
    /**
     * åˆ¤å®šæ•°æ®æ˜¯å¦åœ¨æ¸²æŸ“的时间范围内
     *
     * @param {{time:string}} item
     * @returns {boolean} è¯¥
     */
    isInRenderingTimeRange(time) {
      if (this.heightOfRenderAera === 0) {
        return false;
      }
      let { startTimeOfRenderArea, endTimeOfRenderArea } = this;
      if (isUndef(startTimeOfRenderArea) || isUndef(endTimeOfRenderArea)) {
        return false;
      }
      let timeToMs = new Date(time).getTime();
      if (startTimeOfRenderArea <= timeToMs && timeToMs <= endTimeOfRenderArea) {
        return true;
      }
      return false;
    },
    /**
     * è®¡ç®—时间块长度
     *
     * @param {{start:string,end:string}} block
     * @returns {number}
     */
    getWidth(block) {
      if (isUndef(block.start) || isUndef(block.end)) {
        // warn(`错误,该数据项不含start值 ä¸Ž end å€¼ ${JSON.stringify(block)},无法计算宽度值。`)
        return 0;
      }
      return this.getWidthAbout2Times(block.start, block.end);
    },
    /**
     * è®¡ç®—时间块偏移
     *
     * @param {{start:string}} block
     * @returns {number}
     */
    getPosition(block) {
      if (isUndef(block.start)) {
        warn(
          `错误,该数据项不含start å€¼ ${JSON.stringify(
            block
          )},无法计算偏移值。`
        );
        return 0;
      }
      return this.getPositonOffset(block.start);
    }
  }
};
</script>
src/lib/v-gantt-chart/lib/components/dynamic-render.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,126 @@
let dynamicRender = {
  props: {
    scrollTop: {
      type: Number,
      required: true
    },
    heightOfRenderAera: {
      type: Number,
      required: true
    },
    cellHeight: {
      type: Number,
      required: true
    },
    datas: {
      type: Array,
      required: true
    }
  },
  data() {
    return {
      showDatas: [],
      //上一次加载的节点
      oldCurrentIndex: 0,
      //预加载的数量,是前后都为2个
      preload: 1 // ä¸º 0 æ—¶åŠ è½½å…¨éƒ¨è¡Œ
    };
  },
  computed: {
    blockHeight() {
      let {
        datas,
        cellHeight
      } = this;
      return datas.length * cellHeight;
    },
    //计算当前第一个数据的index
    currentIndex() {
      return Math.ceil(this.scrollTop / this.cellHeight);
    }
  },
  watch: {
    currentIndex(val) {
      let {
        oldCurrentIndex,
        preload
      } = this;
      if (preload === 0) {
        this.spliceData();
        return
      }
      if (oldCurrentIndex === val) {
        return
      }
      // é¢„先多加载几个,避免过多的触发spliceData,
      let errorValue = 1 // ä¸ºè¯¯å·®å€¼ï¼Œ
      if (val < oldCurrentIndex - (preload - errorValue) || val >
        oldCurrentIndex + (preload - errorValue)) {
        this.oldCurrentIndex = val;
        this.spliceData();
      }
    },
    datas() {
      this.spliceData()
    },
    heightOfRenderAera() {
      this.spliceData()
    },
    cellHeight() {
      this.spliceData()
    }
  },
  created() {
    this.spliceData();
  },
  methods: {
    /**
     * åˆ†å‰²å‡ºdom中显示的数据
     */
    spliceData() {
      let {
        heightOfRenderAera,
        currentIndex,
        cellHeight,
        preload
      } = this;
      //没有高度,不需要渲染元素
      if (heightOfRenderAera === 0 || cellHeight === 0) {
        return []
      }
      if (preload === 0) {
        this.showDatas = this.datas
        return
      }
      let end = currentIndex + Math.ceil(heightOfRenderAera / cellHeight) +
        preload;
      let start = currentIndex - preload > 0 ? currentIndex - preload : 0;
      this.showDatas = this.datas.slice(start, end);
    },
    //
    /**
     * è®¡ç®—第一个撑开前置高度的容器块高度
     */
    calTopSpace() {
      let {
        oldCurrentIndex,
        cellHeight,
        preload
      } = this;
      let start =
        oldCurrentIndex - preload >= 0 ? oldCurrentIndex - preload : 0;
        return  start == 0 ? start * cellHeight : start - 1  * cellHeight
    },
  }
};
export default dynamicRender;
src/lib/v-gantt-chart/lib/components/left-bar/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,37 @@
<template>
  <div class="gantt-leftbar">
    <div class="gantt-leftbar-item "
         :style="{height:calTopSpace()+'px'}">
    </div>
    <div class="gantt-leftbar-item"
         :style="cellHeightStyle"
         v-for="(data,index) in showDatas"
         :key="dataKey?data[dataKey]:index">
      <slot :data="data">
        <div class="gantt-leftbar-defalutItem">need slot</div>
      </slot>
    </div>
  </div>
</template>
<script>
import dr from '../dynamic-render.js'
export default {
  name: "LeftBar",
  mixins:[dr],
  props:{
    dataKey:String,
    datas: {
      type: Array,
      required: true
    }
  },
  computed:{
    cellHeightStyle(){
      return {
        'height':`${this.cellHeight}px`
      }
    }
  }
};
</script>
src/lib/v-gantt-chart/lib/components/mark-line/current-time.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,33 @@
<template>
  <mark-line :markLineTime="currentTime"
             :getPositonOffset="getPositonOffset"
             color="rgba(255,0,0,.4)"></mark-line>
</template>
<script>
import dayjs from "dayjs";
import MarkLine from "./index.vue";
export default {
  name: "CurrentTime",
  components: { MarkLine },
  props: {
    getPositonOffset: {
      type: Function,
      required: true
    }
  },
  data() {
    return {
      currentTime: dayjs().toString()
    };
  },
  created() {
    const timeNow = setInterval(() => {
      this.currentTime = dayjs().toString();
    }, 1000);
    this.$once("hook:beforeDestroy", () => {
      clearInterval(timeNow);
    });
  }
};
</script>
src/lib/v-gantt-chart/lib/components/mark-line/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,47 @@
<template>
  <div v-show="visible"
       class="gantt-markline"
       :style="{'background-color':color,'left':getPosition()+'px'}">
    <div class="gantt-markline-label"
         :style="{'background-color':color}">{{dayjs(markLineTime).format("HH:mm:ss")}}</div>
  </div>
</template>
<script>
import dayjs from "dayjs";
export default {
  name: "MarkLine",
  props: {
    markLineTime: {
      validator(date) {
        return dayjs(date).isValid();
      }
    },
    color: {
      type: String,
      default: "#00a79d"
    },
    getPositonOffset: {
      type: Function,
      required: true
    }
  },
  data() {
    return {
      visible: false,
      dayjs:dayjs
    };
  },
  methods: {
    getPosition() {
      if (this.markLineTime == null) {
        this.visible = false;
        return 0;
      } else {
        this.visible = true;
        return this.getPositonOffset(this.markLineTime);
      }
    }
  }
};
</script>
src/lib/v-gantt-chart/lib/components/time-line/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,162 @@
<template>
  <div class="gantt-timeline"
       :style="{'margin-left':-cellWidth/2+'px'}">
    <div class="gantt-timeline-block"
         v-for="(day,index) in getDays" :style="{width:getTimeScales(day).length*cellWidth+'px'}"
         :key="index">
      <div class="gantt-timeline-day "
           :style="heightStyle">
        {{day.format("YYYY-MM-DD")}}
        {{getDayMy(day.format("YYYY-MM-DD"))}}
        </div>
      <div class="gantt-timeline-scale "
           :style="heightStyle">
        <div :style="cellWidthStyle"
             v-for="(hour,index) in getTimeScales(day)"
             :key="index">
            {{hour}}
          <!-- <span v-if="hour !='01' ">{{hour}}</span> -->
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import dayjs from "dayjs";
import { getBeginTimeOfTimeLine } from "../../utils/timeLineUtils.js";
const START_DAY = Symbol();
const MIDDLE_DAY = Symbol();
const END_DAY = Symbol();
function isSameDay(one, two) {
  return one.isSame(two, "day");
}
export default {
  name: "Timeline",
  props: {
    start: {
      type: dayjs
    },
    end: {
      type: dayjs
    },
    cellWidth: {
      type: Number
    },
    titleHeight: {
      type: Number
    },
    scale: {
      type: Number
    }
  },
  computed: {
    /**
     * å¤©åˆ—表
     * @returns {[dayjs]} è¯¥data中所有需要渲染的数据
     */
    getDays() {
      let temp = [];
      let { start, end } = this;
      for (; !isSameDay(start, end); start = start.add(1, "day")) {
        temp.push(start);
      }
      temp.push(start);
      return temp;
    },
    cellWidthStyle() {
      return {
        width: `${this.cellWidth}px`
      };
    },
    heightStyle() {
      return {
        height: this.titleHeight + "px",
        "line-height": this.titleHeight  + "px",
      };
    }
  },
  methods: {
    // ç®—出星期
    getDayMy(day){
      let weekArray = new Array("星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六");
      return weekArray[new Date(day).getDay()]
    },
    /**
     * èŽ·å–æ—¶é—´åˆ»åº¦æ•°ç»„
     *
     * @param {dayjs} date
     * @returns {[string]} è¯¥data中所有需要渲染的数据
     */
    getTimeScales(date) {
      let { start, end } = this;
      if (isSameDay(date, start)) {
        return this.generateTimeScale(START_DAY);
      } else if (isSameDay(date, end)) {
        return this.generateTimeScale(END_DAY);
      } else {
        return this.generateTimeScale(MIDDLE_DAY);
      }
    },
    /**
     * ç”Ÿæˆæ—¶é—´åˆ»åº¦æ•°ç»„
     *
     * @param {Symbol} type
     * @returns {[string]} è¯¥data中所有需要渲染的数据
     */
    generateTimeScale(type) {
      let totalblock = [];
      let { start, end, scale } = this;
      let a, b;
      switch (type) {
        case START_DAY: //和start同一天
          a = getBeginTimeOfTimeLine(start, scale);
          //start和end同一天特殊处理
          if (isSameDay(start, end)) {
            b = end;
          } else {
            b = start.endOf("day");
          }
          break;
        case END_DAY: //和end åŒä¸€å¤©
          a = end.startOf("day");
          b = end;
          break;
        case MIDDLE_DAY: //start和end中间的天
          a = start.startOf("day");
          b = start.endOf("day");
          break;
        default:
          throw new TypeError("错误的计算类型");
      }
      while (!a.isAfter(b)) {
        if (scale >= 60) {
          totalblock.push(a.format("HH"));
        } else {
          totalblock.push(a.format("HH:mm"));
        }
        a = a.add(scale, "minute");
      }
      return totalblock;
    }
  },
};
</script>
<style lang="scss" scoped>
.gantt-timeline-day{
  border-right: 1px solid #ebeef5;
  border-bottom: 1px solid #ebeef5;
  background: rgb(245, 245, 245);
  color: #909399;
  font-size: 14px;
}
</style>
src/lib/v-gantt-chart/lib/gantt.scss
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,176 @@
$gray: #f0f0f0;
$font-gray:#777;
.gantt {
  &-chart {
    position: relative;
    overflow: hidden;
    height: 100%;
    width: 100%;
    outline: 1px solid $gray;
  }
  &-container{
    width: 100%;
    height: 100%;
  }
  &-header {
    display: flex;
    background-color: #fff;
    outline: 1px solid $gray;
    &-title {
      flex: none;
      width: 100%;
      background: whitesmoke;
      color: #777;
      font-weight: bold;
      text-align: center;
    }
    &-timeline {
      overflow: hidden;
    }
  }
  &-body {
    position: relative;
  }
  &-timeline {
    position: relative;
    text-align: center;
    display: flex;
    &-day {
      overflow: hidden;
      font-weight: bold;
      color: $font-gray;
    }
    &-scale {
      display: flex;
      &>div {
        height: 100%;
        font-size: 0.8rem;
        font-weight: bold;
        color: $font-gray;
      }
    }
    // éšè—ç¬¬ä¸€ä¸ªæ—¶é—´èŠ‚ç‚¹ï¼Œä¸ç„¶ä¼šåªæ˜¾ç¤ºä¸€åŠï¼Œä¸å¥½çœ‹
    &-block:first-child &-scale div:first-child {
      visibility: hidden;
    }
  }
  &-leftbar {
    width: 100%;
    height: 100%;
    background: #fff;
    color: $font-gray;
    font-size: 0.8rem;
    &-wrapper {
      flex: none;
      position: relative;
      overflow: hidden;
      background: #fff;
      outline: 1px solid $gray;
      z-index: 100;
    }
    &-item {}
    &-defalutItem {
      width: 100%;
      height: 100%;
      outline: 1px solid $gray
    }
  }
  &-table {
    display: flex;
    width: 100%;
    height: 100%;
  }
  &-markline-area {
    position: absolute;
    z-index: 99;
  }
  &-markline {
    position: absolute;
    z-index: 100;
    width: 2px;
    height: 100vh;
    &-label {
      padding: 3px;
      float: left;
      color: #fff;
      font-size: 0.7rem;
    }
  }
  &-blocks {
    &-wrapper {
      overflow: hidden;
    }
  }
  &-block {
    position: relative;
    // background-image: url('./assets/block.png');
    background-repeat: repeat;
    &-container {
      position: relative;
      height: 100%;
    }
    &-item {
      position: absolute;
      height: 100%;
    }
    &-defaultBlock {
      width: 100%;
      height: 100%;
      outline: 1px solid $gray;
      background: $gray;
    }
  }
  &-scroll-y {
    overflow-y: scroll;
    position: absolute;
    z-index: 1000;
    top: 0;
    right: 0;
    height: 100%;
    width: 17px;
    &>div {
      width: 17px;
    }
  }
  &-scroll-x {
    overflow-x: scroll;
    position: absolute;
    z-index: 1000;
    left: 0;
    bottom: 0;
    width: 100%;
    height: 17px;
    &>div {
      height: 17px;
    }
  }
}
src/lib/v-gantt-chart/lib/gantt.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,550 @@
<template>
  <div class="gantt-chart"
       @wheel="wheelHandle">
    <div class="gantt-container"
         :style="{height:`calc(100% - ${scrollXBarHeight}px)`,width:`calc(100% - ${scrollYBarWidth}px)`}">
    <!-- <div class="gantt-container"> -->
      <div v-show="!hideHeader"
           class="gantt-header"
           :style="{width:`calc(100% + ${scrollYBarWidth}px)`}">
        <div class="gantt-header-title"
             :style="{'line-height':titleHeight+'px',height:titleHeight+'px','width':titleWidth+'px'}">
          <slot name="title">welcome v-gantt-chart</slot>
        </div>
        <div ref="headerTimeline"
             class="gantt-header-timeline">
          <div class="gantt-timeline-wrapper"
               :style="{width:(totalWidth+scrollYBarWidth)+'px'}">
            <timeline :start="start"
                      :end="end"
                      :cellWidth="cellWidth"
                      :titleHeight="titleHeight"
                      :scale="scale">
            </timeline>
          </div>
        </div>
      </div>
      <div class="gantt-body"
           :style="{height:`calc(100% - ${actualHeaderHeight}px)`}">
          <!-- <div class="gantt-body" style="height:500px"> -->
        <div class="gantt-table">
          <div ref="marklineArea"
               :style="{marginLeft:(titleWidth+50)+'px'}"
               class="gantt-markline-area">
            <!-- <CurrentTime v-if="showCurrentTime"
                         :getPositonOffset="getPositonOffset" /> -->
            <!-- <mark-line v-for="(times,index) in timeLines"
                       :key="index"
                       :markLineTime="times.time"
                       :getPositonOffset="getPositonOffset"
                       :color="times.color"></mark-line> -->
          </div>
          <div ref="leftbarWrapper"
               class="gantt-leftbar-wrapper"
               :style="{'width':(titleWidth)+'px',height:`calc(100% + ${scrollXBarHeight}px)`}">
            <LeftBar :datas="datas"
                     :dataKey="dataKey"
                     :scrollTop="scrollTop"
                     :heightOfRenderAera="heightOfRenderAera"
                     :widthOfRenderAera="widthOfRenderAera"
                     :cellHeight="cellHeight"
                     :style="{height:(totalHeight+scrollXBarHeight)+'px'}">
              <template slot-scope="{data}">
                <slot name="left"
                      :data="data">
                </slot>
              </template>
            </LeftBar>
          </div>
          <div ref="blocksWrapper"
               class="gantt-blocks-wrapper">
            <blocks :scrollTop="scrollTop"
                    :scrollLeft="scrollLeft"
                    :heightOfRenderAera="heightOfRenderAera"
                    :widthOfRenderAera="widthOfRenderAera"
                    :arrayKeys="arrayKeys"
                    :itemKey="itemKey"
                    :dataKey="dataKey"
                    :datas="datas"
                    :cellWidth="cellWidth"
                    :cellHeight="cellHeight"
                    :scale="scale"
                    :getPositonOffset="getPositonOffset"
                    :getWidthAbout2Times="getWidthAbout2Times"
                    :customGenerateBlocks="customGenerateBlocks"
                    :startTimeOfRenderArea="startTimeOfRenderArea"
                    :endTimeOfRenderArea="endTimeOfRenderArea"
                    :style="{width:totalWidth+'px'}">
              <!-- <template slot-scope="{data,item}">
                <slot name="block"
                      :data="data"
                      :item="item">
                </slot>
              </template> -->
              <template
                  slot-scope="{data,item,getPositonOffset,getWidthAbout2Times,isInRenderingTimeRange}">
                <slot name="block"
                      :data="data"
                      :item="item"
                      :getPositonOffset="getPositonOffset"
                      :getWidthAbout2Times="getWidthAbout2Times"
                      :isInRenderingTimeRange="isInRenderingTimeRange"
                      :startTimeOfRenderArea="startTimeOfRenderArea"
                      :endTimeOfRenderArea="endTimeOfRenderArea"></slot>
              </template>
            </blocks>
          </div>
        </div>
      </div>
    </div>
    <div ref="scrollYBar"
         class="gantt-scroll-y"
         :style="{width:`${scrollYBarWidth}px`,
         height:`calc(100% - ${actualHeaderHeight}px`,marginTop:`${actualHeaderHeight}px`}"
         @scroll="syncScrollY">
      <div :style="{height:totalHeight+'px'}"></div>
    </div>
    <div ref="scrollXBar"
         class="gantt-scroll-x"
         :style="{height:`${scrollXBarHeight}px`,
         width:`calc(100% - ${titleWidth}px )`,marginLeft:titleWidth+'px'}"
         @scroll="syncScrollX">
      <div :style="{width:totalWidth+'px'}"></div>
    </div>
  </div>
</template>
<script>
import dayjs from "dayjs";
import ResizeObserver from "resize-observer-polyfill";
import {
  scaleList,
  getBeginTimeOfTimeLine,
  calcScalesAbout2Times
} from "./utils/timeLineUtils.js";
import { isDef, warn } from "./utils/tool.js";
import {
  getPositonOffset as _getPositonOffset,
  getWidthAbout2Times as _getWidthAbout2Times
} from "./utils/gtUtils.js";
import throttle from "./utils/throttle.js";
import Timeline from "./components/time-line/index.vue";
import CurrentTime from "./components/mark-line/current-time.vue";
import LeftBar from "./components/left-bar/index.vue";
import Blocks from "./components/blocks/index.vue";
import MarkLine from "./components/mark-line/index.vue";
export default {
  name: "Gantt",
  components: { Timeline, LeftBar, Blocks, MarkLine, CurrentTime },
  props: {
    startTime: {
      default: () => dayjs(),
      validator(date) {
        let ok = dayjs(date).isValid();
        if (!ok) warn(`非法的开始时间 ${date}`);
        return ok;
      }
    },
    endTime: {
      default: () => dayjs(),
      validator(date) {
        let ok = dayjs(date).isValid();
        if (!ok) warn(`非法的结束时间 ${date}`);
        return ok;
      }
    },
    cellWidth: {
      type: Number,
      default: 50
    },
    cellHeight: {
      type: Number,
      default: 20
    },
    titleHeight: {
      type: Number,
      default: 40
    },
    titleWidth: {
      type: Number,
      default: 200
    },
    scale: {
      type: Number,
      default: 60,
      validator(value) {
        return scaleList.includes(value);
      }
    },
    datas: {
      type: Array,
      default: () => []
    },
    dataKey: {
      type: String,
      default: undefined
    },
    itemKey: {
      type: String,
      default: undefined
    },
    arrayKeys: {
      type: Array,
      default: () => []
    },
    showCurrentTime: {
      type: Boolean,
      default: false
    },
    timeLines: {
      type: Array
    },
    scrollToTime: {
      validator(date) {
        return dayjs(date).isValid();
      }
    },
    scrollToPostion: {
      validator(obj) {
        let validX = isDef(obj.x) ? !Number.isNaN(obj.x) : true;
        let validY = isDef(obj.y) ? !Number.isNaN(obj.y) : true;
        if (!validX && !validY) {
          warn("scrollToPostion x或y æœ‰å€¼ä¸ºéžNumber类型");
          return false;
        }
        return true;
      }
    },
    hideHeader: {
      type: Boolean,
      default: false
    },
    hideXScrollBar: {
      type: Boolean,
      default: false
    },
    hideYScrollBar: {
      type: Boolean,
      default: false
    },
    customGenerateBlocks: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      //缓存节点
      selector: {
        gantt_leftbar: {},
        gantt_table: {},
        gantt_scroll_y: {},
        gantt_timeline: {},
        gantt_scroll_x: {},
        gantt_markArea: {}
      },
      scrollTop: 0,
      scrollLeft: 0,
      //block åŒºåŸŸéœ€è¦æ¸²æŸ“的范围
      //先渲染出空框架,在mounted后再得到真实的渲染范围,然后在根据范围渲染数据,比之前设置一个默认高度宽度,额外的渲染浪费更少了
      heightOfRenderAera: 0,
      widthOfRenderAera: 0,
      startTimeOfRenderArea: null,
      endTimeOfRenderArea: null,
      scrollBarWitdh: 17
    };
  },
  computed: {
    start() {
      return dayjs(this.startTime);
    },
    end() {
      let { start, widthOfRenderAera, scale, cellWidth } = this;
      let end = dayjs(this.endTime);
      let totalWidth = calcScalesAbout2Times(start, end, scale) * cellWidth;
      if (start.isAfter(end) || totalWidth <= widthOfRenderAera) {
        end = start.add((widthOfRenderAera / cellWidth) * scale, "minute");
      }
      return end;
    },
    totalWidth() {
      let { cellWidth, totalScales } = this;
      return cellWidth * totalScales;
    },
    totalScales() {
      let { start, end, scale } = this;
      return calcScalesAbout2Times(start, end, scale);
    },
    totalHeight() {
      let { datas, cellHeight } = this;
      return datas.length * cellHeight;
    },
    beginTimeOfTimeLine() {
      let value = getBeginTimeOfTimeLine(this.start, this.scale);
      return value;
    },
    beginTimeOfTimeLineToString() {
      return this.beginTimeOfTimeLine.toString();
    },
    avialableScrollLeft() {
      // ä¸å‡è¿™ä¸ª1,滚动到时间轴尽头后继续滚动会慢慢的溢出
      let { totalWidth, widthOfRenderAera } = this;
      return totalWidth - widthOfRenderAera - 1;
    },
    avialableScrollTop() {
      let { totalHeight, heightOfRenderAera } = this;
      return totalHeight - heightOfRenderAera - 1;
    },
    scrollXBarHeight() {
      return this.hideXScrollBar ? 0 : this.scrollBarWitdh;
    },
    scrollYBarWidth() {
      return this.hideYScrollBar ? 0 : this.scrollBarWitdh;
    },
    actualHeaderHeight() {
      return this.hideHeader ? 0 : this.titleHeight;
    }
  },
  watch: {
    scrollLeft() {
      this.getTimeRange();
    },
    widthOfRenderAera() {
      this.getTimeRange();
    },
    cellWidth() {
      this.getTimeRange();
    },
    scrollToTime: {
      handler(newV) {
        if (!newV) {
          return;
        }
        let { start, end } = this;
        let time = dayjs(newV);
        if (!(time.isAfter(start) && time.isBefore(end))) {
          warn(`当前滚动至${newV}不在${start}和${end}的范围之内`);
          return;
        }
        let offset = this.getPositonOffset(newV);
        // immediate ä¼šé€ æˆdom è¿˜æ²¡æœ‰æŒ‚载时就进行操作,故需要延迟执行
        this.$nextTick(() =>
          this.syncScrollX(
            {
              target: {
                scrollLeft: offset
              }
            },
            true
          )
        );
      },
      immediate: true
    },
    scrollToPostion: {
      handler(newV) {
        if (!newV) {
          return;
        }
        let x = Number.isNaN(newV.x) ? undefined : newV.x;
        let y = Number.isNaN(newV.y) ? undefined : newV.y;
        this.$nextTick(() => {
          if (isDef(x) && x !== this.scrollLeft) {
            this.syncScrollX({ target: { scrollLeft: x } }, true);
          }
          if (isDef(y) && y !== this.scrollTop) {
            this.syncScrollY({ target: { scrollTop: y } }, true);
          }
        });
      },
      immediate: true
    }
  },
  mounted() {
    this.getSelector();
    // è®¡ç®—准确的渲染区域范围
    const observeContainer = throttle(entries => {
      entries.forEach(entry => {
        const cr = entry.contentRect;
        this.heightOfRenderAera = cr.height;
        this.widthOfRenderAera = cr.width;
      });
    });
    const observer = new ResizeObserver(observeContainer);
    observer.observe(this.$refs.blocksWrapper);
  },
  methods: {
    /**
     * è®¡ç®—需要渲染的时间范围
     *
     */
    getTimeRange() {
      if (this.heightOfRenderAera === 0) {
        return;
      }
      let {
        beginTimeOfTimeLine,
        scrollLeft,
        cellWidth,
        scale,
        widthOfRenderAera
      } = this;
      this.startTimeOfRenderArea = beginTimeOfTimeLine
        .add((scrollLeft / cellWidth) * scale, "minute")
        .toDate()
        .getTime();
      this.endTimeOfRenderArea = beginTimeOfTimeLine
        .add(((scrollLeft + widthOfRenderAera) / cellWidth) * scale, "minute")
        .toDate()
        .getTime();
    },
    getWidthAbout2Times(start, end) {
      let options = {
        scale: this.scale,
        cellWidth: this.cellWidth
      };
      return _getWidthAbout2Times(start, end, options);
    },
    /**
     * ä¸ºæ—¶é—´çº¿è®¡ç®—偏移
     */
    getPositonOffset(date) {
      let options = {
        scale: this.scale,
        cellWidth: this.cellWidth
      };
      return _getPositonOffset(date, this.beginTimeOfTimeLineToString, options);
    },
    //缓存节点
    getSelector() {
      this.selector.gantt_leftbar = this.$refs.leftbarWrapper;
      this.selector.gantt_table = this.$refs.blocksWrapper;
      this.selector.gantt_scroll_y = this.$refs.scrollYBar;
      this.selector.gantt_timeline = this.$refs.headerTimeline;
      this.selector.gantt_scroll_x = this.$refs.scrollXBar;
      this.selector.gantt_markArea = this.$refs.marklineArea;
    },
    wheelHandle(event) {
      let { deltaX, deltaY } = event;
      this.$nextTick(() => {
        let {
          scrollTop,
          scrollLeft,
          avialableScrollLeft,
          avialableScrollTop
        } = this;
        if (deltaY !== 0) {
          if (
            scrollTop + deltaY >= avialableScrollTop &&
            scrollTop !== avialableScrollTop
          ) {
            this.syncScrollY(
              { target: { scrollTop: avialableScrollTop } },
              true
            );
          } else if (
            scrollTop + deltaY < 0 &&
            scrollTop !== 0 /*滚动为0限制*/
          ) {
            this.syncScrollY({ target: { scrollTop: 0 } }, true);
          } else {
            this.syncScrollY(
              { target: { scrollTop: scrollTop + deltaY } },
              true
            );
          }
        }
        if (deltaX !== 0) {
          if (
            scrollLeft + deltaX >= avialableScrollLeft &&
            scrollLeft !== avialableScrollLeft
          ) {
            this.syncScrollX(
              { target: { scrollLeft: avialableScrollLeft } },
              true
            );
          } else if (
            scrollLeft + deltaX < 0 &&
            scrollLeft !== 0 /*滚动为0限制*/
          ) {
            this.syncScrollX({ target: { scrollLeft: 0 } }, true);
          } else {
            this.syncScrollX(
              { target: { scrollLeft: scrollLeft + deltaX } },
              true
            );
          }
        }
      });
    },
    //同步fixleft和block的滚动
    syncScrollY(event, fake = false) {
      let { gantt_leftbar, gantt_table, gantt_scroll_y } = this.selector;
      let topValue = event.target.scrollTop;
      if (fake) {
        //会触发一次真的滚动事件event, åŽé¢çš„代码会在第二个事件中执行
        gantt_scroll_y.scrollTop = topValue;
        return;
      }
      gantt_leftbar.scrollTop = topValue;
      gantt_table.scrollTop = topValue;
      this.scrollTop = topValue;
      this.$emit("scrollTop", topValue);
    },
    syncScrollX(event, fake = false) {
      let {
        gantt_table,
        gantt_timeline,
        gantt_markArea,
        gantt_scroll_x
      } = this.selector;
      let leftValue = event.target.scrollLeft;
      if (fake) {
        //会触发一次真的滚动事件event, åŽé¢çš„代码会在第二个事件中执行
        gantt_scroll_x.scrollLeft = leftValue;
        return;
      }
      gantt_table.scrollLeft = leftValue;
      gantt_timeline.scrollLeft = leftValue;
      gantt_markArea.style.left = "-" + leftValue + "px";
      this.scrollLeft = leftValue;
      this.$emit("scrollLeft", leftValue);
    }
  }
};
</script>
<style lang="scss">
@import "./gantt.scss";
.gantt-leftbar-wrapper{
  // overflow-y: scroll;
  // overflow: visible;
}
.gantt-body{
  // overflow-y: scroll;
}
.gantt-leftbar{
  // overflow-y: scroll;
}
</style>
src/lib/v-gantt-chart/lib/index.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
// gantt.vue写我们的组件
import gantt from './gantt.vue'
// å®šä¹‰æˆ‘们的插件
const myPlugin = {
  // è¯¥æ’件有一个install方法
  // æ–¹æ³•的第一个参数是传入的Vue,第二个参数可以插件的自定义参数
  // eslint-disable-next-line
    install (Vue, options) {
    // å°†å…¶æ³¨å†Œä¸ºvue的组件,'gantt'是组件名,keyboard是我们开发的组件
    Vue.component('v-gantt-chart', gantt)
  }
}
// æ–°å¢ž
if (typeof window !== 'undefined' && window.Vue) {
  window.Vue.use(gantt)
}
// æœ€åŽå°†æ’件导出,并在main.js中通过Vue.use()即可使用插件
export default myPlugin
src/lib/v-gantt-chart/lib/utils/debounce.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
export default function debounce(fn, interval = 500, immediate = false) {
  //fn为要执行的函数
  //interval为等待的时间
  //immediate判断是否立即执行
  var timeout; //定时器
  return function() { //返回一个闭包
    var context = this,
      args = arguments; //先把变量缓存
    var later = function() { //把稍后要执行的代码封装起来
      timeout = null; //成功调用后清除定时器
      if (!immediate) fn.apply(context, args); //不立即执行时才可以调用
    };
    var callNow = immediate && !timeout; //判断是否立即调用,并且如果定时器存在,则不立即调用
    clearTimeout(timeout); //不管什么情况,先清除定时器,这是最稳妥的
    timeout = setTimeout(later, interval); //延迟执行
    if (callNow) fn.apply(context, args); //如果是第一次触发,并且immediate为true,则立即执行
  }
}
src/lib/v-gantt-chart/lib/utils/gtUtils.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,85 @@
// import dayjs from 'dayjs' //替换dayjs å…¼å®¹æ€§ä¼šå¥½ä¸€ç‚¹ï¼Œä½†æ˜¯é€Ÿåº¦å°±å¾ˆæ…¢äº†ï¼Œä¹‹å‰æµ‹äº†ä¸€ä¸‹ï¼Œå¤§æ¦‚å¿«30倍?有点忘记了
//缓存 è§£æžå€¼ï¼ŒåŠ é€Ÿä¸€ç‚¹ç‚¹å§
const cacheParseTime = function () {
  let cacheString = {}
  let cacheValue = {}
  return function(timeName, timeString) {
    if (cacheString[timeName] !== timeString) {
      cacheString[timeName] = timeString;
      cacheValue[timeName] = parseTime(timeString)
    }
    return cacheValue[timeName]
  }
}()
// pStart å…³äºŽç¼“存这个值是因为getWidthAbout2Times和getPositonOffset通常是前后连续调用,start å€¼ä¼šå†ä¸¤ä¸ªå‡½æ•°ä¸­åˆ†åˆ«ç”¨åˆ°ä¸€æ¬¡
/**
 * æ ¹æ®é…ç½®é¡¹è®¡ç®—两个时间的在gantt å›¾ä¸­çš„长度
 * æ³¨ï¼šæ—¶é—´ä¸Šstart æ—©ï¼Œ end æ™š
 *
 * @export
 * @param {string} start
 * @param {string} end
 * @param {{scale:number,cellWidth:number}} arg
 * @returns number
 */
export function getWidthAbout2Times(start, end, arg) {
  let {
    scale,
    cellWidth
  } = arg;
  let pStart = cacheParseTime('pStart', start);
  let pEnd = parseTime(end)
  return diffTimeByMinutes(pStart, pEnd) / scale * cellWidth;
}
/**
 * æ ¹æ®é…ç½®é¡¹è®¡ç®— ç›¸å¯¹äºŽ æ—¶é—´è½´èµ·å§‹æ—¶é—´çš„距离 æ˜¯ getWidthAbout2Times çš„特化
 * æ³¨ï¼šæ—¶é—´ä¸Šï¼Œtime æ™š  beginTimeOfTimeLine æ—©
 *
 * @export
 * @param {string} time
 * @param {string} beginTimeOfTimeLine
 * @param {{scale:number,cellWidth:number}} arg
 * @returns number
 */
export function getPositonOffset(time, beginTimeOfTimeLine, arg) {
  let {
    scale,
    cellWidth,
  } = arg;
  let pTime = cacheParseTime('pStart', time);
  let pBeginTimeOfTimeLine = cacheParseTime('pBeginTimeOfTimeLine', beginTimeOfTimeLine);
  return diffTimeByMinutes(pBeginTimeOfTimeLine, pTime) / scale * cellWidth;
}
function parseTime(time) {
  return new Date(time)
}
/**
 * è®¡ç®—两个时间相差的分钟数
 *
 * @param {string} start
 * @param {string} end
 * @returns
 */
function diffTimeByMinutes(start, end) {
  let diff = end.getTime() - start.getTime()
  return (diff / 1000 / 60)
}
// function parseTime(time){
//   return dayjs(time)
// }
// function diffTimeByMinutes(start,end){
//   return end.diff(start, "m", true)
// }
src/lib/v-gantt-chart/lib/utils/throttle.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,21 @@
export default function throttle(fn, interval = 100) { //fn为要执行的函数,interval为延迟时间
  var _self = fn, //保存需要被延迟执行的函数引用
    timer, //定时器
    firstTime = true; //是否第一次调用
  return function() { //返回一个函数,形成闭包,持久化变量
    var args = arguments, //缓存变量
      _me = this;
    if (firstTime) { //如果是第一次调用,不用延迟执行
      _self.apply(_me, args);
      return firstTime = false;
    }
    if (timer) { //如果定时器还在,说明上一次延迟执行还没有完成
      return false;
    }
    timer = setTimeout(function() { //延迟一段时间执行
      clearTimeout(timer);
      timer = null;
      _self.apply(_me, args);
    }, interval);
  }
}
src/lib/v-gantt-chart/lib/utils/timeLineUtils.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,74 @@
import dayjs from 'dayjs'
export const scaleList = [1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30, 60, 120, 180,
  240,
  360, 720, 1440
]
/**
 * éªŒè¯æ˜¯å¦åˆæ³•scale值
 *
 * @export
 * @param {number} scale
 * @returns
 */
export function validateScale(scale) {
  if (!scaleList.includes(scale)) {
    throw new RangeError(
      `错误的scale值,输入值为${scale},可用的scale值为${scaleList.join(',')}`)
  }
  return true;
}
/**
 * æ ¹æ®ç»™å‡ºçš„scale å’Œ start æ—¶é—´ è®¡ç®—出用于计算和生成图表的启始时间
 * eg:Start ä¸º10:10分 åˆ»åº¦ä¸º60,getBeginTimeOfTimeLine函数给出的时间 ä¸º 10:00分
 *                    åˆ»åº¦ä¸º5,getBeginTimeOfTimeLine函数给出的时间 ä¸º 10:10分
 *                    åˆ»åº¦ä¸º3,getBeginTimeOfTimeLine函数给出的时间 ä¸º 10:09分
 *
 * @export
 * @param {dayjs} start
 * @param {number} [scale=60]
 * @returns {dayjs}计算的启始时间
 */
export function getBeginTimeOfTimeLine(start, scale = 60) {
  validateScale(scale)
  let timeBlocks;
  let startClone = start.clone();
  let rate = scale / 60;
  if (scale > 60) {
    timeBlocks = Math.floor(start.hour() / rate);
    startClone = startClone.hour(timeBlocks * rate).minute(0).second(0);
  } else {
    timeBlocks = Math.floor(start.minute() / scale);
    startClone = startClone.minute(timeBlocks * scale).second(0);
  }
  return startClone;
}
/**
 * æ ¹æ®æ‰€ç»™ scale计算 ä¸¤ä¸ªæ—¶é—´å·®ä¸€å…±å¯ä»¥åˆ†æˆå¤šå°‘个刻度
 * æ³¨æ„ï¼š timdStart å¹¶ä¸æ˜¯å®žé™…的开始计算的时间,会通过getBeginTimeOfTimeLine å‡½æ•°è®¡ç®—出分割开始时间
 *
 * @export
 * @param {dayjs} timeStart å¼€å§‹æ—¶é—´
 * @param {dayjs} timeEnd ç»“束时间
 * @param {number} [scale=60] åˆ†å‰²çš„刻度
 * @returns æ—¶é—´å—数量
 */
export function calcScalesAbout2Times(timeStart, timeEnd, scale = 60) {
  if (timeStart.isAfter(timeEnd)) {
    throw new TypeError('错误的参数顺序,函数calcScalesAbout2Times的第一个时间参数必须大于第二个时间参数')
  }
  validateScale(scale);
  let startBlocksTime = getBeginTimeOfTimeLine(timeStart, scale);
  let count = 0;
  while (!startBlocksTime.isAfter(timeEnd)) {
    count++;
    startBlocksTime = startBlocksTime.add(scale, "minute")
  }
  return count;
}
src/lib/v-gantt-chart/lib/utils/tool.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,25 @@
/**
 * æ˜¯å¦æ²¡æœ‰å€¼
 *
 * @export
 * @param {*} v
 * @returns
 */
export function isUndef(v){
  return v === undefined || v === null
}
/**
 * æ˜¯å¦æœ‰å€¼
 *
 * @export
 * @param {*} v
 * @returns
 */
export function isDef(v){
  return v !== undefined && v !== null
}
export function warn(str){
  // eslint-disable-next-line
  console.warn(str)
}
src/lib/v-gantt-chart/package.json
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,52 @@
{
  "name": "v-gantt-chart",
  "version": "1.3.3",
  "description": "display gantt-like vaule,like use this to order bus schedule.",
  "main": "dist/v-gantt-chart.js",
  "repository": {
    "type": "git",
    "url": "git+https://github.com/w1301625107/Vue-Gantt-chart.git"
  },
  "bugs": {
    "url": "https://github.com/w1301625107/Vue-Gantt-chart/issues"
  },
  "homepage": "https://github.com/w1301625107/Vue-Gantt-chart#readme",
  "keywords": [
    "vue-gantt-chart",
    "gantt",
    "gantt-chart",
    "v-gantt-chart"
  ],
  "author": "wuchouchou",
  "license": "MIT",
  "scripts": {
    "test":" BABEL_ENV=test mocha --require babel-core/register ",
    "build": "cross-env NODE_ENV=production webpack --progress --hide-modules"
  },
  "dependencies": {
    "dayjs": "^1.8.11",
    "resize-observer-polyfill": "^1.5.1",
    "vue": "^2.5.21"
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not ie <= 8"
  ],
  "devDependencies": {
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.2",
    "babel-preset-env": "^1.6.0",
    "babel-preset-stage-3": "^6.24.1",
    "chai": "^4.2.0",
    "cross-env": "^5.0.5",
    "css-loader": "^0.28.7",
    "mocha": "^6.0.2",
    "node-sass": "^4.11.0",
    "sass-loader": "^6.0.6",
    "url-loader": "^1.1.0",
    "vue-loader": "^13.0.5",
    "vue-template-compiler": "^2.5.21",
    "webpack": "^3.6.0"
  }
}
src/lib/v-gantt-chart/test/gtUtils.test.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,103 @@
var expect = require('chai').expect;
var func = require('../lib/utils/gtUtils')
import dayjs from 'dayjs'
describe('测试gtUtils.js', function() {
  describe('测试getWidthAbout2Times函数', function() {
    it('相同时间 è®¡ç®—结果为0', function() {
      expect(func.getWidthAbout2Times(dayjs(
          '2018-10-10 10:00:00'), dayjs(
        '2018-10-10 10:00:00'), {
          scale: 60,
          cellWidth: 60
        }))
        .to.be.equal(0);
    });
    it('数据测试1', function() {
      expect(func.getWidthAbout2Times(dayjs(
        '2018-10-10 10:00:00'), dayjs(
      '2018-10-10 11:00:00'), {
        scale: 60,
        cellWidth: 60
      })).to.equal(60)
    });
    it('数据测试2', function() {
      expect(func.getWidthAbout2Times(dayjs(
        '2018-10-10 00:00:00'), dayjs(
      '2018-10-10 01:10:00'), {
        scale: 1,
        cellWidth: 1
      })).to.equal(70)
    });
    it('数据测试3', function() {
      expect(func.getWidthAbout2Times(dayjs(
        '2018-10-11 10:00:00'), dayjs(
      '2018-10-11 00:00:00'), {
        scale: 10,
        cellWidth: 10
      })).to.equal(-600)
    });
    it('数据测试4', function() {
      expect(func.getWidthAbout2Times(dayjs(
        '2018-10-10 00:00:00'), dayjs(
      '2018-10-10 10:00:00'), {
        scale: 10,
        cellWidth: 60
      })).to.equal(3600)
    });
  });
  describe('测试getPositonOffset函数', function() {
    it('相同时间 è®¡ç®—结果为0', function() {
      expect(func.getPositonOffset(dayjs(
          '2018-10-10 10:00:00'), dayjs(
        '2018-10-10 10:00:00'), {
          scale: 60,
          cellWidth: 60
        }))
        .to.be.equal(0);
    });
    it('数据测试1', function() {
      expect(func.getPositonOffset(dayjs(
        '2018-10-10 10:00:00'), dayjs(
      '2018-10-10 11:00:00'), {
        scale: 60,
        cellWidth: 60
      })).to.equal(-60)
    });
    it('数据测试2', function() {
      expect(func.getPositonOffset(dayjs(
        '2018-10-10 00:00:00'), dayjs(
      '2018-10-10 01:10:00'), {
        scale: 60,
        cellWidth: 60
      })).to.equal(-70)
    });
    it('数据测试3', function() {
      expect(func.getPositonOffset(dayjs(
        '2018-10-11 10:00:00'), dayjs(
      '2018-10-11 00:00:00'), {
        scale: 60,
        cellWidth: 60
      })).to.equal(+600)
    });
    it('数据测试4', function() {
      expect(func.getPositonOffset(dayjs(
        '2018-10-10 00:00:00'), dayjs(
      '2018-10-10 10:00:00'), {
        scale: 60,
        cellWidth: 60
      })).to.equal(-600)
    });
  });
});
src/lib/v-gantt-chart/test/timeblock.test.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,95 @@
var expect = require('chai').expect;
var func = require('../lib/utils/timeLineUtils')
import dayjs from 'dayjs'
describe('测试timeLineUtils.js', function() {
  describe('测试calcScalesAbout2Times函数', function() {
    it('相同时间 è®¡ç®—结果为1', function() {
      expect(func.calcScalesAbout2Times(dayjs(
          '2018-10-10 10:00:00'), dayjs('2018-10-10 10:00:00'), ))
        .to.be.equal(1);
    });
    it('start åœ¨ end ä¹‹åŽ æŠ¥é”™', function() {
      expect(() => func.calcScalesAbout2Times(dayjs(
          '2018-10-12 10:00:00'), dayjs('2018-10-10 10:00:00'),
        11)).to.throw('错误的参数顺序');
    });
    it('数据测试1', function() {
      expect(func.calcScalesAbout2Times(dayjs(
          '2018-10-10 10:00:00'), dayjs('2018-10-10 11:00:00'),
        10)).to.equal(7)
    });
    it('数据测试2', function() {
      expect(func.calcScalesAbout2Times(dayjs(
          '2018-10-10 00:00:00'), dayjs('2018-10-10 11:00:00'),
        60)).to.equal(12)
    });
    it('数据测试3', function() {
      expect(func.calcScalesAbout2Times(dayjs(
          '2018-10-10 10:00:00'), dayjs('2018-10-11 00:00:00'),
        60)).to.equal(15)
    });
    it('数据测试4', function() {
      expect(func.calcScalesAbout2Times(dayjs(
          '2018-10-10 00:00:00'), dayjs('2018-10-11 00:00:00'),
        60)).to.equal(25)
    });
  });
  describe('测试getBeginTimeOfTimeLine函数', function() {
    it('测试数据1', function() {
      expect( func.getBeginTimeOfTimeLine(dayjs('2018-10-11 00:00:00')).toString())
        .to.be.equal(dayjs('2018-10-11 00:00:00').toString());
    });
    it('测试数据2', function() {
      expect( func.getBeginTimeOfTimeLine(dayjs('2018-10-11 00:00:00'),3).toString())
        .to.be.equal(dayjs('2018-10-11 00:00:00').toString());
    });
    it('测试数据3', function() {
      expect( func.getBeginTimeOfTimeLine(dayjs('2018-10-11 00:04:00'),3).toString())
        .to.be.equal(dayjs('2018-10-11 00:03:00').toString());
    });
    it('测试数据4', function() {
      expect( func.getBeginTimeOfTimeLine(dayjs('2018-10-11 01:11:00'),10).toString())
        .to.be.equal(dayjs('2018-10-11 01:10:00').toString());
    });
  });
  describe('测试validateScale函数', function() {
    it('空值异常', function() {
      expect(() => func.validateScale())
        .to.throw();
    });
    it('null å€¼', function() {
      expect(() => func.validateScale(null))
        .to.throw();
    });
    it('undefined å€¼', function() {
      expect(() => func.validateScale(undefined))
        .to.throw();
    });
    it('异常scale å€¼æŠ¥é”™', function() {
      expect(() => func.validateScale())
        .to.throw();
    });
    it('正常值', function() {
      expect(func.validateScale(1))
        .to.be.true;
    });
  });
});
src/lib/v-gantt-chart/webpack.config.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,106 @@
var path = require('path')
var webpack = require('webpack')
module.exports = {
  entry: './lib/index.js',
  output: {
    path: path.resolve(__dirname, './dist'),
    publicPath: '/dist/',
    filename: 'v-gantt-chart.js',
    library: 'vGanttChart',
    libraryTarget: 'umd',
    umdNamedDefine: true
  },
  module: {
    rules: [{
        test: /\.css$/,
        use: [
          'vue-style-loader',
          'css-loader'
        ],
      },
      {
        test: /\.scss$/,
        use: [
          'vue-style-loader',
          'css-loader',
          'sass-loader'
        ],
      },
      {
        test: /\.sass$/,
        use: [
          'vue-style-loader',
          'css-loader',
          'sass-loader?indentedSyntax'
        ],
      },
      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: {
          loaders: {
            // Since sass-loader (weirdly) has SCSS as its default parse mode, we map
            // the "scss" and "sass" values for the lang attribute to the right configs here.
            // other preprocessors should work out of the box, no loader config like this necessary.
            'scss': [
              'vue-style-loader',
              'css-loader',
              'sass-loader'
            ],
            'sass': [
              'vue-style-loader',
              'css-loader',
              'sass-loader?indentedSyntax'
            ]
          }
          // other vue-loader options go here
        }
      },
      {
        test: /\.js$/,
        loader: 'babel-loader',
        exclude: /node_modules/
      },
      {
        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: 'img/[name].[hash:7].[ext]'
        }
      },
    ]
  },
  resolve: {
    alias: {
      'vue$': 'vue/dist/vue.esm.js'
    },
    extensions: ['*', '.js', '.vue', '.json']
  },
  performance: {
    hints: false
  },
  devtool: '#eval-source-map'
}
if (process.env.NODE_ENV === 'production') {
  module.exports.devtool = '#source-map'
  // http://vue-loader.vuejs.org/en/workflow/production.html
  module.exports.plugins = (module.exports.plugins || []).concat([
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: '"production"'
      }
    }),
    new webpack.optimize.UglifyJsPlugin({
      sourceMap: true,
      compress: {
        warnings: false
      }
    }),
    new webpack.LoaderOptionsPlugin({
      minimize: true
    })
  ])
}
src/views/sbgl/byjl.vue
@@ -1,8 +1,825 @@
<template />
<template>
  <div>
    <el-tabs>
      <el-row style="margin-bottom:20px">
        <!-- <el-col :span="2">
       <el-input v-model="form.Seach"  @keyup.enter.native="SeachKey" placeholder="请输入关键词" size="small"></el-input>
        </el-col>-->
        <el-col :span="7" :offset="1">
          <span class="t_size" style="margin-left:7px">排程日期</span>
          <el-date-picker
            v-model="value1"
            type="daterange"
            range-separator="~"
            format="yyyy-MM-dd"
            value-format="yyyy-MM-dd"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            size="small"
            :picker-options="pickerOptions1"
          />
        </el-col>
        <el-col :span="3">
          <span class="t_size">排程方式</span>
          <el-select v-model="types" size="small" style="width:120px" @change="changeTypes">
            <el-option value="N" label="设备优先" />
            <el-option value="Y" label="时间优先" />
          </el-select>
        </el-col>
        <el-col :span="3" :offset="1">
          <div style="height:32px;">
            <span class="t_size">时间刻度</span>
            <select id="scale" v-model.number="scale">
              <option v-for="i in scaleList" :key="i">{{ i }}</option>
            </select>
            <span class="t_size">分钟</span>
          </div>
        </el-col>
        <el-col :span="3">
          <div style="height:32px;">
            <span class="t_size">换型时间</span>
            <el-input
              id="scale"
              v-model="times"
              type="number"
              size="mini"
              style="display:inline-block;width:80px;"
              @change="no_zero"
            />
            <span class="t_size">分钟</span>
          </div>
        </el-col>
        <el-col :span="3">
          <div style="height:32px;line-height: 28px;">
            <span class="t_size">预排进度</span>
            <span>
              <span style="text-decoration:underline;">{{ real_num }}</span> /
              <span style="text-decoration:underline">{{ meter }}</span>
            </span>
          </div>
        </el-col>
        <el-col :span="3">
          <el-button
            type="primary"
            size="mini"
            icon="el-icon-document-remove"
            style="margin-left:20px;"
          >预排
            <!--            @click="click_schedule"-->
          </el-button>
          <el-button
            type="primary"
            size="mini"
            icon="el-icon-document-checked"
          >提交
            <!--            @click="click_yes"-->
          </el-button>
          <p />
        </el-col>
      </el-row>
      <el-row />
    </el-tabs>
    <div class="container">
      <v-gantt-chart
        :start-time="time_data[0]"
        :end-time="time_data[1]"
        :cell-width="cellWidth"
        :cell-height="cellHeight"
        :time-lines="timeLines"
        :title-height="titleHeight"
        :scale="scale"
        :title-width="titleWidth"
        show-current-time
        :hide-header="hideHeader"
        :data-key="dataKey"
        :array-keys="arrayKeys"
        :scroll-to-postion="positionA"
        :datas="bm_data"
      >
        <!--        @scrollLeft="scrollLeftA"-->
        <template slot="block" slot-scope="{data,item}">
          <Test
            :data="data"
            :update-time-lines="updateTimeLines"
            :cell-height="cellHeight"
            :current-time="currentTime"
            :item="item"
          />
        </template>
        <template slot="left" slot-scope="{data}">
          <div class="name">
            <div class="carId">
              <el-checkbox
                v-model="data.status"
                style="margin-right:5px;"
              />
              <!--              @change="click_box(data)"-->
              {{ data.id }} {{ data.name }}
            </div>
            <div class="speed">
              <el-tooltip class="item" effect="dark" content="查看" placement="top">
                <el-button type="text" size="mini">
                  <!--                  @click="look(data)"-->
                  <i class="el-icon-document size i-color" />
                </el-button>
              </el-tooltip>
            </div>
          </div>
        </template>
        <template slot="title">
          <span class="tc">工位列表</span>
          <el-checkbox v-model="all_status" class="box_style" @change="changeLift()" />
          <input v-model.number="cellWidth" type="range" min="20" max="100" class="box_styles">
        </template>
      </v-gantt-chart>
    </div>
  </div>
</template>
<script>
import dayjs from 'dayjs'
import { mockDatas } from '@/views/sbgl/index1'
export default {
  name: 'Byjl'
  name: 'Byjl',
  data() {
    return {
      show: true,
      pickerOptions1: {
        disabledDate(time) {
          return time.getTime() <= Date.now() - 24 * 60 * 60 * 1000
        }
      },
      real_num: 0,
      keep_data: [],
      all_status: true,
      look_data: [],
      look_total: 0,
      cl_name: '',
      cl_code: '',
      work_order: '',
      false_arr: [],
      ckeckVal: true,
      AdvaScheUom: '',
      list: [],
      form: {
        WorkShop: '',
        PartNumber: '',
        PartName: '',
        rows: 10,
        page: 1
      },
      showDialog: false,
      time_data: [],
      forms: {
        WorkCode: '',
        WorkShop: '',
        PartNumber: '',
        BotProceCode: '',
        StartTime: '',
        EndTime: ''
      },
      click_one: 0,
      datasC: [],
      radio: '',
      value1: '',
      types: 'N',
      no: false,
      total: 0,
      mn_data: [],
      bm_data: [],
      facility_data: [],
      end_start: '',
      timeLines: [
        {
          time: dayjs()
            .add(2, 'hour')
            .toString()
        },
        {
          time: dayjs()
            .add(5, 'hour')
            .toString(),
          color: '#747e80'
        }
      ],
      formUpdata: {
        WorkCode: '',
        BotProceCode: '',
        json: []
      },
      currentTime: dayjs(),
      startTime: dayjs()
        .subtract(5, 'hour')
        .toString(),
      endTime: dayjs()
        .add(2, 'day')
        .add(2, 'hour')
        .toString(),
      cellWidth: 50,
      cellHeight: 30,
      titleHeight: 40,
      titleWidth: 250,
      scale: 60,
      datasNum: 100,
      // datasA: [],
      // datasB: mockDatas(100),
      dataKey: 'id',
      times: 0,
      timeList: timeList,
      scaleList: scaleList,
      scrollToTime: dayjs()
        .add(1, 'day')
        .toString(),
      scrollToPostion: { x: 10000, y: 10000 },
      hideHeader: false,
      arrayKeys: ['gtArray', 'error'],
      scrollToY: 0,
      positionB: {},
      positionA: {},
      meter: 0, // èŠ‚æ‹
      title_list: [],
      imp_id: '',
      submit_flag: false,
      search_from: {
        page: 1,
        rows: 10,
        WorkTime: '',
        BotProceName: ''
      },
      testValue: {
        'rus': {
          'statusCode': '',
          'message': '',
          'MOD_S': '',
          'MAR_S': '',
          'EQP_S': '',
          'CUT_S': '',
          'FIXT_S': '',
          'HouseNumber': '',
          'navTabId': '',
          'dialogid': '',
          'rel': '',
          'dt': null,
          'list': {},
          'callbackType': '',
          'forwardUrl': ''
        },
        'rows': [
          {
            'YearDate': '2022-09-01',
            'children': [
              {
                'AdvaDevicNumber': 'LKFDL_SC-PC029',
                'AdvaDevicName': '金鼎数控车床029',
                'AdvaDevicCropMob': '78',
                'AdvaDevicRhythm': '10',
                'OneStartDate': '08:00~11:30',
                'TwoStartDate': '12:30~17:00',
                'ThreeStartDate': '',
                'FourStartDate': '',
                'FiveStartDate': ''
              }
            ]
          },
          {
            'YearDate': '2022-09-02',
            'children': [
              {
                'AdvaDevicNumber': 'LKFDL_SC-PC029',
                'AdvaDevicName': '金鼎数控车床029',
                'AdvaDevicCropMob': '78',
                'AdvaDevicRhythm': '10',
                'OneStartDate': '08:00~11:30',
                'TwoStartDate': '12:30~17:00',
                'ThreeStartDate': '',
                'FourStartDate': '',
                'FiveStartDate': ''
              }
            ]
          },
          {
            'YearDate': '2022-09-03',
            'children': [
              {
                'AdvaDevicNumber': 'LKFDL_SC-PC029',
                'AdvaDevicName': '金鼎数控车床029',
                'AdvaDevicCropMob': '78',
                'AdvaDevicRhythm': '10',
                'OneStartDate': '08:00~11:30',
                'TwoStartDate': '12:30~17:00',
                'ThreeStartDate': '',
                'FourStartDate': '',
                'FiveStartDate': ''
              }
            ]
          },
          {
            'YearDate': '2022-09-04',
            'children': [
              {
                'AdvaDevicNumber': 'LKFDL_SC-PC029',
                'AdvaDevicName': '金鼎数控车床029',
                'AdvaDevicCropMob': '78',
                'AdvaDevicRhythm': '10',
                'OneStartDate': '08:00~11:30',
                'TwoStartDate': '12:30~17:00',
                'ThreeStartDate': '',
                'FourStartDate': '',
                'FiveStartDate': ''
              }
            ]
          },
          {
            'YearDate': '2022-09-05',
            'children': [
              {
                'AdvaDevicNumber': 'LKFDL_SC-PC029',
                'AdvaDevicName': '金鼎数控车床029',
                'AdvaDevicCropMob': '78',
                'AdvaDevicRhythm': '10',
                'OneStartDate': '08:00~11:30',
                'TwoStartDate': '12:30~17:00',
                'ThreeStartDate': '',
                'FourStartDate': '',
                'FiveStartDate': ''
              }
            ]
          },
          {
            'YearDate': '2022-09-06',
            'children': [
              {
                'AdvaDevicNumber': 'LKFDL_SC-PC029',
                'AdvaDevicName': '金鼎数控车床029',
                'AdvaDevicCropMob': '78',
                'AdvaDevicRhythm': '10',
                'OneStartDate': '08:00~11:30',
                'TwoStartDate': '12:30~17:00',
                'ThreeStartDate': '',
                'FourStartDate': '',
                'FiveStartDate': ''
              }
            ]
          }
        ],
        'Cont': null
      }
    }
  },
  mounted() {
    this.OnclickAdvancedSchedulingDevice()
  },
  methods: {
    OnclickAdvancedSchedulingDevice() {
      this.facility_top()
      // automaticScheduling
      //   .OnclickAdvancedSchedulingDevice(this.forms)
      //   .then(res => {
      const res = this.testValue
      // if (res.rus.message) {
      //   this.$message({
      //     showClose: true,
      //     type: 'error',
      //     message: res.rus.message
      //   })
      // }
      this.submit_flag = false
      const list = []
      this.time_all = res
      const cont = res.Cont
      this.real_num = 0
      for (const i in this.time_all.rows[0].children) {
        const obj = {
          id: '',
          name: '',
          AdvaDevicRhythm: '',
          status: true,
          colorPair: {
            dark: 'rgb(83, 186, 241,0.8)',
            light: 'rgb(83, 186, 241,0.1)',
            light_capacity: 'rgb(209,239,237,0.8)',
            h_schedule: ' rgb(100,255,192,0.8)',
            scheduleing: 'rgb(20,182,231,0.8)'
          },
          gtArray: []
        }
        obj.id = this.time_all.rows[0].children[i].AdvaDevicNumber
        obj.name = this.time_all.rows[0].children[i].AdvaDevicName
        obj.AdvaDevicRhythm = this.time_all.rows[0].children[
          i
        ].AdvaDevicRhythm
        list.push(obj)
      }
      console.log(list, 1)
      for (const i in this.time_all.rows) {
        for (const j in this.time_all.rows[i].children) {
          if (this.time_all.rows[i].children[j].OneStartDate != '') {
            this.time_all.rows[i].children[
              j
            ].OneStartDate = this.time_all.rows[i].children[
              j
            ].OneStartDate.split('~')
            this.time_all.rows[i].children[j].OneStartDate[0] =
              this.time_all.rows[i].YearDate +
              ' ' +
              this.time_all.rows[i].children[j].OneStartDate[0]
            this.time_all.rows[i].children[j].OneStartDate[1] =
              this.time_all.rows[i].YearDate +
              ' ' +
              this.time_all.rows[i].children[j].OneStartDate[1]
          }
          if (this.time_all.rows[i].children[j].TwoStartDate != '') {
            this.time_all.rows[i].children[
              j
            ].TwoStartDate = this.time_all.rows[i].children[
              j
            ].TwoStartDate.split('~')
            this.time_all.rows[i].children[j].TwoStartDate[0] =
              this.time_all.rows[i].YearDate +
              ' ' +
              this.time_all.rows[i].children[j].TwoStartDate[0]
            this.time_all.rows[i].children[j].TwoStartDate[1] =
              this.time_all.rows[i].YearDate +
              ' ' +
              this.time_all.rows[i].children[j].TwoStartDate[1]
          }
          if (this.time_all.rows[i].children[j].ThreeStartDate != '') {
            this.time_all.rows[i].children[
              j
            ].ThreeStartDate = this.time_all.rows[i].children[
              j
            ].ThreeStartDate.split('~')
            this.time_all.rows[i].children[j].ThreeStartDate[0] =
              this.time_all.rows[i].YearDate +
              ' ' +
              this.time_all.rows[i].children[j].ThreeStartDate[0]
            this.time_all.rows[i].children[j].ThreeStartDate[1] =
              this.time_all.rows[i].YearDate +
              ' ' +
              this.time_all.rows[i].children[j].ThreeStartDate[1]
          }
          if (this.time_all.rows[i].children[j].FourStartDate != '') {
            this.time_all.rows[i].children[
              j
            ].FourStartDate = this.time_all.rows[i].children[
              j
            ].FourStartDate.split('~')
            this.time_all.rows[i].children[j].FourStartDate[0] =
              this.time_all.rows[i].YearDate +
              ' ' +
              this.time_all.rows[i].children[j].FourStartDate[0]
            this.time_all.rows[i].children[j].FourStartDate[1] =
              this.time_all.rows[i].YearDate +
              ' ' +
              this.time_all.rows[i].children[j].FourStartDate[1]
          }
          if (this.time_all.rows[i].children[j].FiveStartDate != '') {
            this.time_all.rows[i].children[
              j
            ].FiveStartDate = this.time_all.rows[i].children[
              j
            ].FiveStartDate.split('~')
            this.time_all.rows[i].children[j].FiveStartDate[0] =
              this.time_all.rows[i].YearDate +
              ' ' +
              this.time_all.rows[i].children[j].FiveStartDate[0]
            this.time_all.rows[i].children[j].FiveStartDate[1] =
              this.time_all.rows[i].YearDate +
              ' ' +
              this.time_all.rows[i].children[j].FiveStartDate[1]
          }
        }
      }
      // ç»„合新的结构
      const newList = []
      for (const i in this.time_all.rows) {
        for (const j in this.time_all.rows[i].children) {
          if (this.time_all.rows[i].children[j].OneStartDate != '') {
            const data1 = {
              id: '',
              start: '',
              end: '',
              mod: ''
            }
            data1.id = this.time_all.rows[i].children[j].AdvaDevicNumber
            data1.start = this.time_all.rows[i].children[j].OneStartDate[0]
            data1.end = this.time_all.rows[i].children[j].OneStartDate[1]
            data1.mod =
              (this.time_all.rows[i].children[j].AdvaDevicCropMob * 1) /
              100
            newList.push(data1)
          }
          if (this.time_all.rows[i].children[j].TwoStartDate != '') {
            const data2 = {
              id: '',
              start: '',
              end: '',
              mod: ''
            }
            data2.id = this.time_all.rows[i].children[j].AdvaDevicNumber
            data2.start = this.time_all.rows[i].children[j].TwoStartDate[0]
            data2.end = this.time_all.rows[i].children[j].TwoStartDate[1]
            data2.mod =
              (this.time_all.rows[i].children[j].AdvaDevicCropMob * 1) /
              100
            newList.push(data2)
          }
          if (this.time_all.rows[i].children[j].ThreeStartDate != '') {
            const data3 = {
              id: '',
              start: '',
              end: '',
              mod: ''
            }
            data3.id = this.time_all.rows[i].children[j].AdvaDevicNumber
            data3.start = this.time_all.rows[i].children[
              j
            ].ThreeStartDate[0]
            data3.end = this.time_all.rows[i].children[j].ThreeStartDate[1]
            data3.mod =
              (this.time_all.rows[i].children[j].AdvaDevicCropMob * 1) /
              100
            newList.push(data3)
          }
          if (this.time_all.rows[i].children[j].FourStartDate != '') {
            const data4 = {
              id: '',
              start: '',
              end: '',
              mod: ''
            }
            data4.id = this.time_all.rows[i].children[j].AdvaDevicNumber
            data4.start = this.time_all.rows[i].children[
              j
            ].FourStartDate[0]
            data4.end = this.time_all.rows[i].children[j].FourStartDate[1]
            data4.mod =
              (this.time_all.rows[i].children[j].AdvaDevicCropMob * 1) /
              100
            newList.push(data4)
          }
          if (this.time_all.rows[i].children[j].FiveStartDate != '') {
            const data5 = {
              id: '',
              start: '',
              end: '',
              mod: ''
            }
            data5.id = this.time_all.rows[i].children[j].AdvaDevicNumber
            data5.start = this.time_all.rows[i].children[
              j
            ].FiveStartDate[0]
            data5.end = this.time_all.rows[i].children[j].FiveStartDate[1]
            data5.mod =
              (this.time_all.rows[i].children[j].AdvaDevicCropMob * 1) /
              100
            newList.push(data5)
          }
        }
      }
      for (const i in list) {
        this.pushTiem(newList, list[i].id, list[i].gtArray)
      }
      this.bm_data = list
      const _this = this
      if (cont != '') {
        for (const i in cont) {
          for (const j in this.bm_data) {
            if (this.bm_data[j].id == cont[i].EQP_CODE) {
              const data = {
                id: cont[i].EQP_CODE,
                number: cont[i].ALLOC_QTY,
                cl_name: cont[i].PART_NAME,
                cl_code: this.cl_code,
                work_order: cont[i].WO_CODE,
                STATUS: _this.AdvaScheUom,
                start: cont[i].TIME_START,
                end: cont[i].TIME_END,
                type: cont[i].STATUS == 'S' ? 'h_schedule' : 'bm_schedule'
              }
              this.bm_data[j].flag = 'isCont'
              this.bm_data[j].gtArray.unshift(data)
            }
          }
        }
      }
      if (this.false_arr != '') {
        for (const j in this.bm_data) {
          if (this.false_arr.indexOf(this.bm_data[j].id) >= 0) {
            this.bm_data[j].gtArray = []
            this.bm_data[j].status = false
          }
        }
      }
      // })
    },
    // è®¾å¤‡ä¼˜å…ˆ
    facility_top() {
      // automaticScheduling
      //   .OnclickAdvancedSchedulingDevice(this.forms)
      //   .then(res => {
      const res = this.testValue
      this.show = true
      const data = res.rows
      const cont = res.Cont
      this.title_list = []
      for (const i in data[0].children) {
        const obj = {
          id: '',
          name: '',
          status: true,
          AdvaDevicRhythm: '',
          // mod:'',
          colorPair: {
            dark: 'rgb(83, 186, 241,0.8)',
            light: 'rgb(83, 186, 241,0.1)',
            light_capacity: 'rgb(209,239,237,0.8)',
            h_schedule: ' rgb(100,255,192,0.8)',
            scheduleing: 'rgb(20,182,231,0.8)'
          },
          gtArray: []
        }
        obj.id = data[0].children[i].AdvaDevicNumber
        obj.name = data[0].children[i].AdvaDevicName
        obj.AdvaDevicRhythm = data[0].children[i].AdvaDevicRhythm
        // obj.mod =data[0].children[i].AdvaDevicCropMob *1
        this.title_list.push(obj)
      }
      for (const i in data) {
        for (const j in data[i].children) {
          if (data[i].children[j].OneStartDate != '') {
            data[i].children[j].OneStartDate = data[i].children[
              j
            ].OneStartDate.split('~')
            data[i].children[j].OneStartDate[0] =
              data[i].YearDate + ' ' + data[i].children[j].OneStartDate[0]
            data[i].children[j].OneStartDate[1] =
              data[i].YearDate + ' ' + data[i].children[j].OneStartDate[1]
          }
          if (data[i].children[j].TwoStartDate != '') {
            data[i].children[j].TwoStartDate = data[i].children[
              j
            ].TwoStartDate.split('~')
            data[i].children[j].TwoStartDate[0] =
              data[i].YearDate + ' ' + data[i].children[j].TwoStartDate[0]
            data[i].children[j].TwoStartDate[1] =
              data[i].YearDate + ' ' + data[i].children[j].TwoStartDate[1]
          }
          if (data[i].children[j].ThreeStartDate != '') {
            data[i].children[j].ThreeStartDate = data[i].children[
              j
            ].ThreeStartDate.split('~')
            data[i].children[j].ThreeStartDate[0] =
              data[i].YearDate +
              ' ' +
              data[i].children[j].ThreeStartDate[0]
            data[i].children[j].ThreeStartDate[1] =
              data[i].YearDate +
              ' ' +
              data[i].children[j].ThreeStartDate[1]
          }
          if (data[i].children[j].FourStartDate != '') {
            data[i].children[j].FourStartDate = data[i].children[
              j
            ].FourStartDate.split('~')
            data[i].children[j].FourStartDate[0] =
              data[i].YearDate + ' ' + data[i].children[j].FourStartDate[0]
            data[i].children[j].FourStartDate[1] =
              data[i].YearDate + ' ' + data[i].children[j].FourStartDate[1]
          }
          if (data[i].children[j].FiveStartDate != '') {
            data[i].children[j].FiveStartDate = data[i].children[
              j
            ].FiveStartDate.split('~')
            data[i].children[j].FiveStartDate[0] =
              data[i].YearDate + ' ' + data[i].children[j].FiveStartDate[0]
            data[i].children[j].FiveStartDate[1] =
              data[i].YearDate + ' ' + data[i].children[j].FiveStartDate[1]
          }
        }
      }
      // æ›´æ”¹æ ¼å¼
      this.facility_data = []
      for (const i in data) {
        const time = {
          date: data[i].YearDate,
          AdvaDevicRhythm: '',
          gtArray: []
        }
        if (data[i].children != '') {
          time.AdvaDevicRhythm = data[i].children[0].AdvaDevicRhythm
        }
        for (const j in data[i].children) {
          if (data[i].children[j].OneStartDate != '') {
            const icu1 = {
              name: data[i].children[j].AdvaDevicName,
              id: data[i].children[j].AdvaDevicNumber,
              type: 'capacity',
              rhythm: data[i].children[j].AdvaDevicRhythm,
              start: data[i].children[j].OneStartDate[0],
              end: data[i].children[j].OneStartDate[1],
              mod: (data[i].children[j].AdvaDevicCropMob * 1) / 100
            }
            time.gtArray.push(icu1)
          }
          if (data[i].children[j].TwoStartDate != '') {
            const icu2 = {
              name: data[i].children[j].AdvaDevicName,
              id: data[i].children[j].AdvaDevicNumber,
              type: 'capacity',
              rhythm: data[i].children[j].AdvaDevicRhythm,
              start: data[i].children[j].TwoStartDate[0],
              end: data[i].children[j].TwoStartDate[1],
              mod: (data[i].children[j].AdvaDevicCropMob * 1) / 100
            }
            time.gtArray.push(icu2)
          }
          if (data[i].children[j].ThreeStartDate != '') {
            const icu3 = {
              name: data[i].children[j].AdvaDevicName,
              id: data[i].children[j].AdvaDevicNumber,
              type: 'capacity',
              rhythm: data[i].children[j].AdvaDevicRhythm,
              start: data[i].children[j].ThreeStartDate[0],
              end: data[i].children[j].ThreeStartDate[1],
              mod: (data[i].children[j].AdvaDevicCropMob * 1) / 100
            }
            time.gtArray.push(icu3)
          }
          if (data[i].children[j].FourStartDate != '') {
            const icu4 = {
              name: data[i].children[j].AdvaDevicName,
              id: data[i].children[j].AdvaDevicNumber,
              type: 'capacity',
              rhythm: data[i].children[j].AdvaDevicRhythm,
              start: data[i].children[j].FourStartDate[0],
              end: data[i].children[j].FourStartDate[1],
              mod: (data[i].children[j].AdvaDevicCropMob * 1) / 100
            }
            time.gtArray.push(icu4)
          }
          if (data[i].children[j].FiveStartDate != '') {
            const icu5 = {
              name: data[i].children[j].AdvaDevicName,
              id: data[i].children[j].AdvaDevicNumber,
              type: 'capacity',
              rhythm: data[i].children[j].AdvaDevicRhythm,
              start: data[i].children[j].FiveStartDate[0],
              end: data[i].children[j].FiveStartDate[1],
              mod: (data[i].children[j].AdvaDevicCropMob * 1) / 100
            }
            time.gtArray.push(icu5)
          }
        }
        this.facility_data.push(time)
      }
      if (cont != '') {
        for (const i in cont) {
          const date_time = cont[i].TIME_START.split(' ')
          const cont_date = date_time[0]
          for (const j in this.facility_data) {
            const data = {
              id: cont[i].EQP_CODE,
              date: cont_date,
              number: cont[i].ALLOC_QTY,
              cl_name: cont[i].PART_NAME,
              cl_code: this.cl_code,
              work_order: cont[i].WO_CODE,
              start: cont[i].TIME_START,
              end: cont[i].TIME_END,
              type: 'h_schedule'
            }
            if (this.facility_data[j].date == data.date) {
              this.facility_data[j].gtArray.unshift(data)
            }
          }
        }
      }
      //   })
    },
    updateTimeLines() {
    }
  }
}
</script>
src/views/sbgl/djjl.vue
@@ -1,11 +1,1853 @@
<template />
<!--<template>-->
<!--  <div id="app">-->
<!--    <div class="app-container">-->
<!--      <el-tabs>-->
<!--        <el-form ref="form" :model="form" :rules="rulescx" label-width="100px" size="medium">-->
<!--          <el-row>-->
<!--            <el-col :span="6" :offset="1">-->
<!--              <el-form-item prop="WorkShop" label="生产车间">-->
<!--                <el-select v-model="form.WorkShop" style="width:257px" filterable>-->
<!--                  <el-option-->
<!--                    v-for="item in list"-->
<!--                    :key="item.CODE"-->
<!--                    :label="item.NAME"-->
<!--                    :value="item.CODE"-->
<!--                  />-->
<!--                </el-select>-->
<!--              </el-form-item>-->
<!--            </el-col>-->
<!--            <el-col :span="6" :offset="1">-->
<!--              <el-form-item prop="PartNumber" label="产品编码">-->
<!--                <el-input v-model="form.PartNumber" placeholder="请输入" style="width:257px" />-->
<!--              </el-form-item>-->
<!--            </el-col>-->
<!--            <el-col :span="5" :offset="1">-->
<!--              <el-form-item prop="PartName" label="产品名称">-->
<!--                <el-input v-model="form.PartName" placeholder="请输入" style="width:257px" />-->
<!--              </el-form-item>-->
<!--            </el-col>-->
<script>
export default {
  name: 'Djjl'
}
</script>
<!--            <el-col :span="3" :offset="1">-->
<!--              <el-button type="text" class="marginLeft rg color" @click="resetFormcx()">重置</el-button>-->
<!--              <el-button-->
<!--                class="filter-item marginLeft button_style rg"-->
<!--                size="medium"-->
<!--                icon="el-icon-search"-->
<!--                @click="Search()"-->
<!--              >查询-->
<!--              </el-button>-->
<!--            </el-col>-->
<!--          </el-row>-->
<!--        </el-form>-->
<!--      </el-tabs>-->
<!--      <el-table-->
<!--        class="table"-->
<!--        :data="mn_data"-->
<!--        :header-cell-style="{background:'#f5f5f5'}"-->
<!--        height="280"-->
<!--        @sort-change="sortChange"-->
<!--      >-->
<!--        <el-table-column width="34" fixed>-->
<!--          <template slot-scope="scope">-->
<!--            <el-radio-->
<!--              v-model="radio"-->
<!--              :label="scope.$index"-->
<!--              class="textRadio"-->
<!--              @change.native="getCurrentRow(scope.row)"-->
<!--            >&nbsp;-->
<!--            </el-radio>-->
<!--          </template>-->
<!--        </el-table-column>-->
<!--        <el-table-column-->
<!--          label="序号"-->
<!--          prop="AdvaScheSeq"-->
<!--          width="80"-->
<!--          sortable="custom"-->
<!--          :sort-orders="['ascending', 'descending']"-->
<!--        />-->
<!--        <el-table-column-->
<!--          label="优先级"-->
<!--          prop="AdvaSchePiroQue"-->
<!--          sortable="custom"-->
<!--          :sort-orders="['ascending', 'descending']"-->
<!--        >-->
<!--          <template slot-scope="scope">-->
<!--            <div v-if="scope.row.AdvaSchePiroQue == '正常'">-->
<!--              <span class="icon_true" />-->
<!--              {{ scope.row.AdvaSchePiroQue }}-->
<!--            </div>-->
<!--            <div v-if="scope.row.AdvaSchePiroQue == '紧急'">-->
<!--              <span class="icon_gz" />-->
<!--              {{ scope.row.AdvaSchePiroQue }}-->
<!--            </div>-->
<!--            <div v-if="scope.row.AdvaSchePiroQue == '特急'">-->
<!--              <span class="icon_ty" />-->
<!--              {{ scope.row.AdvaSchePiroQue }}-->
<!--            </div>-->
<!--          </template>-->
<!--        </el-table-column>-->
<!--        <el-table-column-->
<!--          label="生产车间"-->
<!--          prop="AdvaScheWorkShop"-->
<!--          sortable="custom"-->
<!--          :sort-orders="['ascending', 'descending']"-->
<!--        />-->
<!--        <el-table-column-->
<!--          label="工单编号"-->
<!--          prop="AdvaScheWorkCode"-->
<!--          sortable="custom"-->
<!--          :sort-orders="['ascending', 'descending']"-->
<!--        />-->
<!--        <el-table-column-->
<!--          label="产品编码"-->
<!--          prop="AdvaSchePartNumber"-->
<!--          sortable="custom"-->
<!--          :sort-orders="['ascending', 'descending']"-->
<!--        />-->
<!--        <el-table-column-->
<!--          label="产品名称"-->
<!--          prop="AdvaSchePartName"-->
<!--          width="150"-->
<!--          sortable="custom"-->
<!--          :sort-orders="['ascending', 'descending']"-->
<!--        />-->
<!--        <el-table-column-->
<!--          label="产品规格"-->
<!--          prop="AdvaSchePartSpec"-->
<!--          sortable="custom"-->
<!--          :sort-orders="['ascending', 'descending']"-->
<!--        />-->
<!--        <el-table-column-->
<!--          label="数量"-->
<!--          prop="AdvaScheQty"-->
<!--          width="80"-->
<!--          sortable="custom"-->
<!--          :sort-orders="['ascending', 'descending']"-->
<!--        />-->
<!--        <el-table-column-->
<!--          label="要求交付时间"-->
<!--          prop="AdvaScheEndDate"-->
<!--          width="200"-->
<!--          sortable="custom"-->
<!--          :sort-orders="['ascending', 'descending']"-->
<!--        >-->
<!--          <template slot-scope="scope">{{ scope.row.AdvaScheEndDate }}</template>-->
<!--        </el-table-column>-->
<!--        &lt;!&ndash; <el-table-column  label="结束日期" prop="AdvaScheEndDate">-->
<!--        </el-table-column>&ndash;&gt;-->
<!--        <el-table-column label="交付状态" prop="AdvaScheSpeed" sortable="custom" :sort-orders="['ascending', 'descending']">-->
<!--          <template slot-scope="scope">-->
<!--            <div v-if="scope.row.Flag == 'Y' && scope.row.AdvaScheStus != 'NEW'">-->
<!--              <span class="icon_true" /> æ­£å¸¸-->
<!--            </div>-->
<!--            <div v-if="scope.row.Flag == 'N' && scope.row.AdvaScheStus != 'NEW'">-->
<!--              <span v-if="scope.row.Flag == 'N'" class="icon_ty" />延期-->
<!--            </div>-->
<!--          </template>-->
<!--        </el-table-column>-->
<!--        <el-table-column-->
<!--          label="排程工序"-->
<!--          prop="AdvaScheBotProcName"-->
<!--          sortable="custom"-->
<!--          :sort-orders="['ascending', 'descending']"-->
<!--          width="160"-->
<!--        />-->
<!--        <el-table-column label="计划排程时间" width="200" sortable="custom" :sort-orders="['ascending', 'descending']">-->
<!--          <template-->
<!--            slot-scope="scope"-->
<!--          >{{ scope.row.AdvaSchePCStartDate }} ~ {{ scope.row.AdvaSchePCEndDate }}-->
<!--          </template>-->
<!--        </el-table-column>-->
<!--      </el-table>-->
<!--      &lt;!&ndash;      <pagination-view&ndash;&gt;-->
<!--      &lt;!&ndash;        :currentPage="form.page"&ndash;&gt;-->
<!--      &lt;!&ndash;        :total="total"&ndash;&gt;-->
<!--      &lt;!&ndash;        @size-change="sizeChange"&ndash;&gt;-->
<!--      &lt;!&ndash;        @current-change="pageChange"&ndash;&gt;-->
<!--      &lt;!&ndash;      ></pagination-view>&ndash;&gt;-->
<!--    </div>-->
<style scoped>
<!--    <el-dialog title="查看" :visible.sync="showDialog" width="60%">-->
<!--      <el-table class="table" :data="look_data" :header-cell-style="{background:'#f5f5f5'}">-->
<!--        <el-table-column label="序号" prop="AdvaTaskSeq" width="80" />-->
<!--        <el-table-column label="工单编号" prop="AdvaTaskWork" />-->
<!--        <el-table-column label="工单状态" prop="AdvaTaskStatus" />-->
<!--        <el-table-column label="产品编码" prop="AdvaTaskPartNumber" />-->
<!--        <el-table-column label="开始时间" prop="AdvaTaskStartDate" width="160" />-->
<!--        <el-table-column label="结束时间" prop="AdvaTaskEndDate" width="160" />-->
<!--        <el-table-column label="生产数量" prop="AdvaTaskQty" />-->
<!--        <el-table-column label="生产工序" prop="AdvaTaskBotProcName" />-->
<!--      </el-table>-->
<!--      <div style="overflow: hidden">-->
<!--        &lt;!&ndash;        <pagination-view&ndash;&gt;-->
<!--        &lt;!&ndash;          :currentPage="search_from.page"&ndash;&gt;-->
<!--        &lt;!&ndash;          :total="look_total"&ndash;&gt;-->
<!--        &lt;!&ndash;          @size-change="sizeChange_look"&ndash;&gt;-->
<!--        &lt;!&ndash;          @current-change="pageChange_look"&ndash;&gt;-->
<!--        &lt;!&ndash;        ></pagination-view>&ndash;&gt;-->
<!--      </div>-->
<!--    </el-dialog>-->
</style>
<!--    <el-tabs v-show="show">-->
<!--      <el-row style="margin-bottom:20px">-->
<!--        &lt;!&ndash; <el-col :span="2">-->
<!--       <el-input v-model="form.Seach"  @keyup.enter.native="SeachKey" placeholder="请输入关键词" size="small"></el-input>-->
<!--        </el-col>&ndash;&gt;-->
<!--        <el-col :span="7" :offset="1">-->
<!--          <span class="t_size" style="margin-left:7px">排程日期</span>-->
<!--          <el-date-picker-->
<!--            v-model="value1"-->
<!--            type="daterange"-->
<!--            range-separator="~"-->
<!--            format="yyyy-MM-dd"-->
<!--            value-format="yyyy-MM-dd"-->
<!--            start-placeholder="开始日期"-->
<!--            end-placeholder="结束日期"-->
<!--            size="small"-->
<!--            :picker-options="pickerOptions1"-->
<!--            @change="change_time"-->
<!--          />-->
<!--        </el-col>-->
<!--        <el-col :span="3">-->
<!--          <span class="t_size">排程方式</span>-->
<!--          <el-select v-model="types" size="small" style="width:120px" @change="changeTypes">-->
<!--            <el-option value="N" label="设备优先" />-->
<!--            <el-option value="Y" label="时间优先" />-->
<!--          </el-select>-->
<!--        </el-col>-->
<!--        <el-col :span="3" :offset="1">-->
<!--          <div style="height:32px;">-->
<!--            <span class="t_size">时间刻度</span>-->
<!--            <select id="scale" v-model.number="scale">-->
<!--              <option v-for="i in scaleList" :key="i">{{ i }}</option>-->
<!--            </select>-->
<!--            <span class="t_size">分钟</span>-->
<!--          </div>-->
<!--        </el-col>-->
<!--        <el-col :span="3">-->
<!--          <div style="height:32px;">-->
<!--            <span class="t_size">换型时间</span>-->
<!--            <el-input-->
<!--              id="scale"-->
<!--              v-model="times"-->
<!--              type="number"-->
<!--              size="mini"-->
<!--              style="display:inline-block;width:80px;"-->
<!--              @change="no_zero"-->
<!--            />-->
<!--            <span class="t_size">分钟</span>-->
<!--          </div>-->
<!--        </el-col>-->
<!--        <el-col :span="3">-->
<!--          <div style="height:32px;line-height: 28px;">-->
<!--            <span class="t_size">预排进度</span>-->
<!--            <span>-->
<!--              <span style="text-decoration:underline;">{{ real_num }}</span> /-->
<!--              <span style="text-decoration:underline">{{ meter }}</span>-->
<!--            </span>-->
<!--          </div>-->
<!--        </el-col>-->
<!--        <el-col :span="3">-->
<!--          <el-button-->
<!--            type="primary"-->
<!--            size="mini"-->
<!--            icon="el-icon-document-remove"-->
<!--            style="margin-left:20px;"-->
<!--            @click="click_schedule"-->
<!--          >预排-->
<!--          </el-button>-->
<!--          <el-button-->
<!--            type="primary"-->
<!--            size="mini"-->
<!--            icon="el-icon-document-checked"-->
<!--            @click="click_yes"-->
<!--          >提交-->
<!--          </el-button>-->
<!--          <p />-->
<!--        </el-col>-->
<!--      </el-row>-->
<!--      <el-row />-->
<!--    </el-tabs>-->
<!--    <div v-show="show" class="container">-->
<!--      <v-gantt-chart-->
<!--        :start-time="time_data[0]"-->
<!--        :end-time="time_data[1]"-->
<!--        :cell-width="cellWidth"-->
<!--        :cell-height="cellHeight"-->
<!--        :time-lines="timeLines"-->
<!--        :title-height="titleHeight"-->
<!--        :scale="scale"-->
<!--        :title-width="titleWidth"-->
<!--        show-current-time-->
<!--        :hide-header="hideHeader"-->
<!--        :data-key="dataKey"-->
<!--        :array-keys="arrayKeys"-->
<!--        :scroll-to-postion="positionA"-->
<!--        :datas="bm_data"-->
<!--        @scrollLeft="scrollLeftA"-->
<!--      >-->
<!--        &lt;!&ndash; <template v-slot:block="{data,item}"> &ndash;&gt;-->
<!--        <template slot="block" slot-scope="{data,item}">-->
<!--          <Test-->
<!--            :data="data"-->
<!--            :update-time-lines="updateTimeLines"-->
<!--            :cell-height="cellHeight"-->
<!--            :current-time="currentTime"-->
<!--            :item="item"-->
<!--          />-->
<!--        </template>-->
<!--        <template slot="left" slot-scope="{data}">-->
<!--          <div class="name">-->
<!--            <div class="carId">-->
<!--              <el-checkbox-->
<!--                v-model="data.status"-->
<!--                style="margin-right:5px;"-->
<!--                @change="click_box(data)"-->
<!--              />-->
<!--              {{ data.id }} {{ data.name }}-->
<!--            </div>-->
<!--            <div class="speed">-->
<!--              <el-tooltip class="item" effect="dark" content="查看" placement="top">-->
<!--                <el-button type="text" size="mini" @click="look(data)">-->
<!--                  <i class="el-icon-document size i-color" />-->
<!--                </el-button>-->
<!--              </el-tooltip>-->
<!--            </div>-->
<!--          </div>-->
<!--        </template>-->
<!--        <template slot="title">-->
<!--          <span class="tc">工位列表</span>-->
<!--          <el-checkbox v-model="all_status" class="box_style" @change="changeLift()" />-->
<!--          <input v-model.number="cellWidth" type="range" min="20" max="100" class="box_styles">-->
<!--        </template>-->
<!--      </v-gantt-chart>-->
<!--    </div>-->
<!--  </div>-->
<!--</template>-->
<!--<script>-->
<!--import Test from '@/components/Test'-->
<!--// import PaginationView from '@/components/PaginationView'-->
<!--// import TestLeft from '@/components/TestLeft'-->
<!--import { mockDatas } from './index1.js'-->
<!--import dayjs from 'dayjs'-->
<!--import automaticScheduling from '@/api/automaticScheduling'-->
<!--const scaleList = `30,60,240,360`.split(',').map(n => parseInt(n))-->
<!--const timeList = `0,30,60,120,240,480`.split(',').map(n => parseInt(n))-->
<!--export default {-->
<!--  components: { Test },-->
<!--  data() {-->
<!--    return {-->
<!--      show: false,-->
<!--      pickerOptions1: {-->
<!--        disabledDate(time) {-->
<!--          return time.getTime() <= Date.now() - 24 * 60 * 60 * 1000-->
<!--        }-->
<!--      },-->
<!--      real_num: 0,-->
<!--      keep_data: [],-->
<!--      all_status: true,-->
<!--      look_data: [],-->
<!--      look_total: 0,-->
<!--      cl_name: '',-->
<!--      cl_code: '',-->
<!--      work_order: '',-->
<!--      false_arr: [],-->
<!--      ckeckVal: true,-->
<!--      AdvaScheUom: '',-->
<!--      list: [],-->
<!--      form: {-->
<!--        WorkShop: '',-->
<!--        PartNumber: '',-->
<!--        PartName: '',-->
<!--        rows: 10,-->
<!--        page: 1-->
<!--      },-->
<!--      showDialog: false,-->
<!--      time_data: [],-->
<!--      forms: {-->
<!--        WorkCode: '',-->
<!--        WorkShop: '',-->
<!--        PartNumber: '',-->
<!--        BotProceCode: '',-->
<!--        StartTime: '',-->
<!--        EndTime: ''-->
<!--      },-->
<!--      click_one: 0,-->
<!--      datasC: [],-->
<!--      radio: '',-->
<!--      value1: '',-->
<!--      types: 'N',-->
<!--      no: false,-->
<!--      total: 0,-->
<!--      mn_data: [],-->
<!--      bm_data: [],-->
<!--      facility_data: [],-->
<!--      end_start: '',-->
<!--      timeLines: [-->
<!--        {-->
<!--          time: dayjs()-->
<!--            .add(2, 'hour')-->
<!--            .toString()-->
<!--        },-->
<!--        {-->
<!--          time: dayjs()-->
<!--            .add(5, 'hour')-->
<!--            .toString(),-->
<!--          color: '#747e80'-->
<!--        }-->
<!--      ],-->
<!--      formUpdata: {-->
<!--        WorkCode: '',-->
<!--        BotProceCode: '',-->
<!--        json: []-->
<!--      },-->
<!--      currentTime: dayjs(),-->
<!--      startTime: dayjs()-->
<!--        .subtract(5, 'hour')-->
<!--        .toString(),-->
<!--      endTime: dayjs()-->
<!--        .add(2, 'day')-->
<!--        .add(2, 'hour')-->
<!--        .toString(),-->
<!--      cellWidth: 50,-->
<!--      cellHeight: 30,-->
<!--      titleHeight: 40,-->
<!--      titleWidth: 250,-->
<!--      scale: 60,-->
<!--      datasNum: 100,-->
<!--      datasA: [],-->
<!--      datasB: mockDatas(100),-->
<!--      dataKey: 'id',-->
<!--      times: 0,-->
<!--      timeList: timeList,-->
<!--      scaleList: scaleList,-->
<!--      scrollToTime: dayjs()-->
<!--        .add(1, 'day')-->
<!--        .toString(),-->
<!--      scrollToPostion: { x: 10000, y: 10000 },-->
<!--      hideHeader: false,-->
<!--      arrayKeys: ['gtArray', 'error'],-->
<!--      scrollToY: 0,-->
<!--      positionB: {},-->
<!--      positionA: {},-->
<!--      meter: 0, // èŠ‚æ‹-->
<!--      title_list: [],-->
<!--      imp_id: '',-->
<!--      submit_flag: false,-->
<!--      search_from: {-->
<!--        page: 1,-->
<!--        rows: 10,-->
<!--        WorkTime: '',-->
<!--        BotProceName: ''-->
<!--      }-->
<!--    }-->
<!--  },-->
<!--  watch: {-->
<!--    datasNum(newV) {-->
<!--      this.datasA = mockDatas(newV)-->
<!--      this.datasB = mockDatas(newV)-->
<!--    },-->
<!--    scrollToY(val) {-->
<!--      this.positionA = { x: val }-->
<!--    }-->
<!--  },-->
<!--  created: function() {-->
<!--    this.AdvancedSchedulingSearch()-->
<!--    this.AdvancedSchedulingWorkShop()-->
<!--  },-->
<!--  methods: {-->
<!--    AdvancedSchedulingWorkShop() {-->
<!--      automaticScheduling.AdvancedSchedulingWorkShop().then(res => {-->
<!--        this.list = res-->
<!--      })-->
<!--    },-->
<!--    Search() {-->
<!--      this.form.page = 1-->
<!--      this.show = false-->
<!--      this.radio = ''-->
<!--      this.AdvancedSchedulingSearch()-->
<!--    },-->
<!--    resetFormcx() {-->
<!--      this.$nextTick(() => {-->
<!--        this.$refs.form.resetFields()-->
<!--      })-->
<!--    },-->
<!--    no_zero() {-->
<!--      if (this.times < 0) {-->
<!--        this.times = 0-->
<!--      }-->
<!--    },-->
<!--    sortChange(column, prop, order) {-->
<!--      this.radio = '';-->
<!--      (this.form.prop = column.prop), (this.form.order = column.order)-->
<!--      this.show = false-->
<!--      this.AdvancedSchedulingSearch()-->
<!--    },-->
<!--    SeachKey() {-->
<!--      this.form.page = 1-->
<!--      this.AdvancedSchedulingSearch()-->
<!--      this.show = false-->
<!--      this.radio = ''-->
<!--    },-->
<!--    changeLift() {-->
<!--      if (this.all_status) {-->
<!--        this.false_arr = []-->
<!--        this.OnclickAdvancedSchedulingDevice()-->
<!--      } else {-->
<!--        for (const i in this.bm_data) {-->
<!--          this.bm_data[i].status = false-->
<!--          this.bm_data[i].gtArray = []-->
<!--        }-->
<!--        for (const i in this.facility_data) {-->
<!--          this.facility_data[i].gtArray = []-->
<!--        }-->
<!--      }-->
<!--    },-->
<!--    changeTypes() {-->
<!--      this.OnclickAdvancedSchedulingDevice()-->
<!--    },-->
<!--    change_time() {-->
<!--      this.time_data[0] = this.value1[0] + ' 00:00'-->
<!--      this.time_data[1] = this.value1[1] + ' 23:59'-->
<!--      this.forms.StartTime = this.value1[0]-->
<!--      this.forms.EndTime = this.value1[1]-->
<!--      this.OnclickAdvancedSchedulingDevice()-->
<!--    },-->
<!--    click_box(val) {-->
<!--      if (!val.status) {-->
<!--        for (const i in this.facility_data) {-->
<!--          const new_arr = []-->
<!--          for (const j in this.facility_data[i].gtArray) {-->
<!--            if (this.facility_data[i].gtArray[j].id == val.id) {-->
<!--            } else {-->
<!--              new_arr.push(this.facility_data[i].gtArray[j])-->
<!--            }-->
<!--          }-->
<!--          this.facility_data[i].gtArray = new_arr-->
<!--        }-->
<!--      } else {-->
<!--        this.false_arr = []-->
<!--        for (const i in this.bm_data) {-->
<!--          if (!this.bm_data[i].status) {-->
<!--            this.false_arr.push(this.bm_data[i].id)-->
<!--          }-->
<!--        }-->
<!--        this.OnclickAdvancedSchedulingDevice()-->
<!--      }-->
<!--      if (!val.status) {-->
<!--        for (const i in this.bm_data) {-->
<!--          if (!this.bm_data[i].status) {-->
<!--            this.bm_data[i].gtArray = []-->
<!--          }-->
<!--        }-->
<!--      } else {-->
<!--        this.false_arr = []-->
<!--        for (const i in this.bm_data) {-->
<!--          if (!this.bm_data[i].status) {-->
<!--            this.false_arr.push(this.bm_data[i].id)-->
<!--          }-->
<!--        }-->
<!--        this.OnclickAdvancedSchedulingDevice()-->
<!--      }-->
<!--      for (const i in this.bm_data) {-->
<!--        const arr = []-->
<!--        for (const j in this.bm_data[i].gtArray) {-->
<!--          if (this.bm_data[i].gtArray[j].type != 'schedule') {-->
<!--            arr.push(this.bm_data[i].gtArray[j])-->
<!--          }-->
<!--        }-->
<!--        this.bm_data[i].gtArray = arr-->
<!--      }-->
<!--      this.real_num = 0-->
<!--    },-->
<!--    look(data) {-->
<!--      this.showDialog = true-->
<!--      this.search_from.DeviceCode = data.id-->
<!--      this.AdvancedSchedulingEquipmenTask()-->
<!--    },-->
<!--    AdvancedSchedulingEquipmenTask() {-->
<!--      automaticScheduling-->
<!--        .AdvancedSchedulingEquipmenTask(this.search_from)-->
<!--        .then(res => {-->
<!--          this.look_data = res.rows-->
<!--          this.look_total = res.total-->
<!--        })-->
<!--    },-->
<!--    sizeChange_look(val) {-->
<!--      this.search_from.rows = val-->
<!--      this.AdvancedSchedulingEquipmenTask()-->
<!--    },-->
<!--    pageChange_look(val) {-->
<!--      this.search_from.page = val-->
<!--      this.AdvancedSchedulingEquipmenTask()-->
<!--    },-->
<!--    sizeChange(val) {-->
<!--      this.form.rows = val-->
<!--      this.show = false-->
<!--      this.radio = ''-->
<!--      this.AdvancedSchedulingSearch()-->
<!--    },-->
<!--    pageChange(val) {-->
<!--      this.form.page = val-->
<!--      this.show = false-->
<!--      this.radio = ''-->
<!--      this.AdvancedSchedulingSearch()-->
<!--    },-->
<!--    // æŸ¥è¯¢-->
<!--    AdvancedSchedulingSearch() {-->
<!--      automaticScheduling.AdvancedSchedulingSearch(this.form).then(res => {-->
<!--        this.mn_data = res.rows-->
<!--        this.total = res.total-->
<!--        this.oneClick()-->
<!--      })-->
<!--    },-->
<!--    // ç‚¹å‡»å¸¦å‡ºæ•°æ®-->
<!--    OnclickAdvancedSchedulingDevice() {-->
<!--      this.facility_top()-->
<!--      automaticScheduling-->
<!--        .OnclickAdvancedSchedulingDevice(this.forms)-->
<!--        .then(res => {-->
<!--          if (res.rus.message) {-->
<!--            this.$message({-->
<!--              showClose: true,-->
<!--              type: 'error',-->
<!--              message: res.rus.message-->
<!--            })-->
<!--          }-->
<!--          this.submit_flag = false-->
<!--          const list = []-->
<!--          this.time_all = res-->
<!--          const cont = res.Cont-->
<!--          this.real_num = 0-->
<!--          for (const i in this.time_all.rows[0].children) {-->
<!--            const obj = {-->
<!--              id: '',-->
<!--              name: '',-->
<!--              AdvaDevicRhythm: '',-->
<!--              status: true,-->
<!--              colorPair: {-->
<!--                dark: 'rgb(83, 186, 241,0.8)',-->
<!--                light: 'rgb(83, 186, 241,0.1)',-->
<!--                light_capacity: 'rgb(209,239,237,0.8)',-->
<!--                h_schedule: ' rgb(100,255,192,0.8)',-->
<!--                scheduleing: 'rgb(20,182,231,0.8)'-->
<!--              },-->
<!--              gtArray: []-->
<!--            }-->
<!--            obj.id = this.time_all.rows[0].children[i].AdvaDevicNumber-->
<!--            obj.name = this.time_all.rows[0].children[i].AdvaDevicName-->
<!--            obj.AdvaDevicRhythm = this.time_all.rows[0].children[-->
<!--              i-->
<!--            ].AdvaDevicRhythm-->
<!--            list.push(obj)-->
<!--          }-->
<!--          for (const i in this.time_all.rows) {-->
<!--            for (const j in this.time_all.rows[i].children) {-->
<!--              if (this.time_all.rows[i].children[j].OneStartDate != '') {-->
<!--                this.time_all.rows[i].children[-->
<!--                  j-->
<!--                ].OneStartDate = this.time_all.rows[i].children[-->
<!--                  j-->
<!--                ].OneStartDate.split('~')-->
<!--                this.time_all.rows[i].children[j].OneStartDate[0] =-->
<!--                  this.time_all.rows[i].YearDate +-->
<!--                  ' ' +-->
<!--                  this.time_all.rows[i].children[j].OneStartDate[0]-->
<!--                this.time_all.rows[i].children[j].OneStartDate[1] =-->
<!--                  this.time_all.rows[i].YearDate +-->
<!--                  ' ' +-->
<!--                  this.time_all.rows[i].children[j].OneStartDate[1]-->
<!--              }-->
<!--              if (this.time_all.rows[i].children[j].TwoStartDate != '') {-->
<!--                this.time_all.rows[i].children[-->
<!--                  j-->
<!--                ].TwoStartDate = this.time_all.rows[i].children[-->
<!--                  j-->
<!--                ].TwoStartDate.split('~')-->
<!--                this.time_all.rows[i].children[j].TwoStartDate[0] =-->
<!--                  this.time_all.rows[i].YearDate +-->
<!--                  ' ' +-->
<!--                  this.time_all.rows[i].children[j].TwoStartDate[0]-->
<!--                this.time_all.rows[i].children[j].TwoStartDate[1] =-->
<!--                  this.time_all.rows[i].YearDate +-->
<!--                  ' ' +-->
<!--                  this.time_all.rows[i].children[j].TwoStartDate[1]-->
<!--              }-->
<!--              if (this.time_all.rows[i].children[j].ThreeStartDate != '') {-->
<!--                this.time_all.rows[i].children[-->
<!--                  j-->
<!--                ].ThreeStartDate = this.time_all.rows[i].children[-->
<!--                  j-->
<!--                ].ThreeStartDate.split('~')-->
<!--                this.time_all.rows[i].children[j].ThreeStartDate[0] =-->
<!--                  this.time_all.rows[i].YearDate +-->
<!--                  ' ' +-->
<!--                  this.time_all.rows[i].children[j].ThreeStartDate[0]-->
<!--                this.time_all.rows[i].children[j].ThreeStartDate[1] =-->
<!--                  this.time_all.rows[i].YearDate +-->
<!--                  ' ' +-->
<!--                  this.time_all.rows[i].children[j].ThreeStartDate[1]-->
<!--              }-->
<!--              if (this.time_all.rows[i].children[j].FourStartDate != '') {-->
<!--                this.time_all.rows[i].children[-->
<!--                  j-->
<!--                ].FourStartDate = this.time_all.rows[i].children[-->
<!--                  j-->
<!--                ].FourStartDate.split('~')-->
<!--                this.time_all.rows[i].children[j].FourStartDate[0] =-->
<!--                  this.time_all.rows[i].YearDate +-->
<!--                  ' ' +-->
<!--                  this.time_all.rows[i].children[j].FourStartDate[0]-->
<!--                this.time_all.rows[i].children[j].FourStartDate[1] =-->
<!--                  this.time_all.rows[i].YearDate +-->
<!--                  ' ' +-->
<!--                  this.time_all.rows[i].children[j].FourStartDate[1]-->
<!--              }-->
<!--              if (this.time_all.rows[i].children[j].FiveStartDate != '') {-->
<!--                this.time_all.rows[i].children[-->
<!--                  j-->
<!--                ].FiveStartDate = this.time_all.rows[i].children[-->
<!--                  j-->
<!--                ].FiveStartDate.split('~')-->
<!--                this.time_all.rows[i].children[j].FiveStartDate[0] =-->
<!--                  this.time_all.rows[i].YearDate +-->
<!--                  ' ' +-->
<!--                  this.time_all.rows[i].children[j].FiveStartDate[0]-->
<!--                this.time_all.rows[i].children[j].FiveStartDate[1] =-->
<!--                  this.time_all.rows[i].YearDate +-->
<!--                  ' ' +-->
<!--                  this.time_all.rows[i].children[j].FiveStartDate[1]-->
<!--              }-->
<!--            }-->
<!--          }-->
<!--          // ç»„合新的结构-->
<!--          const newList = []-->
<!--          for (const i in this.time_all.rows) {-->
<!--            for (const j in this.time_all.rows[i].children) {-->
<!--              if (this.time_all.rows[i].children[j].OneStartDate != '') {-->
<!--                const data1 = {-->
<!--                  id: '',-->
<!--                  start: '',-->
<!--                  end: '',-->
<!--                  mod: ''-->
<!--                }-->
<!--                data1.id = this.time_all.rows[i].children[j].AdvaDevicNumber-->
<!--                data1.start = this.time_all.rows[i].children[j].OneStartDate[0]-->
<!--                data1.end = this.time_all.rows[i].children[j].OneStartDate[1]-->
<!--                data1.mod =-->
<!--                  (this.time_all.rows[i].children[j].AdvaDevicCropMob * 1) /-->
<!--                  100-->
<!--                newList.push(data1)-->
<!--              }-->
<!--              if (this.time_all.rows[i].children[j].TwoStartDate != '') {-->
<!--                const data2 = {-->
<!--                  id: '',-->
<!--                  start: '',-->
<!--                  end: '',-->
<!--                  mod: ''-->
<!--                }-->
<!--                data2.id = this.time_all.rows[i].children[j].AdvaDevicNumber-->
<!--                data2.start = this.time_all.rows[i].children[j].TwoStartDate[0]-->
<!--                data2.end = this.time_all.rows[i].children[j].TwoStartDate[1]-->
<!--                data2.mod =-->
<!--                  (this.time_all.rows[i].children[j].AdvaDevicCropMob * 1) /-->
<!--                  100-->
<!--                newList.push(data2)-->
<!--              }-->
<!--              if (this.time_all.rows[i].children[j].ThreeStartDate != '') {-->
<!--                const data3 = {-->
<!--                  id: '',-->
<!--                  start: '',-->
<!--                  end: '',-->
<!--                  mod: ''-->
<!--                }-->
<!--                data3.id = this.time_all.rows[i].children[j].AdvaDevicNumber-->
<!--                data3.start = this.time_all.rows[i].children[-->
<!--                  j-->
<!--                ].ThreeStartDate[0]-->
<!--                data3.end = this.time_all.rows[i].children[j].ThreeStartDate[1]-->
<!--                data3.mod =-->
<!--                  (this.time_all.rows[i].children[j].AdvaDevicCropMob * 1) /-->
<!--                  100-->
<!--                newList.push(data3)-->
<!--              }-->
<!--              if (this.time_all.rows[i].children[j].FourStartDate != '') {-->
<!--                const data4 = {-->
<!--                  id: '',-->
<!--                  start: '',-->
<!--                  end: '',-->
<!--                  mod: ''-->
<!--                }-->
<!--                data4.id = this.time_all.rows[i].children[j].AdvaDevicNumber-->
<!--                data4.start = this.time_all.rows[i].children[-->
<!--                  j-->
<!--                ].FourStartDate[0]-->
<!--                data4.end = this.time_all.rows[i].children[j].FourStartDate[1]-->
<!--                data4.mod =-->
<!--                  (this.time_all.rows[i].children[j].AdvaDevicCropMob * 1) /-->
<!--                  100-->
<!--                newList.push(data4)-->
<!--              }-->
<!--              if (this.time_all.rows[i].children[j].FiveStartDate != '') {-->
<!--                const data5 = {-->
<!--                  id: '',-->
<!--                  start: '',-->
<!--                  end: '',-->
<!--                  mod: ''-->
<!--                }-->
<!--                data5.id = this.time_all.rows[i].children[j].AdvaDevicNumber-->
<!--                data5.start = this.time_all.rows[i].children[-->
<!--                  j-->
<!--                ].FiveStartDate[0]-->
<!--                data5.end = this.time_all.rows[i].children[j].FiveStartDate[1]-->
<!--                data5.mod =-->
<!--                  (this.time_all.rows[i].children[j].AdvaDevicCropMob * 1) /-->
<!--                  100-->
<!--                newList.push(data5)-->
<!--              }-->
<!--            }-->
<!--          }-->
<!--          for (const i in list) {-->
<!--            this.pushTiem(newList, list[i].id, list[i].gtArray)-->
<!--          }-->
<!--          this.bm_data = list-->
<!--          const _this = this-->
<!--          if (cont != '') {-->
<!--            for (const i in cont) {-->
<!--              for (const j in this.bm_data) {-->
<!--                if (this.bm_data[j].id == cont[i].EQP_CODE) {-->
<!--                  const data = {-->
<!--                    id: cont[i].EQP_CODE,-->
<!--                    number: cont[i].ALLOC_QTY,-->
<!--                    cl_name: cont[i].PART_NAME,-->
<!--                    cl_code: this.cl_code,-->
<!--                    work_order: cont[i].WO_CODE,-->
<!--                    STATUS: _this.AdvaScheUom,-->
<!--                    start: cont[i].TIME_START,-->
<!--                    end: cont[i].TIME_END,-->
<!--                    type: cont[i].STATUS == 'S' ? 'h_schedule' : 'bm_schedule'-->
<!--                  }-->
<!--                  this.bm_data[j].flag = 'isCont'-->
<!--                  this.bm_data[j].gtArray.unshift(data)-->
<!--                }-->
<!--              }-->
<!--            }-->
<!--          }-->
<!--          if (this.false_arr != '') {-->
<!--            for (const j in this.bm_data) {-->
<!--              if (this.false_arr.indexOf(this.bm_data[j].id) >= 0) {-->
<!--                this.bm_data[j].gtArray = []-->
<!--                this.bm_data[j].status = false-->
<!--              }-->
<!--            }-->
<!--          }-->
<!--        })-->
<!--    },-->
<!--    // æ¢åž‹æ—¶é—´-->
<!--    MinutesTest(time) {-->
<!--      var sdate1 = new Date(time)-->
<!--      sdate1.setMinutes(sdate1.getMinutes() + this.times * 1)-->
<!--      var now =-->
<!--        sdate1.getFullYear() +-->
<!--        '-' +-->
<!--        this.add_one(sdate1.getMonth()) +-->
<!--        '-' +-->
<!--        sdate1.getDate() +-->
<!--        ' ' +-->
<!--        sdate1.getHours() +-->
<!--        ':' +-->
<!--        sdate1.getMinutes() +-->
<!--        ':' +-->
<!--        sdate1.getSeconds()-->
<!--      return now-->
<!--    },-->
<!--    // +1-->
<!--    add_one(date) {-->
<!--      return parseInt(date) + 1-->
<!--    },-->
<!--    // æ’入产能时间段-->
<!--    pushTiem(newList, id, arr) {-->
<!--      for (const i in newList) {-->
<!--        if (newList[i].id == id) {-->
<!--          const data = {-->
<!--            start: newList[i].start,-->
<!--            end: newList[i].end,-->
<!--            id: newList[i].id,-->
<!--            mod: newList[i].mod,-->
<!--            type: 'capacity'-->
<!--          }-->
<!--          arr.push(data)-->
<!--        }-->
<!--      }-->
<!--    },-->
<!--    getNowFormatDate() {-->
<!--      var date = new Date()-->
<!--      var seperator1 = '-'-->
<!--      var year = date.getFullYear()-->
<!--      var month = date.getMonth() + 1-->
<!--      // var strDate = date.getDate()+1;-->
<!--      var strDate = date.getDate()-->
<!--      if (month >= 1 && month <= 9) {-->
<!--        month = '0' + month-->
<!--      }-->
<!--      if (strDate >= 0 && strDate <= 9) {-->
<!--        strDate = '0' + strDate-->
<!--      }-->
<!--      var currentdate = year + seperator1 + month + seperator1 + strDate-->
<!--      return currentdate-->
<!--    },-->
<!--    getCurrentRow(row) {-->
<!--      // this.show =true-->
<!--      this.meter = row.AdvaScheQty * 1 - row.AdvaScheYPQty * 1 // å¯ä»¥åšä¸ªæ•°-->
<!--      this.value1 = []-->
<!--      this.cl_name = row.AdvaSchePartName-->
<!--      this.cl_code = row.AdvaSchePartNumber-->
<!--      this.AdvaScheUom = row.AdvaScheUom-->
<!--      this.work_order = row.AdvaScheWorkCode-->
<!--      this.value1.push(this.getNowFormatDate())-->
<!--      this.value1.push(row.AdvaScheEndDate)-->
<!--      if (this.value1 != '') {-->
<!--        this.time_data[0] = this.value1[0] + ' 00:00'-->
<!--        this.time_data[1] = this.value1[1] + ' 23:59'-->
<!--      }-->
<!--      this.forms.WorkCode = row.AdvaScheWorkCode-->
<!--      this.forms.WorkShop = row.AdvaScheWorkShopid-->
<!--      this.forms.PartNumber = row.AdvaSchePartNumber-->
<!--      this.forms.BotProceCode = row.AdvaScheBotProcid-->
<!--      this.forms.StartTime = this.getNowFormatDate()-->
<!--      this.forms.EndTime = row.AdvaScheEndDate-->
<!--      this.OnclickAdvancedSchedulingDevice()-->
<!--      this.formUpdata.WorkCode = row.AdvaScheWorkCode-->
<!--      this.formUpdata.BotProceCode = row.AdvaScheBotProcid-->
<!--      this.search_from.WorkTime =-->
<!--        this.getNowFormatDate() + '~' + row.AdvaScheEndDate-->
<!--      this.search_from.BotProceName = row.AdvaScheBotProcName-->
<!--    },-->
<!--    // æäº¤æŽ’程-->
<!--    click_yes() {-->
<!--      if (this.submit_flag) {-->
<!--        this.$message({-->
<!--          showClose: true,-->
<!--          type: 'error',-->
<!--          message: '数量未排完,请设置产能时间'-->
<!--        })-->
<!--      } else {-->
<!--        const list = [] // æäº¤æ•°ç»„-->
<!--        for (const i in this.bm_data) {-->
<!--          const arr = []-->
<!--          for (const j in this.bm_data[i].gtArray) {-->
<!--            if (this.bm_data[i].gtArray[j].type == 'schedule') {-->
<!--              arr.push(this.bm_data[i].gtArray[j])-->
<!--            }-->
<!--          }-->
<!--          if (arr != '') {-->
<!--            for (const i in arr) {-->
<!--              const data = {-->
<!--                AlreDevicNumber: '',-->
<!--                AlreStartDate: '',-->
<!--                AlreEndDate: '',-->
<!--                AlreQty: ''-->
<!--              }-->
<!--              data.AlreDevicNumber = arr[i].id-->
<!--              data.AlreStartDate = arr[i].start-->
<!--              data.AlreEndDate = arr[i].end-->
<!--              data.AlreQty = arr[i].number-->
<!--              list.push(data)-->
<!--            }-->
<!--          }-->
<!--        }-->
<!--        // æŽ’程相同设备获取开始时间 ç»“束时间 æ•°é‡çš„æ€»å’Œ-->
<!--        // è¿‡æ»¤-->
<!--        let updata = []-->
<!--        for (const i in list) {-->
<!--          if (list[i].AlreStartDate != '') {-->
<!--            updata.push(list[i])-->
<!--          }-->
<!--        }-->
<!--        updata = JSON.stringify(updata)-->
<!--        this.formUpdata.json = updata-->
<!--        if (list == '') {-->
<!--          this.$message({-->
<!--            showClose: true,-->
<!--            message: '请先预排',-->
<!--            type: 'error'-->
<!--          })-->
<!--          return false-->
<!--        }-->
<!--        automaticScheduling-->
<!--          .SubmitAlreadyScheduling(this.formUpdata)-->
<!--          .then(res => {-->
<!--            if (res.statusCode == 300) {-->
<!--              this.$message({-->
<!--                showClose: true,-->
<!--                message: res.message,-->
<!--                type: 'error'-->
<!--              })-->
<!--            } else {-->
<!--              this.$message({-->
<!--                showClose: true,-->
<!--                message: res.message,-->
<!--                type: 'success'-->
<!--              })-->
<!--            }-->
<!--            this.meter = 0-->
<!--            this.real_num = 0-->
<!--            this.OnclickAdvancedSchedulingDevice()-->
<!--            this.AdvancedSchedulingSearch()-->
<!--          })-->
<!--      }-->
<!--    },-->
<!--    // æ—¶é—´/设备优先排程-->
<!--    click_schedule() {-->
<!--      const timestamp = new Date().toLocaleDateString()-->
<!--      if (new Date(this.value1[0]) < new Date(timestamp)) {-->
<!--        this.$message({-->
<!--          showClose: true,-->
<!--          type: 'error',-->
<!--          message: '排程时间不可以小于当前时间'-->
<!--        })-->
<!--        return false-->
<!--      }-->
<!--      this.nitialize()-->
<!--      // è®¾å¤‡ä¼˜å…ˆ-->
<!--      if (this.bm_data != '' && this.types == 'N') {-->
<!--        this.fun_time()-->
<!--        this.change_num(this.bm_data)-->
<!--      } else if (this.facility_data != '' && this.types == 'Y') {-->
<!--        this.time_nitalize()-->
<!--        this.fun_facility()-->
<!--        this.dataTransition()-->
<!--        this.change_num(this.bm_data)-->
<!--      }-->
<!--    },-->
<!--    // æ‰‹åŠ¨è¿‡æ»¤æ‰€æœ‰æ—¶é—´å·²æŽ’ç¨‹-->
<!--    time_nitalize() {-->
<!--      for (const i in this.facility_data) {-->
<!--        this.facility_data[i].gtArray = this.facility_data[i].gtArray.filter(item => item.type != 'schedule')-->
<!--      }-->
<!--    },-->
<!--    // æ‰‹åŠ¨è¿‡æ»¤æ‰€æœ‰è®¾å¤‡å·²æŽ’ç¨‹-->
<!--    nitialize() {-->
<!--      for (const i in this.bm_data) {-->
<!--        const newArr = []-->
<!--        for (const j in this.bm_data[i].gtArray) {-->
<!--          if (this.bm_data[i].gtArray[j].type != 'schedule') {-->
<!--            newArr.push(this.bm_data[i].gtArray[j])-->
<!--          }-->
<!--        }-->
<!--        this.bm_data[i].gtArray = newArr-->
<!--      }-->
<!--    },-->
<!--    // ç»™æŽ’程最后一个修改数量-->
<!--    change_num(arr) {-->
<!--      this.real_num = 0 // çœŸå®žå·²æŽ’数量-->
<!--      let num = 0 // å–整已排数量-->
<!--      const arr_num = [] // å·²æŽ’数据-->
<!--      let mend_num = 0-->
<!--      const len = 0-->
<!--      for (const i in arr) {-->
<!--        for (const j in arr[i].gtArray) {-->
<!--          if (arr[i].gtArray[j].type == 'schedule') {-->
<!--            arr_num.unshift(arr[i].gtArray[j])-->
<!--          }-->
<!--        }-->
<!--      }-->
<!--      for (const n in arr_num) {-->
<!--        this.real_num += arr_num[n].real_number-->
<!--        num += arr_num[n].number * 1-->
<!--      }-->
<!--      this.real_num = Math.ceil(this.real_num)-->
<!--      const y10 = this.meter - this.real_num-->
<!--      if (y10 <= 10) {-->
<!--        this.real_num = this.meter-->
<!--        mend_num = this.meter - num-->
<!--      } else {-->
<!--      }-->
<!--      if (this.real_num * 1 == this.meter * 1) {-->
<!--        // mend_num =  this.meter - num-->
<!--      } else {-->
<!--        this.submit_flag = true-->
<!--      }-->
<!--      for (const i in this.bm_data) {-->
<!--        for (const j in this.bm_data[i].gtArray) {-->
<!--          if (-->
<!--            this.bm_data[i].gtArray[j].type == 'schedule' &&-->
<!--            this.bm_data[i].gtArray[j].end_num-->
<!--          ) {-->
<!--            this.bm_data[i].gtArray[j].number =-->
<!--              this.bm_data[i].gtArray[j].number * 1 + mend_num-->
<!--          }-->
<!--        }-->
<!--      }-->
<!--    },-->
<!--    fun_time() {-->
<!--      let all_num = this.meter-->
<!--      const all_time = []-->
<!--      let flag1 = 0-->
<!--      const mod = this.bm_data[0].mod-->
<!--      //  let nowTime = this.bm_data[0].AdvaDevicRhythm*all_num-->
<!--      for (const i in this.bm_data) {-->
<!--        let end_arr = [] // å·²æŽ’程的数组-->
<!--        let nend_arr = [] // å¾…排程的数组-->
<!--        const add_arr = [] // å·²æŽ’程的数组-->
<!--        let capacity_arr = [] // è¦æŽ’程的数组-->
<!--        this.bm_data[i].gtArray.sort((a, b) => new Date(a.end).getTime() - new Date(b.end).getTime())-->
<!--        // let capacity_end = ''-->
<!--        end_arr = this.bm_data[i].gtArray.filter(item => item.type == 'h_schedule')-->
<!--        nend_arr = this.bm_data[i].gtArray.filter(item => item.type == 'capacity')-->
<!--        if (end_arr && end_arr.length > 0) {-->
<!--          capacity_arr = nend_arr.map(item => {-->
<!--            // æŽ’除掉已经排程的存在hshedule,start,end都相等的情况-->
<!--            const schedule = end_arr.filter(schedule => {-->
<!--              return new Date(item.start).getTime() <= new Date(schedule.start).getTime() &&-->
<!--                new Date(item.end).getTime() > new Date(schedule.end).getTime()-->
<!--            })-->
<!--            if (schedule && schedule.length > 0) {-->
<!--              item.start = this.MinutesTest(schedule[0]['end'])-->
<!--            }-->
<!--            const schedule1 = end_arr.filter(schedule => {-->
<!--              return new Date(item.start).getTime() == new Date(schedule.start).getTime() &&-->
<!--                new Date(item.end).getTime() == new Date(schedule.end).getTime()-->
<!--            })-->
<!--            if (schedule1 && schedule1.length > 0) {-->
<!--              item.capacity = false-->
<!--            }-->
<!--            return item-->
<!--          }).filter(item => item.capacity != false)-->
<!--        } else {-->
<!--          capacity_arr = nend_arr-->
<!--        }-->
<!--        const id_obj = {-->
<!--          id: '',-->
<!--          start_time: ''-->
<!--        }-->
<!--        if (end_arr != '') {-->
<!--          (id_obj.id = end_arr[0].id), (id_obj.start_time = end_arr[0].end)-->
<!--        }-->
<!--        for (const w in capacity_arr) {-->
<!--          let end_time = ''-->
<!--          let mistiming = ''-->
<!--          const data = {-->
<!--            id: capacity_arr[w].id,-->
<!--            start: '',-->
<!--            end: '',-->
<!--            type: 'schedule',-->
<!--            cl_name: this.cl_name,-->
<!--            cl_code: this.cl_code,-->
<!--            work_order: this.work_order,-->
<!--            number: 0,-->
<!--            real_number: 0-->
<!--          }-->
<!--          if (-->
<!--            id_obj.start_time != '' &&-->
<!--            flag1 == 0 &&-->
<!--            new Date(id_obj.start_time) >= new Date(capacity_arr[w].start)-->
<!--          ) {-->
<!--            data.start = this.MinutesTest(id_obj.start_time)-->
<!--            flag1 = 1-->
<!--          } else {-->
<!--            data.start = capacity_arr[w].start-->
<!--          }-->
<!--          let nowTime =-->
<!--            (this.bm_data[i].AdvaDevicRhythm * all_num) / capacity_arr[w].mod-->
<!--          end_time = this.formSeconds(nowTime, data.start, capacity_arr[w].mod) // æ€»å…±çš„结束时间-->
<!--          data.end = end_time-->
<!--          mistiming = this.formTime(-->
<!--            end_time,-->
<!--            capacity_arr[w].end,-->
<!--            capacity_arr[w].mod-->
<!--          ) // æ€»å…±çš„结束时间-当前的结束时间 = å‰©ä¸‹å¤šä¹…æ—¶é—´-->
<!--          if (mistiming >= 0) {-->
<!--            console.log(-->
<!--              new Date(data.end) - new Date(data.start),-->
<!--              capacity_arr[w].mod,-->
<!--              this.bm_data[i].AdvaDevicRhythm,-->
<!--              '阿斯顿发斯蒂芬'-->
<!--            )-->
<!--            data.number =-->
<!--              ((new Date(data.end) - new Date(data.start)) *-->
<!--                capacity_arr[w].mod) /-->
<!--              this.bm_data[i].AdvaDevicRhythm /-->
<!--              1000-->
<!--            data.real_number =-->
<!--              ((new Date(data.end) - new Date(data.start)) *-->
<!--                capacity_arr[w].mod) /-->
<!--              this.bm_data[i].AdvaDevicRhythm /-->
<!--              1000-->
<!--            data.number = data.number.toFixed(0)-->
<!--            data.end_num = true-->
<!--            if (new Date(data.start) >= new Date(data.end)) {-->
<!--            } else {-->
<!--              this.bm_data[i].gtArray.push(data)-->
<!--            }-->
<!--            return false-->
<!--          } else {-->
<!--            data.end = capacity_arr[w].end-->
<!--            data.number =-->
<!--              ((new Date(data.end) - new Date(data.start)) *-->
<!--                capacity_arr[w].mod) /-->
<!--              this.bm_data[i].AdvaDevicRhythm /-->
<!--              1000-->
<!--            data.real_number =-->
<!--              ((new Date(data.end) - new Date(data.start)) *-->
<!--                capacity_arr[w].mod) /-->
<!--              this.bm_data[i].AdvaDevicRhythm /-->
<!--              1000-->
<!--            data.number = data.number.toFixed(0)-->
<!--            nowTime =-->
<!--              (all_num - data.real_number) * this.bm_data[i].AdvaDevicRhythm-->
<!--            all_num = all_num - data.real_number-->
<!--            if (new Date(data.start) >= new Date(data.end)) {-->
<!--            } else {-->
<!--              this.bm_data[i].gtArray.push(data)-->
<!--            }-->
<!--          }-->
<!--        }-->
<!--      }-->
<!--    },-->
<!--    // è®¾å¤‡æŽ’程方法-->
<!--    fun_facility() {-->
<!--      // æŽ’除未勾选项-->
<!--      for (const i in this.facility_data) {-->
<!--        const newArr = []-->
<!--        for (const j in this.facility_data[i].gtArray) {-->
<!--          if (this.false_arr.indexOf(this.facility_data[i].gtArray[j].id) < 0) {-->
<!--            newArr.push(this.facility_data[i].gtArray[j])-->
<!--          }-->
<!--        }-->
<!--        this.facility_data[i].gtArray = newArr-->
<!--      }-->
<!--      let all_num = this.meter-->
<!--      const all_time = []-->
<!--      const flag1 = 0-->
<!--      // let nowTime = this.facility_data[0].AdvaDevicRhythm*all_num  //数量OK-->
<!--      for (const i in this.facility_data) {-->
<!--        let end_arr = []-->
<!--        let nend_arr = [] // æŽ’程的数组-->
<!--        const add_arr = [] // å·²æŽ’程的数组-->
<!--        let capacity_arr = [] // è¦æŽ’程的数组-->
<!--        // this.facility_data[i].gtArray.sort((a,b) => new Date(a.end).getTime() - new Date(b.end).getTime())-->
<!--        // let capacity_end = ''-->
<!--        end_arr = this.facility_data[i].gtArray.filter(item => item.type == 'h_schedule')-->
<!--        nend_arr = this.facility_data[i].gtArray.filter(item => item.type == 'capacity')-->
<!--        console.log(nend_arr)-->
<!--        capacity_arr = JSON.parse(JSON.stringify(nend_arr))-->
<!--        end_arr.forEach(item => {-->
<!--          for (let i = 0; i < capacity_arr.length; i++) {-->
<!--            if (new Date(capacity_arr[i].start).getTime() === new Date(item.start).getTime()) {-->
<!--              console.log(i, capacity_arr[i], '哇哈哈')-->
<!--              capacity_arr.splice(i, 1)-->
<!--              break-->
<!--            }-->
<!--          }-->
<!--        })-->
<!--        console.log(capacity_arr, '大西瓜')-->
<!--        if (!capacity_arr || capacity_arr.length == 0) break-->
<!--        // const firstCapacity = capacity_arr[0]-->
<!--        const schedule_arr = end_arr.filter(item => {-->
<!--          const remain = nend_arr.some(sitem => {-->
<!--            return new Date(sitem.start).getTime() === new Date(item.start).getTime() &&-->
<!--              new Date(item.end).getTime() < new Date(sitem.end).getTime()-->
<!--          })-->
<!--          return remain-->
<!--        })-->
<!--        console.log(schedule_arr)-->
<!--        if (schedule_arr && schedule_arr.length > 0) {-->
<!--          const scheduleCan = schedule_arr.map(item => {-->
<!--            const capcity = nend_arr.filter(sitem => {-->
<!--              return new Date(sitem.start).getTime() === new Date(item.start).getTime() &&-->
<!--                new Date(item.end).getTime() < new Date(sitem.end).getTime()-->
<!--            })[0]-->
<!--            console.log('capacity', capcity)-->
<!--            capcity.start = this.MinutesTest(item.end)-->
<!--            return capcity-->
<!--          })-->
<!--          const newSchedule = JSON.parse(JSON.stringify(scheduleCan))-->
<!--          capacity_arr = newSchedule.concat(capacity_arr)-->
<!--        }-->
<!--        console.log(schedule_arr)-->
<!--        console.log('可排程数组', capacity_arr)-->
<!--        const id_obj = {}-->
<!--        if (end_arr != '') {-->
<!--          (id_obj.id = end_arr[0].id), (id_obj.start_time = end_arr[0].end)-->
<!--        }-->
<!--        for (const w in capacity_arr) {-->
<!--          let end_time-->
<!--          let mistiming-->
<!--          const data = {-->
<!--            id: capacity_arr[w].id,-->
<!--            start: '',-->
<!--            end: '',-->
<!--            type: 'schedule',-->
<!--            cl_name: this.cl_name,-->
<!--            cl_code: this.cl_code,-->
<!--            work_order: this.work_order,-->
<!--            number: 0,-->
<!--            real_number: 0-->
<!--          }-->
<!--          //  console.log(id_obj.start_time)-->
<!--          if (-->
<!--            id_obj &&-->
<!--            new Date(id_obj.start_time).getTime() >=-->
<!--            new Date(capacity_arr[w].start).getTime()-->
<!--          ) {-->
<!--            if (data.id == id_obj.id) {-->
<!--              data.start = this.MinutesTest(id_obj.start_time)-->
<!--              //  flag1 =1-->
<!--            } else {-->
<!--              data.start = capacity_arr[w].start-->
<!--              //  console.log(data.start)-->
<!--              //  flag1 =1-->
<!--            }-->
<!--          } else {-->
<!--            data.start = capacity_arr[w].start-->
<!--          }-->
<!--          // let nowTime = this.facility_data[0].AdvaDevicRhythm*all_num-->
<!--          let nowTime =-->
<!--            (capacity_arr[w].rhythm * all_num) / capacity_arr[w].mod-->
<!--          end_time = this.formSeconds(nowTime, data.start)-->
<!--          data.end = end_time-->
<!--          mistiming = this.formTime(end_time, capacity_arr[w].end)-->
<!--          if (mistiming >= 0) {-->
<!--            data.number =-->
<!--              ((new Date(data.end) - new Date(data.start)) *-->
<!--                capacity_arr[w].mod) /-->
<!--              capacity_arr[w].rhythm /-->
<!--              1000-->
<!--            data.real_number =-->
<!--              ((new Date(data.end) - new Date(data.start)) *-->
<!--                capacity_arr[w].mod) /-->
<!--              capacity_arr[w].rhythm /-->
<!--              1000-->
<!--            data.number = data.number.toFixed(0)-->
<!--            data.end_num = true-->
<!--            if (new Date(data.start) >= new Date(data.end)) {-->
<!--            } else {-->
<!--              this.facility_data[i].gtArray.push(data)-->
<!--            }-->
<!--            return false-->
<!--          } else {-->
<!--            data.end = capacity_arr[w].end-->
<!--            data.number =-->
<!--              ((new Date(data.end) - new Date(data.start)) *-->
<!--                capacity_arr[w].mod) /-->
<!--              capacity_arr[w].rhythm /-->
<!--              1000-->
<!--            data.real_number =-->
<!--              ((new Date(data.end) - new Date(data.start)) *-->
<!--                capacity_arr[w].mod) /-->
<!--              capacity_arr[w].rhythm /-->
<!--              1000-->
<!--            data.number = data.number.toFixed(0)-->
<!--            nowTime = (all_num - data.real_number) * capacity_arr[w].rhythm-->
<!--            all_num = all_num - data.real_number-->
<!--            //  nowTime = mistiming * -1-->
<!--            if (new Date(data.start) >= new Date(data.end)) {-->
<!--            } else {-->
<!--              this.facility_data[i].gtArray.push(data)-->
<!--            }-->
<!--          }-->
<!--        }-->
<!--      }-->
<!--    },-->
<!--    // ç»™è®¾å¤‡è½¬æ¢æ ¼å¼-->
<!--    dataTransition() {-->
<!--      this.bm_data = []-->
<!--      const data = this.facility_data-->
<!--      const all = []-->
<!--      const list = this.title_list-->
<!--      for (const i in data) {-->
<!--        for (const j in data[i].gtArray) {-->
<!--          all.push(data[i].gtArray[j])-->
<!--        }-->
<!--      }-->
<!--      for (const i in list) {-->
<!--        list[i].gtArray = []-->
<!--        this.pushTiemsss(all, list[i].id, list[i].gtArray)-->
<!--      }-->
<!--      for (const n in list) {-->
<!--        if (list[n].gtArray.length == 0) {-->
<!--          list[n].status = false-->
<!--        }-->
<!--      }-->
<!--      // console.log(list)-->
<!--      this.bm_data = list-->
<!--    },-->
<!--    // æ’入产能时间段-->
<!--    pushTiemsss(newList, id, arr) {-->
<!--      for (const i in newList) {-->
<!--        if (newList[i].id == id) {-->
<!--          arr.push(newList[i])-->
<!--        }-->
<!--      }-->
<!--    },-->
<!--    // è®¾å¤‡ä¼˜å…ˆ-->
<!--    facility_top() {-->
<!--      automaticScheduling-->
<!--        .OnclickAdvancedSchedulingDevice(this.forms)-->
<!--        .then(res => {-->
<!--          this.show = true-->
<!--          const data = res.rows-->
<!--          const cont = res.Cont-->
<!--          this.title_list = []-->
<!--          for (const i in data[0].children) {-->
<!--            const obj = {-->
<!--              id: '',-->
<!--              name: '',-->
<!--              status: true,-->
<!--              AdvaDevicRhythm: '',-->
<!--              // mod:'',-->
<!--              colorPair: {-->
<!--                dark: 'rgb(83, 186, 241,0.8)',-->
<!--                light: 'rgb(83, 186, 241,0.1)',-->
<!--                light_capacity: 'rgb(209,239,237,0.8)',-->
<!--                h_schedule: ' rgb(100,255,192,0.8)',-->
<!--                scheduleing: 'rgb(20,182,231,0.8)'-->
<!--              },-->
<!--              gtArray: []-->
<!--            }-->
<!--            obj.id = data[0].children[i].AdvaDevicNumber-->
<!--            obj.name = data[0].children[i].AdvaDevicName-->
<!--            obj.AdvaDevicRhythm = data[0].children[i].AdvaDevicRhythm-->
<!--            // obj.mod =data[0].children[i].AdvaDevicCropMob *1-->
<!--            this.title_list.push(obj)-->
<!--          }-->
<!--          for (const i in data) {-->
<!--            for (const j in data[i].children) {-->
<!--              if (data[i].children[j].OneStartDate != '') {-->
<!--                data[i].children[j].OneStartDate = data[i].children[-->
<!--                  j-->
<!--                ].OneStartDate.split('~')-->
<!--                data[i].children[j].OneStartDate[0] =-->
<!--                  data[i].YearDate + ' ' + data[i].children[j].OneStartDate[0]-->
<!--                data[i].children[j].OneStartDate[1] =-->
<!--                  data[i].YearDate + ' ' + data[i].children[j].OneStartDate[1]-->
<!--              }-->
<!--              if (data[i].children[j].TwoStartDate != '') {-->
<!--                data[i].children[j].TwoStartDate = data[i].children[-->
<!--                  j-->
<!--                ].TwoStartDate.split('~')-->
<!--                data[i].children[j].TwoStartDate[0] =-->
<!--                  data[i].YearDate + ' ' + data[i].children[j].TwoStartDate[0]-->
<!--                data[i].children[j].TwoStartDate[1] =-->
<!--                  data[i].YearDate + ' ' + data[i].children[j].TwoStartDate[1]-->
<!--              }-->
<!--              if (data[i].children[j].ThreeStartDate != '') {-->
<!--                data[i].children[j].ThreeStartDate = data[i].children[-->
<!--                  j-->
<!--                ].ThreeStartDate.split('~')-->
<!--                data[i].children[j].ThreeStartDate[0] =-->
<!--                  data[i].YearDate +-->
<!--                  ' ' +-->
<!--                  data[i].children[j].ThreeStartDate[0]-->
<!--                data[i].children[j].ThreeStartDate[1] =-->
<!--                  data[i].YearDate +-->
<!--                  ' ' +-->
<!--                  data[i].children[j].ThreeStartDate[1]-->
<!--              }-->
<!--              if (data[i].children[j].FourStartDate != '') {-->
<!--                data[i].children[j].FourStartDate = data[i].children[-->
<!--                  j-->
<!--                ].FourStartDate.split('~')-->
<!--                data[i].children[j].FourStartDate[0] =-->
<!--                  data[i].YearDate + ' ' + data[i].children[j].FourStartDate[0]-->
<!--                data[i].children[j].FourStartDate[1] =-->
<!--                  data[i].YearDate + ' ' + data[i].children[j].FourStartDate[1]-->
<!--              }-->
<!--              if (data[i].children[j].FiveStartDate != '') {-->
<!--                data[i].children[j].FiveStartDate = data[i].children[-->
<!--                  j-->
<!--                ].FiveStartDate.split('~')-->
<!--                data[i].children[j].FiveStartDate[0] =-->
<!--                  data[i].YearDate + ' ' + data[i].children[j].FiveStartDate[0]-->
<!--                data[i].children[j].FiveStartDate[1] =-->
<!--                  data[i].YearDate + ' ' + data[i].children[j].FiveStartDate[1]-->
<!--              }-->
<!--            }-->
<!--          }-->
<!--          // æ›´æ”¹æ ¼å¼-->
<!--          this.facility_data = []-->
<!--          for (const i in data) {-->
<!--            const time = {-->
<!--              date: data[i].YearDate,-->
<!--              AdvaDevicRhythm: '',-->
<!--              gtArray: []-->
<!--            }-->
<!--            if (data[i].children != '') {-->
<!--              time.AdvaDevicRhythm = data[i].children[0].AdvaDevicRhythm-->
<!--            }-->
<!--            for (const j in data[i].children) {-->
<!--              if (data[i].children[j].OneStartDate != '') {-->
<!--                const icu1 = {-->
<!--                  name: data[i].children[j].AdvaDevicName,-->
<!--                  id: data[i].children[j].AdvaDevicNumber,-->
<!--                  type: 'capacity',-->
<!--                  rhythm: data[i].children[j].AdvaDevicRhythm,-->
<!--                  start: data[i].children[j].OneStartDate[0],-->
<!--                  end: data[i].children[j].OneStartDate[1],-->
<!--                  mod: (data[i].children[j].AdvaDevicCropMob * 1) / 100-->
<!--                }-->
<!--                time.gtArray.push(icu1)-->
<!--              }-->
<!--              if (data[i].children[j].TwoStartDate != '') {-->
<!--                const icu2 = {-->
<!--                  name: data[i].children[j].AdvaDevicName,-->
<!--                  id: data[i].children[j].AdvaDevicNumber,-->
<!--                  type: 'capacity',-->
<!--                  rhythm: data[i].children[j].AdvaDevicRhythm,-->
<!--                  start: data[i].children[j].TwoStartDate[0],-->
<!--                  end: data[i].children[j].TwoStartDate[1],-->
<!--                  mod: (data[i].children[j].AdvaDevicCropMob * 1) / 100-->
<!--                }-->
<!--                time.gtArray.push(icu2)-->
<!--              }-->
<!--              if (data[i].children[j].ThreeStartDate != '') {-->
<!--                const icu3 = {-->
<!--                  name: data[i].children[j].AdvaDevicName,-->
<!--                  id: data[i].children[j].AdvaDevicNumber,-->
<!--                  type: 'capacity',-->
<!--                  rhythm: data[i].children[j].AdvaDevicRhythm,-->
<!--                  start: data[i].children[j].ThreeStartDate[0],-->
<!--                  end: data[i].children[j].ThreeStartDate[1],-->
<!--                  mod: (data[i].children[j].AdvaDevicCropMob * 1) / 100-->
<!--                }-->
<!--                time.gtArray.push(icu3)-->
<!--              }-->
<!--              if (data[i].children[j].FourStartDate != '') {-->
<!--                const icu4 = {-->
<!--                  name: data[i].children[j].AdvaDevicName,-->
<!--                  id: data[i].children[j].AdvaDevicNumber,-->
<!--                  type: 'capacity',-->
<!--                  rhythm: data[i].children[j].AdvaDevicRhythm,-->
<!--                  start: data[i].children[j].FourStartDate[0],-->
<!--                  end: data[i].children[j].FourStartDate[1],-->
<!--                  mod: (data[i].children[j].AdvaDevicCropMob * 1) / 100-->
<!--                }-->
<!--                time.gtArray.push(icu4)-->
<!--              }-->
<!--              if (data[i].children[j].FiveStartDate != '') {-->
<!--                const icu5 = {-->
<!--                  name: data[i].children[j].AdvaDevicName,-->
<!--                  id: data[i].children[j].AdvaDevicNumber,-->
<!--                  type: 'capacity',-->
<!--                  rhythm: data[i].children[j].AdvaDevicRhythm,-->
<!--                  start: data[i].children[j].FiveStartDate[0],-->
<!--                  end: data[i].children[j].FiveStartDate[1],-->
<!--                  mod: (data[i].children[j].AdvaDevicCropMob * 1) / 100-->
<!--                }-->
<!--                time.gtArray.push(icu5)-->
<!--              }-->
<!--            }-->
<!--            this.facility_data.push(time)-->
<!--          }-->
<!--          if (cont != '') {-->
<!--            for (const i in cont) {-->
<!--              const date_time = cont[i].TIME_START.split(' ')-->
<!--              const cont_date = date_time[0]-->
<!--              for (const j in this.facility_data) {-->
<!--                const data = {-->
<!--                  id: cont[i].EQP_CODE,-->
<!--                  date: cont_date,-->
<!--                  number: cont[i].ALLOC_QTY,-->
<!--                  cl_name: cont[i].PART_NAME,-->
<!--                  cl_code: this.cl_code,-->
<!--                  work_order: cont[i].WO_CODE,-->
<!--                  start: cont[i].TIME_START,-->
<!--                  end: cont[i].TIME_END,-->
<!--                  type: 'h_schedule'-->
<!--                }-->
<!--                if (this.facility_data[j].date == data.date) {-->
<!--                  this.facility_data[j].gtArray.unshift(data)-->
<!--                }-->
<!--              }-->
<!--            }-->
<!--          }-->
<!--        })-->
<!--    },-->
<!--    // æŽ’程方法-->
<!--    formSeconds(s1, start, mod) {-->
<!--      const nowData = new Date(start)-->
<!--      // ç®—出当前排程的结束时间-->
<!--      return this.transitionTime(-->
<!--        new Date(nowData.setSeconds(nowData.getSeconds() + s1))-->
<!--      )-->
<!--    },-->
<!--    // è½¬åŒ–标准时间-->
<!--    transitionTime(time) {-->
<!--      const d = new Date(time)-->
<!--      return (-->
<!--        d.getFullYear() +-->
<!--        '-' +-->
<!--        (d.getMonth() + 1) +-->
<!--        '-' +-->
<!--        d.getDate() +-->
<!--        ' ' +-->
<!--        d.getHours() +-->
<!--        ':' +-->
<!--        d.getMinutes() +-->
<!--        ':' +-->
<!--        d.getSeconds()-->
<!--      )-->
<!--    },-->
<!--    // æ—¶é—´æ¯”较-->
<!--    formTime(d1, d2, mod) {-->
<!--      // d1 æŽ’除结束时间  d2 å½“前产能结束时间-->
<!--      const time1 = new Date(d1)-->
<!--      const time2 = new Date(d2)-->
<!--      return parseInt(time2 - time1) / 1000-->
<!--    },-->
<!--    formatSeconds(value) {-->
<!--      var secondTime = parseInt(value) // ç§’-->
<!--      var minuteTime = 0 // åˆ†-->
<!--      var hourTime = 0 // å°æ—¶-->
<!--      if (secondTime > 60) {-->
<!--        // å¦‚果秒数大于60,将秒数转换成整数-->
<!--        // èŽ·å–åˆ†é’Ÿï¼Œé™¤ä»¥60取整数,得到整数分钟-->
<!--        minuteTime = parseInt(secondTime / 60)-->
<!--        // èŽ·å–ç§’æ•°ï¼Œç§’æ•°å–ä½˜ï¼Œå¾—åˆ°æ•´æ•°ç§’æ•°-->
<!--        secondTime = parseInt(secondTime % 60)-->
<!--        // å¦‚果分钟大于60,将分钟转换成小时-->
<!--        if (minuteTime > 60) {-->
<!--          // èŽ·å–å°æ—¶ï¼ŒèŽ·å–åˆ†é’Ÿé™¤ä»¥60,得到整数小时-->
<!--          hourTime = parseInt(minuteTime / 60)-->
<!--          // èŽ·å–å°æ—¶åŽå–ä½˜çš„åˆ†ï¼ŒèŽ·å–åˆ†é’Ÿé™¤ä»¥60取佘的分-->
<!--          minuteTime = parseInt(minuteTime % 60)-->
<!--        }-->
<!--      }-->
<!--      var result = '' + parseInt(secondTime) + ''-->
<!--      if (minuteTime > 0) {-->
<!--        result = '' + parseInt(minuteTime) + ':' + result-->
<!--      }-->
<!--      if (hourTime > 0) {-->
<!--        result = '' + parseInt(hourTime) + ':' + result-->
<!--      }-->
<!--      return result-->
<!--    },-->
<!--    updateTimeLines(timeA, timeB) {-->
<!--      this.timeLines = [-->
<!--        {-->
<!--          time: timeA-->
<!--        },-->
<!--        {-->
<!--          time: timeB,-->
<!--          color: '#747e80'-->
<!--        }-->
<!--      ]-->
<!--    },-->
<!--    scrollLeftA(val) {-->
<!--      this.positionB = { x: val }-->
<!--    },-->
<!--    scrollLeftB(val) {-->
<!--      this.positionA = { x: val }-->
<!--    },-->
<!--    // è®¾ç½®åˆå§‹åŒ–数据-->
<!--    oneClick() {-->
<!--      // this.getCurrentRow(this.mn_data[0])-->
<!--    }-->
<!--  }-->
<!--}-->
<!--</script>-->
<!--<style scoped>-->
<!--body {-->
<!--  font: 12px;-->
<!--  margin: 0;-->
<!--  padding: 0;-->
<!--  width: 100%;-->
<!--  height: 100%;-->
<!--}-->
<!--.box_style {-->
<!--  position: relative;-->
<!--  top: 40px;-->
<!--  left: -75px;-->
<!--}-->
<!--.box_styles {-->
<!--  position: relative;-->
<!--  top: 40px;-->
<!--  left: 0;-->
<!--}-->
<!--#app {-->
<!--  display: flex;-->
<!--  flex-direction: column;-->
<!--  padding: 0 10px;-->
<!--  /* height: calc(100vh - 100px); */-->
<!--}-->
<!--label {-->
<!--  margin-left: 10px;-->
<!--}-->
<!--input {-->
<!--  width: 40px;-->
<!--  height: 20px;-->
<!--  vertical-align: middle;-->
<!--}-->
<!--input[type="range"] {-->
<!--  width: 100px;-->
<!--}-->
<!--.top-bar {-->
<!--  /* height: 30px; */-->
<!--  margin-bottom: 20px;-->
<!--}-->
<!--.container {-->
<!--  display: flex;-->
<!--  flex-direction: column;-->
<!--  flex: 1;-->
<!--}-->
<!--.main-footer {-->
<!--  /* height: 30px; */-->
<!--}-->
<!--.ib {-->
<!--  display: inline-block;-->
<!--}-->
<!--.w250 {-->
<!--  width: 250px;-->
<!--}-->
<!--.el-slider {-->
<!--  width: 100px;-->
<!--}-->
<!--.tc {-->
<!--  text-align: center;-->
<!--}-->
<!--.name {-->
<!--  display: flex;-->
<!--  box-sizing: border-box;-->
<!--  overflow: hidden;-->
<!--  height: 100%;-->
<!--  width: 100%;-->
<!--  padding: 0 5px 0 0;-->
<!--  border-radius: 8px 0 0 8px;-->
<!--  align-items: center;-->
<!--}-->
<!--.colorBar {-->
<!--  width: 10px;-->
<!--  height: 100%;-->
<!--}-->
<!--.carId {-->
<!--  flex: 1;-->
<!--}-->
<!--.tc {-->
<!--  color: #909399;-->
<!--  font-size: 14px;-->
<!--}-->
<!--.type {-->
<!--  padding: 0 5px 0 0;-->
<!--  font-size: 1.2rem;-->
<!--}-->
<!--.t_size {-->
<!--  font-size: 14px;-->
<!--}-->
<!--.icon_true {-->
<!--  height: 8px;-->
<!--  display: inline-block;-->
<!--  width: 8px;-->
<!--  background: #00a79d;-->
<!--  margin-right: 7px;-->
<!--  border-radius: 15px;-->
<!--}-->
<!--.icon_ty {-->
<!--  height: 8px;-->
<!--  display: inline-block;-->
<!--  width: 8px;-->
<!--  background: red;-->
<!--  margin-right: 7px;-->
<!--  border-radius: 15px;-->
<!--}-->
<!--.icon_gz {-->
<!--  height: 8px;-->
<!--  display: inline-block;-->
<!--  width: 8px;-->
<!--  background: yellow;-->
<!--  margin-right: 7px;-->
<!--  border-radius: 15px;-->
<!--}-->
<!--/* .el-col-offset-1 {-->
<!--    margin-left: 0.5% !important;-->
<!--} */-->
<!--.marginLeft {-->
<!--  margin-left: 15px;-->
<!--}-->
<!--.button_style {-->
<!--  background: #00a79d;-->
<!--  color: #ffff;-->
<!--  border-color: #00a79d;-->
<!--}-->
<!--.rg {-->
<!--  float: right;-->
<!--}-->
<!--.color {-->
<!--  color: #909399;-->
<!--}-->
<!--</style>-->
src/views/sbgl/index1.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,57 @@
import dayjs from 'dayjs'
import Mock from 'mockjs'
const colorList = ['(252, 105, 100)', '(247, 167, 71)', '(116, 202, 90)', '(83, 186, 241)', '(208, 142, 2231)']
const nameList = '希望号,飞翼号,光明号,窥探号,力神号,警官号,闪电流星号,博士号,霹雳火神号,狙击手号,希望之光号,南海忍者号,火速E3号,山神号,安全卫士号,铁锤号,寿星号,星星号,罗曼斯卡,欲望号,霹雳雷电号,消防号,欧洲之星号'.split(',')
const typeList = '🚅,🚈,🚄'.split(',')
const Random = Mock.Random
var template = {
  'id': () => 'JHR' + Random.natural(100, 999) + Random.character('upper') + Random.character('upper'),
  'name': () => Random.pick(nameList),
  'type': () => Random.pick(typeList),
  'colorPair': () => {
    const a = 'rgb' + Random.pick(colorList)
    return {
      dark: a.replace(')', ',0.8)'),
      light: a.replace(')', ',0.1)')
    }
  },
  'speed': () => Random.natural(0, 200),
  'gtArray': () => {
    const temp = []
    let i = 0
    const j = Random.natural(1, 9)
    let tempStart = dayjs().subtract(12, 'hour')
    let tempEnd = dayjs().subtract(12, 'hour')
    while (i < j) {
      tempStart = tempEnd.add(Random.natural(1, 5), 'hour')
      tempEnd = tempStart.add(Random.natural(1, 5), 'hour')
      temp.push({
        'id': 'D' + Random.natural(1000, 9999),
        'passenger': Random.natural(10, 200),
        'start': tempStart.toString(),
        'end': tempEnd.toString()
      })
      i++
    }
    return temp
  }
}
function mockDatas(nums) {
  const datas = []
  for (let i = 0,
    j = Random.natural(nums, nums); i < j; i++) {
    datas.push(Mock.mock(template))
  }
  return datas
}
export {
  mockDatas
}
src/views/scgl/gd.vue
@@ -247,16 +247,16 @@
              <div v-else>/</div>
            </template>
          </el-table-column>
          <el-table-column
            prop="route_name"
            label="关联工艺路线"
            min-width="110"
          >
            <template slot-scope="{row}">
              <i v-if="row.route_name" class="el-icon-share" @click="routeClick(row)" />
              <i v-else style="color:rgb(180 ,181, 185)" class="el-icon-share" @click="routeClick(row)" />
            </template>
          </el-table-column>
          <!--          <el-table-column-->
          <!--            prop="route_name"-->
          <!--            label="关联工艺路线"-->
          <!--            min-width="110"-->
          <!--          >-->
          <!--            <template slot-scope="{row}">-->
          <!--              <i v-if="row.route_name" class="el-icon-share" @click="routeClick(row)" />-->
          <!--              <i v-else style="color:rgb(180 ,181, 185)" class="el-icon-share" @click="routeClick(row)" />-->
          <!--            </template>-->
          <!--          </el-table-column>-->
          <el-table-column
            prop="plan_startdate"
            label="计划开始时间"
src/views/scgl/sckbg.vue
@@ -7,13 +7,15 @@
            <div style="display: flex;align-items: center">
              <div style="width: 90px">扫描条码:</div>
              <!--              oninput="value=value.replace(/[^0-9a-zA-Z;_]/g,'')"-->
              <el-input
                id="keyWords"
                v-model="form.orderstepqrcode"
                name="produceCode"
                style="width: 300px"
                @keyup.native="e=>judgeIsScanning(e,'produceCode')"
                @keyup.enter.native="val=>enterNative(val,'produceCode')"
              />
            </div>
            <div v-if="false" style="display: flex;padding-right: 10px">
              <el-button @click="ZZstart">
@@ -39,19 +41,6 @@
              :cell-style="this.$cellStyle"
              @sort-change="sortChange"
            >
              <!--              <el-table-column-->
              <!--                width="50"-->
              <!--                fixed-->
              <!--              >-->
              <!--                <template slot-scope="{row}">-->
              <!--                  <el-radio-->
              <!--                    v-model="radioSelected"-->
              <!--                    :label="row.wo"-->
              <!--                    style="color: #fff;padding-left: 10px; margin-right: -25px;"-->
              <!--                    @change.native="getCurrentRow(row.wo)"-->
              <!--                  />-->
              <!--                </template>-->
              <!--              </el-table-column>-->
              <el-table-column
                prop="RowNum"
                width="50"
@@ -212,6 +201,7 @@
                v-model="WXform.orderstepqrcode"
                name="WXproduceCode"
                style="width: 300px"
                @keyup.native="e=>judgeIsScanning(e,'WXproduceCode')"
                @keyup.enter.native="val=>enterNative(val,'WXproduceCode')"
              />
            </div>
@@ -239,19 +229,6 @@
              :cell-style="this.$cellStyle"
              @sort-change="WXsortChange"
            >
              <!--              <el-table-column-->
              <!--                width="50"-->
              <!--                fixed-->
              <!--              >-->
              <!--                <template slot-scope="{row}">-->
              <!--                  <el-radio-->
              <!--                    v-model="radioSelected"-->
              <!--                    :label="row.wo_code"-->
              <!--                    style="color: #fff;padding-left: 10px; margin-right: -25px;"-->
              <!--                    @change.native="getWXCurrentRow(row.wo_code)"-->
              <!--                  />-->
              <!--                </template>-->
              <!--              </el-table-column>-->
              <el-table-column
                prop="RowNum"
                width="50"
@@ -399,6 +376,7 @@
                v-model="badForm.orderstepqrcode"
                name="badProduceCode"
                style="width: 300px"
                @keyup.native="e=>judgeIsScanning(e,'badProduceCode')"
                @keyup.enter.native="val=>enterNative(val,'badProduceCode')"
              />
            </div>
@@ -1326,23 +1304,37 @@
      },
      badTableDataDialog: [], // ä¸è‰¯å¯¹è¯æ¡†table表格
      OperationArr: [], // äººå‘˜æ•°ç»„
      sendButtonIsDisabled: false// ä¸‹è¾¾æŒ‰é’®æ˜¯å¦å¯ç‚¹å‡»
      sendButtonIsDisabled: false, // ä¸‹è¾¾æŒ‰é’®æ˜¯å¦å¯ç‚¹å‡»
      judgeIsScanningArr: []// åˆ¤æ–­æ˜¯å¦æ‰«ç æ•°ç»„
    }
  },
  // computed: {
  //   qrLink: function() {
  //     return this.$store.getters.getPreviewUrl
  //   }
  // },
  // watch: {
  //   qrLink: function(newVal, oldNew) {
  //     if (newVal !== oldNew) {
  //       this.$nextTick(() => {
  //         this.bindQRCode(newVal)
  //       })
  //     }
  //   }
  // },
  watch: {
    // 'form.orderstepqrcode': {
    //   handler(newValue) {
    //     this.form.orderstepqrcode = newValue
    //
    //     // åœ¨è¿™é‡Œè°ƒç”¨ï¼Œå¹¶æ‰§è¡Œthis.fnThrottle(this.search, 500, 2000)();
    //     this.fnThrottle(this.enterNative, 500, 2000, 'produceCode')()
    //   }
    // },
    // 'WXform.orderstepqrcode': {
    //   handler(newValue) {
    //     this.form.orderstepqrcode = newValue
    //
    //     // åœ¨è¿™é‡Œè°ƒç”¨ï¼Œå¹¶æ‰§è¡Œthis.fnThrottle(this.search, 500, 2000)();
    //     this.fnThrottle(this.enterNative, 500, 2000, 'WXproduceCode')()
    //   }
    // },
    // 'badForm.orderstepqrcode': {
    //   handler(newValue) {
    //     this.form.orderstepqrcode = newValue
    //
    //     // åœ¨è¿™é‡Œè°ƒç”¨ï¼Œå¹¶æ‰§è¡Œthis.fnThrottle(this.search, 500, 2000)();
    //     this.fnThrottle(this.enterNative, 500, 2000, 'badProduceCode')()
    //   }
    // }
  },
  created() {
    this.getMesOrderStepSearch()
    this.tabClick()
@@ -1361,6 +1353,7 @@
    this.getMesOrderSelectUserAll() // èŽ·å–æ‰€æœ‰äººå‘˜
  },
  methods: {
    tableRowClassName({ row, rowIndex }) {
      return 'custom-row'
    },
@@ -1448,9 +1441,53 @@
        })
      }
    },
    // é˜²æŠ–      //扫码用的是防抖
    fnThrottle(method, delay, duration, belong) {
      var that = this
      var timer = this.timer
      var begin = new Date().getTime()
      return function() {
        var current = new Date().getTime()
        clearTimeout(timer)
        if (current - begin >= duration) {
          // method()
          // that.VALUE()
          begin = current
        } else {
          that.timer = setTimeout(function() {
            // method()
            if (belong === 'produceCode') {
              that.enterNative(that.form.orderstepqrcode, belong)
            }
            if (belong === 'WXproduceCode') {
              that.enterNative(that.WXform.orderstepqrcode, belong)
            }
            if (belong === 'badProduceCode') {
              that.enterNative(that.badForm.orderstepqrcode, belong)
            }
          }, delay)
        }
      }
    },
    // åˆ¤æ–­æ˜¯å¦æ˜¯æ‰«ç æžªæ‰«ç 
    judgeIsScanning(e, belong) {
      const timenow = e.timeStamp
      let flag = true
      this.judgeIsScanningArr.push(timenow)
      let i
      for (i in this.judgeIsScanningArr) {
        flag = Math.ceil(this.judgeIsScanningArr[this.judgeIsScanningArr.length - 1]) - Math.ceil(this.judgeIsScanningArr[this.judgeIsScanningArr.length - 2]) < 10
        if (i > 0 && this.judgeIsScanningArr.length === parseInt(i) + 1) {
          if (flag) {
            this.fnThrottle(this.enterNative, 500, 2000, belong)()
            return
          }
        }
      }
    },
    // æ‰«ç é”®ç›˜å›žè½¦äº‹ä»¶
    async enterNative(val, belong) {
      console.log(val, belong)
      console.log(val, belong, 89898989)
      // å¼€å·¥ï¼šcode="200"  count=0
      // æŠ¥å·¥ï¼šcode="200"  count=1
      // å‘料:code="200"  count=2
@@ -1745,6 +1782,10 @@
    },
    // å¯¹è¯æ¡†å…³é—­äº‹ä»¶
    handleClose() {
      this.form.orderstepqrcode = ''
      this.WXform.orderstepqrcode = ''
      this.badForm.orderstepqrcode = ''
      this.dialogForm.wo_code = '', // å·¥å•编号
      this.dialogForm.partcode = '', // äº§å“ç¼–码
      this.dialogForm.partname = '', // äº§å“åç§°
@@ -1848,7 +1889,7 @@
              if (res.code === '200') {
                this.$message.success('收料成功!')
                if (this.dialogForm.nextstepcode !== '') {
                if (this.dialogForm.nextstepcode === '') {
                  this.WXprint2(this.OperationArr.find(item => item.usercode === this.dialogForm.operation).username)
                  this.dialogVisible2 = true
                }
@@ -1924,8 +1965,7 @@
              if (res.code === '200') {
                this.$message.success('报工成功!')
                console.log(this.dialogForm.nextstepcode, 1)
                if (this.dialogForm.nextstepcode !== '') {
                if (this.dialogForm.nextstepcode === '') {
                  this.ZZprint2(this.OperationArr.find(item => item.usercode === this.dialogForm.operation).username)
                  this.dialogVisible2 = true
                }
src/views/scgl/sckbg_back.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,2394 @@
<template>
  <div>
    <div class="body" style="padding-top: 10px;" :style="{height:mainHeight+'px'}">
      <el-tabs ref="elTabs" v-model="activeName" type="border-card" @tab-click="tabClick">
        <el-tab-pane label="生产列表">
          <div style="margin-left: 10px;margin-top:10px;display: flex;justify-content: space-between">
            <div style="display: flex;align-items: center">
              <div style="width: 90px">扫描条码:</div>
              <!--              oninput="value=value.replace(/[^0-9a-zA-Z;_]/g,'')"-->
              <el-input
                id="keyWords"
                v-model="form.orderstepqrcode"
                name="produceCode"
                style="width: 300px"
                @keyup.enter.native="val=>enterNative(val,'produceCode')"
              />
            </div>
            <div v-if="false" style="display: flex;padding-right: 10px">
              <el-button @click="ZZstart">
                <svg-icon icon-class="start_time" style="margin-right: 2px" />
                å¼€å§‹
              </el-button>
              <el-button @click="ZZreport">
                <svg-icon icon-class="report_work" style="margin-right: 2px" />
                æŠ¥å·¥
              </el-button>
            </div>
          </div>
          <el-divider />
          <div class="elTableDiv">
            <el-table
              :data="tableData"
              :height="isIpad? (tableHeight+50):tableHeight"
              border
              :row-class-name="tableRowClassName"
              :style="{width: 100+'%',height:tableHeight+'px',}"
              highlight-current-row
              :header-cell-style="this.$headerCellStyle"
              :cell-style="this.$cellStyle"
              @sort-change="sortChange"
            >
              <!--              <el-table-column-->
              <!--                width="50"-->
              <!--                fixed-->
              <!--              >-->
              <!--                <template slot-scope="{row}">-->
              <!--                  <el-radio-->
              <!--                    v-model="radioSelected"-->
              <!--                    :label="row.wo"-->
              <!--                    style="color: #fff;padding-left: 10px; margin-right: -25px;"-->
              <!--                    @change.native="getCurrentRow(row.wo)"-->
              <!--                  />-->
              <!--                </template>-->
              <!--              </el-table-column>-->
              <el-table-column
                prop="RowNum"
                width="50"
                label="序号"
                fixed
              />
              <el-table-column
                prop="status"
                label="状态"
                sortable="custom"
                width="80"
              >
                <template slot-scope="{row}">
                  <div v-if="row.status==='NEW'">新订单</div>
                  <div v-if="row.status==='ALLO'">已派发</div>
                  <div v-if="row.status==='START'">开工</div>
                  <div v-if="row.status==='CLOSED'">完工</div>
                </template>
              </el-table-column>
              <el-table-column
                prop="wo_code"
                label="工单号"
                width="160"
                show-tooltip-when-overflow
                sortable="custom"
              />
              <el-table-column
                prop="partcode"
                label="产品编码"
                min-width="110"
                sortable="custom"
              />
              <el-table-column
                prop="partname"
                width="160"
                show-tooltip-when-overflow
                label="产品名称"
                sortable="custom"
              />
              <el-table-column
                prop="stepname"
                label="工序"
                show-tooltip-when-overflow
                width="120"
                sortable="custom"
              />
              <!--              <el-table-column-->
              <!--                prop="descr"-->
              <!--                label="工序描述"-->
              <!--                min-width="150"-->
              <!--                sortable="custom"-->
              <!--              >-->
              <!--                <template slot-scope="{row}">-->
              <!--                  <div v-if="row.descr">{{ row.descr }}</div>-->
              <!--                  <div v-else>/</div>-->
              <!--                </template>-->
              <!--              </el-table-column>-->
              <el-table-column
                prop="plan_qty"
                label="任务数量"
                width="110"
                sortable="custom"
              />
              <el-table-column
                label="未报工数量"
                width="120"
              >
                <!--                sortable="custom"-->
                <template slot-scope="{row}">
                  <div>{{ row.plan_qty - row.good_qty - row.ng_qty }}</div>
                </template>
              </el-table-column>
              <el-table-column
                prop="good_qty"
                label="已报工数量"
                sortable="custom"
                width="160"
              />
              <el-table-column
                prop="ng_qty"
                label="不良数量"
                width="150"
                sortable="custom"
              />
              <el-table-column
                prop="bad_qty"
                label="已报废数量"
                width="120"
                sortable="custom"
              />
              <el-table-column
                prop="plan_startdate"
                label="计划开工日期"
                width="150"
                sortable="custom"
              >
                <template slot-scope="{row}">
                  <div v-if="row.plan_startdate">{{ row.plan_startdate.substring(0,11) }}</div>
                  <div v-else>/</div>
                </template>
              </el-table-column>
              <el-table-column
                prop="plan_enddate"
                label="计划完工日期"
                width="150"
                sortable="custom"
                fixed="right"
              >
                <template slot-scope="{row}">
                  <div v-if="row.plan_startdate">{{ row.plan_startdate.substring(0,11) }}</div>
                  <div v-else>/</div>
                </template>
              </el-table-column>
              <!--              <el-table-column-->
              <!--                label="操作"-->
              <!--                width="150"-->
              <!--                fixed="right"-->
              <!--              >-->
              <!--                <template slot-scope="{row}">-->
              <!--                  <div class="operationClass">-->
              <!--                    <el-button type="text" @click="edit('edit',row)">编辑</el-button>-->
              <!--                    <el-button type="text" @click="del(row)">删除</el-button>-->
              <!--                  </div>-->
              <!--                </template>-->
              <!--              </el-table-column>-->
            </el-table>
          </div>
          <!--分页-->
          <pagination
            :total="total"
            :page.sync="form.page"
            :limit.sync="form.rows"
            align="right"
            layout="total,prev, pager, next,sizes"
            popper-class="select_bottom"
            @pagination="getMesOrderStepSearch"
          />
        </el-tab-pane>
        <el-tab-pane label="外协列表">
          <div style="margin-left: 10px;margin-top:10px;display: flex;justify-content: space-between">
            <div style="display: flex;align-items: center">
              <div style="width: 90px;">外协类型:</div>
              <el-select
                v-model="WXSelected"
                filterable
                style="width: 200px"
                placeholder="请选择"
              >
                <el-option
                  v-for="item in WXSelectArr"
                  :key="item.code"
                  :label="item.name"
                  :value="item.code"
                />
              </el-select>
              <div style="width: 90px;margin-left: 20px">扫描条码:</div>
              <el-input
                v-model="WXform.orderstepqrcode"
                name="WXproduceCode"
                style="width: 300px"
                @keyup.enter.native="val=>enterNative(val,'WXproduceCode')"
              />
            </div>
            <div v-if="false" style="display: flex;padding-right: 10px">
              <el-button @click="WXsend">
                <svg-icon icon-class="start_time" style="margin-right: 2px" />
                å‘æ–™
              </el-button>
              <el-button @click="WXback">
                <svg-icon icon-class="report_work" style="margin-right: 2px" />
                æ”¶æ–™
              </el-button>
            </div>
          </div>
          <el-divider />
          <div class="elTableDiv">
            <el-table
              :data="WXtableData"
              :height="isIpad? (tableHeight+50):tableHeight"
              border
              :row-class-name="tableRowClassName"
              :style="{width: 100+'%',height:tableHeight+'px',}"
              highlight-current-row
              :header-cell-style="this.$headerCellStyle"
              :cell-style="this.$cellStyle"
              @sort-change="WXsortChange"
            >
              <!--              <el-table-column-->
              <!--                width="50"-->
              <!--                fixed-->
              <!--              >-->
              <!--                <template slot-scope="{row}">-->
              <!--                  <el-radio-->
              <!--                    v-model="radioSelected"-->
              <!--                    :label="row.wo_code"-->
              <!--                    style="color: #fff;padding-left: 10px; margin-right: -25px;"-->
              <!--                    @change.native="getWXCurrentRow(row.wo_code)"-->
              <!--                  />-->
              <!--                </template>-->
              <!--              </el-table-column>-->
              <el-table-column
                prop="RowNum"
                width="50"
                label="序号"
                fixed
              />
              <el-table-column
                prop="status"
                label="状态"
                sortable="custom"
                width="80"
              >
                <template slot-scope="{row}">
                  <div v-if="row.status==='NEW'">新订单</div>
                  <div v-if="row.status==='ALLO'">已派发</div>
                  <div v-if="row.status==='START'">已发料</div>
                  <div v-if="row.status==='CLOSED'">已收料</div>
                </template>
              </el-table-column>
              <el-table-column
                prop="wo_code"
                label="工单号"
                width="160"
                show-tooltip-when-overflow
                sortable="custom"
              />
              <el-table-column
                prop="partcode"
                label="产品编码"
                width="110"
                sortable="custom"
              />
              <el-table-column
                prop="partname"
                label="产品名称"
                width="160"
                show-tooltip-when-overflow
                sortable="custom"
              />
              <el-table-column
                prop="stepname"
                label="工序"
                width="120"
                sortable="custom"
              />
              <!--              <el-table-column-->
              <!--                prop="descr"-->
              <!--                label="工序描述"-->
              <!--                min-width="150"-->
              <!--                sortable="custom"-->
              <!--              >-->
              <!--                <template slot-scope="{row}">-->
              <!--                  <div v-if="row.descr">{{ row.descr }}</div>-->
              <!--                  <div v-else>/</div>-->
              <!--                </template>-->
              <!--              </el-table-column>-->
              <el-table-column
                prop="plan_qty"
                label="任务数量"
                width="110"
                sortable="custom"
              />
              <el-table-column
                label="未报工数量"
                width="120"
              >
                <!--                sortable="custom"-->
                <template slot-scope="{row}">
                  <div>{{ row.plan_qty - row.good_qty - row.ng_qty }}</div>
                </template>
              </el-table-column>
              <el-table-column
                prop="good_qty"
                label="已收料数量"
                sortable="custom"
                width="160"
              />
              <el-table-column
                prop="ng_qty"
                label="不良数量"
                width="150"
                sortable="custom"
              />
              <el-table-column
                prop="bad_qty"
                label="已报废数量"
                min-width="120"
                sortable="custom"
              />
              <el-table-column
                prop="plan_startdate"
                label="计划开工日期"
                width="150"
                sortable="custom"
              >
                <template slot-scope="{row}">
                  <div v-if="row.plan_startdate">{{ row.plan_startdate.substring(0,11) }}</div>
                  <div v-else>/</div>
                </template>
              </el-table-column>
              <el-table-column
                prop="plan_enddate"
                label="计划完工日期"
                width="150"
                sortable="custom"
                fixed="right"
              >
                <template slot-scope="{row}">
                  <div v-if="row.plan_startdate">{{ row.plan_startdate.substring(0,11) }}</div>
                  <div v-else>/</div>
                </template>
              </el-table-column>
              <!--              <el-table-column-->
              <!--                label="操作"-->
              <!--                width="150"-->
              <!--                fixed="right"-->
              <!--              >-->
              <!--                <template slot-scope="{row}">-->
              <!--                  <div class="operationClass">-->
              <!--                    <el-button type="text" @click="edit('edit',row)">编辑</el-button>-->
              <!--                    <el-button type="text" @click="del(row)">删除</el-button>-->
              <!--                  </div>-->
              <!--                </template>-->
              <!--              </el-table-column>-->
            </el-table>
          </div>
          <!--分页-->
          <pagination
            :total="WXtotal"
            :page.sync="WXform.page"
            :limit.sync="WXform.rows"
            align="right"
            layout="total,prev, pager, next,sizes"
            popper-class="select_bottom"
            @pagination="getMesOrderStepSearch"
          />
        </el-tab-pane>
        <el-tab-pane label="不良待处理列表">
          <div style="margin-left: 10px;margin-top:10px;display: flex;justify-content: space-between">
            <div style="display: flex;align-items: center">
              <div style="width: 90px">扫描条码:</div>
              <!--              oninput="value=value.replace(/[^0-9a-zA-Z;_]/g,'')"-->
              <el-input
                v-model="badForm.orderstepqrcode"
                name="badProduceCode"
                style="width: 300px"
                @keyup.enter.native="val=>enterNative(val,'badProduceCode')"
              />
            </div>
          </div>
          <el-divider />
          <div class="elTableDiv">
            <el-table
              :data="badTableData"
              :height="isIpad? (tableHeight+50):tableHeight"
              border
              :row-class-name="tableRowClassName"
              :style="{width: 100+'%',height:tableHeight+'px',}"
              highlight-current-row
              :header-cell-style="this.$headerCellStyle"
              :cell-style="this.$cellStyle"
              @sort-change="badSortChange"
            >
              <el-table-column
                prop="RowNum"
                width="50"
                label="序号"
                fixed
              />
              <el-table-column
                prop="wo_code"
                label="工单号"
                min-width="160"
                sortable="custom"
              />
              <el-table-column
                prop="partcode"
                label="产品编码"
                min-width="110"
                sortable="custom"
              />
              <el-table-column
                prop="partname"
                min-width="160"
                label="产品名称"
                sortable="custom"
              />
              <el-table-column
                prop="stepname"
                label="工序"
                min-width="120"
                sortable="custom"
              />
              <el-table-column
                prop="plan_qty"
                label="任务数量"
                width="110"
                sortable="custom"
              />
              <el-table-column
                prop="good_qty"
                label="已报工数量"
                sortable="custom"
                min-width="160"
              />
              <el-table-column
                prop="ng_qty"
                label="不良数量"
                width="150"
                sortable="custom"
              />
              <el-table-column
                prop="bad_qty"
                label="已报废数量"
                width="120"
                sortable="custom"
              />
              <el-table-column
                label="操作"
                width="120"
                fixed="right"
              >
                <template slot-scope="{row}">
                  <div class="operationClass">
                    <el-button type="text" @click="repairHandle(row)">维修处理</el-button>
                  </div>
                </template>
              </el-table-column>
            </el-table>
          </div>
          <!--分页-->
          <pagination
            :total="badTotal"
            :page.sync="badForm.page"
            :limit.sync="badForm.rows"
            align="right"
            layout="total,prev, pager, next,sizes"
            popper-class="select_bottom"
            @pagination="getBadList"
          />
        </el-tab-pane>
      </el-tabs>
    </div>
    <el-dialog
      :title="dialogTitle"
      :visible.sync="dialogVisible"
      width="850px"
      class="dialogVisible"
      :top="dialogTitle==='自制报工'?'5vh':'15vh'"
      :close-on-click-modal="false"
      @close="handleClose"
      @closed="handleClose"
    >
      <el-form
        ref="dialogForm"
        inline
        :rules="dialogFormRules"
        :model="dialogForm"
        label-width="110px"
      >
        <el-form-item label="工单编号:">
          <div style="width: 200px">{{ dialogForm.wo_code }}</div>
        </el-form-item>
        <el-form-item label="产品编码:">
          <div style="width: 200px">{{ dialogForm.partcode }}</div>
        </el-form-item>
        <el-form-item label="产品名称:">
          <div style="width: 200px">{{ dialogForm.partname }}</div>
        </el-form-item>
        <el-form-item label="产品规格:">
          <div style="width: 200px">{{ dialogForm.partspec }}</div>
        </el-form-item>
        <el-form-item label="当前工序:">
          <div style="width: 200px">{{ dialogForm.stepname }}</div>
        </el-form-item>
        <el-form-item v-if="false" label="工序描述:">
          <!--          <el-tooltip   class="item" effect="dark" content="原材料切按材料切按材料切按时打卡数据的卡" placement="top-start">-->
          <div style="width: 200px;white-space: nowrap;text-overflow: ellipsis;overflow: hidden;">
            {{ dialogForm.stepdesc }}
          </div>
          <!--          </el-tooltip>-->
        </el-form-item>
        <el-form-item label="任务数量:">
          <div style="width: 200px">{{ dialogForm.planqty }}</div>
        </el-form-item>
        <el-form-item v-if="dialogTitle==='自制开始'" label="未开/已开:">
          <div style="width: 200px">{{ dialogForm.noreportqty }}/{{ dialogForm.reportqty }}</div>
        </el-form-item>
        <el-form-item v-if="dialogTitle==='自制报工'" label="未报/已报:">
          <div style="width: 200px">{{ dialogForm.noreportqty }}/{{ dialogForm.reportqty }}</div>
        </el-form-item>
        <el-form-item v-if="dialogTitle==='外协发料'" label="未发/已发:">
          <div style="width: 200px">{{ dialogForm.noreportqty }}/{{ dialogForm.reportqty }}</div>
        </el-form-item>
        <el-form-item v-if="dialogTitle==='外协收料'" label="未收/已收:">
          <div style="width: 200px">{{ dialogForm.noreportqty }}/{{ dialogForm.reportqty }}</div>
        </el-form-item>
        <!--自制开始-->
        <el-form-item v-if="dialogTitle==='自制开始'" label="开工数量:">
          <div style="width: 200px">{{ dialogForm.startqty }}</div>
          <!--          <div style="width: 200px">{{  dialogForm.noreportqty }}</div>-->
        </el-form-item>
        <el-form-item v-if="dialogTitle==='自制开始'" prop="eqpcode" label="生产设备:">
          <el-select
            v-model="dialogForm.eqpcode"
            style="width: 200px;"
            placeholder="请选择"
          >
            <el-option
              v-for="item in ZZeqpArr"
              :key="item.code"
              :label="item.name"
              :value="item.code"
            />
          </el-select>
        </el-form-item>
        <!--     è‡ªåˆ¶æŠ¥å·¥   -->
        <el-form-item v-if="dialogTitle==='自制报工'" label="下道工序:">
          <div style="width: 200px">{{ dialogForm.nextstepname }}</div>
        </el-form-item>
        <el-form-item v-if="dialogTitle==='自制报工'" prop="usergroupcode" label="生产班组:">
          <el-select
            v-model="dialogForm.usergroupcode"
            style="width: 200px;"
            placeholder="请选择"
            @change="usergroupChange"
          >
            <el-option
              v-for="item in ZZtreams"
              :key="item.group_code"
              :label="item.group_name"
              :value="item.group_code"
            />
          </el-select>
        </el-form-item>
        <el-form-item v-if="dialogTitle==='自制报工'" label="设备名称:" prop="eqpcode">
          <el-select
            v-model="dialogForm.eqpcode"
            style="width: 200px;"
            placeholder="请选择"
          >
            <el-option
              v-for="item in ZZeqpArr"
              :key="item.code"
              :label="item.name"
              :value="item.code"
            />
          </el-select>
        </el-form-item>
        <el-form-item v-if="dialogTitle==='自制报工'" label="报工数量:" prop="startqty">
          <el-input v-model="dialogForm.startqty" oninput="value=value.replace(/[^0-9.]/g,'')" style="width: 200px;" />
          <!--          <el-input v-model="dialogForm.noreportqty" oninput="value=value.replace(/[^0-9.]/g,'')" style="width: 200px;" />-->
        </el-form-item>
        <el-form-item v-if="dialogTitle==='自制报工'" label="不良数量:">
          <el-input v-model="dialogForm.noputqty" oninput="value=value.replace(/[^0-9.]/g,'')" style="width: 200px;" />
        </el-form-item>
        <el-form-item v-if="dialogTitle==='自制报工'" label="不良原因:">
          <el-select
            v-model="dialogForm.badcode"
            style="width: 200px;"
            placeholder="请选择"
            :disabled="parseFloat(dialogForm.noputqty)===0||dialogForm.noputqty.trim()===''"
            multiple
          >
            <el-option
              v-for="item in badArr"
              :key="item.code"
              :label="item.name"
              :value="item.code"
            />
          </el-select>
        </el-form-item>
        <!--        <el-form-item v-if="dialogTitle==='自制报工'" label="报工人员:">-->
        <!--          <el-input v-model="dialogForm.remarks" type="textarea" style="width: 200px;" />-->
        <!--        </el-form-item>-->
        <el-form-item v-if="dialogTitle==='自制报工'" label="报工人:">
          <el-select
            v-model="dialogForm.operation"
            style="width: 200px;"
            placeholder="请选择"
          >
            <el-option
              v-for="item in OperationArr"
              :key="item.usercode"
              :label="item.username"
              :value="item.usercode"
            />
          </el-select>
        </el-form-item>
        <el-form-item v-if="dialogTitle==='自制报工'" label="备注:">
          <el-input v-model="dialogForm.remarks" type="textarea" style="width: 200px;" />
        </el-form-item>
        <div v-if="dialogTitle==='自制报工'">
          <i class="el-icon-s-operation" style="color:#42b983;" /> äººå‘˜åˆ—表
          <el-button type="primary" style="margin: 10px 0" @click="userAdd">增行</el-button>
          <el-table
            :data="userTableData"
            border
            :row-class-name="tableRowClassName"
            :header-cell-style="this.$headerCellStyle"
            :cell-style="this.$cellStyle"
            height="180"
            highlight-current-row
            style="width: 100%"
          >
            <el-table-column
              width="100"
              label="序号"
              type="index"
              fixed
            />
            <el-table-column
              prop="username"
              label="人员名称"
            >
              <template slot-scope="{row}">
                <div v-if="row.isVisible===0">{{ row.username }}</div>
                <el-select
                  v-if="row.isVisible===1"
                  v-model="row.username"
                  style="width: 200px;"
                  placeholder="请选择"
                  @change="val=>usernameChange(val,row)"
                >
                  <el-option
                    v-for="item in ZZuserArr"
                    :key="item.usercode"
                    :label="item.username"
                    :value="item.usercode"
                  />
                </el-select>
              </template>
            </el-table-column>
            <el-table-column
              prop="RowNum"
              label="操作"
              fixed="right"
            >
              <template slot-scope="{row}">
                <div class="operationClass">
                  <el-button v-if="row.isVisible===0" type="text" @click="userDel(row)">删除</el-button>
                  <el-button v-if="row.isVisible===1&&!userIsSave" type="text" @click="userSave(row)">保存</el-button>
                  <el-button v-if="row.isVisible===1" type="text" @click="userCancel(row)">取消</el-button>
                </div>
              </template>
            </el-table-column>
          </el-table>
          <!--分页-->
          <pagination
            :total="UserTotal"
            :page.sync="Userform.page"
            :limit.sync="Userform.rows"
            align="right"
            layout="total,prev, pager, next,sizes"
            popper-class="select_bottom"
            @pagination="getMesOrderStepSearch"
          />
        </div>
        <!--     å¤–协发料-->
        <el-form-item
          v-if="dialogTitle==='外协发料'"
          label="外协供方:"
          prop="wxcode"
        >
          <el-select
            v-model="dialogForm.wxcode"
            style="width: 200px;"
            placeholder="请选择"
            filterable
          >
            <el-option
              v-for="item in WXouterprovide"
              :key="item.code"
              :label="item.name"
              :value="item.code"
            />
          </el-select>
        </el-form-item>
        <el-form-item
          v-if="dialogTitle==='外协发料'"
          label="发料人员:"
          prop="outuser"
        >
          <el-select
            v-model="dialogForm.outuser"
            style="width: 200px;"
            placeholder="请选择"
            filterable
          >
            <el-option
              v-for="item in WXoutuser"
              :key="item.usercode"
              :label="item.username"
              :value="item.usercode"
            />
          </el-select>
        </el-form-item>
        <el-form-item
          v-if="dialogTitle==='外协发料'"
          label="发料数量:"
          prop="fqty"
        >
          <el-input v-model="dialogForm.fqty" oninput="value=value.replace(/[^0-9.]/g,'')" style="width: 200px;" />
        </el-form-item>
        <!--     å¤–协收料-->
        <el-form-item
          v-if="dialogTitle==='外协收料'"
          label="下道工序:"
        >
          <div style="width: 200px">{{ dialogForm.nextstepname }}</div>
        </el-form-item>
        <el-form-item
          v-if="dialogTitle==='外协收料'"
          label="外协供方:"
          prop="wxcode"
        >
          <el-select
            v-model="dialogForm.wxcode"
            style="width: 200px;"
            placeholder="请选择"
          >
            <el-option
              v-for="item in WXouterprovide"
              :key="item.code"
              :label="item.name"
              :value="item.code"
            />
          </el-select>
        </el-form-item>
        <el-form-item
          v-if="dialogTitle==='外协收料'"
          label="收料人员:"
          prop="inuser"
        >
          <el-select
            v-model="dialogForm.inuser"
            style="width: 200px;"
            placeholder="请选择"
          >
            <el-option
              v-for="item in WXoutuser"
              :key="item.usercode"
              :label="item.username"
              :value="item.usercode"
            />
          </el-select>
        </el-form-item>
        <el-form-item
          v-if="dialogTitle==='外协收料'"
          label="收料数量:"
          prop="sqty"
        >
          <el-input
            v-model="dialogForm.sqty"
            style="width: 200px"
            oninput="value=value.replace(/[^0-9.]/g,'')"
          />
        </el-form-item>
        <el-form-item
          v-if="dialogTitle==='外协收料'"
          label="不良数量:"
          prop="noputqty"
        >
          <el-input
            v-model="dialogForm.noputqty"
            style="width: 200px"
            oninput="value=value.replace(/[^0-9.]/g,'')"
          />
        </el-form-item>
        <el-form-item
          v-if="dialogTitle==='外协收料'"
          label="不良原因:"
        >
          <!--          prop="badcode"-->
          <el-select
            v-model="dialogForm.badcode"
            style="width: 200px;"
            multiple
            :disabled="parseFloat(dialogForm.noputqty)===0||dialogForm.noputqty.trim()===''"
            placeholder="请选择"
          >
            <el-option
              v-for="item in badArr"
              :key="item.code"
              :label="item.name"
              :value="item.code"
            />
          </el-select>
        </el-form-item>
        <el-form-item v-if="dialogTitle==='外协收料'" label="收料人:">
          <el-select
            v-model="dialogForm.operation"
            style="width: 200px;"
            placeholder="请选择"
          >
            <el-option
              v-for="item in OperationArr"
              :key="item.usercode"
              :label="item.username"
              :value="item.usercode"
            />
          </el-select>
        </el-form-item>
        <el-form-item v-if="dialogTitle==='外协收料'" label="备注:">
          <el-input v-model="dialogForm.remarks" type="textarea" style="width: 200px;" />
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <div class="footerButton">
          <el-button @click="dialogVisibleCancel">取 æ¶ˆ</el-button>
          <el-button v-if="dialogTitle==='自制开始'" type="primary" @click="dialogVisibleConfirm">开 å·¥</el-button>
          <el-button v-if="dialogTitle==='自制报工'" type="primary" @click="dialogVisibleConfirm">提交/打印</el-button>
          <el-button v-if="dialogTitle==='外协发料'" type="primary" @click="dialogVisibleConfirm">发料</el-button>
          <el-button v-if="dialogTitle==='外协收料'" type="primary" @click="dialogVisibleConfirm">收料/打印</el-button>
        </div>
      </span>
    </el-dialog>
    <!--打印预览页面  å°æ ‡ç­¾-->
    <el-dialog
      title="预览"
      :visible.sync="dialogVisible2"
      width="1140"
      top="10vh"
      :close-on-click-modal="false"
      @close="dialogVisible2Close"
    >
      <!-- è¦æ‰“印的区域 -->
      <div id="printMe2" style="padding: 30px;">
        <div
          style="display: flex;width: 280px;height: 150px;border: 1px solid #000;text-align: center;font-size: 10px;"
        >
          <div style="width: 90px;display: flex;flex-direction: column;border-right: 1px solid #000">
            <div
              style="display: flex;height: 90px;border-bottom:1px solid #000;
              justify-content: center;align-items: center;position: relative"
            >
              <div id="qrCode2" ref="qrCodeDiv2" style="overflow-y: hidden;height:60px;position: absolute;left: 14px;" />
            </div>
            <div style="display: flex;height: 30px;justify-content: flex-start;border-bottom:1px solid #000;align-items: center">
              <div style="margin-left: 5px;width: 28px">数量:</div>
              {{ qrForm.startqty }}
            </div>
            <div style="display: flex;height: 30px;justify-content: flex-start;align-items: center">
              <div style="margin-left: 5px;width: 42px">处理人:</div>
              {{ qrForm.operator }}
            </div>
          </div>
          <div style="width:190px;display: flex;flex-direction: column">
            <div
              style="display: flex;height: 20%;border-bottom:1px solid #000;justify-content: flex-start;align-items: center;text-align: left"
            >
              <div style="width: 60px;margin-left: 5px;">工单编号:</div>
              <div>{{ qrForm.wo_code }}</div>
            </div>
            <div
              style="display: flex;height: 20%;border-bottom:1px solid #000;justify-content: flex-start;align-items: center ;text-align: left"
            >
              <div style="width: 60px;margin-left: 5px;">产品编码:</div>
              <div>{{ qrForm.partcode }}</div>
            </div>
            <div
              style="display: flex;height: 20%;border-bottom:1px solid #000 ;justify-content: flex-start;align-items: center;text-align: left"
            >
              <div style="width:60px;margin-left: 5px;">产品名称:</div>
              <div>{{ qrForm.partname }}</div>
            </div>
            <div
              style="display: flex;height: 20%;border-bottom:1px solid #000 ;justify-content: flex-start;align-items: center;text-align: left"
            >
              <div style="width:60px;margin-left: 5px;">下道工序:</div>
              <div>{{ qrForm.nextstepname }}</div>
            </div>
            <div style="display: flex;height: 20%;justify-content: flex-start;align-items: center;text-align: left">
              <div style="width: 60px;margin-left: 5px;">处理时间:</div>
              <div>{{ qrForm.operatorTime }}</div>
            </div>
          </div>
        </div>
      </div>
      <span slot="footer" class="dialog-footer">
        <div class="footerButton">
          <el-button @click="dialogVisible2 = false">取 æ¶ˆ</el-button>
          <el-button v-print="printObj2" type="primary">ç¡® å®š</el-button>
        </div>
      </span>
    </el-dialog>
    <!--    ä¸è‰¯å¤„理列表对话框-->
    <el-dialog
      title="维修处理"
      :visible.sync="badDialogVisible"
      width="990px"
      class="badDialogVisible"
      top="10vh"
      :close-on-click-modal="false"
      @close="handleCloseBad"
      @closed="handleCloseBad"
    >
      <el-form
        inline
        :model="badDialogForm"
        label-width="110px"
      >
        <el-form-item label="工单编号:">
          <div style="width: 200px">{{ badDialogForm.wo_code }}</div>
        </el-form-item>
        <el-form-item label="产品编码:">
          <div style="width: 200px">{{ badDialogForm.partcode }}</div>
        </el-form-item>
        <el-form-item label="产品名称:">
          <div style="width: 200px">{{ badDialogForm.partname }}</div>
        </el-form-item>
        <el-form-item label="产品规格:">
          <div style="width: 200px">{{ badDialogForm.partspec }}</div>
        </el-form-item>
        <el-form-item label="当前工序:">
          <div style="width: 200px">{{ badDialogForm.stepname }}</div>
        </el-form-item>
        <el-form-item label="下道工序:">
          <div style="width: 200px">{{ badDialogForm.nextstepname }}</div>
        </el-form-item>
        <el-form-item label="任务数量:">
          <div style="width: 200px">{{ badDialogForm.plan_qty }}</div>
        </el-form-item>
        <el-form-item label="报工数量:">
          <div style="width: 200px">{{ badDialogForm.good_qty }}</div>
        </el-form-item>
        <el-form-item label="不良数量:">
          <div style="width: 200px">{{ badDialogForm.ng_qty }}</div>
        </el-form-item>
        <el-form-item label="维修人员:">
          <el-select
            v-model="badDialogForm.operation"
            style="width: 200px;"
            placeholder="请选择"
          >
            <el-option
              v-for="item in OperationArr"
              :key="item.usercode"
              :label="item.username"
              :value="item.usercode"
            />
          </el-select>
        </el-form-item>
      </el-form>
      <div style="margin-bottom:20px">
        <i class="el-icon-s-operation" style="color:#42b983;" /> ä¸è‰¯ä¿¡æ¯æ˜Žç»†ï¼š
      </div>
      <div class="elTableDiv">
        <el-table
          :data="badTableDataDialog"
          :height="isIpad? (tableHeight-350):(tableHeight-400)"
          border
          :row-class-name="tableRowClassName"
          :style="{width: 100+'%',height:(tableHeight-400)+'px',}"
          highlight-current-row
          :header-cell-style="this.$headerCellStyle"
          :cell-style="this.$cellStyle"
        >
          <el-table-column
            type="index"
            width="50"
            label="序号"
            fixed
          />
          <el-table-column
            prop="step_code"
            label="工序编码"
            min-width="80"
          />
          <el-table-column
            prop="stepname"
            label="工序名称"
            min-width="80"
          />
          <el-table-column
            prop="plan_qty"
            label="任务数量"
            width="80"
          />
          <el-table-column
            label="报工数量"
            width="80"
            prop="report_qty"
          />
          <el-table-column
            prop="ng_qty"
            label="不良数量"
            width="80"
          />
          <el-table-column
            prop="badqty"
            label="已报废数量"
            width="100"
          />
          <el-table-column
            prop="defect_name"
            label="不良原因"
            show-tooltip-when-overflow
            width="80"
          />
          <el-table-column
            prop="repair_qty"
            label="维修合格数量"
            width="110"
          >
            <template slot-scope="{row}">
              <!--              {{ row.repair_qty }}-->
              <div v-if="row.isVisible===0">{{ row.repair_qty }}</div>
              <el-input v-if="row.isVisible===1" v-model="row.repair_qty" oninput="value=value.replace(/[^0-9]/g,'')" />
            </template>
          </el-table-column>
          <el-table-column
            prop="bad_qty"
            label="报废数量"
            width="90"
          >
            <!--            oninput="value=value.replace(/[0-9]/g,'')"-->
            <template slot-scope="{row}">
              <div v-if="row.isVisible===0">{{ row.bad_qty }}</div>
              <el-input v-if="row.isVisible===1" v-model="row.bad_qty" oninput="value=value.replace(/[^0-9]/g,'')" />
            </template>
          </el-table-column>
          <el-table-column
            label="操作"
            width="100"
          >
            <template slot-scope="{row}">
              <div class="operationClass">
                <el-button v-if="row.isVisible===0" type="text" @click="badEdit(row)">编辑</el-button>
                <el-button v-if="row.isVisible===0" type="text" @click="badDel(row)">删除</el-button>
                <el-button v-if="row.isVisible===1" type="text" @click="badSave(row)">确认</el-button>
                <el-button v-if="row.isVisible===1" type="text" @click="badCancel(row)">取消</el-button>
              </div>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <span slot="footer" class="dialog-footer">
        <div class="footerButton">
          <el-button @click="badDialogVisibleCancel">取 æ¶ˆ</el-button>
          <el-button type="primary" @click="badDialogVisibleConfirm ">保 å­˜/打 å°</el-button>
        </div>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import Pagination from '@/components/Pagination'
import $ from 'jquery'
import {
  MesOrderGroupSelectUser,
  MesOrderSelectUser,
  MesOrderStepReportSelectUserGroup,
  MesOrderStepSearch,
  MesOrderStepStart,
  MesOrderStepStartSelectEqp,
  MesOrderWxStepSearch,
  MesOrderStepSelectWX,
  SavaMesOrderStepOut,
  MesOrderStepSelectCause,
  SavaMesOrderStepIn,
  SavaMesOrderStepStart,
  SavaMesOrderStepReport, MesOrderNgStepSearch, MesOrderNgSubStepSearch, EditOrderNgStepSeave
} from '@/api/scgl'
import { urlAddRandomNo, webapp_ws_ajax_run, webapp_ws_autoupdate } from '@/utils/grwebapp'
import QRCode from 'qrcodejs2'
import { getCookie } from '@/utils/auth'
import { handleDatetime2 } from '@/utils/global'
const SER_HZ = /^[\u4e00-\u9fa5]+$/
export default {
  name: 'SCKBG',
  components: {
    Pagination
  },
  data() {
    const validateName = (rule, value, callback) => {
      if (!value) {
        return callback(new Error('请输入编码'))
      } else {
        if (SER_HZ.test(value)) {
          return callback(new Error('编码不能为中文'))
        } else {
          callback()
        }
      }
    }
    const validateTypeCode = (rule, value, callback) => {
      if (!value) {
        return callback(new Error('请选择上级'))
      } else {
        callback()
      }
    }
    return {
      mainHeight: 0,
      tableHeight: 0,
      isIpad: false,
      // produceCode: '', // å·¥åºç 
      // WXproduceCode: '', // å¤–协工序码
      radioSelected: '', // å·¥åºé€‰ä¸­
      WXradioSelected: '', // å·¥åºé€‰ä¸­
      form: {
        orderstepqrcode: '', // æ‰«æçš„二维码信息
        prop: 'wo_code', // æŽ’序字段
        order: 'asc', // æŽ’序字段
        page: 1, // ç¬¬å‡ é¡µ
        rows: 20 // æ¯é¡µå¤šå°‘条
      },
      total: 10,
      tableData: [],
      WXform: { // å¤–协表单
        orderstepqrcode: '', // æ‰«æçš„二维码信息
        prop: 'wo_code', // æŽ’序字段z
        order: 'asc', // æŽ’序字段
        page: 1, // ç¬¬å‡ é¡µ
        rows: 20 // æ¯é¡µå¤šå°‘条
      },
      WXtotal: 10, // å¤–协表单总数
      WXtableData: [], // å¤–协表
      WXSelectArr: [// å¤–协类型下拉列表
        { code: 'OUT', name: '发料' },
        { code: 'IN', name: '收料' }
      ],
      WXSelected: 'OUT', // å¤–协下拉列表选中值
      dialogVisible: false,
      dialogTitle: '', // è‡ªåˆ¶å¼€å§‹ã€è‡ªåˆ¶æŠ¥å·¥ã€å¤–协发料、外协收料
      dialogForm: {
        wo_code: '', // å·¥å•编号
        partcode: '', // äº§å“ç¼–码
        partname: '', // äº§å“åç§°
        partspec: '', // äº§å“è§„æ ¼
        stepseq: '', // å·¥åºåºå·
        stepcode: '', // å·¥åºç¼–码
        stepname: '', // å½“前工序名
        nextstepname: '', // ä¸‹ä¸€é“工序名
        stepdesc: '', // å·¥åºæè¿°
        planqty: '', // ä»»åŠ¡æ•°é‡
        reportqty: '', // å·²æŠ¥æ•°é‡
        noreportqty: '', // æœªæŠ¥æ•°é‡
        startqty: '', // å¼€(报)工数量
        wxcode: '', // å¤–协供应商编码
        outuser: '', // å‘料人员
        taskqty: '', // ä»»åŠ¡æ•°é‡
        fqty: '', // å‘料数量
        inuser: '', // æ”¶æ–™äººå‘˜
        sqty: '', // æ”¶æ–™æ•°é‡
        ngqty: '', // ä¸è‰¯æ•°é‡
        badcode: '', // ä¸è‰¯åŽŸå› ç¼–ç 
        noputqty: '', // ä¸è‰¯æ•°é‡
        eqpcode: '', // ç”Ÿäº§è®¾å¤‡ç¼–码
        usergroupcode: '', // ç­ç»„编码
        reportuser: '', // æŠ¥å·¥äººå‘˜
        startqtySum: '', // ä¸èƒ½è¶…过的数值
        operation: getCookie('navTabId'), // æŠ¥å·¥äººï¼ˆæ”¶æ–™äººï¼‰
        remarks: ''// å¤‡æ³¨
      },
      ZZuserArr: [], // è‡ªåˆ¶ç”¨æˆ·æ‰€æœ‰
      ZZtreams: [], // è‡ªåˆ¶ç”Ÿäº§ç­ç»„数组
      ZZeqpArr: [], // è‡ªåˆ¶è®¾å¤‡åç§°
      badArr: [], // ä¸è‰¯åŽŸå› æ•°ç»„
      WXouterprovide: [], // å¤–协供方数组
      WXoutuser: [], // å‘料人员数组
      userTableData: [], // äººå‘˜åˆ—表
      UserTotal: 0,
      Userform: {},
      userIsSave: false, // æ­¤äººå‘˜æ˜¯å¦å¯ä¿æŒ
      dialogFormRules: {
        outuser: [
          { required: true, message: '请选择发料人员', trigger: ['blur', 'change'] }
        ],
        fqty: [
          { required: true, message: '请输入发料数量', trigger: ['blur', 'change'] }
        ],
        wxcode: [
          { required: true, message: '请选择外协供方', trigger: ['blur', 'change'] }
        ],
        inuser: [
          { required: true, message: '请选择收料人员', trigger: ['blur', 'change'] }
        ],
        sqty: [
          { required: true, message: '请输入收料数量', trigger: ['blur', 'change'] }
        ],
        // noputqty: [
        //   { required: true, message: '请输入不良数量', trigger: ['blur', 'change'] }
        // ],
        // badcode: [
        //   { required: true, message: '请选择不良原因', trigger: ['blur', 'change'] }
        // ]
        eqpcode: [
          { required: true, message: '请选择生产设备', trigger: ['blur', 'change'] }
        ],
        usergroupcode: [
          { required: true, message: '请选择生产班组', trigger: ['blur', 'change'] }
        ],
        startqty: [
          { required: true, message: '请输入报工数量', trigger: ['blur', 'change'] }
        ]
      },
      activeName: '',
      dialogVisible2: false,
      printObj2: {
        id: 'printMe2',
        popTitle: '打印模板',
        preview: false,
        extraHead: '<meta http-equiv="Content-Language" content="zh-cn"/>',
        closeCallback(vue) { // å…³é—­æ‰“印的回调事件(无法确定点击的是确认还是取消)
          console.log('11212', vue)
          // vue.dialogVisible = false
          vue.dialogVisible2 = false
          vue.dialogVisible = false
        },
        beforeOpenCallback(vue) {
          vue.printLoading = true
          console.log('打开之前')
          console.log()
        },
        openCallback(vue) {
          vue.printLoading = false
          console.log('执行了打印')
        }
      },
      qrForm: { // æ‰“印内容
        qrvalue: '',
        startqty: '',
        wo_code: '',
        partcode: '',
        partname: '',
        nextstepname: '',
        operator: '', // æ“ä½œäºº
        operatorTime: ''// æ“ä½œæ—¶é—´
      },
      badForm: {
        orderstepqrcode: '', // æ‰«æçš„二维码
        prop: 'wo_code',
        order: 'asc',
        page: 1,
        rows: 20
      },
      badTableData: [], // ä¸è‰¯å¤„理列表table数据
      badTotal: 0,
      badDialogVisible: false,
      badDialogForm: {
        operation: getCookie('navTabId')
      },
      badTableDataDialog: [], // ä¸è‰¯å¯¹è¯æ¡†table表格
      OperationArr: [], // äººå‘˜æ•°ç»„
      sendButtonIsDisabled: false // ä¸‹è¾¾æŒ‰é’®æ˜¯å¦å¯ç‚¹å‡»
    }
  },
  watch: {
    'form.orderstepqrcode': {
      handler(newValue) {
        this.form.orderstepqrcode = newValue
        // åœ¨è¿™é‡Œè°ƒç”¨ï¼Œå¹¶æ‰§è¡Œthis.fnThrottle(this.search, 500, 2000)();
        this.fnThrottle(this.enterNative, 500, 2000, 'produceCode')()
      }
    },
    'WXform.orderstepqrcode': {
      handler(newValue) {
        this.form.orderstepqrcode = newValue
        // åœ¨è¿™é‡Œè°ƒç”¨ï¼Œå¹¶æ‰§è¡Œthis.fnThrottle(this.search, 500, 2000)();
        this.fnThrottle(this.enterNative, 500, 2000, 'WXproduceCode')()
      }
    },
    'badForm.orderstepqrcode': {
      handler(newValue) {
        this.form.orderstepqrcode = newValue
        // åœ¨è¿™é‡Œè°ƒç”¨ï¼Œå¹¶æ‰§è¡Œthis.fnThrottle(this.search, 500, 2000)();
        this.fnThrottle(this.enterNative, 500, 2000, 'badProduceCode')()
      }
    }
  },
  // computed: {
  //   qrLink: function() {
  //     return this.$store.getters.getPreviewUrl
  //   }
  // },
  // watch: {
  //   qrLink: function(newVal, oldNew) {
  //     if (newVal !== oldNew) {
  //       this.$nextTick(() => {
  //         this.bindQRCode(newVal)
  //       })
  //     }
  //   }
  // },
  created() {
    this.getMesOrderStepSearch()
    this.tabClick()
  },
  mounted() {
    window.addEventListener('resize', this.getHeight)
    this.getHeight()
    this.$nextTick(() => {
      $("input[name='produceCode']")[0].focus()
      // this.bindQRCode('10001;001')
    })
    // webapp_urlprotocol_startup()
    // webapp_ws_autoupdate(true)
    this.getMesOrderSelectUserAll() // èŽ·å–æ‰€æœ‰äººå‘˜
  },
  methods: {
    // é˜²æŠ–      //扫码用的是防抖
    fnThrottle(method, delay, duration, belong) {
      var that = this
      var timer = this.timer
      var begin = new Date().getTime()
      return function() {
        var current = new Date().getTime()
        clearTimeout(timer)
        if (current - begin >= duration) {
          // method()
          // that.VALUE()
          begin = current
        } else {
          that.timer = setTimeout(function() {
            // method()
            if (belong === 'produceCode') {
              that.enterNative(that.form.orderstepqrcode, belong)
            }
            if (belong === 'WXproduceCode') {
              that.enterNative(that.WXform.orderstepqrcode, belong)
            }
            if (belong === 'badProduceCode') {
              that.enterNative(that.badForm.orderstepqrcode, belong)
            }
          }, delay)
        }
      }
    },
    tableRowClassName({ row, rowIndex }) {
      return 'custom-row'
    },
    async getMesOrderStepSearch() {
      const res = await MesOrderStepSearch(this.form)
      if (res.code === '200') {
        this.tableData = res.data
        this.total = res.count
      }
    },
    async getMesOrderWxStepSearch() {
      const res = await MesOrderWxStepSearch(this.WXform)
      if (res.code === '200') {
        this.WXtableData = res.data
      }
    },
    // æŽ’序改变时
    sortChange({ column, prop, order }) {
      if (order === 'descending') {
        order = 'desc'
      } else if (order === 'ascending') {
        order = 'asc'
      } else {
        order = 'desc'
      }
      this.form.order = order
      this.form.prop = prop
      this.getMesOrderStepSearch()
    },
    // WX排序改变时
    WXsortChange({ column, prop, order }) {
      if (order === 'descending') {
        order = 'desc'
      } else if (order === 'ascending') {
        order = 'asc'
      } else {
        order = 'desc'
      }
      this.WXform.order = order
      this.WXform.prop = prop
      this.getMesOrderWxStepSearch()
    },
    badSortChange({ column, prop, order }) {
      if (order === 'descending') {
        order = 'desc'
      } else if (order === 'ascending') {
        order = 'asc'
      } else {
        order = 'desc'
      }
      this.badForm.order = order
      this.badForm.prop = prop
      this.getBadList()
    },
    // è‡ªåˆ¶é¡µç­¾åŽŸç‚¹ç‚¹å‡»
    getCurrentRow(val) {
    },
    // å¤–协页签原点点击
    getWXCurrentRow(val) {
      console.log(val)
      this.WXradioSelected = val
    },
    // tab按钮切换鼠标自动聚焦
    tabClick(val, d) {
      if (this.$refs.elTabs.currentName === '0') {
        this.$nextTick(() => {
          this.getMesOrderStepSearch()
          $("input[name='produceCode']")[0].focus()
          this.WXform.orderstepqrcode = ''
        })
      }
      if (this.$refs.elTabs.currentName === '1') {
        this.$nextTick(() => {
          this.getMesOrderWxStepSearch()
          $("input[name='WXproduceCode']")[0].focus()
          this.form.orderstepqrcode = ''
        })
      }
      if (this.$refs.elTabs.currentName === '2') {
        this.$nextTick(() => {
          this.getBadList()
          $("input[name='badProduceCode']")[0].focus()
          this.badForm.orderstepqrcode = ''
        })
      }
    },
    // æ‰«ç é”®ç›˜å›žè½¦äº‹ä»¶
    async enterNative(val, belong) {
      console.log(val, belong)
      // å¼€å·¥ï¼šcode="200"  count=0
      // æŠ¥å·¥ï¼šcode="200"  count=1
      // å‘料:code="200"  count=2
      // æ”¶æ–™ï¼šcode="200"  count=3
      // èµ°åˆ—表形式 code="200"  count=4
      if (belong === 'produceCode') {
        const orderstepqrcode = this.form.orderstepqrcode
        const data = {
          OperType: 'ZZ',
          orderstepqrcode: orderstepqrcode,
          SelectType: ''
        }
        const res = await MesOrderStepStart(data)
        if (res.code === '200' && res.count === 0) {
          await this.ZZstart(res.data)
        }
        if (res.code === '200' && res.count === 1) {
          await this.ZZreport(res.data)
        }
      }
      if (belong === 'WXproduceCode') {
        const orderstepqrcode = this.WXform.orderstepqrcode
        const data = {
          OperType: 'WX',
          orderstepqrcode: orderstepqrcode,
          SelectType: this.WXSelected// OUT、IN
        }
        const res = await MesOrderStepStart(data)
        if (res.code === '200' && res.count === 2) {
          await this.WXsend(res.data)
        }
        if (res.code === '200' && res.count === 3) {
          await this.WXback(res.data)
        }
      }
      if (belong === 'badProduceCode') {
        // this.badForm.orderstepqrcode=
        await this.getBadList()
        await this.repairHandle(this.badForm.orderstepqrcode)
        this.badDialogVisible = true
      }
    },
    // æŸ¥è¯¢
    search() {
      this.getMesOrderStepSearch()
    },
    // è‡ªåˆ¶å¼€å§‹
    async ZZstart(obj) {
      // if (!this.ZZisExecutable) {
      //   return this.$message.info('请先扫码工序二维码!')
      // }
      this.dialogTitle = '自制开始'
      this.dialogVisible = true
      this.$nextTick(() => {
        this.dialogForm.wo_code = obj.wo_code
        this.dialogForm.partcode = obj.partnumber
        this.dialogForm.partname = obj.partname
        this.dialogForm.partspec = obj.partspec
        this.dialogForm.stepseq = obj.seq
        this.dialogForm.stepcode = obj.stepcode
        this.dialogForm.stepname = obj.stepname
        this.dialogForm.stepdesc = obj.stepdesc
        this.dialogForm.planqty = obj.planqty
        this.dialogForm.reportqty = obj.reportqty
        this.dialogForm.noreportqty = obj.noreportqty
        // this.dialogForm.startqty = obj.startqty
        this.dialogForm.startqty = obj.noreportqty
      })
      await this.getMesOrderStepStartSelectEqp()
    },
    // è‡ªåˆ¶æŠ¥å·¥
    async ZZreport(obj) {
      // if (!this.ZZisExecutable) {
      //   return this.$message.info('请先扫码工序二维码!')
      // }
      this.dialogTitle = '自制报工'
      this.dialogVisible = true
      this.$nextTick(() => {
        this.dialogForm.wo_code = obj.wo_code
        this.dialogForm.partcode = obj.partnumber
        this.dialogForm.partname = obj.partname
        this.dialogForm.partspec = obj.partspec
        this.dialogForm.stepseq = obj.seq
        this.dialogForm.stepcode = obj.stepcode
        this.dialogForm.stepname = obj.stepname
        this.dialogForm.stepdesc = obj.stepdesc
        this.dialogForm.planqty = obj.planqty
        this.dialogForm.reportqty = obj.reportqty
        this.dialogForm.noputqty = obj.noputqty
        this.dialogForm.noreportqty = obj.noreportqty
        // this.dialogForm.startqty = obj.startqty
        this.dialogForm.startqty = obj.noreportqty
        this.dialogForm.nextstepname = obj.nextstepname
        this.dialogForm.nextstepcode = obj.nextstepcode
        this.dialogForm.startqtySum = obj.noreportqty
      })
      await this.getMesOrderStepStartSelectEqp()
      await this.getMesOrderStepReportSelectUserGroup()
      await this.getMesOrderStepSelectCause('ZZ')
      await this.getMesOrderSelectUserZZ()
    },
    // å¤–协发料
    async WXsend(obj) {
      // if (this.WXradioSelected.length < 1 && obj.length < 1) {
      //   return this.$message.info('请先选择工序!')
      // }
      // console.log(this.WXform.orderstepqrcode === '', 6)
      // if (this.WXform.orderstepqrcode === '') {
      //   return this.$message.info('请先输入工序!')
      // }
      this.dialogTitle = '外协发料'
      this.dialogVisible = true
      this.$nextTick(() => {
        this.dialogForm.wo_code = obj.wo_code
        this.dialogForm.partcode = obj.partnumber
        this.dialogForm.partname = obj.partname
        this.dialogForm.partspec = obj.partspec
        this.dialogForm.stepname = obj.stepname
        this.dialogForm.stepdesc = obj.stepdesc
        this.dialogForm.planqty = obj.planqty
        this.dialogForm.reportqty = obj.reportqty
        this.dialogForm.noreportqty = obj.noreportqty
        this.dialogForm.fqty = obj.startqty
        this.dialogForm.stepcode = obj.stepcode
        this.dialogForm.stepseq = obj.seq
      })
      await this.getMesOrderStepSelectWX()
      await this.getMesOrderSelectUser()
    },
    // å¤–协收料
    async WXback(obj) {
      // if (this.WXform.orderstepqrcode === '') {
      //   return this.$message.info('请先输入工序!')
      // }
      this.dialogTitle = '外协收料'
      this.dialogVisible = true
      this.$nextTick(() => {
        this.dialogForm.wo_code = obj.wo_code
        this.dialogForm.partcode = obj.partnumber
        this.dialogForm.partname = obj.partname
        this.dialogForm.partspec = obj.partspec
        this.dialogForm.stepname = obj.stepname
        this.dialogForm.stepdesc = obj.stepdesc
        this.dialogForm.planqty = obj.planqty
        this.dialogForm.reportqty = obj.reportqty
        this.dialogForm.noreportqty = obj.noreportqty
        this.dialogForm.stepcode = obj.stepcode
        this.dialogForm.nextstepname = obj.nextstepname
        this.dialogForm.nextstepcode = obj.nextstepcode
        this.dialogForm.noputqty = obj.noputqty
        this.dialogForm.stepseq = obj.seq
        this.dialogForm.sqty = obj.startqty
        this.dialogForm.startqtySum = obj.startqty
      })
      await this.getMesOrderStepSelectWX()
      await this.getMesOrderSelectUser()
      await this.getMesOrderStepSelectCause('WX')
    },
    // ç”Ÿäº§ç­ç»„下拉改变
    usergroupChange(val) {
      this.dialogForm.usergroupcode = val
      this.getMesOrderSelectUserZZ2()
    },
    // èŽ·å–è‡ªåˆ¶æŠ¥å·¥ç”Ÿäº§ç­ç»„ä¸‹æ‹‰åˆ—è¡¨
    async getMesOrderStepReportSelectUserGroup() {
      const { data: res } = await MesOrderStepReportSelectUserGroup()
      this.ZZtreams = res
    },
    // èŽ·å–è‡ªåˆ¶æŠ¥å·¥è¡¨æ ¼user所有
    async getMesOrderSelectUserZZ() {
      const { data: res } = await MesOrderSelectUser({ usercode: this.dialogForm.usergroupcode })
      this.ZZuserArr = res
    },
    async getMesOrderSelectUserZZ2() {
      const { data: res } = await MesOrderSelectUser({ usercode: '' })
      this.ZZuserArr = res
      await this.getUserTableData()
    },
    // èŽ·å–è‡ªåˆ¶ç”Ÿäº§è®¾å¤‡ä¸‹æ‹‰
    async getMesOrderStepStartSelectEqp() {
      const { data: res } = await MesOrderStepStartSelectEqp({ orderstepqrcode: this.form.orderstepqrcode })
      this.ZZeqpArr = res
    },
    // èŽ·å–WX供方接口
    async getMesOrderStepSelectWX() {
      const { data: res } = await MesOrderStepSelectWX({ orderstepqrcode: this.WXform.orderstepqrcode })
      this.WXouterprovide = res
    },
    // èŽ·å–æ”¶å‘æ–™äººå‘˜ä¸‹æ‹‰æŽ¥å£
    async getMesOrderSelectUser() {
      const { data: res } = await MesOrderSelectUser({ usercode: this.dialogForm.outuser })
      this.WXoutuser = res
    },
    // èŽ·å–æ”¶æ–™ä¸è‰¯åŽŸå› ä¸‹æ‹‰
    async getMesOrderStepSelectCause(val) {
      let orderstepqrcode = ''
      if (val === 'WX') {
        orderstepqrcode = this.WXform.orderstepqrcode
      }
      if (val === 'ZZ') {
        orderstepqrcode = this.form.orderstepqrcode
      }
      const { data: res } = await MesOrderStepSelectCause({ orderstepqrcode: orderstepqrcode })
      this.badArr = res
    },
    // æŠ¥å·¥æŸ¥è¯¢ç”¨æˆ·è¡¨
    async getUserTableData() {
      const { data: res } = await MesOrderGroupSelectUser({ usergroupcode: this.dialogForm.usergroupcode })
      this.userTableData = res
      this.userTableData.forEach(item => {
        let number = Math.random() * Math.random()// ä½œä¸ºåˆ é™¤æ—¶çš„æ ‡è¯†ç¬¦
        number = number === 0 ? (10 + Math.random()) : number
        item.isVisible = 0
        item.number = number
      })
      this.ZZuserArr = [...this.ZZuserArr].filter(x => [...this.userTableData].every(y => y.usercode !== x.usercode))
    },
    // ç”¨æˆ·æ·»åŠ 
    userAdd() {
      let number = Math.random() * Math.random()// ä½œä¸ºåˆ é™¤æ—¶çš„æ ‡è¯†ç¬¦
      number = number === 0 ? (10 + Math.random()) : number
      console.log(this.userTableData, 6)
      this.userTableData.unshift({ usercode: '', username: '', isVisible: 1, number: number })
    },
    // ç”¨æˆ·åˆ—表删除
    userDel(row) {
      this.ZZuserArr.splice(0, 0, {
        usercode: row.usercode,
        username: row.username
      })
      this.userTableData.forEach((item, index) => {
        if (item.number === row.number) {
          this.userTableData.splice(index, 1)
        }
      })
    },
    // ç”¨æˆ·åˆ—表保存
    userSave(row) {
      console.log(row, 123)
      if (row.usercode === '') {
        return this.$message.info('人员名称不能为空!')
      }
      this.ZZuserArr.forEach((item, index) => {
        if (item.usercode === row.usercode) {
          this.ZZuserArr.splice(index, 1)
        }
      })
      this.userTableData.forEach(item => {
        if (item.number === row.number) {
          item.isVisible = 0
        }
      })
    },
    // ç”¨æˆ·åˆ—表取消
    userCancel(row) {
      this.userTableData.forEach((item, index) => {
        if (item.number === row.number) {
          this.userTableData.splice(index, 1)
        }
      })
    },
    // ç”¨æˆ·åˆ—表人员名称值选中
    usernameChange(val, row) {
      this.userTableData.forEach(item => {
        if (item.usercode === val) {
          this.userIsSave = true
          return this.$message.info('此人员已在列中!')
        }
        if (item.number === row.number) {
          this.userIsSave = false
          item.usercode = val
          item.username = this.ZZuserArr.find(item => item.usercode === val).username
        }
      })
    },
    // å¯¹è¯æ¡†å…³é—­äº‹ä»¶
    handleClose() {
      this.form.orderstepqrcode = ''
      this.WXform.orderstepqrcode = ''
      this.badForm.orderstepqrcode = ''
      this.dialogForm.wo_code = '', // å·¥å•编号
      this.dialogForm.partcode = '', // äº§å“ç¼–码
      this.dialogForm.partname = '', // äº§å“åç§°
      this.dialogForm.partspec = '', // äº§å“è§„æ ¼
      this.dialogForm.stepseq = '', // å·¥åºåºå·
      this.dialogForm.stepcode = '', // å·¥åºç¼–码
      this.dialogForm.stepname = '', // å½“前工序名
      this.dialogForm.nextstepname = '', // ä¸‹ä¸€é“工序名
      this.dialogForm.stepdesc = '', // å·¥åºæè¿°
      this.dialogForm.planqty = '', // ä»»åŠ¡æ•°é‡
      this.dialogForm.reportqty = '', // å·²æŠ¥æ•°é‡
      this.dialogForm.noreportqty = '', // æœªæŠ¥æ•°é‡
      this.dialogForm.startqty = '', // å¼€(报)工数量
      this.dialogForm.wxcode = '', // å¤–协供应商编码
      this.dialogForm.outuser = '', // å‘料人员
      this.dialogForm.taskqty = '', // ä»»åŠ¡æ•°é‡
      this.dialogForm.fqty = '', // å‘料数量
      this.dialogForm.inuser = '', // æ”¶æ–™äººå‘˜
      this.dialogForm.sqty = '', // æ”¶æ–™æ•°é‡
      this.dialogForm.ngqty = '', // ä¸è‰¯æ•°é‡
      this.dialogForm.badcode = '', // ä¸è‰¯åŽŸå› ç¼–ç 
      this.dialogForm.noputqty = '', // ä¸è‰¯æ•°é‡
      this.dialogForm.eqpcode = '', // ç”Ÿäº§è®¾å¤‡ç¼–码
      this.dialogForm.usergroupcode = '', // ç­ç»„编码
      this.dialogForm.reportuser = '', // æŠ¥å·¥äººå‘˜
      this.dialogForm.startqtySum = '' // ä¸èƒ½è¶…过的数值
      this.dialogForm.nextstepcode = '' // ä¸‹é“工序编码
      this.dialogForm.remarks = '' // å¤‡æ³¨
      this.dialogForm.operation = getCookie('navTabId') // æŠ¥å·¥äººï¼ˆæ”¶æ–™äººï¼‰
      this.userTableData = [] // äººå‘˜åˆ—表
      this.$refs.dialogForm.clearValidate()
    },
    // å¯¹è¯æ¡†å–消
    dialogVisibleCancel() {
      this.dialogVisible = false
      this.tabClick()
    },
    // å¯¹è¯æ¡†ç¡®è®¤
    dialogVisibleConfirm() {
      this.$refs.dialogForm.validate(valid => {
        if (valid) {
          if (this.dialogTitle === '外协发料') {
            if (parseFloat(this.dialogForm.fqty) > parseFloat(this.dialogForm.noreportqty)) {
              return this.$message.info('发料数量不能大于未发数量!')
            }
            const data = {
              mesordercode: this.dialogForm.wo_code, // å·¥å•编号
              partcode: this.dialogForm.partcode, // äº§å“ç¼–码
              stepseq: this.dialogForm.stepseq, // å·¥åºåºå·   æš‚时缺
              stepcode: this.dialogForm.stepcode, // å·¥åºç¼–码
              wxcode: this.dialogForm.wxcode, // å¤–协供应商编码
              outuser: this.dialogForm.outuser, // å‘料人员
              taskqty: this.dialogForm.planqty, // ä»»åŠ¡æ•°é‡
              fqty: this.dialogForm.fqty // å‘料数量
            }
            SavaMesOrderStepOut(data).then(res => {
              if (res.code === '200') {
                this.$message.success('发料成功!')
                this.dialogVisible = false
                this.tabClick()
              } else {
                this.$message.error('发料失败!')
              }
            })
          }
          if (this.dialogTitle === '外协收料') {
            if (parseFloat(this.dialogForm.startqtySum) < parseFloat(this.dialogForm.sqty) + parseFloat(this.dialogForm.noputqty)) {
              return this.$message.info('收料数量加不良数量不能大于了未收数量!')
            }
            if (parseFloat(this.dialogForm.noputqty) > 0) {
              if (this.dialogForm.badcode.length < 1) {
                return this.$message.info('请选择不良原因!')
              }
            }
            const data = {
              mesordercode: this.dialogForm.wo_code, // å·¥å•编号
              partcode: this.dialogForm.partcode, // äº§å“ç¼–码
              stepseq: this.dialogForm.stepseq, // å·¥åºåºå·
              stepcode: this.dialogForm.stepcode, // å·¥åºç¼–码
              wxcode: this.dialogForm.wxcode, // å¤–协供应商编码
              inuser: this.dialogForm.inuser, // å‘料人员
              taskqty: this.dialogForm.planqty, // ä»»åŠ¡æ•°é‡
              sqty: this.dialogForm.sqty, // æ”¶æ–™æ•°é‡
              remarks: this.dialogForm.remarks, // å¤‡æ³¨
              ngqty: this.dialogForm.noputqty === '' ? 0 : this.dialogForm.noputqty, // ä¸è‰¯æ•°é‡
              badcode: this.dialogForm.badcode.length < 1 ? '' : this.dialogForm.badcode.join(';')// ä¸è‰¯åŽŸå› 
            }
            SavaMesOrderStepIn(data).then(res => {
              if (res.code === '200') {
                this.$message.success('收料成功!')
                if (this.dialogForm.nextstepcode === '') {
                  this.WXprint2(this.OperationArr.find(item => item.usercode === this.dialogForm.operation).username)
                  this.dialogVisible2 = true
                }
                this.dialogVisible = false
                this.tabClick()
              } else {
                this.$message.error('收料失败!')
              }
            })
          }
          if (this.dialogTitle === '自制开始') {
            const data = {
              mesordercode: this.dialogForm.wo_code, // å·¥å•编号
              partcode: this.dialogForm.partcode, // äº§å“ç¼–码
              stepseq: this.dialogForm.stepseq, // å·¥åºåºå·   æš‚时缺
              stepcode: this.dialogForm.stepcode, // å·¥åºç¼–码
              eqpcode: this.dialogForm.eqpcode, // ç”Ÿäº§è®¾å¤‡
              taskqty: this.dialogForm.planqty, // ä»»åŠ¡æ•°é‡
              startqty: this.dialogForm.startqty// å¼€å§‹æ•°é‡
            }
            SavaMesOrderStepStart(data).then(res => {
              if (res.code === '200') {
                this.$message.success('开工成功!')
                this.dialogVisible = false
                this.tabClick()
              } else {
                this.$message.error('开工失败!')
              }
            })
          }
          if (this.dialogTitle === '自制报工') {
            if (parseFloat(this.dialogForm.startqtySum) < parseFloat(this.dialogForm.startqty) + parseFloat(this.dialogForm.noputqty)) {
              return this.$message.info('报工数量加不良数量不能大于了未报数量!')
            }
            if (this.userTableData.length < 1) {
              return this.$message.info('人员列表不能为空!')
            }
            if (parseFloat(this.dialogForm.noputqty) > 0) {
              if (this.dialogForm.badcode.length < 1) {
                return this.$message.info('请选择不良原因!')
              }
            }
            // this.userTableData = [...new Set(this.userTableData)]// æ•°ç»„去重
            this.userTableData = this.userTableData.filter(item => item.usercode !== '')
            // æ•°ç»„中对象相同的去重
            this.userTableData = this.userTableData.filter((currentValue, currentIndex, selfArr) => {
              return selfArr.findIndex(item => item.usercode === currentValue.usercode) === currentIndex
            })
            // console.log(this.userTableData, 1)
            const reportuser = this.userTableData.map(item => item.usercode).join(';')
            const data = {
              mesordercode: this.dialogForm.wo_code, // å·¥å•编号
              partcode: this.dialogForm.partcode, // äº§å“ç¼–码
              stepseq: this.dialogForm.stepseq, // å·¥åºåºå·
              stepcode: this.dialogForm.stepcode, // å·¥åºç¼–码
              eqpcode: this.dialogForm.eqpcode, // è®¾å¤‡ç¼–码
              usergroupcode: this.dialogForm.usergroupcode, // ç­ç»„编码
              reportuser: reportuser, // æŠ¥å·¥äººå‘˜
              taskqty: this.dialogForm.planqty, // ä»»åŠ¡æ•°é‡
              // startqty: this.dialogForm.startqty, // å¼€å·¥æ•°é‡
              startqty: this.dialogForm.reportqty, // å¼€å·¥æ•°é‡
              // reportqty: this.dialogForm.reportqty, // æŠ¥å·¥æ•°é‡
              reportqty: this.dialogForm.startqty, // æŠ¥å·¥æ•°é‡
              remarks: this.dialogForm.remarks, // å¤‡æ³¨
              ngqty: this.dialogForm.noputqty === '' ? 0 : this.dialogForm.noputqty, // ä¸è‰¯æ•°é‡
              badcode: this.dialogForm.badcode.length < 1 ? '' : this.dialogForm.badcode.join(';')// ä¸è‰¯åŽŸå› 
            }
            SavaMesOrderStepReport(data).then(res => {
              if (res.code === '200') {
                this.$message.success('报工成功!')
                if (this.dialogForm.nextstepcode === '') {
                  this.ZZprint2(this.OperationArr.find(item => item.usercode === this.dialogForm.operation).username)
                  this.dialogVisible2 = true
                }
                this.dialogVisible = false
                this.tabClick()
              } else {
                this.$message.error('报工失败!')
              }
            })
          }
        }
      })
    },
    // ç”ŸæˆäºŒç»´ç 
    bindQRCode(text) {
      new QRCode(this.$refs.qrCodeDiv2, {
        text: text,
        // width: 50,
        width: 60,
        // height: 50,
        height: 60,
        colorDark: '#000', // äºŒç»´ç é¢œè‰²
        colorLight: '#ffffff', // äºŒç»´ç èƒŒæ™¯è‰²
        correctLevel: QRCode.CorrectLevel.L// å®¹é”™çŽ‡ï¼ŒL/M/H
      })
    },
    ZZprint2(username) {
      this.qrForm.qrvalue = this.dialogForm.wo_code + ';' + this.dialogForm.nextstepcode
      this.qrForm.startqty = this.dialogForm.startqty
      this.qrForm.wo_code = this.dialogForm.wo_code
      this.qrForm.partcode = this.dialogForm.partcode
      this.qrForm.partname = this.dialogForm.partname
      this.qrForm.nextstepname = this.dialogForm.nextstepname
      this.qrForm.operator = username
      this.qrForm.operatorTime = handleDatetime2(new Date())
      this.$nextTick(() => {
        this.bindQRCode(this.qrForm.qrvalue)
      })
    },
    WXprint2(username) {
      this.qrForm.qrvalue = this.dialogForm.wo_code + ';' + this.dialogForm.nextstepcode
      this.qrForm.startqty = this.dialogForm.sqty
      this.qrForm.wo_code = this.dialogForm.wo_code
      this.qrForm.partcode = this.dialogForm.partcode
      this.qrForm.partname = this.dialogForm.partname
      this.qrForm.nextstepname = this.dialogForm.nextstepname
      this.qrForm.operator = username
      this.qrForm.operatorTime = handleDatetime2(new Date())
      this.$nextTick(() => {
        this.bindQRCode(this.qrForm.qrvalue)
      })
    },
    dialogVisible2Close() {
      this.qrForm.qrvalue = ''
      this.qrForm.startqty = ''
      this.qrForm.wo_code = ''
      this.qrForm.partcode = ''
      this.qrForm.partname = ''
      this.qrForm.nextstepname = ''
      this.qrForm.operator = ''
      this.qrForm.operatorTime = ''
      // this.$refs.qrCodeDiv2 = ''
    },
    // èŽ·å–é¡µé¢é«˜åº¦
    getHeight() {
      this.$nextTick(() => {
        this.mainHeight = window.innerHeight - 85
        this.tableHeight = this.mainHeight - 220
        this.isIpad = window.innerHeight < 769
        if (window.innerHeight < 769) {
          this.tableHeight = this.tableHeight - 50
        }
      })
    },
    // èŽ·å–ä¸è‰¯å¤„ç†åˆ—è¡¨
    async getBadList() {
      const res = await MesOrderNgStepSearch(this.badForm)
      this.badTableData = res.data
      this.badTotal = res.count
    },
    badDialogVisibleCancel() {
      this.badDialogVisible = false
    },
    badDialogVisibleConfirm() {
      const data = {
        Data: this.badTableDataDialog
      }
      EditOrderNgStepSeave(data, this.badDialogForm.operation).then(res => {
        if (res.code === '200' || res.code === '301') {
          this.getBadList()
          this.badDialogVisible = false
          this.badPrint(this.OperationArr.find(item => item.usercode === this.badDialogForm.operation).username)
          this.dialogVisible2 = true
          return this.$message.success('保存成功!')
        }
      })
    },
    badPrint(username) {
      this.qrForm.qrvalue = this.badDialogForm.wo_code + ';' + this.badDialogForm.nextstepcode
      this.qrForm.startqty = this.badDialogForm.plan_qty
      this.qrForm.wo_code = this.badDialogForm.wo_code
      this.qrForm.partcode = this.badDialogForm.partcode
      this.qrForm.partname = this.badDialogForm.partname
      this.qrForm.nextstepname = this.badDialogForm.nextstepname
      this.qrForm.operator = username
      this.qrForm.operatorTime = handleDatetime2(new Date())
      console.log(this.qrForm, 22)
      this.$nextTick(() => {
        this.bindQRCode(this.qrForm.qrvalue)
      })
    },
    handleCloseBad() {
      this.badDialogForm = {}
      this.badDialogForm.operation = getCookie('navTabId')
      this.badTableDataDialog = []
    },
    async  getMesOrderSelectUserAll() {
      const { data: res } = await MesOrderSelectUser({ usercode: '' })
      this.OperationArr = res
    },
    // ç‚¹å‡»ç»´ä¿®å¤„理按钮  æˆ–  æ‰«ææ¡ç çš„æ‰«æå›žè½¦äº‹ä»¶
    async repairHandle(row) {
      let data
      if (row.wo_code) {
        data = {
          orderstepqrcode: row.wo_code + ';' + row.stepcode
        }
      } else {
        data = {
          orderstepqrcode: row
        }
      }
      const { data: res } = await MesOrderNgSubStepSearch(data)
      this.$nextTick(() => {
        this.badDialogForm.wo_code = res.data1.wo_code
        this.badDialogForm.partcode = res.data1.partnumber
        this.badDialogForm.partname = res.data1.partname
        this.badDialogForm.partspec = res.data1.partspec
        this.badDialogForm.stepname = res.data1.stepname
        this.badDialogForm.nextstepcode = res.data1.nextstepcode
        this.badDialogForm.nextstepname = res.data1.nextstepname
        this.badDialogForm.plan_qty = res.data1.planqty
        this.badDialogForm.good_qty = res.data1.noreportqty // æŠ¥å·¥æ•°é‡
        this.badDialogForm.ng_qty = res.data1.noputqty // ä¸è‰¯æ•°é‡
        this.badTableDataDialog = res.data2
        this.badTableDataDialog.forEach(item => {
          item.repair_qty = 0
          item.bad_qty = 0
          item.isVisible = 0
          // item.defect_code = [...new Set(item.defect_code.split(','))].join(',')
          // item.defect_name = [...new Set(item.defect_name.split(','))].join(',')
        })
        console.log(this.badTableDataDialog, 321)
        this.badDialogVisible = true
      })
    },
    badEdit(row) {
      console.log(row)
      this.badTableDataDialog.forEach((item, index) => {
        if (item.id === row.id && item.m_id === row.m_id) {
          this.badTableDataDialog.splice(index, 1, {
            bad_qty: row.bad_qty,
            repair_qty: row.repair_qty,
            isVisible: 1,
            defect_code: row.defect_code,
            defect_name: row.defect_name,
            badqty: row.badqty,
            id: row.id,
            m_id: row.m_id,
            materiel_code: row.materiel_code,
            ng_qty: row.ng_qty,
            plan_qty: row.plan_qty,
            report_qty: row.report_qty,
            seq: row.seq,
            step_code: row.step_code,
            stepname: row.stepname,
            style: row.style,
            wo_code: row.wo_code
          })
        }
      })
    },
    badSave(row) {
      if (parseFloat(row.bad_qty) + parseFloat(row.repair_qty) > parseFloat(row.ng_qty)) {
        this.badCancel(row)
        return this.$message.info('维修数量与报废数量之和不能大于不良数量!')
      }
      this.badTableDataDialog.forEach((item, index) => {
        if (item.id === row.id && item.m_id === row.m_id) {
          this.badTableDataDialog.splice(index, 1, {
            bad_qty: parseFloat(row.bad_qty),
            repair_qty: parseFloat(row.repair_qty),
            isVisible: 0,
            defect_code: row.defect_code,
            defect_name: row.defect_name,
            id: row.id,
            m_id: row.m_id,
            badqty: row.badqty,
            materiel_code: row.materiel_code,
            ng_qty: row.ng_qty,
            plan_qty: row.plan_qty,
            report_qty: row.report_qty,
            seq: row.seq,
            step_code: row.step_code,
            stepname: row.stepname,
            style: row.style,
            wo_code: row.wo_code
          })
        }
      })
    },
    badCancel(row) {
      this.badTableDataDialog.forEach((item, index) => {
        if (item.id === row.id && item.m_id === row.m_id) {
          this.badTableDataDialog.splice(index, 1, {
            // bad_qty: row.bad_qty,
            // repair_qty: row.repair_qty,
            bad_qty: 0,
            repair_qty: 0,
            isVisible: 0,
            defect_code: row.defect_code,
            defect_name: row.defect_name,
            id: row.id,
            m_id: row.m_id,
            badqty: row.badqty,
            materiel_code: row.materiel_code,
            ng_qty: row.ng_qty,
            plan_qty: row.plan_qty,
            report_qty: row.report_qty,
            seq: row.seq,
            step_code: row.step_code,
            stepname: row.stepname,
            style: row.style,
            wo_code: row.wo_code
          })
        }
      })
    },
    badDel(row) {
      this.badTableDataDialog.forEach((item, index) => {
        if (item.id === row.id && item.m_id === row.m_id) {
          this.badTableDataDialog.splice(index, 1)
        }
      })
    }
  }
}
</script>
<style lang="scss" scoped>
$main_color: #42b983;
.el-button--text {
  font-size: 14px;
  cursor: pointer;
}
.operationClass {
  height: 23px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}
::v-deep .el-checkbox.is-bordered + .el-checkbox.is-bordered {
  margin: 10px 30px 0px 0;
}
::v-deep .el-radio__input.is-checked + .el-radio__label {
  color: $main_color;
}
::v-deep .el-radio.is-bordered + .el-radio.is-bordered {
  margin: 10px 30px 0px 0;
}
//.dialogVisible{
::v-deep .el-select .el-input .el-select__caret {
  display: flex;
  align-items: center;
  justify-content: center;
}
//}
.elTableDiv {
  ::v-deep .el-radio__label {
    display: none;
  }
}
</style>
<style media="print">
/*@media print {*/
@page {
  size: auto;
  margin: 3mm;
  font-size: 10px;
}
</style>
<!--公共页面样式-->
<style lang="scss" scoped>
$main_color: #42b983;
::v-deep .el-button--text {
  font-size: 14px;
  cursor: pointer;
}
.el-icon-share, .el-icon-delete, .el-icon-edit-outline {
  color: $main_color;
  cursor: pointer;
}
.el-icon-edit-outline {
  margin-right: 15px;
}
::v-deep .el-button--primary, .el-button--default, .el-button--info {
  height: 34px;
  display: flex;
  align-items: center;
  padding: 0 15px;
}
::v-deep .el-button--primary {
  //background-color: $main_color !important;
}
::v-deep .el-button--default {
  background-color: #f8f8fa;
  border: none;
}
::v-deep .el-input__inner {
  height: 34px;
  line-height: 34px;
  //color: #a7a7a7;
}
::v-deep .el-dialog__body {
  padding: 20px 100px !important;
}
::v-deep .dialogVisibleRoles .el-dialog__body {
  padding: 20px 20px !important;
}
::v-deep .importPickerClass .el-dialog__body {
  padding: 20px 20px !important;
}
::v-deep .badDialogVisible .el-dialog__body {
  padding: 20px 20px !important;
}
::v-deep .el-dialog__footer {
  display: flex;
  justify-content: flex-end;
}
::v-deep .el-table .caret-wrapper {
  transform: scale(0.8);
}
::v-deep .cell {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
::v-deep .el-table::before {
  height: 0;
}
::v-deep .el-table__body-wrapper {
  background-color: #f8f8fa;
}
::v-deep .el-table__body .el-table__row.hover-row td {
  background-color: #eaecef;
}
::v-deep .el-form--inline .el-form-item__label {
  color: #a7a7a7;
}
.body ::v-deep .el-divider {
  border: 1px solid #eee;
  width: 99%;
  margin: 10px auto;
}
.body ::v-deep .el-form-item {
  margin-bottom: 0;
}
</style>
<style>
.el-table .custom-row {
  background: #f8f8fa;
}
</style>
src/views/zlgl/gxjy.vue
@@ -13,7 +13,9 @@
          <el-input
            v-model="form.orderstepqrcode"
            name="GXproduceCode"
            style="width: 300px"
            @keyup.native="e=>judgeIsScanning(e,'GXproduceCode')"
            @keyup.enter.native="val=>enterNative(val,'GXproduceCode')"
          />
        </div>
@@ -396,7 +398,8 @@
      multipleSelection: [], // è¡¨æ ¼å¤šé€‰æ¡†
      tabClickIndex: null, // ç‚¹å‡»çš„单元格
      tabClickLabel: '', // å½“前点击的列名
      isCancel: false// æ˜¯å¦ç‚¹å‡»å–消按钮
      isCancel: false, // æ˜¯å¦ç‚¹å‡»å–消按钮
      judgeIsScanningArr: []// åˆ¤æ–­æ˜¯å¦æ‰«ç æ•°ç»„
    }
  },
  created() {
@@ -499,6 +502,42 @@
      row.name = res.name
      row.stepcheckitem_desc = res.descr
    },
    // é˜²æŠ–      //扫码用的是防抖
    fnThrottle(method, delay, duration, belong) {
      var that = this
      var timer = this.timer
      var begin = new Date().getTime()
      return function() {
        var current = new Date().getTime()
        clearTimeout(timer)
        if (current - begin >= duration) {
          // method()
          // that.VALUE()
          begin = current
        } else {
          that.timer = setTimeout(function() {
            // method()
            that.enterNative(that.form.orderstepqrcode, belong)
          }, delay)
        }
      }
    },
    // åˆ¤æ–­æ˜¯å¦æ˜¯æ‰«ç æžªæ‰«ç 
    judgeIsScanning(e, belong) {
      const timenow = e.timeStamp
      let flag = true
      this.judgeIsScanningArr.push(timenow)
      let i
      for (i in this.judgeIsScanningArr) {
        flag = Math.ceil(this.judgeIsScanningArr[this.judgeIsScanningArr.length - 1]) - Math.ceil(this.judgeIsScanningArr[this.judgeIsScanningArr.length - 2]) < 10
        if (i > 0 && this.judgeIsScanningArr.length === parseInt(i) + 1) {
          if (flag) {
            this.fnThrottle(this.enterNative, 500, 2000, belong)()
            return
          }
        }
      }
    },
    // æ‰«ç é”®ç›˜å›žè½¦äº‹ä»¶
    async enterNative(val, belong) {
      if (belong === 'GXproduceCode') {