const UsersPage = {
async render() { return '
'; },
async mount() {
document.getElementById('page-title').textContent = '用户管理';
document.getElementById('page-actions').innerHTML = '';
await this.load();
},
async load() {
const ct = document.getElementById('page-content');
try {
const users = await API.get('/users');
const srcLabel = { netease:'网易', skin:'皮肤站' };
ct.innerHTML = `
| # | 用户名 | 邮箱 | 游戏名 | 游戏UID | 来源 | 身份 | 角色 | 状态 | 时间 | 操作 |
${users.map(u => `
| ${u.id} | ${U.esc(u.username)} | ${U.esc(u.email)} |
${U.esc(u.game_name)} | ${U.esc(u.game_uid)} |
${srcLabel[u.source] || u.source || '网易'} |
${(u.identity_count||0) > 1 ? `${u.identity_count} 个` : (u.identity_count||0) === 1 ? '1' : '-'} |
${U.badge(u.role,'role')} |
${u.active ? '启用' : '禁用'} |
${U.date(u.created_at)} |
|
`).join('')}
`;
} catch (e) { ct.innerHTML = `${e.message}
`; }
},
createUser() {
this.loadServersForCreate();
},
async loadServersForCreate() {
let groups = [];
try { groups = await API.get('/polls/groups'); } catch {}
const checks = groups.map(g => {
return ``;
}).join('');
U.modal('添加用户', `
`);
document.getElementById('cu-form').onsubmit = async e => {
e.preventDefault();
const servers = [];
document.querySelectorAll('.cu-srv:checked').forEach(cb => { const [g,s] = cb.value.split('::'); servers.push({group_name:g,server_name:s}); });
try {
await API.post('/users', {
username: document.getElementById('cu-u').value, password: document.getElementById('cu-p').value,
email: document.getElementById('cu-e').value, role: document.getElementById('cu-r').value,
game_name: document.getElementById('cu-gn').value, game_uid: document.getElementById('cu-gu').value,
source: document.getElementById('cu-s').value,
admin_servers: servers,
});
App.closeModal(); this.load();
} catch (ex) { alert(ex.message); }
};
setTimeout(() => UsersPage.toggleCreateServers(), 50);
},
toggleCreateServers() {
const role = document.getElementById('cu-r').value;
const div = document.getElementById('cu-servers');
div.classList.toggle('hidden', role === 'player');
},
editUser(id, username, email, gameName, gameUid, role, active, source) {
this.loadUserServers(id, username, email, gameName, gameUid, role, active, source);
},
async loadUserServers(id, username, email, gameName, gameUid, role, active, source) {
let groups = [], userServers = [], identities = [];
try { groups = await API.get('/polls/groups'); } catch {}
try { userServers = await API.get('/users/'+id+'/servers'); } catch {}
try { identities = await API.get('/users/'+id).then(u => u.identities || []); } catch {}
const checks = groups.map(g => {
const key = g.group_name+'::'+g.server_name;
const has = userServers.some(s => s.group_name===g.group_name && s.server_name===g.server_name);
return ``;
}).join('');
U.modal('编辑用户', `
`);
document.getElementById('eu-form').onsubmit = async e => {
e.preventDefault();
const servers = [];
document.querySelectorAll('.eu-srv:checked').forEach(cb => { const [g,s] = cb.value.split('::'); servers.push({group_name:g,server_name:s}); });
const data = {
email: document.getElementById('eu-e').value, role: document.getElementById('eu-r').value,
game_name: document.getElementById('eu-gn').value, game_uid: document.getElementById('eu-gu').value,
active: document.getElementById('eu-a').value === '1', source: document.getElementById('eu-s').value,
admin_servers: servers,
};
const pw = document.getElementById('eu-p').value; if (pw) data.password = pw;
try { await API.put('/users/'+id, data); App.closeModal(); this.load(); } catch (ex) { alert(ex.message); }
};
},
async addIdentity(userId) {
const source = document.getElementById('eu-ident-source').value;
const name = document.getElementById('eu-ident-name').value.trim();
const uid = document.getElementById('eu-ident-uid').value.trim();
if (!name) return alert('请填写游戏名');
try {
await API.post(`/users/${userId}/identities`, { source, game_name: name, game_uid: uid });
alert('绑定成功');
// 刷新弹窗中的身份列表
const u = await API.get('/users/'+userId);
const box = document.getElementById('identities-box');
const list = u.identities || [];
box.innerHTML = list.length===0 ? '暂无身份记录' : list.map(it=>`
${it.source==='netease'?'网易端':'皮肤站'}
${U.esc(it.game_name)}${it.game_uid?' (UID: '+U.esc(it.game_uid)+')':''}
${U.date(it.created_at)}
${list.length>1?``:'主身份'}
`).join('');
document.getElementById('eu-ident-name').value = '';
document.getElementById('eu-ident-uid').value = '';
} catch (ex) { alert(ex.message); }
},
async removeIdentity(userId, identityId) {
if (!await U.confirm('确认解绑该身份?')) return;
try {
await API.delete(`/users/${userId}/identities/${identityId}`);
alert('已解绑');
const u = await API.get('/users/'+userId);
const box = document.getElementById('identities-box');
const list = u.identities || [];
box.innerHTML = list.length===0 ? '暂无身份记录' : list.map(it=>`
${it.source==='netease'?'网易端':'皮肤站'}
${U.esc(it.game_name)}${it.game_uid?' (UID: '+U.esc(it.game_uid)+')':''}
${U.date(it.created_at)}
${list.length>1?``:'主身份'}
`).join('');
} catch (ex) { alert(ex.message); }
}
};