繁体   English   中英

多个数据同时进入全日历

[英]Multiple data enters the full calendar at the same time

使用名为 showBom(index) 的按钮将数据放入表中。 将此表拖到日历中。 问题在于,按下 showBom(index) 按钮后,立即将尽可能多的数据输入到日历中。 为什么?

日历和可拖动的父级

  methods: {
    async showBom(index) {
      this.$store.commit('setBomData', []) 
      this.bomDatas = this.getBomData ? [...this.getBomData] : []

      this.showBomModal.fill(false)
      this.showBomModal = this.showBomModal.map(() => false)
      this.showBomModal[index] = true
      this.openedBomIndex = index

      const productUnit = this.planDatas[index].product_unit;
      const { id } = this.planDatas[index];
      this.$store.commit('setSelectedPlanId', id);

      this.setBomProductUnit(productUnit);

      this.$store.commit('setProductUnitData', productUnit)
      await this.$store.dispatch('getBom', { product_unit: productUnit })

      console.log(productUnit, id)
    },

单击 showBom 时出现的表格和日历

<!-- eslint-disable-next-line no-unused-vars -->
<!-- eslint-disable-next-line no-restricted-syntax -->
<template>
  <div class="bom">
    <div class="bomTable-processList">
      <div>
        <table>
          <thead>
            <tr>
              <th colspan="6">BOM 관리</th>
            </tr>
            <tr>
              <th>미완 <input type="radio" aria-label="미완" name="bom" /></th>
              <th>작성중 <input type="radio" aria-label="작성중" name="bom" /></th>
              <th>작성완료 <input type="radio" aria-label="작성완료" name="bom" /></th>
              <th colspan="3"><button @click="putBom()">완료</button></th>
            </tr>
          </thead>
          <tbody id="external-events">
            <tr
              class="fc-event"
              v-for="(bomData, index) in getBomData"
              :key="index"
              draggable="true"
              @dragstart="handleDragStart($event, bomData)"
            >
                <td v-for="(process, pIndex) in bomData.process" :key="pIndex">{{ process }}</td>
              <td class="minusBtn">
                <button @click="deleteBom( bomDatas[index])">-</button>
              </td>
              <td class="upBtn">
                <button @click="moveRowUp(index)">▲</button>
              </td>
              <td class="downBtn">
                <button @click="moveRowDown(index)">▼</button>
              </td>
            </tr>
          </tbody>
        </table>
      </div>
      <processList />
    </div>
    <equipmentList />
    <div class="full">
      <div id="external-events"></div>
      <div id="calendar-container" @drop="handleDrop" @dragover="handleDragOver">
        <FullCalendar
          class="demo-app-calendar"
          ref="fullCalendar"
          :options="calendarOptions"
          :editable="true"
          :events="calendarEvents"
          @eventAdd="onEventAdd"
          @eventClick="handleEventClick"
          @drop="handleDrop"
          droppable="true"
        />
      </div>
    </div>
  </div>
</template>
<script lang="js">
import processList from '@/components/detail/processList.vue'
import equipmentList from '@/components/detail/equipmentList.vue'

import { mapGetters } from 'vuex'

import FullCalendar from '@fullcalendar/vue'
import dayGridPlugin from '@fullcalendar/daygrid'
import interactionPlugin, { Draggable } from '@fullcalendar/interaction'
import resourceTimelinePlugin from '@fullcalendar/resource-timeline'

export default {
  components: {
    FullCalendar,
    processList,
    equipmentList,
  },
  data() {
    return {
      draggedData: null,
      calendarOptions: {
        schedulerLicenseKey: 'CC-Attribution-NonCommercial-NoDerivatives',
        plugins: [dayGridPlugin, interactionPlugin, resourceTimelinePlugin],
        initialView: 'dayGrid1',
        slotDuration: '24:00:00',
        resources: [],
        events: [],
        height: 600,
        headerToolbar: {
          left: 'prev,next today',
          center: 'title',
          right: 'dayGrid1,dayGrid2',
        },
        views: {
          dayGrid1: {
            type: 'resourceTimelineDay',
            duration: { days: 30 },
            buttonText: '15',
          },
          dayGrid2: {
            type: 'resourceTimelineDay',
            duration: { days: 60 },
            buttonText: '30',
          },
        },
        dayHeaderFormat: {
          weekday: 'short',
          month: 'numeric',
          day: 'numeric',
          omitCommas: true,
        },
        editable: true,
        droppable: true,
        eventResizableFromStart: true,
        eventDidMount: this.handleEventMount,
      },
      removeAfterDrop: false,
      calendarEvents: [],
    }
  },
  watch: {
    getBomData: {
      handler() {
        this.$nextTick(() => {
          this.initializeDraggable();
        });
      },
      deep: true,
      immediate: true,
    },
    facilityDatas: {
      deep: true,
      handler() {
        this.calendarOptions.resources = this.facilityDatas.map((facility, index) => ({
          id: index.toString(),
          title: facility.facility_name,
        }))
      },
    },
  },
  computed: {
    ...mapGetters(['getBomData', 'getProductUnitData', 'getFacilityData']),
    facilityDatas: {
      get() {
        return this.getFacilityData
      },
      set(value) {
        const updatedValue = value.map((item) => ({
          ...item,
        }))
        this.$store.commit('setFacilityData', updatedValue)
      },
    },
    bomDatas: {
      get() {
        return this.$store.getters.getBomData;
      },
      set(value) {
        const updatedValue = value.map((item) => ({
          ...item,
        }))
        this.$store.commit('setBomData', updatedValue)
      },
    },
    productUnit() {
      return this.getProductUnitData
    },
  },
  async mounted() {
    const payload = {
      product_unit: this.productUnit,
    }
    await this.$store.dispatch('getBom', payload)
    this.bomDatas = this.getBomData ? [...this.getBomData] : []

    this.calendarOptions.resources = this.facilityDatas.map((facility, index) => ({
      id: index.toString(),
      title: facility.facility_name,
    }))

    await this.initializeDraggable()

    this.fullCalendar = this.$refs.fullCalendar.$refs.calendar
  },
  methods: {
    moveRowUp(index) {
      if (index > 0) {
        const temp = { ...this.bomDatas[index] }
        const prevData = { ...this.bomDatas[index - 1] }

        const tempProcessOrder = temp.process_order
        temp.process_order = prevData.process_order
        prevData.process_order = tempProcessOrder

        this.$set(this.bomDatas, index, prevData)
        this.$set(this.bomDatas, index - 1, temp)
        this.bomDatas = [...this.bomDatas]
      }
    },

    moveRowDown(index) {
      if (index < this.bomDatas.length - 1) {
        const temp = { ...this.bomDatas[index] }
        const nextData = { ...this.bomDatas[index + 1] }

        const tempProcessOrder = temp.process_order
        temp.process_order = nextData.process_order
        nextData.process_order = tempProcessOrder

        this.$set(this.bomDatas, index, nextData)
        this.$set(this.bomDatas, index + 1, temp)
        this.bomDatas = [...this.bomDatas]
      }
    },
    async putBom() {
      for (const bomData of this.bomDatas) {
        if (bomData.id) {
          const { id, process_order } = bomData
          await this.$store.dispatch('putBom', { id, process_order })
        }
      }

      const payload = {
        product_unit: this.productUnit,
      }
      await this.$store.dispatch('getBom', payload)
    },

    async deleteBom(bomData) {
      console.log(bomData)
      if (window.confirm('정말로 삭제하시겠습니까?')) {
        await this.$store.dispatch('deleteBom', {
          product_unit: bomData.product_unit,
          process_order: bomData.process_order,
        });

        const payload = {
          product_unit: this.productUnit,

        }
        await this.$store.dispatch('getBom', payload)
      }
    },
    handleEventClick(info) {
      if (confirm('삭제하시겠습니까?')) {
        info.event.remove()
        const index = this.calendarEvents.findIndex((event) => event.id === info.event.id)
        if (index !== -1) {
          this.calendarEvents.splice(index, 1)
        }
      }
    },
    handleEventMount(info) {
      const eventEl = info.el
      eventEl.addEventListener('dblclick', () => {
        this.handleEventClick(info)
      })
    },
    onEventAdd(info) {
      const { event } = info

      const newEvent = {
        title: event.title,
        start: event.start,
        allDay: event.allDay,
      }
      this.calendarEvents.push(newEvent)
    },
    handleDragStart(event, bomData) {
      event.preventDefault()
      if (bomData) {
        event.dataTransfer.setData('text', JSON.stringify(bomData))
        this.draggedData = {
          product_unit: bomData.product_unit,
          process_name: bomData.process,
        }
      } else {
        console.error('bomData is undefined or null')
      }
    },

    handleDrop(event) {
      event.preventDefault()
      const dragData = this.draggedData
      this.draggedData = null

      if (dragData) {
        const dateClickedArg = {
          date: this.fullCalendar.getApi().getDate(),
          allDay: true,
        }

        const newEvent = {
          title: `${dragData.product_unit} - ${dragData.process}`,
          start: dateClickedArg.date,
          allDay: dateClickedArg.allDay,
        }

        this.calendarEvents.push(newEvent)

        if (this.removeAfterDrop) {
          const index = this.bomDatas.findIndex((data) => data === dragData)
          if (index !== -1) {
            this.bomDatas.splice(index, 1)
          }
        }
      }
    },
    initializeDraggable() {
      const containerEl = document.getElementById('external-events')
      if (containerEl) {
        const eventElements = containerEl.getElementsByClassName('fc-event')
        Array.from(eventElements).forEach((eventEl, index) => {
          new Draggable(eventEl, {
            eventData: () => {
              const bomData = this.bomDatas[index]
              return {
                title: `${bomData.product_unit} - ${bomData.process}`,
              }
            },
          })
          eventEl.addEventListener('dragstart', (event) => {
            const bomData = this.bomDatas[index]
            const dragData = {
              product_unit: bomData.product_unit,
              process_name: bomData.process_name,
            }
            event.dataTransfer.setData('text', JSON.stringify(bomData))
            this.draggedData = dragData
          })
        })

        const calendarContainerEl = document.getElementById('calendar-container')
        if (calendarContainerEl) {
          calendarContainerEl.addEventListener('drop', this.handleDrop)
          calendarContainerEl.addEventListener('dragover', this.handleDragOver)
        }
      }
    },
    handleDragOver(event) {
      event.preventDefault()
    },
  },
}
</script>

这是一个错误的视频。 https://youtu.be/ss0SatTlyXA

 watch: {
    getBomData: {
      handler() {
        this.$nextTick(() => {
          this.initializeDraggable();
        });
      },
      deep: true,
      immediate: true,
    },
}

我删除了上面的部分并从挂载中调用它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM