Greasy Fork

来自缓存

创会

创会脚本

// ==UserScript==
// @name         创会
// @namespace    http://tampermonkey.net/
// @version      1.0.0
// @description  创会脚本
// @author       lhq
// @match        https://meeting.tencent.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=tencent.com
// @grant        GM_xmlhttpRequest
// @connect      159.75.172.230
// @license      MIT
// ==/UserScript==

const meetingDetail = "https://meeting.tencent.com/user-center/user-meeting-list/detailed-meeting-info";
const meetingList = "https://meeting.tencent.com/user-center/user-meeting-list";
let timer = null;
const baseUrl = "http://159.75.172.230:8084/";
let user = null;
let meetingArr = []
let meetingInfo = {
    id: '',
    meetingName: '',
    startTime:'',
    meetingStartBufferTime:'',
    endTime:'',
    meetingEndBufferTime: '',
    secret: ''
}

//获取页面类型
const pageType = () => {
    if (window.location.href === meetingList) {
        return "meetingList";
    } else if (window.location.href.startsWith(meetingDetail)) {
        return "meetingDetail";
    } else {
        return null;
    }
};
const setInputValue = (inputElement, key) => {
    Object.defineProperty(inputElement, "value", {
        get: function () {
            return this._value;
        },
        set: function (newValue) {
            this._value = newValue;
            this.dispatchEvent(new Event("input", { bubbles: true }));
        },
    });
    inputElement.value = key;
};
//触发输入框事件
const simulateInputEvent = (inputElement) => {
    const inputEvent = new Event("input", {
        bubbles: true,
        cancelable: true,
    });
    const changeEvent = new Event("change", {
        bubbles: true,
        cancelable: true,
    });
    // 派发input事件
    inputElement.dispatchEvent(inputEvent);
    // 派发change事件
    inputElement.dispatchEvent(changeEvent);
};

