您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
快捷导入pingcode任务
// ==UserScript== // @name pingcode helper // @namespace http://tampermonkey.net/ // @version 2024-04-09 // @description 快捷导入pingcode任务 // @author 飞天小猪 // @match http://pc.tongqisumu.com:30001/pjm/projects/* // @icon https://gongjux.com/files/3/4453uhm5937m/32/favicon.ico // @grant none // @require https://gf.qytechs.cn/scripts/453166-jquery/code/jquery.js?version=1105525 // @license MIT // ==/UserScript== (function () { 'use strict'; let projectInfo const headers = { cookie: document.cookie, userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36' } const setButton = () => { // 创建一个新的button元素 var button = document.createElement('button'); button.textContent = '虤'; // 设置按钮文字 // 设置按钮的基本样式(包括固定定位与默认透明度) button.style.cssText = ` position: fixed; /* 或者 absolute,取决于您的布局需求 */ top: 30px; left: 10px; z-index: 99999; background-color: #007bff; color: white; padding: 6px 12px; border: none; border-radius: 5px; cursor: pointer; opacity: 0.3; transition: opacity 0.3s ease; `; // 添加鼠标悬浮时的透明度变化 button.addEventListener('mouseover', function () { this.style.opacity = 1; }); // 添加鼠标离开时的透明度变化 button.addEventListener('mouseout', function () { this.style.opacity = 0.3; }); button.addEventListener('click', showPanel) // 将按钮添加到文档中 document.body.appendChild(button); } const showPanel = async () => { const info = extractProjectIdAndSprintId(location.href) if (info.sprintId && info.projectName) { const { data } = await axios.get(`http://pc.tongqisumu.com:30001/api/agile/projects/${info.projectName}?addons=true&members=true&t=${new Date().getTime()}`, { headers }) if (data.code === 200) { projectInfo = data.data await getPanelInfo() } else { alert("数据解析失败") } } else { alert("数据解析失败") } } const extractProjectIdAndSprintId = (url) => { const pathParts = url.split('/'); const projectIndex = pathParts.indexOf('projects'); const sprintIndex = pathParts.indexOf('sprint'); if (projectIndex >= 0 && projectIndex + 1 < pathParts.length && sprintIndex >= 0 && sprintIndex + 1 < pathParts.length) { const projectName = pathParts[projectIndex + 1]; const sprintId = pathParts[sprintIndex + 1]; return { projectName: projectName, sprintId: sprintId }; } return null; } const getPanelInfo = async () => { const info = extractProjectIdAndSprintId(location.href) const params = { "sprint_id": info.sprintId, "criteria": { "search": { "keywords": "", "scopes": [ "identifier", "title" ] }, "conditions": [], "mode": 1, "show_type": 1, "group_by": "", "sort_by": "identifier", "sort_type": 1 }, "pi": 0, "ps": 100 } const { data } = await axios.post(`http://pc.tongqisumu.com:30001/api/agile/projects/${projectInfo.value._id}/scrum/sprint/views/work-item/content`, params, { headers }); if (data.code === 200) { const storys = data.data.value.filter(i => i.type === 3) genDom(storys) } else { alert(`项目故事获取失败,msg:${data.message}`) } } const genDom = (storys) => { const mask = document.createElement('div'); mask.addEventListener('click', (event) => { // 判断点击的是mask本身还是其子元素 if (event.target === mask) { document.body.removeChild(mask); } else { event.stopPropagation(); // 阻止子元素点击事件向上冒泡到mask } }); mask.classList.add('mask'); mask.style.cssText = ` background-color: rgba(0, 0, 0, 0.2); position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: 1000; display: flex; justify-content: center; align-items: center; box-sizing: border-box; ` document.body.appendChild(mask); const tableWrap = document.createElement('div') tableWrap.classList.add('table-wrap'); tableWrap.style.cssText = ` max-width: 1000px; max-height: 900px; min-height: 700px; min-width: 720px; width: 50vw; height: 70vh; background-color: #fff; overflow-y: auto; padding: 10px; ` // 创建关闭按钮 const closeBtn = document.createElement('button') closeBtn.textContent = '关闭' closeBtn.style.cssText = ` background-color: #F56C6C; color: white; padding: 6px 12px; border: none; border-radius: 5px; cursor: pointer; margin-right: 10px; ` closeBtn.addEventListener('click', () => { document.body.removeChild(mask); }) const select = document.createElement('select') select.style.cssText = ` width: 200px; padding: 4px 8px; border-radius: 4px; border-color: #2165f9; margin-right: 10px; ` for (let i = 0; i < storys.length; i++) { const option = document.createElement('option') option.value = storys[i]._id option.innerText = storys[i].title select.appendChild(option) } const prevFixInput = document.createElement('input') prevFixInput.placeholder = '统一标题前缀' prevFixInput.style.cssText = ` margin-right: 10px; padding: 3px; border-radius: 4px; border: 1px solid #2165f9;` const endFixInput = document.createElement('input') endFixInput.placeholder = '统一标题后缀' endFixInput.style.cssText = ` margin-right: 10px; padding: 3px; border-radius: 4px; border: 1px solid #2165f9;` // 创建批量插入按钮 const requestBtn = document.createElement('button') requestBtn.textContent = '批量插入' requestBtn.style.cssText = ` background-color: #2165f9; color: white; padding: 6px 12px; border: none; border-radius: 5px; cursor: pointer; ` requestBtn.addEventListener('click', () => { if (!textArea.value) return alert('请至少输入一条任务子模块名称') const rows = textArea.value.split('\n') const storyId = select.value const queue = rows.map(i => { const [title, start, end] = i.split('\t') const fixTitle = prevFixInput.value + title + endFixInput.value return { title: fixTitle, start: new Date(start + ' 00:00:00').getTime() / 1000, end: new Date(end + ' 00:00:00').getTime() / 1000 } }) requestQueue(queue, storyId) }) // 创建操作区域 const btnArea = document.createElement('div') btnArea.style.cssText = ` height: 40px; margin-bottom: 8px; box-sizing: border-box; padding: 4px 0; ` const textAreaWrap = document.createElement('div') textAreaWrap.style.cssText = ` height: 240px; width: 100%; overflow-y: auto; padding: 10px; box-sizing: border-box; ` const textArea = document.createElement('textarea') textArea.placeholder = '请输入要插入的任务子模块名称 格式为 标题\\t 起始时间:YYYY-MM-DD \\t 结束时间:YYYY-MM-DD' textArea.style.cssText = ` width: 100%; height: calc(100% - 6px); border: 1px solid #2165f9; box-sizing: border-box; padding: 10px; border-radius: 4px; ` const tip = document.createElement('div') tip.id = 'process-tip' tip.innerText = '当前任务 0/0' tip.style.cssText = ` padding-left:10px; ` const textAreaWrap2 = document.createElement('div') textAreaWrap2.style.cssText = ` height: 240px; width: 100%; overflow-y: auto; padding: 10px; box-sizing: border-box; ` const textArea2 = document.createElement('textarea') textArea2.id = 'textArea2_0131' textArea2.disabled = true textArea2.placeholder = '' textArea2.style.cssText = ` width: 100%; height: calc(100% - 6px); border: 1px solid #2165f9; box-sizing: border-box; padding: 10px; border-radius: 4px; background-color: #282c34; color: #61aeee; ` btnArea.appendChild(closeBtn) btnArea.appendChild(select) btnArea.appendChild(prevFixInput) btnArea.appendChild(endFixInput) btnArea.appendChild(requestBtn) tableWrap.appendChild(btnArea) textAreaWrap.appendChild(textArea) textAreaWrap2.appendChild(textArea2) tableWrap.appendChild(textAreaWrap) tableWrap.appendChild(tip) tableWrap.appendChild(textAreaWrap2) mask.appendChild(tableWrap) } const request = async (url, data) => { return axios.post(url, data, { headers }) } const requestQueue = async (queue, storyId) => { const url = 'http://pc.tongqisumu.com:30001/api/agile/v2/work-item' for (let i = 0; i < queue.length; i++) { const processTip = document.getElementById('process-tip') processTip.innerText = `当前任务 ${i + 1}/${queue.length}` const data = { "start": { "date": queue[i].start, // 开始时间 / 1000 "with_time": 0 }, "due": { "date": queue[i].end, // 结束时间 / 1000 "with_time": 0 }, "participants": [], "project_id": projectInfo.value._id, // 项目id "type": 4, // 任务对应的type类型 "parent_id": storyId, // 故事id "properties": {}, "raw_values": { "title": queue[i].title, "project_id": projectInfo.value._id, "type": 4, "parent_id": storyId, "start": { "date": queue[i].start, "with_time": 0 }, "due": { "date": queue[i].end, "with_time": 0 }, "participants": [] }, "title": queue[i].title // 标题 } const res = await request(url, data) const textArea2 = document.getElementById('textArea2_0131') if (res.data.code === 200) { textArea2.value += `SUCCESS: ${queue[i].title} 添加成功\n` textArea2.scrollTop = textArea2.scrollHeight } else { textArea2.value += `ERROR: ${queue[i].title} 添加失败 ---> ${res.data.message}\n` textArea2.scrollTop = textArea2.scrollHeight } } } const sleep = (time) => { return new Promise((resolve, reject) => { setTimeout(() => { resolve() }, time * 1000) }) } async function init() { $('head').append('<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>') // 名称:layer,版本:3.5.1,原始地址:https://www.layuicdn.com/#Layer // 等待layer加载成功 while (true) { if (typeof axios != 'undefined') { break } await sleep(0.5) } setButton() } init() })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址