Extension for dev.hundsun.com

A new extension

Size

8.8 KB

Version

1.0.1

Created

Jan 21, 2026

Updated

14 days ago

1// ==UserScript==
2// @name		Extension for dev.hundsun.com
3// @description		A new extension
4// @version		1.0.1
5// @match		https://*.dev.hundsun.com/*
6// @icon		https://dev.hundsun.com/frameV2/logo.ico
7// ==/UserScript==
8(function() {
9    'use strict';
10
11    // 工具函数:等待元素出现
12    function waitForElement(selector, timeout = 10000) {
13        return new Promise((resolve, reject) => {
14            const startTime = Date.now();
15            
16            const checkElement = () => {
17                const element = document.querySelector(selector);
18                if (element) {
19                    console.log(`找到元素: ${selector}`);
20                    resolve(element);
21                } else if (Date.now() - startTime > timeout) {
22                    console.error(`等待元素超时: ${selector}`);
23                    reject(new Error(`等待元素超时: ${selector}`));
24                } else {
25                    setTimeout(checkElement, 100);
26                }
27            };
28            
29            checkElement();
30        });
31    }
32
33    // 工具函数:延迟
34    function delay(ms) {
35        return new Promise(resolve => setTimeout(resolve, ms));
36    }
37
38    // 主要功能:处理单个需求
39    async function processStory(storyElement, index, total) {
40        try {
41            console.log(`\n========== 处理第 ${index + 1}/${total} 个需求 ==========`);
42            
43            // 1. 点击需求标题
44            const titleElement = storyElement.querySelector('.title.link.ellipsis');
45            if (!titleElement) {
46                console.error('未找到需求标题元素');
47                return;
48            }
49            
50            const storyTitle = titleElement.textContent.trim();
51            console.log(`需求标题: ${storyTitle}`);
52            
53            titleElement.click();
54            console.log('已点击需求标题');
55            
56            // 2. 等待详情窗口出现
57            await delay(1000);
58            const detailWindow = await waitForElement('.storyDetails-arrow-Tab', 5000);
59            console.log('详情窗口已打开');
60            
61            // 3. 找到并点击"任务安排"tab(第二个tab)
62            const tabs = document.querySelectorAll('.tab_wrap .tab.detail');
63            console.log(`找到 ${tabs.length} 个tab`);
64            
65            if (tabs.length < 2) {
66                console.error('未找到任务安排tab');
67                return;
68            }
69            
70            const taskTab = tabs[1]; // 第二个tab是"任务"
71            console.log(`点击tab: ${taskTab.textContent.trim()}`);
72            taskTab.click();
73            
74            // 4. 等待任务列表加载
75            await delay(1500);
76            
77            // 5. 获取已安排的任务列表
78            const taskList = document.querySelectorAll('.storyDetails-arrow-Tab .task-item, .storyDetails-arrow-Tab .el-table__row');
79            console.log(`当前需求已安排任务数量: ${taskList.length}`);
80            
81            // 6. 查找并点击批量创建图标
82            const batchCreateIcon = document.querySelector('.storyDetails-arrow-Tab .icon.iconfontcustom.stack-create-wrapper[title="批量创建"]');
83            
84            if (!batchCreateIcon) {
85                console.warn('未找到批量创建图标,尝试其他选择器...');
86                // 尝试其他可能的选择器
87                const alternativeIcon = document.querySelector('.storyDetails-arrow-Tab span[title="批量创建"]');
88                if (alternativeIcon) {
89                    console.log('找到批量创建图标(备用选择器)');
90                    alternativeIcon.click();
91                } else {
92                    console.error('无法找到批量创建图标');
93                    return;
94                }
95            } else {
96                console.log('找到批量创建图标,准备点击');
97                batchCreateIcon.click();
98            }
99            
100            // 7. 等待批量创建窗口弹出
101            await delay(1000);
102            const batchCreateWindow = await waitForElement('.el-dialog__wrapper, .batch-create-dialog', 3000);
103            console.log('批量任务创建窗口已弹出');
104            
105            // 8. 等待用户操作后关闭窗口
106            await delay(2000);
107            
108            // 9. 关闭详情窗口
109            const closeBtn = document.querySelector('.storyDetails-arrow-Tab .close-btn, .storyDetails-arrow-Tab .el-icon-close');
110            if (closeBtn) {
111                closeBtn.click();
112                console.log('已关闭详情窗口');
113            }
114            
115            await delay(500);
116            
117        } catch (error) {
118            console.error('处理需求时出错:', error);
119        }
120    }
121
122    // 主要功能:一键任务拆解
123    async function oneClickTaskBreakdown() {
124        try {
125            console.log('========== 开始一键任务拆解 ==========');
126            
127            // 1. 获取所有需求列表
128            const storyElements = document.querySelectorAll('.el-table__body .el-table__row');
129            
130            if (storyElements.length === 0) {
131                alert('未找到需求列表,请确保页面已加载完成');
132                console.error('未找到需求列表');
133                return;
134            }
135            
136            console.log(`找到 ${storyElements.length} 个需求`);
137            
138            // 2. 遍历处理每个需求
139            for (let i = 0; i < storyElements.length; i++) {
140                await processStory(storyElements[i], i, storyElements.length);
141                
142                // 每处理完一个需求,等待一段时间
143                if (i < storyElements.length - 1) {
144                    console.log('等待处理下一个需求...');
145                    await delay(1000);
146                }
147            }
148            
149            console.log('========== 一键任务拆解完成 ==========');
150            alert('一键任务拆解完成!');
151            
152        } catch (error) {
153            console.error('一键任务拆解出错:', error);
154            alert('一键任务拆解出错: ' + error.message);
155        }
156    }
157
158    // 添加按钮样式
159    TM_addStyle(`
160        .task-breakdown-btn {
161            margin-left: 10px;
162            padding: 9px 15px;
163            background-color: #67C23A;
164            color: white;
165            border: none;
166            border-radius: 4px;
167            cursor: pointer;
168            font-size: 12px;
169            transition: background-color 0.3s;
170        }
171        
172        .task-breakdown-btn:hover {
173            background-color: #85CE61;
174        }
175        
176        .task-breakdown-btn:active {
177            background-color: #5DAF34;
178        }
179        
180        .task-breakdown-btn:disabled {
181            background-color: #A0CFFF;
182            cursor: not-allowed;
183        }
184    `);
185
186    // 初始化函数
187    function init() {
188        console.log('一键任务拆解扩展已加载');
189        
190        // 等待页面加载完成
191        const checkAndAddButton = () => {
192            const createBtnWrapper = document.querySelector('.d-button.big-btn');
193            
194            if (createBtnWrapper && !document.querySelector('.task-breakdown-btn')) {
195                console.log('找到创建需求按钮,添加一键任务拆解按钮');
196                
197                // 创建一键任务拆解按钮
198                const breakdownBtn = document.createElement('button');
199                breakdownBtn.className = 'task-breakdown-btn';
200                breakdownBtn.textContent = '一键任务拆解';
201                breakdownBtn.title = '遍历所有需求并打开批量任务创建窗口';
202                
203                // 绑定点击事件
204                breakdownBtn.addEventListener('click', async () => {
205                    breakdownBtn.disabled = true;
206                    breakdownBtn.textContent = '处理中...';
207                    
208                    try {
209                        await oneClickTaskBreakdown();
210                    } finally {
211                        breakdownBtn.disabled = false;
212                        breakdownBtn.textContent = '一键任务拆解';
213                    }
214                });
215                
216                // 将按钮插入到创建需求按钮旁边
217                createBtnWrapper.parentElement.insertBefore(breakdownBtn, createBtnWrapper.nextSibling);
218                
219                console.log('一键任务拆解按钮已添加');
220            } else if (!createBtnWrapper) {
221                // 如果还没找到,继续等待
222                setTimeout(checkAndAddButton, 500);
223            }
224        };
225        
226        // 开始检查并添加按钮
227        if (document.readyState === 'loading') {
228            document.addEventListener('DOMContentLoaded', checkAndAddButton);
229        } else {
230            checkAndAddButton();
231        }
232    }
233
234    // 启动
235    init();
236})();
Extension for dev.hundsun.com | Robomonkey