//给输入框赋值
const simulateKeyboardInput = (inputElement, value) => {
    inputElement.value = "";
    simulateInputEvent(inputElement);
    const chars = value.split("");
    chars.forEach((char) => {
        const event = new KeyboardEvent("keypress", {
            bubbles: true,
            cancelable: true,
            charCode: char.charCodeAt(0),
        });
        // 模拟输入字符
        inputElement.value += char;
    });
    simulateInputEvent(inputElement);
};
//获取用户信息
const getUserInfo = () => {
    const res = sessionStorage.getItem('persist:root')
    if(res) {
        const res1 = JSON.parse(res)?.userInfos
        if(res1) {
            return JSON.parse(res1)
        }
        return null
    }
    return null
}
//选择50分页
const setPageSize = () => {
    const endDialog = document.querySelector(".meetinglist-pagination .met-dropdown-btn");
    if (endDialog) {
        endDialog.click();
        setTimeout(() => {
            const listItems = Array.from(document.querySelectorAll('#met-overlay-root li'))
            .filter(li => li.textContent.trim() === '50');
            if (listItems[0]) listItems[0].click();
        },1000)
    }

}
//判断是否为今天
function checkAndFormatDate(dateStr) {
    const today = new Date();
    const currentYear = today.getFullYear();
    const currentMonth = today.getMonth() + 1;
    const currentDay = today.getDate();
    const [month, day] = dateStr.split('月').map(str => parseInt(str, 10));
    if (month === currentMonth && day === currentDay) {
        return '今天';
    } else {
        const formattedMonth = month < 10 ? `0${month}` : `${month}`;
        const formattedDay = day < 10 ? `0${day}` : `${day}`;
        return `${formattedMonth}月${formattedDay}日`;
    }
}
//创建符合条件的会议数据集合
function findElementsAndExtractParentClasses(className, searchString) {
    const elements = document.querySelectorAll(`.${className}`);
    const resultArray = [];
    elements.forEach(element => {
        if (element.textContent.includes(searchString)) {
            const parentElement = element.closest('tr');
            if (parentElement) {
                const classValue = parentElement.className;
                const clickEle = `[class="${classValue}"] .meeting-subject-btn`
                resultArray.push({
                    meetingId:classValue,
                    clickEle,
                    startTime: '',
                    endTime: ''
                })
            }
        }
    })
    return resultArray
}
//进入详情页获取数据并退出
function getStartAndEndTimeLabels() {
    setTimeout(() => {
        const storedData = sessionStorage.getItem('persist:root');
        if (storedData) {
            try {
                const parsedData = JSON.parse(storedData);
                const items = document.querySelectorAll('.met-form__item');
                if (parsedData.meetingItemInfo) {
                    const meetingItemInfo = JSON.parse(parsedData.meetingItemInfo);
                    const mItem = meetingArr.find(i => i.meetingId == meetingItemInfo.meeting_code)
                    console.log(mItem,meetingItemInfo.meeting_code);
                    if (mItem) {
                        mItem.startTime = items[3].querySelector('.met-form__text').textContent.replace("年", "/").replace("月", "/").replace("日", "")
                        mItem.endTime = items[4].querySelector('.met-form__text').textContent.replace("年", "/").replace("月", "/").replace("日", "")
                    }
                    const elements = document.querySelector('.step-1');
                    elements.click()
                    setTimeout(() => {
                        setPageSize()
                    }, 1000);
                }
            } catch (error) {
                console.error('Error parsing JSON data:', error);
            }
        }
    }, 2000);

}
//执行收集数据
function getData() {
    const pollInterval = setInterval(() => {
        console.log("Polling meeting array...");
        let allItemsSatisfied = true; // 标志所有项是否都满足条件
        meetingArr.forEach(item => {
            const { startTime, endTime, clickEle } = item;
            // startTime
            if (!startTime || !endTime) {
                const elements = document.querySelector(clickEle);
                // 模拟点击事件
                if (elements) {
                    elements.click(); // 触发点击事件
                    getStartAndEndTimeLabels()
                } else {
                    console.warn(`Element not found for selector: ${clickEle}`);
                }
                // 如果有任一项未满足条件,则将标志设置为false
                allItemsSatisfied = false;
            } else {
                console.log(`MeetingId: ${item.meetingId} is satisfied.`);
            }
        });
        // 如果所有项都满足条件,则停止轮询
        if (allItemsSatisfied) {
            console.log("停止轮询");
            clearInterval(pollInterval);
            // 获取缓冲时间
            const startBuffer = parseBufferTime(meetingInfo.meetingStartBufferTime);
            const endBuffer = parseBufferTime(meetingInfo.meetingEndBufferTime);
            // 计算新会议的时间范围
            const newMeetingRange = calculateTimeRange(
                meetingInfo.startTime,
                meetingInfo.endTime,
                startBuffer,
                endBuffer
            );
            // 检查是否有交集
            const hasIntersection = checkIntersection(meetingArr, newMeetingRange);
            if (hasIntersection) {
                taskFail()
            }else {
                setMeeting()
            }

        }
    }, 6000);
}

