SOURCE

console 命令行工具 X clear

                    
>
console
<!DOCTYPE html>
<html lang="ch">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        #app {
            margin: 12px;
        }

        .month-box {
            display: flex;
            justify-content: space-between;
            align-items: center;
            background: darkolivegreen;
            border-radius: 2px;
        }

        .month-cell {
            width: 8.3333%;
            height: 32px;
            display: flex;
            justify-content: center;
            align-items: center;
        }

        .task-box {
            margin-bottom: 24px;
            border: 1px dotted yellowgreen;
            border-radius: 5px;
            position: relative;
            z-index: 3;
        }

        .task-row {
            width: 100%;
            height: 1px;
            position: absolute;
            top: 0;
            z-index: 5;
            background: grey;
        }

        .task-cell {
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            font-size: 12px;
            cursor: pointer;
            border: 1px solid grey;
            border-radius: 3px;
            position: absolute;
            left: 0;
            top: 0;
            z-index: 10;
            transition: all .5s ease .2s;
        }

        .text-test {
            width: 600px;
            height: 200px;
        }
    </style>
</head>

<body>
    <div id="app">
        <div class="month-box" :style="{width: 12 * cellWidth + 'px'}">
            <span class="month-cell">1 月</span>
            <span class="month-cell">2 月</span>
            <span class="month-cell">3 月</span>
            <span class="month-cell">4 月</span>
            <span class="month-cell">5 月</span>
            <span class="month-cell">6 月</span>
            <span class="month-cell">7 月</span>
            <span class="month-cell">8 月</span>
            <span class="month-cell">9 月</span>
            <span class="month-cell">10 月</span>
            <span class="month-cell">11 月</span>
            <span class="month-cell">12 月</span>
        </div>
        <div class="task-box" :style="{width: 12 * cellWidth + 'px', height: rows * cellHeight + 'px'}">
            <div class="task-row" v-for="row in rows" :key="row" :style="{top: row * cellHeight - 1 + 'px'}"></div>
            <div class="task-cell" v-for="(item, index) in taskList" :key="index" @click="showDetail(item)"
                :style="{width: cellWidth * (item.end - item.start + 1) + 'px', height: cellHeight + 'px', left: item.style.left + 'px', top: item.style.top + 'px', background: `linear-gradient(to right, ${randomColor(0.2)}, ${randomColor(0.2)})`}">
                <p>{{item.start}} - {{item.end}}</p>
            </div>
        </div>

        <textarea class="text-test" resize="none"></textarea>
    </div>

    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.13/vue.min.js"></script>
    <script>
        let cellWidth = 128,
            cellHeight = 54
        /*
        const taskList = [
            {
                name: '1-2',
                start: 1,
                end: 2,
                style: {}
            }, {
                name: '1-2',
                start: 1,
                end: 2,
                style: {}
            }, {
                name: '3-5',
                start: 3,
                end: 5,
                style: {}
            }, {
                name: '6-7',
                start: 6,
                end: 7,
                style: {}
            }, {
                name: '4-4',
                start: 4,
                end: 4,
                style: {}
            }, {
                name: '2-11',
                start: 2,
                end: 11,
                style: {}
            }, {
                name: '1-5',
                start: 1,
                end: 5,
                style: {}
            }, {
                name: '8-11',
                start: 8,
                end: 11,
                style: {}
            }, {
                name: '3-5',
                start: 3,
                end: 5,
                style: {}
            }, {
                name: '1-1',
                start: 1,
                end: 1,
                style: {}
            }, {
                name: '7-12',
                start: 7,
                end: 12,
                style: {}
            }, {
                name: '3-7',
                start: 3,
                end: 7,
                style: {}
            }, {
                name: '12-12',
                start: 12,
                end: 12,
                style: {}
            }, {
                name: '6-6',
                start: 6,
                end: 6,
                style: {}
            }]
        */
        const num = randomNum(8, 12),
            taskList = []
        for (let i = 0; i < num; i++) {
            let start = randomNum(1, 12), end = randomNum(1, 12)
            taskList.push({
                name: `${Math.min(start, end)}-${Math.max(start, end)}`,
                start: Math.min(start, end),
                end: Math.max(start, end),
                style: {}
            })
        }
        function createArr(len = 1, val = 0) {
            let res = Object.prototype.toString.call(val), value = val
            /* if (res === '[object Object]') {
                value = { ...val }
            } else if (res === '[object Array]') {
                value = [...val]
            }
            value = JSON.parse(JSON.stringify(value)) */
            const arr = []
            for (let i = 0; i < len; i++) {
                arr.push(value)
            }
            return arr
        }

        function createSectionArr(start, end) {
            if (start === end) {
                return [start]
            }
            const arr = []
            for (let i = start; i <= end; i++) {
                arr.push(i)
            }
            return arr
        }

        console.log(taskList)

        const hashMonthData = {},
            hashStartMonthData = {}
        taskList.forEach((item, index) => {
            const { start, end } = item
            for (let i = start; i <= end; i++) {
                if (!hashMonthData[i]) {
                    hashMonthData[i] = 1
                } else {
                    hashMonthData[i]++
                }
            }
            if (!hashStartMonthData[start]) {
                hashStartMonthData[start] = [item]
            } else {
                hashStartMonthData[start].push(item)
            }
        })
        console.log(hashMonthData)
        console.log(hashStartMonthData)
        const rows = Math.max(...Object.values(hashMonthData))
        console.log('rows: ', rows)
        // const taskPhoto = createArr(rows, createArr(12, 0))
        const taskPhoto = []
        for (let i = 0; i < rows; i++) {
            taskPhoto.push(createArr(12, 0))
        }
        console.log('taskPhoto: ', taskPhoto)

        for (const key in hashStartMonthData) {
            const arr = hashStartMonthData[key]
            // console.log(`起始月${key}月 arr: `, arr)
            // 1月
            if (key === '1') {
                console.log('一月!!!')
                console.log('arr.length: ', arr.length)
                arr.forEach((item, index) => {
                    // console.log('index: ', index)
                    item.style = {
                        left: (key - 1) * cellWidth,
                        top: index * cellHeight
                    }
                    const { start, end } = item
                    console.log(`${start} - ${end}`)
                    const spliceArr = createSectionArr(start, end)
                    console.log(spliceArr)
                    taskPhoto[index].splice(0 /* 月份 - 1 */, spliceArr.length, ...spliceArr)
                    // console.log('��������������', JSON.parse(JSON.stringify(taskPhoto)))
                })
            } else {
                console.log(`${key} 月!!!`)
                console.log('arr.length: ', arr.length)
                arr.forEach((item, index) => {
                    // console.log('index: ', index)
                    const { start, end } = item
                    console.log(`${start} - ${end}`)
                    const spliceArr = createSectionArr(start, end)
                    console.log(spliceArr)
                    // taskPhoto[index].splice(0, spliceArr.length, ...spliceArr)
                    isEmpty(key - 1 /* 月份 - 1 */, spliceArr, item)
                })
            }
        }
        console.log('taskPhoth: ', taskPhoto)

        function isEmpty(month, spliceArr, item) {
            for (let i = 0; i < rows; i++) {
                // console.log('i: ', i)
                if (taskPhoto[i][month] === 0) {
                    console.log(`第 ${i} 行,${month + 1} 月为空!`)
                    item.style = {
                        left: month * cellWidth,
                        top: i * cellHeight
                    }
                    taskPhoto[i].splice(month, spliceArr.length, ...spliceArr)
                    return false
                }
            }
        }

        function randomNum(min, max) {
            return Math.floor(Math.random() * (max - min + 1)) + min
        }

        function randomColor(alpha = 0.5) {
            return `rgba(${this.randomNum(0, 128)}, ${this.randomNum(0, 128)}, ${this.randomNum(0, 128)}, ${alpha})`
        }

        // vue
        const app = new Vue({
            el: '#app',
            data: {
                cellWidth,
                cellHeight,
                taskList,
                rows
            },
            methods: {
                randomNum,
                randomColor,
                showDetail(item) {
                    const info = JSON.parse(JSON.stringify(item))
                    delete info.style
                    // alert(JSON.stringify(info))
                    this.copyTxt(JSON.stringify(info))
                },
                copyTxt(txt) {
                    const cInput = document.createElement('input')
                    cInput.value = txt
                    // cInput.style.width = 0
                    // cInput.style.height = 0
                    document.body.appendChild(cInput)
                    cInput.select()
                    document.execCommand('Copy')
                    cInput.remove()
                }
            }
        })
    </script>
</body>

</html>