318 lines
12 KiB
HTML
318 lines
12 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>权限诊断工具</title>
|
||
<style>
|
||
body {
|
||
font-family: Arial, sans-serif;
|
||
margin: 20px;
|
||
background: #f5f5f5;
|
||
}
|
||
.container {
|
||
max-width: 1000px;
|
||
margin: 0 auto;
|
||
background: white;
|
||
padding: 20px;
|
||
border-radius: 8px;
|
||
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||
}
|
||
.debug-section {
|
||
border: 1px solid #ddd;
|
||
padding: 15px;
|
||
margin: 10px 0;
|
||
border-radius: 5px;
|
||
background: #f9f9f9;
|
||
}
|
||
.debug-title {
|
||
font-weight: bold;
|
||
color: #333;
|
||
margin-bottom: 10px;
|
||
font-size: 16px;
|
||
}
|
||
.permission-item {
|
||
padding: 5px;
|
||
margin: 3px 0;
|
||
background: #e8f5e8;
|
||
border-radius: 3px;
|
||
font-family: monospace;
|
||
}
|
||
.error {
|
||
color: red;
|
||
background: #ffe6e6;
|
||
}
|
||
.success {
|
||
color: green;
|
||
background: #e6ffe6;
|
||
}
|
||
.warning {
|
||
color: orange;
|
||
background: #fff3e0;
|
||
}
|
||
.code-block {
|
||
background: #f0f0f0;
|
||
padding: 10px;
|
||
border-radius: 4px;
|
||
font-family: monospace;
|
||
margin: 10px 0;
|
||
}
|
||
button {
|
||
background: #007bff;
|
||
color: white;
|
||
border: none;
|
||
padding: 10px 15px;
|
||
border-radius: 5px;
|
||
cursor: pointer;
|
||
margin: 5px;
|
||
}
|
||
button:hover {
|
||
background: #0056b3;
|
||
}
|
||
.highlight {
|
||
background: yellow;
|
||
font-weight: bold;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="container">
|
||
<h1>🔍 奖学金申请权限诊断工具</h1>
|
||
<p><strong>问题描述</strong>:jwc010用户看不到"班主任批量申请"按钮</p>
|
||
<p><strong>预期权限</strong>:<code>jcbt:application:add</code></p>
|
||
|
||
<button onclick="startDiagnosis()">开始诊断</button>
|
||
<button onclick="clearResults()">清空结果</button>
|
||
|
||
<div id="results"></div>
|
||
</div>
|
||
|
||
<script>
|
||
function startDiagnosis() {
|
||
const results = document.getElementById('results');
|
||
results.innerHTML = '';
|
||
|
||
addSection('🚀 开始权限诊断...', 'info');
|
||
|
||
// 1. 检查当前URL和页面
|
||
checkCurrentPage();
|
||
|
||
// 2. 检查本地存储
|
||
checkLocalStorage();
|
||
|
||
// 3. 检查全局变量
|
||
checkGlobalVariables();
|
||
|
||
// 4. 检查Vue Store
|
||
checkVueStore();
|
||
|
||
// 5. 检查DOM元素
|
||
checkDOMElements();
|
||
|
||
// 6. 提供调试命令
|
||
provideDebugCommands();
|
||
|
||
addSection('✅ 诊断完成!请检查上述结果。', 'success');
|
||
}
|
||
|
||
function checkCurrentPage() {
|
||
addSection('📍 当前页面信息', 'info');
|
||
addResult('当前URL', window.location.href);
|
||
addResult('页面标题', document.title);
|
||
addResult('用户代理', navigator.userAgent);
|
||
}
|
||
|
||
function checkLocalStorage() {
|
||
addSection('💾 本地存储检查', 'info');
|
||
|
||
// 检查Token
|
||
const token = localStorage.getItem('token') || sessionStorage.getItem('token');
|
||
addResult('Token存在', token ? '✅ 是' : '❌ 否');
|
||
if (token) {
|
||
addResult('Token长度', token.length);
|
||
addResult('Token前20字符', token.substring(0, 20) + '...');
|
||
}
|
||
|
||
// 检查用户信息
|
||
const userInfo = localStorage.getItem('userInfo') || sessionStorage.getItem('userInfo');
|
||
if (userInfo) {
|
||
try {
|
||
const user = JSON.parse(userInfo);
|
||
addResult('用户信息', JSON.stringify(user, null, 2));
|
||
} catch (e) {
|
||
addResult('用户信息解析失败', e.message, 'error');
|
||
}
|
||
}
|
||
|
||
// 检查权限信息
|
||
const permissions = localStorage.getItem('permissions') || sessionStorage.getItem('permissions');
|
||
if (permissions) {
|
||
try {
|
||
const perms = JSON.parse(permissions);
|
||
addResult('本地权限数量', Array.isArray(perms) ? perms.length : 'N/A');
|
||
if (Array.isArray(perms)) {
|
||
const targetPerm = 'jcbt:application:add';
|
||
const hasTargetPerm = perms.includes(targetPerm);
|
||
addResult(`目标权限 ${targetPerm}`, hasTargetPerm ? '✅ 存在' : '❌ 不存在', hasTargetPerm ? 'success' : 'error');
|
||
|
||
// 显示所有jcbt相关权限
|
||
const jcbtPerms = perms.filter(p => p.includes('jcbt'));
|
||
addResult('JCBT相关权限', jcbtPerms.length > 0 ? jcbtPerms.join(', ') : '无');
|
||
}
|
||
} catch (e) {
|
||
addResult('权限信息解析失败', e.message, 'error');
|
||
}
|
||
} else {
|
||
addResult('本地权限信息', '❌ 不存在', 'error');
|
||
}
|
||
}
|
||
|
||
function checkGlobalVariables() {
|
||
addSection('🌍 全局变量检查', 'info');
|
||
|
||
// 检查Vue应用
|
||
if (window.Vue) {
|
||
addResult('Vue版本', window.Vue.version || 'Vue 3.x');
|
||
} else {
|
||
addResult('Vue', '❌ 未找到');
|
||
}
|
||
|
||
// 检查Pinia
|
||
if (window.__VUE_DEVTOOLS_GLOBAL_HOOK__) {
|
||
addResult('Vue Devtools', '✅ 已安装');
|
||
}
|
||
}
|
||
|
||
function checkVueStore() {
|
||
addSection('🗄️ Vue Store检查', 'info');
|
||
|
||
// 这里需要在Vue应用中执行
|
||
addResult('注意', '以下命令需要在浏览器控制台的Vue应用上下文中执行:', 'warning');
|
||
|
||
const vueCommands = [
|
||
'// 检查用户权限',
|
||
'const userStore = useUserStore();',
|
||
'console.log("用户权限:", userStore.permissions);',
|
||
'console.log("用户角色:", userStore.roles);',
|
||
'console.log("用户ID:", userStore.userId);',
|
||
'console.log("用户名:", userStore.name);',
|
||
'',
|
||
'// 检查目标权限',
|
||
'const targetPerm = "jcbt:application:add";',
|
||
'const hasPermission = userStore.permissions.includes(targetPerm);',
|
||
'console.log(`是否有权限 ${targetPerm}:`, hasPermission);',
|
||
'',
|
||
'// 检查权限指令逻辑',
|
||
'import { checkPermi } from "@/utils/permission";',
|
||
'const result = checkPermi(["jcbt:application:add"]);',
|
||
'console.log("权限检查结果:", result);'
|
||
];
|
||
|
||
vueCommands.forEach(cmd => {
|
||
addCodeBlock(cmd);
|
||
});
|
||
}
|
||
|
||
function checkDOMElements() {
|
||
addSection('🔍 DOM元素检查', 'info');
|
||
|
||
// 查找奖学金申请相关的按钮
|
||
const buttons = document.querySelectorAll('button');
|
||
let foundButton = false;
|
||
|
||
buttons.forEach((btn, index) => {
|
||
const text = btn.textContent.trim();
|
||
if (text.includes('申请') || text.includes('新增') || text.includes('批量')) {
|
||
foundButton = true;
|
||
addResult(`按钮 ${index + 1}`, `"${text}" - 可见: ${btn.style.display !== 'none'}`, 'info');
|
||
}
|
||
});
|
||
|
||
if (!foundButton) {
|
||
addResult('相关按钮', '❌ 未找到申请/新增/批量相关按钮', 'error');
|
||
}
|
||
|
||
// 检查是否在正确的页面
|
||
const url = window.location.href;
|
||
if (url.includes('jcbt') && url.includes('application')) {
|
||
addResult('页面匹配', '✅ 在奖学金申请页面', 'success');
|
||
} else {
|
||
addResult('页面匹配', '❌ 不在奖学金申请页面', 'error');
|
||
}
|
||
}
|
||
|
||
function provideDebugCommands() {
|
||
addSection('🛠️ 调试命令', 'info');
|
||
|
||
addResult('在浏览器控制台执行以下命令进行深度调试:', '', 'info');
|
||
|
||
const commands = [
|
||
'// 1. 检查用户完整信息',
|
||
'fetch("/getInfo", { headers: { "Authorization": "Bearer " + localStorage.getItem("token") } })',
|
||
' .then(res => res.json())',
|
||
' .then(data => console.log("用户信息:", data));',
|
||
'',
|
||
'// 2. 手动检查权限',
|
||
'console.log("当前用户权限:", JSON.parse(localStorage.getItem("permissions") || "[]"));',
|
||
'',
|
||
'// 3. 检查Vue实例',
|
||
'const app = document.querySelector("#app").__vueParentComponent;',
|
||
'console.log("Vue应用:", app);',
|
||
'',
|
||
'// 4. 强制显示按钮(测试用)',
|
||
'document.querySelectorAll("button").forEach(btn => {',
|
||
' if (btn.textContent.includes("申请")) {',
|
||
' btn.style.display = "inline-block";',
|
||
' btn.style.opacity = "1";',
|
||
' console.log("强制显示按钮:", btn.textContent);',
|
||
' }',
|
||
'});'
|
||
];
|
||
|
||
commands.forEach(cmd => {
|
||
addCodeBlock(cmd);
|
||
});
|
||
}
|
||
|
||
function addSection(title, type = 'info') {
|
||
const results = document.getElementById('results');
|
||
const section = document.createElement('div');
|
||
section.className = `debug-section ${type}`;
|
||
section.innerHTML = `<div class="debug-title">${title}</div>`;
|
||
results.appendChild(section);
|
||
return section;
|
||
}
|
||
|
||
function addResult(label, value, type = 'info') {
|
||
const results = document.getElementById('results');
|
||
const lastSection = results.lastElementChild;
|
||
const item = document.createElement('div');
|
||
item.className = `permission-item ${type}`;
|
||
item.innerHTML = `<strong>${label}:</strong> ${value}`;
|
||
lastSection.appendChild(item);
|
||
}
|
||
|
||
function addCodeBlock(code) {
|
||
const results = document.getElementById('results');
|
||
const lastSection = results.lastElementChild;
|
||
const block = document.createElement('div');
|
||
block.className = 'code-block';
|
||
block.textContent = code;
|
||
lastSection.appendChild(block);
|
||
}
|
||
|
||
function clearResults() {
|
||
document.getElementById('results').innerHTML = '';
|
||
}
|
||
|
||
// 页面加载时自动检查基础信息
|
||
window.onload = function() {
|
||
addSection('💡 使用说明', 'info');
|
||
addResult('步骤1', '确保您在奖学金申请管理页面(http://localhost/jcbt/scholarship/application)');
|
||
addResult('步骤2', '点击"开始诊断"按钮');
|
||
addResult('步骤3', '查看诊断结果,特别关注权限相关信息');
|
||
addResult('步骤4', '按照提供的调试命令在浏览器控制台进一步检查');
|
||
};
|
||
</script>
|
||
</body>
|
||
</html> |