// 将时间字符串转换为时间戳
function convertToTimestamp(dateTimeStr) {
    // 替换 / 为 - 以兼容 Date 构造函数
    const formattedDate = dateTimeStr.replace(/\//g, '-');
    const date = new Date(formattedDate);
    return date.getTime(); // 返回毫秒级时间戳
}

// 将缓冲时间字符串转换为毫秒
function parseBufferTime(bufferStr) {
    const parts = bufferStr.split(':').map(Number);
    const hours = parts[0] || 0;
    const minutes = parts[1] || 0;
    return hours * 3600 * 1000 + minutes * 60 * 1000; // 转换为毫秒
}

// 计算时间范围
function calculateTimeRange(startTimeStr, endTimeStr, startBuffer, endBuffer) {
    const startTime = convertToTimestamp(startTimeStr);
    const endTime = convertToTimestamp(endTimeStr);
    const start = startTime - startBuffer;
    const end = endTime + endBuffer;
    return { start, end };
}

// 检查时间范围是否有交集
function checkIntersection(existingMeetings, newRange) {
    const newStart = newRange.start;
    const newEnd = newRange.end;
    for (const meeting of existingMeetings) {
        const existingStart = convertToTimestamp(meeting.startTime);
        const existingEnd = convertToTimestamp(meeting.endTime);
        // 检查是否有交集
        if (newStart < existingEnd && newEnd > existingStart) {
            return true; // 存在交集
        }
    }
    return false; // 不存在交集
}


// 预定会议
function setMeeting() {
    const elements = document.querySelector('.met-btn.toolbar-schedule-btn');
    if (elements) elements.click();
    setTimeout(() => {
        inputInfo()
    },2000)
}

// 填写会议
function inputInfo() {
    const formItems = document.querySelectorAll('.met-form__item');
    if (formItems.length > 0) {
        // 获取第一个.met-form__item中的<input>元素
        const firstFormItem = formItems[0];
        const inputElement = firstFormItem.querySelector('input');
        if (inputElement) {
            setInputValue(inputElement,meetingInfo.meetingName)
        }
        // 获取第一个.met-form__item中的<input>元素
        const firstFormItem1 = formItems[1];
        const inputElement4 = firstFormItem1.querySelector('.end .met-datepicker input');
        const inputElement5 = firstFormItem1.querySelector('.end .custom-time-picker .hour');
        const inputElement6 = firstFormItem1.querySelector('.end .custom-time-picker .minute');
        console.log(inputElement4,inputElement5,inputElement6);
        const inputele2 = firstFormItem1.querySelector('.end .met-datepicker__input-normal');
        inputele2.click()

        setTimeout(() => {
            const eles2 = document.querySelectorAll('.met-calendar__cell.met-calendar__cell--date');
            if (inputElement4 && inputElement5 && inputElement6) {
                const [startTime1, startTime2] = meetingInfo.endTime.split(" ");
                const [hourPart, minutePart] = startTime2.split(":");
                console.log(startTime1,hourPart,minutePart);
                //setInputValue(inputElement4,startTime1)
                setTimeout(() => {
                    const index = timeSub(meetingInfo.endTime)
                    clickTime(index)
                },1000)
                setInputValue(inputElement5,hourPart)
                setInputValue(inputElement6,minutePart)
            }
            setTimeout(() => {
                const inputElement1 = firstFormItem1.querySelector('.start .met-datepicker input');
                const inputElement2 = firstFormItem1.querySelector('.start .custom-time-picker .hour');
                const inputElement3 = firstFormItem1.querySelector('.start .custom-time-picker .minute');
                const inputele1 = firstFormItem1.querySelector('.start .met-datepicker__input-normal');
                console.log(inputElement1,inputElement2,inputElement3);
                inputele1.click()
                setTimeout(() => {
                    const eles1 = document.querySelectorAll('.met-calendar__cell.met-calendar__cell--date');
                    if (inputElement1 && inputElement2 && inputElement3) {
                        const [startTime1, startTime2] = meetingInfo.startTime.split(" ");
                        const [hourPart, minutePart] = startTime2.split(":");
                        console.log(startTime1,hourPart,minutePart);
                        //setInputValue(inputElement1,startTime1)
                        setTimeout(() => {
                            const index = timeSub(meetingInfo.endTime)
                            clickTime(index)
                            setCheckbox()
                        },1000)
                        setInputValue(inputElement2,hourPart)
                        setInputValue(inputElement3,minutePart)
                    }

                },1000)
            },3000)
        },1000)

    }
}

const setCheckbox = () => {
    const passEle = document.querySelector('#host-pass-code input');
    if (passEle) {
        passEle.click();
        setTimeout(() => {
            const passwordEle = document.querySelector('#host-pass-code input[type="password"]');
            if (passwordEle) setInputValue(passwordEle,meetingInfo.secret)
            const waterEle = document.querySelector('label[name="water_mark"] input');
            if (waterEle) waterEle.click();
            const confirmEle = document.querySelector('.met-btn.meeting-button-area-confirm');
            if (confirmEle) confirmEle.click();
            setTimeout(() => {
                if(pageType() == 'meetingDetail') {
                    taskSuccess()
                }else {
                    taskFail()
                }
            },5000)
        },1000)
    }

}
const timeSub = (time) => {
    const now = new Date();
    const targetTime = new Date(time);
    const timeDifference = targetTime - now;
    const daysDifference = timeDifference / (24 * 60 * 60 * 1000);
    const daysDifferenceFloor = Math.floor(daysDifference);
    return daysDifferenceFloor
}
const formatTime = (time) => {
    const dateString = time;
    const date = new Date(dateString);
    const month = date.getMonth() + 1;
    const day = date.getDate();
    return `${month}月${day}日`;
}
const clickTime = (i) => {
    const allCells = document.querySelectorAll('.met-calendar__cell.met-calendar__cell--date');
    let selectedIndex = -1;
    allCells.forEach((cell, index) => {
        if (cell.classList.contains('is-selected')) {
            selectedIndex = index;
        }
    });
    if (selectedIndex === -1) {
        console.error('未找到包含 is-selected 类的元素');
    } else {
        const offset = i;
        const targetIndex = selectedIndex + offset;
        if (targetIndex >= 0 && targetIndex < allCells.length) {
            const targetCell = allCells[targetIndex];
            console.log('目标元素:', targetCell);
            targetCell.click()
        } else {
            console.error('目标位置超出范围');
        }
    }
}
//开始任务
const start = () => {
    if(pageType() === 'meetingList'){
        meetingArr = []
        const time = formatTime(meetingInfo.startTime)
        console.log(time);
        const dateStr = checkAndFormatDate(time)
        console.log(dateStr);
        setPageSize()
        setTimeout(() => {
            const arr = findElementsAndExtractParentClasses('meeting-begin-time-in-date',dateStr)
            meetingArr = arr
            if(meetingArr.length > 0) {
                getData()
            }else {
                setMeeting()
            }
        }, 2000);
    } else {
        window.location.href = meetingList
    }
}
//请求API
const requestApi = (userId) => {
    user = getUserInfo()
    GM_xmlhttpRequest({
        method: "GET",
        url: `${baseUrl}refreshMeetingRoomState?userId=${user.userid}&userState=1`,
        onload: function (response) {
            const res = response?.responseText ? JSON.parse(response.responseText) : null;
            console.log('------------------------------response',response);
            console.log('------------------------------res',res);
            if (res) {
                meetingInfo.id = res.id
                meetingInfo.secret = res.secret
                meetingInfo.meetingName = res.meetingName
                meetingInfo.meetingStartBufferTime = res.meetingStartBufferTime
                meetingInfo.meetingEndBufferTime = res.meetingEndBufferTime
                meetingInfo.startTime = `${res.meetingStartDay.replace(/-/g, "/")} ${res.meetingStartTime}`
                meetingInfo.endTime = `${res.meetingEndDay.replace(/-/g, "/")} ${res.meetingEndTime}`
                console.log(meetingInfo);
                clearInterval(timer);
                start()
            }
        },
        onerror: function (response) {
            console.log("请求失败");
        },
    });
};
// 获取任务
const getTask = (userId) => {
    timer = setInterval(() => {
        requestApi();
    }, 5000);
};
// 任务成功
const taskSuccess = (userId) => {
    GM_xmlhttpRequest({
        method: "GET",
        url: `${baseUrl}refreshMeetingRoomState?userId=${user.userid}&userState=3&meetingRoomId=${meetingInfo.id}`,
        onload: function (response) {
            getTask()
        },
        onerror: function (response) {
            console.log("请求失败");
        },
    });
};
// 任务失败
const taskFail = (userId) => {
    GM_xmlhttpRequest({
        method: "GET",
        url: `${baseUrl}refreshMeetingRoomState?userId=${user.userid}&userState=4&meetingRoomId=${meetingInfo.id}`,
        onload: function (response) {
            getTask()
        },
        onerror: function (response) {
            console.log("请求失败");
        },
    });
};
(function() {
    getTask()
})();