<!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;
|
max-width: 800px;
|
margin: 0 auto;
|
padding: 20px;
|
}
|
.section {
|
margin: 20px 0;
|
padding: 15px;
|
border: 1px solid #ddd;
|
border-radius: 5px;
|
}
|
button {
|
background-color: #007bff;
|
color: white;
|
border: none;
|
padding: 10px 20px;
|
border-radius: 4px;
|
cursor: pointer;
|
margin: 5px;
|
}
|
button:hover {
|
background-color: #0056b3;
|
}
|
.error {
|
color: red;
|
}
|
.success {
|
color: green;
|
}
|
.log {
|
background-color: #f8f9fa;
|
border: 1px solid #dee2e6;
|
border-radius: 4px;
|
padding: 10px;
|
margin: 10px 0;
|
white-space: pre-wrap;
|
font-family: monospace;
|
max-height: 300px;
|
overflow-y: auto;
|
}
|
</style>
|
</head>
|
<body>
|
<h1>修复员工角色代码</h1>
|
|
<div class="section">
|
<h3>1. 检查认证状态</h3>
|
<button onclick="checkAuth()">检查认证状态</button>
|
<div id="authStatus"></div>
|
</div>
|
|
<div class="section">
|
<h3>2. 获取所有员工</h3>
|
<button onclick="fetchEmployees()">获取员工列表</button>
|
<div id="employeeList"></div>
|
</div>
|
|
<div class="section">
|
<h3>3. 获取有效角色</h3>
|
<button onclick="fetchRoles()">获取角色列表</button>
|
<div id="roleList"></div>
|
</div>
|
|
<div class="section">
|
<h3>4. 修复无效角色</h3>
|
<button onclick="fixInvalidRoles()">修复无效角色代码</button>
|
<div id="fixResult"></div>
|
</div>
|
|
<div class="section">
|
<h3>操作日志</h3>
|
<div id="log" class="log"></div>
|
<button onclick="clearLog()">清空日志</button>
|
</div>
|
|
<script>
|
const API_BASE_URL = 'http://localhost:8080/api';
|
const GRAPHQL_ENDPOINT = `${API_BASE_URL}/graphql`;
|
|
let employees = [];
|
let validRoles = [];
|
|
function log(message) {
|
const logDiv = document.getElementById('log');
|
const timestamp = new Date().toLocaleTimeString();
|
logDiv.textContent += `[${timestamp}] ${message}\n`;
|
logDiv.scrollTop = logDiv.scrollHeight;
|
}
|
|
function clearLog() {
|
document.getElementById('log').textContent = '';
|
}
|
|
async function graphqlRequest(query, variables = {}) {
|
const token = localStorage.getItem('token');
|
|
const response = await fetch(GRAPHQL_ENDPOINT, {
|
method: 'POST',
|
headers: {
|
'Content-Type': 'application/json',
|
...(token && { 'Authorization': `Bearer ${token}` })
|
},
|
body: JSON.stringify({
|
query,
|
variables
|
})
|
});
|
|
const result = await response.json();
|
|
if (result.errors) {
|
throw new Error(result.errors[0].message);
|
}
|
|
return result.data;
|
}
|
|
async function checkAuth() {
|
const statusDiv = document.getElementById('authStatus');
|
const token = localStorage.getItem('token');
|
|
if (!token) {
|
statusDiv.innerHTML = '<span class="error">未找到认证令牌,请先登录</span>';
|
log('错误: 未找到认证令牌');
|
return;
|
}
|
|
try {
|
// 尝试获取用户信息来验证token
|
const query = `
|
query {
|
employees {
|
id
|
name
|
}
|
}
|
`;
|
|
await graphqlRequest(query);
|
statusDiv.innerHTML = '<span class="success">认证状态正常</span>';
|
log('认证状态检查通过');
|
} catch (error) {
|
statusDiv.innerHTML = `<span class="error">认证失败: ${error.message}</span>`;
|
log(`认证失败: ${error.message}`);
|
}
|
}
|
|
async function fetchEmployees() {
|
const listDiv = document.getElementById('employeeList');
|
|
try {
|
const query = `
|
query {
|
employees {
|
id
|
name
|
phone
|
roleId
|
description
|
}
|
}
|
`;
|
|
const data = await graphqlRequest(query);
|
employees = data.employees;
|
|
let html = `<p>找到 ${employees.length} 个员工:</p><ul>`;
|
employees.forEach(emp => {
|
html += `<li>ID: ${emp.id}, 姓名: ${emp.name}, 角色: ${emp.roleId}</li>`;
|
});
|
html += '</ul>';
|
|
listDiv.innerHTML = html;
|
log(`成功获取 ${employees.length} 个员工`);
|
} catch (error) {
|
listDiv.innerHTML = `<span class="error">获取员工失败: ${error.message}</span>`;
|
log(`获取员工失败: ${error.message}`);
|
}
|
}
|
|
async function fetchRoles() {
|
const listDiv = document.getElementById('roleList');
|
|
try {
|
const query = `
|
query {
|
activeRoles {
|
id
|
code
|
name
|
description
|
}
|
}
|
`;
|
|
const data = await graphqlRequest(query);
|
validRoles = data.activeRoles;
|
|
let html = `<p>找到 ${validRoles.length} 个有效角色:</p><ul>`;
|
validRoles.forEach(role => {
|
html += `<li>代码: ${role.code}, 名称: ${role.name}</li>`;
|
});
|
html += '</ul>';
|
|
listDiv.innerHTML = html;
|
log(`成功获取 ${validRoles.length} 个有效角色`);
|
} catch (error) {
|
listDiv.innerHTML = `<span class="error">获取角色失败: ${error.message}</span>`;
|
log(`获取角色失败: ${error.message}`);
|
}
|
}
|
|
async function fixInvalidRoles() {
|
const resultDiv = document.getElementById('fixResult');
|
|
if (employees.length === 0) {
|
resultDiv.innerHTML = '<span class="error">请先获取员工列表</span>';
|
return;
|
}
|
|
if (validRoles.length === 0) {
|
resultDiv.innerHTML = '<span class="error">请先获取角色列表</span>';
|
return;
|
}
|
|
const validRoleCodes = validRoles.map(role => role.code);
|
const invalidEmployees = employees.filter(emp => !validRoleCodes.includes(emp.roleId));
|
|
if (invalidEmployees.length === 0) {
|
resultDiv.innerHTML = '<span class="success">所有员工的角色代码都是有效的</span>';
|
log('所有员工的角色代码都是有效的');
|
return;
|
}
|
|
log(`发现 ${invalidEmployees.length} 个员工的角色代码无效`);
|
|
// 角色映射规则
|
const roleMapping = {
|
'MANAGER': 'SUPER_ADMIN',
|
'EMPLOYEE': 'AUDITOR',
|
'ADMIN': 'SUPER_ADMIN'
|
};
|
|
let fixedCount = 0;
|
let errors = [];
|
|
for (const emp of invalidEmployees) {
|
const newRoleId = roleMapping[emp.roleId] || 'AUDITOR'; // 默认映射到AUDITOR
|
|
try {
|
const mutation = `
|
mutation SaveEmployee($input: EmployeeInput!) {
|
saveEmployee(input: $input) {
|
id
|
name
|
roleId
|
}
|
}
|
`;
|
|
const variables = {
|
input: {
|
id: parseInt(emp.id),
|
name: emp.name,
|
phone: emp.phone,
|
roleId: newRoleId,
|
description: emp.description
|
}
|
};
|
|
await graphqlRequest(mutation, variables);
|
fixedCount++;
|
log(`修复员工 ${emp.name} (ID: ${emp.id}): ${emp.roleId} -> ${newRoleId}`);
|
} catch (error) {
|
errors.push(`员工 ${emp.name} (ID: ${emp.id}): ${error.message}`);
|
log(`修复员工 ${emp.name} 失败: ${error.message}`);
|
}
|
}
|
|
let html = `<p class="success">成功修复 ${fixedCount} 个员工的角色代码</p>`;
|
if (errors.length > 0) {
|
html += `<p class="error">修复失败 ${errors.length} 个:</p><ul>`;
|
errors.forEach(error => {
|
html += `<li>${error}</li>`;
|
});
|
html += '</ul>';
|
}
|
|
resultDiv.innerHTML = html;
|
log(`修复完成: 成功 ${fixedCount} 个, 失败 ${errors.length} 个`);
|
}
|
|
// 页面加载时检查认证状态
|
window.onload = function() {
|
checkAuth();
|
};
|
</script>
|
</body>
|
</html>
|