// ==UserScript== // @name 企业微信后台权限管理优化 // @namespace https://bbs.tampermonkey.net.cn/ // @version 0.3.0 // @description 在页面上创建一个悬浮按钮,点击后显示所有的管理员姓名和他所管理的部门 // @author 肆散的尘埃i // @icon https://wwcdn.weixin.qq.com/node/wework/images/startPagePreview_logo.0a7763ab2f.svg // @match http*://work.weixin.qq.com/* // @require https://scriptcat.org/lib/637/1.4.3/ajaxHooker.js // @require https://scriptcat.org/lib/2311/1.1.0/createFloatingButton.js // @require https://scriptcat.org/lib/2253/1.0.1/show_message.js // @grant none // ==/UserScript== (function() { 'use strict'; // 使用技术:https://bbs.tampermonkey.net.cn/forum.php?mod=viewthread&tid=3284&page=1 // 设置脚本启动时间,根据访问访问此链接的时间,适当添加 @run-at document-start ajaxHooker.hook(request => { // 角色列表 if (request.url.includes('/wework_admin/profile/role/getRoleList')) { request.response = res => { const responseText = res.response; // 注意保存原数据 // 存储 localStorage.setItem("RoleList",responseText); console.log("已获取到数据,并且存入localStorage,名称为:RoleList") // 创建悬浮按钮,设置名称并绑定点击事件 createFloatingButton(() => { performing_function(); }, "显示菜单"); show_message({ message: '已获取到数据', type: 'success', position: 'top-right', opacity: 0.9, }); }; } }); let originalTableData = []; // 保存原始数据,供重置时使用 // 创建全屏显示的 div function createFullScreenDIV(htmlString) { // 禁用页面滚动 document.body.style.overflow = 'hidden'; // 创建全屏遮罩层 const overlay = document.createElement('div'); overlay.style.cssText = ` position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; background: rgba(0, 0, 0, 0.8); z-index: 10000; display: flex; justify-content: center; align-items: center; overflow-y: auto; `; // 创建内容容器 const contentContainer = document.createElement('div'); contentContainer.style.cssText = ` max-height: 80vh; max-width: 90vw; overflow-y: auto; background-color: white; padding: 20px; border-radius: 8px; `; // 创建关闭按钮 const closeButton = document.createElement('div'); closeButton.innerText = '×'; closeButton.style.cssText = ` position: absolute; top: 10px; right: 25px; width: 30px; height: 30px; background: rgba(255, 255, 255, 0.3); color: white; text-align: center; line-height: 30px; font-size: 20px; cursor: pointer; border-radius: 50%; z-index: 10001; `; // 关闭全屏显示的函数 function closeFullScreen() { document.body.removeChild(overlay); document.body.style.overflow = ''; document.removeEventListener('keydown', handleKeyDown); // 移除键盘事件监听器 } // 处理键盘事件的函数 function handleKeyDown(event) { if (event.key === 'Escape') { closeFullScreen(); } } // 添加键盘事件监听器,监听 ESC 键 document.addEventListener('keydown', handleKeyDown); // 设置关闭按钮的点击事件 closeButton.addEventListener('click', closeFullScreen); // 将传入的 HTML 字符串添加到内容容器中 contentContainer.appendChild(htmlString); // 将内容容器和关闭按钮添加到遮罩层中 overlay.appendChild(contentContainer); overlay.appendChild(closeButton); // 将遮罩层添加到文档中 document.body.appendChild(overlay); } // 初始化表格,并保存原始数据 function initTable(roleList) { const table = document.createElement('table'); table.style.cssText = ` width: 100%; border-collapse: collapse; background-color: white; `; const headerRow = document.createElement('tr'); const headers = ['序号', '管理员名称', '组织权限列表']; headers.forEach(headerText => { const th = document.createElement('th'); th.innerText = headerText; th.style.cssText = ` border: 1px solid #ddd; padding: 8px; text-align: center; background-color: #f2f2f2; font-weight: bold; `; headerRow.appendChild(th); }); table.appendChild(headerRow); originalTableData = []; // 清空之前的原始数据 roleList.forEach((role, index) => { // 创建一行 const tr = document.createElement('tr'); // 序号 const idTd = document.createElement('td'); idTd.innerText = index + 1; idTd.style.cssText = ` width: 5%; border: 1px solid #ddd; padding: 8px; text-align: center; `; // tr.appendChild(idTd); // 管理员姓名 const adminNameTd = document.createElement('td'); if (role.admin_list.item.length > 0) { const admin_list = role.admin_list.item.map(item => `${item.name}` ).join(', '); adminNameTd.innerHTML = admin_list; } else { adminNameTd.innerText = '无管理员'; } adminNameTd.style.cssText = ` width: 10%; border: 1px solid #ddd; padding: 8px; text-align: center; `; // tr.appendChild(adminNameTd); // 所管理的组织 const partyAuthTd = document.createElement('td'); const filteredPartyAuthList = role.party_auth_list.item .filter(item => item.name !== '未加入组织的成员') .map(item => { const span = document.createElement('span'); span.textContent = item.name; span.style.cssText = ` display: inline-block; padding: 5px 10px; background-color: #f0f0f0; color: #333; border: 1px solid #ccc; border-radius: 4px; font-size: 14px; line-height: 1.5; cursor: default; margin-right: 8px; margin-top: 4px; margin-bottom: 4px; ` return span.outerHTML; // 返回 span 元素的 HTML 字符串 }) .join(''); partyAuthTd.innerHTML = filteredPartyAuthList || "超级管理员"; partyAuthTd.style.cssText = ` width: 80%; border: 1px solid #ddd; padding: 8px; text-align: left; `; // tr.appendChild(partyAuthTd); //TODO 统一加入到表格内,序号有些问题 // 如果“组织权限列表”不为空,则添加到表格。不显示超级管理员 if(filteredPartyAuthList.length > 0){ tr.appendChild(idTd); tr.appendChild(adminNameTd); tr.appendChild(partyAuthTd); } originalTableData.push(tr.cloneNode(true)); // 保存每行的初始状态 table.appendChild(tr); }); return table; } // 搜索函数,只处理组织权限列表搜索,并高亮匹配到的部分 function searchTable(partyAuthSearch) { // 获取表格 const table = document.querySelector('table'); // 保存表格的原始宽度 const originalWidth = table.offsetWidth; // 获取所有的表格行 const tableRows = document.querySelectorAll('table tr'); tableRows.forEach(row => { // 查找每一行的第三个单元格(假设包含组织权限信息) const partyAuthCell = row.querySelector('td:nth-child(3)'); if (partyAuthCell) { // 获取组织权限文本并转换为小写,方便搜索 const partyAuthText = partyAuthCell.innerHTML.toLowerCase(); const searchTerm = partyAuthSearch.toLowerCase(); // 恢复所有标签的样式 const spans = Array.from(partyAuthCell.getElementsByTagName('span')); spans.forEach(span => { const spanText = span.textContent.toLowerCase(); if (spanText.includes(searchTerm)) { // 高亮匹配的标签 span.style.backgroundColor = 'yellow'; span.style.fontWeight = 'bold'; } else { // 恢复未匹配的标签样式 span.style.backgroundColor = '#f0f0f0'; span.style.color = '#333'; span.style.border = '1px solid #ccc'; span.style.fontWeight = 'normal'; } }); if (partyAuthText.includes(searchTerm)) { // 如果匹配,显示这一行 row.style.display = ''; } else { // 如果不匹配,隐藏这一行 row.style.display = 'none'; } } }); // 恢复表格的宽度 table.style.width = `${originalWidth}px`; } // 定义重置表格的函数 function resetTable(partyAuthInput, tableRows) { // 清空搜索框的输入内容 if (partyAuthInput) { partyAuthInput.value = ''; } // 显示所有的表格行 tableRows.forEach(row => { // 显示每一行 row.style.display = ''; // 恢复每一行中标签的样式 const spans = Array.from(row.getElementsByTagName('span')); spans.forEach(span => { span.style.backgroundColor = '#f0f0f0'; span.style.color = '#333'; span.style.border = '1px solid #ccc'; span.style.fontWeight = 'normal'; }); }); } // 创建搜索栏容器 function createSearchContainer(tableRows) { const searchContainer = document.createElement('div'); searchContainer.style.cssText = ` margin-bottom: 20px; /* 增加底部间距 */ display: flex; justify-content: flex-start; /* 左对齐容器内元素 */ align-items: center; /* 垂直居中对齐 */ gap: 15px; /* 增加元素之间的间距 */ padding: 10px; /* 增加内边距 */ background-color: #f9f9f9; /* 设置背景颜色 */ border-radius: 8px; /* 设置圆角 */ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); /* 添加阴影效果 */ width: 100%; /* 搜索容器宽度占满父容器 */ box-sizing: border-box; /* 确保内边距包含在宽度内 */ `; // 创建搜索输入框 const partyAuthInput = createSearchInput(); searchContainer.appendChild(partyAuthInput); // 创建天蓝色的搜索按钮 const searchButton = createButton('搜索', '#4c98fa', () => searchTable(partyAuthInput.value)); searchContainer.appendChild(searchButton); // 创建灰色的重置按钮 const resetButton = createButton('重置', '#6c757d', () => resetTable(partyAuthInput, tableRows)); searchContainer.appendChild(resetButton); return searchContainer; } // 创建搜索输入框 function createSearchInput() { const input = document.createElement('input'); input.placeholder = '搜索组织权限'; input.style.cssText = ` width: 300px; /* 设置固定宽度 */ height: 40px; /* 设置固定高度,与按钮一致 */ padding: 0 15px; /* 上下内边距为0,左右为15px */ border: 2px solid #ced4da; /* 加粗边框 */ border-radius: 4px; /* 设置圆角 */ font-size: 16px; /* 字体大小 */ box-sizing: border-box; /* 确保内边距和边框包含在高度内 */ transition: border-color 0.3s; /* 添加过渡效果 */ `; // 添加聚焦时的边框颜色变化 input.addEventListener('focus', () => { input.style.borderColor = '#80bdff'; input.style.outline = 'none'; }); input.addEventListener('blur', () => { input.style.borderColor = '#ced4da'; }); return input; } // 创建按钮的通用函数 function createButton(text, backgroundColor, onClick) { const button = document.createElement('button'); button.innerText = text; button.style.cssText = ` padding: 0 20px; /* 上下内边距为0,左右为20px */ height: 40px; /* 设置固定高度,与输入框一致 */ background-color: ${backgroundColor}; color: white; border: none; border-radius: 4px; /* 设置圆角 */ cursor: pointer; font-size: 16px; /* 字体大小 */ transition: background-color 0.3s; /* 添加过渡效果 */ `; // 添加悬停时的背景颜色变化 button.addEventListener('mouseover', () => { button.style.backgroundColor = shadeColor(backgroundColor, -10); }); button.addEventListener('mouseout', () => { button.style.backgroundColor = backgroundColor; }); button.addEventListener('click', onClick); // 设置点击事件 return button; } // 辅助函数:调整颜色深浅 function shadeColor(color, percent) { const f = parseInt(color.slice(1), 16), t = percent < 0 ? 0 : 255, p = Math.abs(percent) / 100, R = f >> 16, G = (f >> 8) & 0x00FF, B = f & 0x0000FF; const newColor = "#" + ( 0x1000000 + (Math.round((t - R) * p) + R) * 0x10000 + (Math.round((t - G) * p) + G) * 0x100 + (Math.round((t - B) * p) + B) ).toString(16).slice(1); return newColor; } // 入口函数 function performing_function() { // 从 localStorage 获取 RoleList 并解析 const roleList = JSON.parse(localStorage.getItem("RoleList")); const data = roleList.data.role_list.item; // 初始化表格 const table = initTable(data); const tableRows = table.querySelectorAll('tr'); // 获取表格所有行 // 创建外部容器 const container = document.createElement('div'); container.style.cssText = ` width: 100%; /* 容器宽度占满父容器 */ padding: 20px; /* 添加内边距 */ box-sizing: border-box; /* 确保内边距包含在宽度内 */ `; // 创建搜索栏容器并设置样式 const searchContainer = createSearchContainer(tableRows); container.appendChild(searchContainer); // 添加表格到容器 container.appendChild(table); // 全屏显示内容 createFullScreenDIV(container); } })();