小小儁爺
2026-01-21 527250b10d6ecda0a8f3f9ea426dbe0bbc630a2c
src/views/gantt/index.vue
@@ -15,6 +15,20 @@
          :value="item.code"
        />
      </el-select>
      <el-select
        v-model="priorityMethod"
        size="mini"
        style="margin-left: 10px;"
        placeholder="请选择"
        @change="prepareArrange"
      >
        <el-option
          v-for="item in priorityMethodArr"
          :key="item.code"
          :label="item.name"
          :value="item.code"
        />
      </el-select>
      <el-date-picker
        v-model="ganttDateRange"
        style="margin-left: 10px;"
@@ -57,6 +71,7 @@
import { gantt } from '@/components/dhtmlxGantt'
import '@/components/dhtmlxGantt/codebase/dhtmlxgantt.css'
import { handleDateReduceOneDay, handleDatetime, handleDatetime2 } from '@/utils/global'
import { nanoid } from 'nanoid'
export default {
  data() {
@@ -77,7 +92,13 @@
      allTasks: [], // 存储所有任务数据
      paginatedTasks: [], // 当前页的任务数据
      fivePeriodsTimeName: ['OneStartDate', 'TwoStartDate', 'ThreeStartDate', 'FourStartDate', 'FiveStartDate']// 五个时间段的键名
      fivePeriodsTimeName: ['OneStartDate', 'TwoStartDate', 'ThreeStartDate', 'FourStartDate', 'FiveStartDate'], // 五个时间段的键名
      needArrangeNumber: 5000, // 假设需要排产数量5000
      priorityMethod: 'device', // device 设备   time  时间
      priorityMethodArr: [
        { code: 'device', name: '设备优先' },
        { code: 'time', name: '时间优先' }
      ]
    }
  },
  mounted() {
@@ -232,62 +253,6 @@
      /* ↑↑↑ Grid Columns configuration ↑↑↑ */
      // 汉化窗口
      gantt.locale.labels = {
        dhx_cal_today_button: '今天',
        day_tab: '日',
        week_tab: '周',
        month_tab: '月',
        new_event: '新建日程',
        icon_save: '保存',
        icon_cancel: '关闭',
        icon_details: '详细',
        icon_edit: '编辑',
        icon_delete: '删除',
        confirm_closing: '请确认是否撤销修改!', // Your changes will be lost, are your sure?
        confirm_deleting: '是否删除计划?',
        section_description: '描述:',
        section_resources: '自定义选择:',
        section_calendar: '自定义选择2:',
        section_time: '时间范围:',
        section_type: '类型:',
        section_text: '计划名称:',
        section_test: '测试:',
        section_projectClass: '项目类型:',
        taskProjectType_0: '项目任务',
        taskProjectType_1: '普通任务',
        section_head: '负责人:',
        section_priority: '优先级:',
        taskProgress: '任务状态',
        taskProgress_0: '未开始',
        taskProgress_1: '进行中',
        taskProgress_2: '已完成',
        taskProgress_3: '已延期',
        taskProgress_4: '搁置中',
        section_template: 'Details',
        /* grid columns */
        column_text: '计划名称',
        column_start_date: '开始时间',
        column_duration: '持续时间',
        column_add: '',
        column_priority: '难度',
        /* link confirmation */
        link: '关联',
        confirm_link_deleting: '将被删除',
        message_ok: '确定',
        message_cancel: '取消',
        link_start: ' (开始)',
        link_end: ' (结束)',
        type_task: '任务',
        type_project: '项目',
        type_milestone: '里程碑',
        minutes: '分钟',
        hours: '小时',
        days: '天',
        weeks: '周',
        months: '月',
        years: '年'
      }
      // gantt.config.order_branch = true
      // gantt.config.open_tree_initially = true
@@ -301,7 +266,11 @@
        // console.log(JSON.parse(JSON.stringify(task)))
        // return '<b>任务:</b> ' + task.text + '<br/><b>开始时间:</b> ' + `${gantt.date.date_to_str('%Y-%m-%d')(start)}` + '<br/><b>结束时间:</b> ' + handleDateReduceOneDay(end)
        // return '<b>任务:</b> ' + task.text + '<br/><b>开始时间:</b> ' + handleDatetime2(start) + '<br/><b>结束时间:</b> ' + handleDateReduceOneDay(end) + '<br/><b>进度:</b> ' + task.progress * 100 + '%'
        return '<b>任务:</b> ' + task.text + '<br/><b>开始时间:</b> ' + handleDatetime2(start) + '<br/><b>结束时间:</b> ' + handleDatetime2(end) + '<br/><b>进度:</b> ' + task.progress * 100 + '%'
        return '<b>任务:</b> ' + task.text +
          '<br/><b>生产数量:</b> ' + task.producedCount +
          '<br/><b>进度:</b> ' + task.progress * 100 + '%' +
          '<br/><b>开始时间:</b> ' + handleDatetime2(start) +
          '<br/><b>结束时间:</b> ' + handleDatetime2(end)
      }
      gantt.templates.task_text = function(start, end, task) {
@@ -312,7 +281,8 @@
        // return task.progress * 100 + '%'
        if (task.type === 'task2') {
          return `<div  class="task2Css">`
          return `<div  class="task2Css">${task.producedCount}</div>`
          // return task.producedCount
        }
        if (task.type === 'task3') {
          return `<div  class="task3Css">`
@@ -521,8 +491,8 @@
            {
              'AdvaDevicNumber': 'SB001',
              'AdvaDevicName': '设备001',
              'AdvaDevicCropMob': '30',
              'AdvaDevicRhythm': '5.0',
              'AdvaDevicCropMob': '30', // 稼动率    需要除100
              'AdvaDevicRhythm': '5.0', // 生产节拍
              'OneStartDate': '08:00~11:30',
              'TwoStartDate': '13:00~18:00',
              'ThreeStartDate': '',
@@ -533,22 +503,6 @@
        }
      ]
      // {
      //   'id': 3,
      //   'text': '设备:金工车间1号设备',
      //   saleOrder: 'SO-2025-05001',
      //   'calendar_id': 'customCalendar1',
      //   partName: '跑步机',
      //   partCode: 'Run01',
      //   description: '排产数量:500 报工数量:100 进度:20%',
      //   'type': 'task',
      //   'start_date': '2025-04-07 00:00',
      //   'parent': '2',
      //   'duration': 4,
      //   'progress': 0,
      //   checked: false
      // },
      const newArr = []
      // 这一步的操作主要是要做产能背景的显示
      rows.forEach((item, index) => {
@@ -558,10 +512,11 @@
          item.children.forEach((it, ind) => {
            // console.log(JSON.stringify(it))
            // 这里应该要生成一个以设备维度为基础的数组   不重不漏
            if (!this.allTasks.map(i => i.partCode).includes(it.AdvaDevicNumber)) {
            if (!newArr.map(i => i.partCode).includes(it.AdvaDevicNumber)) {
              console.log(' it.AdvaDevicNumber,', it.AdvaDevicNumber)
              newArr.push({
                id: it.AdvaDevicNumber,
                type: 'task',
                type: 'project',
                text: '任务名称预留',
                partName: it.AdvaDevicName,
                partCode: it.AdvaDevicNumber,
@@ -573,25 +528,29 @@
                parent: 0,
                saleOrder: 'SO-2026-01001'
              })
              // console.log(this.allTasks, 'allTasks')
            }
            // 因为是五个时间段,所有要有个循环次数为5的循环
            for (let i = 0; i < 5; i++) {
              // console.log(item.YearDate + ' ' + it[this.fivePeriodsTimeName[i]].split('~')[0])
            for (let i = 0; i < 5; i++) { // 这次循环是为了显示产能
              if (it[this.fivePeriodsTimeName[i]]) {
                const duration = this.calculateTimeRangeInMinutes(it[this.fivePeriodsTimeName[i]]) // 工期 单位 分钟
                newArr.push({
                  id: index.toString() + ind.toString() + i.toString(),
                  // id:  index.toString() + ind.toString() + i.toString(),
                  id: nanoid(),
                  type: 'task',
                  text: '任务名称预留',
                  partName: it.AdvaDevicName,
                  partCode: it.AdvaDevicNumber,
                  start_date: item.YearDate + ' ' + it[this.fivePeriodsTimeName[i]].split('~')[0],
                  duration: this.calculateTimeRangeInMinutes(it[this.fivePeriodsTimeName[i]]),
                  start_date: handleDatetime2(item.YearDate + ' ' + it[this.fivePeriodsTimeName[i]].split('~')[0]),
                  duration,
                  checked: false,
                  progress: 0,
                  parent: it.AdvaDevicNumber,
                  saleOrder: 'SO-2026-01001'
                  saleOrder: 'SO-2026-01001',
                  //  要在每一个时间段内算出能生产多少个     工期(分钟)乘以60 除以生产节拍 * 稼动率
                  producedCount: (duration * 60 / it.AdvaDevicRhythm) * (it.AdvaDevicCropMob / 100),
                  AdvaDevicRhythm: it.AdvaDevicRhythm, // 生产节拍
                  AdvaDevicCropMob: it.AdvaDevicCropMob // 稼动率    需要除100
                })
              }
            }
@@ -824,9 +783,11 @@
        }
      ]
      this.totalTasks = this.allTasks.length
      this.updatePaginatedTasks()
      this.renderGanttChart()
      // this.totalTasks = this.allTasks.length
      // this.updatePaginatedTasks()
      // this.renderGanttChart()
      this.prepareArrange()
    },
    // 更新分页后的任务数据
@@ -834,6 +795,7 @@
      const startIndex = (this.currentPage - 1) * this.pageSize
      const endIndex = Math.min(startIndex + this.pageSize, this.allTasks.length)
      this.paginatedTasks = this.allTasks.slice(startIndex, endIndex)
      // this.paginatedTasks = JSON.parse(JSON.stringify(this.allTasks.slice(startIndex, endIndex)))
    },
    // 拆分时间字符串并分别计算分钟值
@@ -911,6 +873,7 @@
    // 页大小改变
    handleSizeChange(newSize) {
      console.log('执行2')
      this.pageSize = newSize
      this.currentPage = 1 // 重置到第一页
      this.updatePaginatedTasks()
@@ -920,6 +883,7 @@
    // 当前页改变
    handleCurrentChange(newPage) {
      console.log('执行1')
      // 计算最大页数,防止超出范围
      const maxPage = Math.ceil(this.totalTasks / this.pageSize)
      if (newPage > maxPage) {
@@ -982,6 +946,63 @@
      // 显示提示信息
      this.$notify.success('已清空所有选择')
    },
    // 预排
    prepareArrange() {
      this.allTasks = this.allTasks.filter(i => i.type !== 'task2')
      // 优先方式  time  device
      if (this.priorityMethod === 'time') {
        this.allTasks.sort((a, b) => a.start_date - b.start_date)
      }
      if (this.priorityMethod === 'device') {
        this.allTasks.sort((a, b) => Number(a.partCode.replace(/\D/g, '')) - Number(b.partCode.replace(/\D/g, '')))
        // this.allTasks.sort((a, b) => Number(b.partCode.replace(/\D/g, '')) - Number(a.partCode.replace(/\D/g, '')))
        // this.allTasks.sort((a, b) => a.producedCount - b.producedCount)
      }
      const newArr = []
      let needArrangeNumber = this.needArrangeNumber
      this.allTasks.forEach(item => {
        if (item.type === 'task') {
          console.log(JSON.parse(JSON.stringify(item)))
          const count = needArrangeNumber > 0 && needArrangeNumber <= item.producedCount ? needArrangeNumber : item.producedCount
          needArrangeNumber = needArrangeNumber - item.producedCount // 剩余待排值
          if (count > 0 && (needArrangeNumber > 0 || Math.abs(needArrangeNumber) < item.producedCount)) { // 一定是大于零且小于整条的生产值的
            // duration  最后一条的数据应该是通过计算得出时间长度的
            const duration = (count / (item.AdvaDevicCropMob / 100)) * item.AdvaDevicRhythm / 60
            newArr.push({
              id: nanoid(),
              type: 'task2',
              text: '任务名称111',
              partName: item.partName,
              partCode: item.partCode,
              start_date: handleDatetime2(item.start_date),
              // duration: item.duration,
              duration: duration,
              checked: false,
              progress: 0,
              parent: item.parent,
              saleOrder: item.saleOrder,
              producedCount: count <= item.producedCount ? count : item.producedCount
            })
          }
        }
      })
      console.log(JSON.parse(JSON.stringify(newArr)), 'newArr')
      // for (let i = 0; i < this.allTasks.length; i++) {
      //
      // }
      this.allTasks = [...this.allTasks, ...newArr]
      // console.log(JSON.parse(JSON.stringify(this.allTasks)), '77')
      console.log(JSON.parse(JSON.stringify(this.allTasks)), '888')
      this.totalTasks = this.allTasks.length
      this.updatePaginatedTasks()
      this.renderGanttChart()
    }
  }