// ==UserScript==
// @name 自动填写工时
// @namespace http://tampermonkey.net/
// @version 2026-01-30
// @description 自动获取工作日信息并在控制台打印日期
// @author You
// @match https://oa.xquant.com/wui/index.html
// @icon https://www.google.com/s2/favicons?sz=64&domain=xquant.com
// @grant none
// ==/UserScript==
(function () {
"use strict";
// 获取当前月份,格式:YYYY-MM
function getCurrentMonth() {
const now = new Date();
const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, "0");
return `${year}-${month}`;
}
// 获取工作日信息(排除休假)
function getWorkdays() {
return new Promise((resolve, reject) => {
console.log("正在获取工作日信息...");
fetch(
"https://oa.xquant.com/api/kq/myattendance/getHrmKQMonthReportInfo",
{
method: "POST",
headers: {
Accept: "*/*",
"Content-Type": "application/x-www-form-urlencoded; charset=utf-8",
"X-Requested-With": "XMLHttpRequest",
Referer: "https://oa.xquant.com/wui/index.html",
},
body: `typevalue=${getCurrentMonth()}&loaddata=1&type=2&`,
},
)
.then((response) => {
if (!response.ok) {
throw new Error(`HTTP错误!状态码: ${response.status}`);
}
return response.json();
})
.then((data) => {
console.log("API响应:", data);
if (data.result) {
const workdays = [];
// 处理每个日期
Object.values(data.result).forEach((day) => {
// 检查是否是工作日且不是休假
if (
day.isWorkDay &&
(!day.types || !day.types.includes("LEAVE"))
) {
workdays.push(day.date);
}
});
// 排序日期
workdays.sort();
console.log("工作日(排除休假):", workdays);
resolve(workdays);
} else {
reject(new Error("API响应中未找到结果"));
}
})
.catch((error) => {
console.error("错误:", error);
reject(error);
});
});
}
// @param targetText 工时细分
// @param rowNum 行号
// @param iframeWindow iframe窗口
function setWorkPlace(targetText, rowNum, iframeWindow) {
try {
const fieldMark = "field13672_" + rowNum;
iframeWindow.WfForm.changeFieldValue(fieldMark, {
value: 243,
specialobj: [
{ id: 243, name: targetText }, // 构造显示对象,防止只显示ID不显示文字
],
});
} catch (e) {
console.warn("⚠️ WfForm 直接赋值失败", e);
}
}
// 创建工时详情弹窗
function createWorkHourDialog() {
return new Promise((resolve, reject) => {
// 创建弹窗容器
const dialog = document.createElement("div");
dialog.style.cssText = `
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: white;
padding: 20px;
border: 1px solid #ccc;
border-radius: 5px;
box-shadow: 0 2px 10px rgba(0,0,0,0.2);
z-index: 10000;
width: 400px;
`;
// 创建表单
const form = document.createElement("form");
form.style.cssText = "display: flex; flex-direction: column; gap: 15px;";
// 工时类型字段
const typeGroup = document.createElement("div");
typeGroup.innerHTML = `
`;
form.appendChild(typeGroup);
// 工时细分字段
const categoryGroup = document.createElement("div");
categoryGroup.innerHTML = `
该输入框自动搜索选择第一个
`;
form.appendChild(categoryGroup);
// 工作内容字段
const contentGroup = document.createElement("div");
contentGroup.innerHTML = `
`;
form.appendChild(contentGroup);
// 按钮
const buttonGroup = document.createElement("div");
buttonGroup.style.cssText =
"display: flex; gap: 10px; justify-content: flex-end;";
buttonGroup.innerHTML = `
`;
form.appendChild(buttonGroup);
// 添加表单到弹窗
dialog.appendChild(form);
// 添加弹窗到页面
document.body.appendChild(dialog);
// 添加事件监听器
const cancelBtn = document.getElementById("cancelBtn");
const confirmBtn = document.getElementById("confirmBtn");
cancelBtn.addEventListener("click", () => {
document.body.removeChild(dialog);
reject(new Error("用户取消"));
});
confirmBtn.addEventListener("click", () => {
const workContent = document.getElementById("workContent").value;
const workHourType = document.getElementById("workHourType").value;
const workHourCategory =
document.getElementById("workHourCategory").value;
document.body.removeChild(dialog);
resolve({ workContent, workHourType, workHourCategory });
});
// 点击外部关闭
dialog.addEventListener("click", (e) => {
if (e.target === dialog) {
document.body.removeChild(dialog);
reject(new Error("用户取消"));
}
});
});
}
// 处理VIP工时按钮点击
function handleVipWorkHourClick() {
// 显示工时详情弹窗
createWorkHourDialog()
.then(({ workContent, workHourType, workHourCategory }) => {
console.log("正在获取工作日...");
// 获取工作日
getWorkdays()
.then((workdays) => {
console.log("找到工作日:", workdays.length);
console.log("工作日信息:");
// 处理表格
const iframe = document.getElementById("mainFrame");
const iframeDocument =
iframe.contentDocument || iframe.contentWindow.document;
iframeDocument.querySelectorAll(".ant-checkbox-input")[2].click();
const iframeWindow = iframe.contentWindow;
console.log("日期, 工时类型, 工时细分, 工作内容");
const rowNum = 0;
//workdays.forEach(date => {
for (let rowNum = 0; rowNum < workdays.length; rowNum++) {
const date = workdays[rowNum];
console.log(
`${date}, ${workHourType}, ${workHourCategory}, ${workContent}`,
);
if (rowNum == 0) {
// 工时类型 = 研发
iframeWindow.WfForm.changeFieldValue("field13667_" + rowNum, {
value: workHourType,
});
// 工时细分
setWorkPlace(workHourCategory, rowNum, iframeWindow);
// 工作内容
iframeWindow.WfForm.changeFieldValue("field13673_" + rowNum, {
value: workContent,
});
}
if (rowNum > 0) {
// 复制行
iframeDocument.getElementById("copybutton0").click();
}
// 给行添加数据
iframeWindow.WfForm.changeFieldValue("field13666_" + rowNum, {
value: date,
});
// 工时
iframeWindow.WfForm.changeFieldValue("field13674_" + rowNum, {
value: "8",
});
console.log(rowNum);
}
})
.catch((error) => {
console.error("获取工作日错误:", error);
});
})
.catch((error) => {
console.log("弹窗取消:", error);
});
}
// 添加VIP工时按钮
function addVipWorkHourButton() {
// 创建按钮容器
const buttonContainer = document.createElement("div");
buttonContainer.style.cssText = `
position: fixed;
top: 60px;
left: auto;
right: 10px;
z-index: 9999;
display: flex;
align-items: stretch;
`;
// 创建可拖动区域
const dragHandle = document.createElement("div");
dragHandle.style.cssText = `
width: 15px;
background: rgba(0, 0, 0, 0.15);
border-radius: 3px 0 0 3px;
cursor: move;
display: flex;
align-items: center;
justify-content: center;
position: relative;
background: #ff9800;
`;
// 添加拖动图标
dragHandle.innerHTML =
'⋮⋮';
// 添加提示
const tooltip = document.createElement("div");
tooltip.style.cssText = `
position: absolute;
top: -30px;
left: 50%;
transform: translateX(-50%);
background: rgba(0, 0, 0, 0.8);
color: white;
padding: 5px 10px;
border-radius: 3px;
font-size: 12px;
white-space: nowrap;
opacity: 0;
visibility: hidden;
transition: opacity 0.3s, visibility 0.3s;
z-index: 10000;
`;
tooltip.textContent = "拖动可调整位置";
dragHandle.appendChild(tooltip);
// 创建按钮
const button = document.createElement("button");
button.textContent = "VIP工时";
button.style.cssText = `
padding: 8px 12px;
background: #ff9800;
color: white;
border: none;
border-radius: 0 3px 3px 0;
cursor: pointer;
font-size: 12px;
font-weight: bold;
user-select: none;
border-left: 1px solid rgba(255, 255, 255, 0.2);
white-space: nowrap;
`;
// 使按钮可拖动
let isDragging = false;
let hasDragged = false;
let offsetX, offsetY;
// 从localStorage读取位置
function loadButtonPosition() {
const savedPosition = localStorage.getItem("vipWorkHourButtonPosition");
if (savedPosition) {
try {
const { x, y } = JSON.parse(savedPosition);
buttonContainer.style.left = `${x}px`;
buttonContainer.style.top = `${y}px`;
buttonContainer.style.right = "auto";
} catch (error) {
console.error("读取按钮位置失败:", error);
}
}
}
// 保存位置到localStorage
function saveButtonPosition(x, y) {
try {
localStorage.setItem(
"vipWorkHourButtonPosition",
JSON.stringify({ x, y }),
);
} catch (error) {
console.error("保存按钮位置失败:", error);
}
}
// 鼠标悬停显示提示
dragHandle.addEventListener("mouseenter", () => {
tooltip.style.opacity = "1";
tooltip.style.visibility = "visible";
});
dragHandle.addEventListener("mouseleave", () => {
tooltip.style.opacity = "0";
tooltip.style.visibility = "hidden";
});
// 拖动开始
dragHandle.addEventListener("mousedown", (e) => {
e.stopPropagation(); // 防止触发按钮点击
isDragging = true;
hasDragged = false;
offsetX = e.clientX - buttonContainer.getBoundingClientRect().left;
offsetY = e.clientY - buttonContainer.getBoundingClientRect().top;
dragHandle.style.cursor = "grabbing";
});
// 拖动中
document.addEventListener("mousemove", (e) => {
if (isDragging) {
hasDragged = true;
const x = e.clientX - offsetX;
const y = e.clientY - offsetY;
buttonContainer.style.left = `${x}px`;
buttonContainer.style.top = `${y}px`;
buttonContainer.style.right = "auto";
}
});
// 拖动结束
document.addEventListener("mouseup", () => {
if (isDragging) {
isDragging = false;
dragHandle.style.cursor = "move";
// 保存位置
const rect = buttonContainer.getBoundingClientRect();
saveButtonPosition(rect.left, rect.top);
}
});
// 点击按钮
button.addEventListener("click", () => {
if (!hasDragged) {
handleVipWorkHourClick();
}
// 重置拖动状态
hasDragged = false;
});
// 加载保存的位置
loadButtonPosition();
// 组装按钮
buttonContainer.appendChild(dragHandle);
buttonContainer.appendChild(button);
document.body.appendChild(buttonContainer);
console.log("VIP工时按钮已添加(可拖动)");
}
// 根据行号查询表格行元素
function getRowByIndex(index) {
return document.querySelector(`tr[data-rowindex="${index}"]`);
}
// 初始化脚本
function init() {
// 页面加载时添加VIP工时按钮
addVipWorkHourButton();
console.log("VIP工时自动填写脚本已初始化");
}
// 页面准备就绪时初始化
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", init);
} else {
init();
}
// 代码结束...
})();