(function () { 'use strict'; var Api = function () { return window.AdminApi; }; var Ui = function () { return window.AdminUi; }; var I = function () { return window.AdminI18n; }; var State = function () { return window.AdminState; }; var Filter = function () { return window.AdminFilter; }; var Menu = function () { return window.AdminMenu; }; var Router = function () { return window.AdminRouter; }; var Form = function () { return window.AdminForm; }; function buildQuery() { var st = State().users; var q = 'users?page=' + st.page + '&size=' + st.size; if (st.q) q += '&q=' + encodeURIComponent(st.q); return q; } function formField(label, inner) { return '
' + inner + '
'; } function roleOptions(selected) { var roles = ['user']; if (State().adminLevel === 'full') roles.push('admin'); return roles.map(function (r) { return ''; }).join(''); } function adminLevelOptions(selected) { return [ { v: 'full', l: '超级管理员' }, { v: 'ops', l: '运营管理员' }, ].map(function (o) { return ''; }).join(''); } function bindAdminLevelField() { var roleEl = Ui().el('ueRole') || Ui().el('ucRole'); var wrap = Ui().el('adminLevelField'); if (!roleEl || !wrap) return; function sync() { wrap.style.display = roleEl.value === 'admin' ? '' : 'none'; } roleEl.onchange = sync; sync(); } function showCreateModal() { var form = '
' + formField('邮箱', '') + formField('密码', '') + formField('角色', '') + (State().adminLevel === 'full' ? formField('管理级别', '', '运营管理员不可访问设置、审计与支付密钥') : '') + Form().actions('创建', 'adminModalSave') + '
'; Ui().openFormModal('新增用户', form, function () { var email = Ui().el('ucEmail').value.trim(); var pwd = Ui().el('ucPwd').value; if (!email || pwd.length < 8) { soonToast('请填写有效邮箱与至少 8 位密码', 'warn'); return false; } var body = { email: email, password: pwd, role: Ui().el('ucRole').value, }; if (body.role === 'admin') { var lv = Ui().el('ucAdminLevel'); body.admin_level = lv ? lv.value : 'ops'; } return Api().postJson('users', body).then(function (r) { if (r) { soonLayerDismiss(); soonToast('用户已创建', 'success'); render(); } }); }, { success: function () { bindAdminLevelField(); }, }); } function showEditModal(user) { var level = user.admin_level || 'full'; var form = '
' + formField('邮箱', '') + formField('角色', '') + (State().adminLevel === 'full' ? formField('管理级别', '
', '仅对管理员账号生效') : '') + Form().actions('保存', 'adminModalSave') + '
'; Ui().openFormModal('编辑用户 #' + user.id, form, function () { var body = { email: Ui().el('ueEmail').value.trim(), role: Ui().el('ueRole').value, }; if (body.role === 'admin') { var lv = Ui().el('ueAdminLevel'); if (lv) body.admin_level = lv.value; } return Api().putJson('users/' + user.id, body).then(function (r) { if (r) { soonLayerDismiss(); soonToast('用户信息已更新', 'success'); render(); } }); }, { success: function () { bindAdminLevelField(); }, }); } function showPasswordModal(userId) { var form = '
' + formField('新密码', '') + formField('确认密码', '') + Form().actions('重置密码', 'adminModalSave') + '
'; Ui().openFormModal('重置密码', form, function () { var p1 = Ui().el('upPwd').value; var p2 = Ui().el('upPwd2').value; if (p1.length < 8) { soonToast('密码至少 8 位', 'warn'); return false; } if (p1 !== p2) { soonToast('两次密码不一致', 'warn'); return false; } return Api().postJson('users/' + userId + '/password', { password: p1 }).then(function (r) { if (r) { soonLayerDismiss(); soonToast('密码已重置', 'success'); } }); }); } function showSubscriptionModal(userId) { Api().get('plans').then(function (j) { if (!j) return; var opts = (j.data.items || []).map(function (p) { return ''; }).join(''); var form = '
' + formField('套餐', '') + formField('有效天数', '') + '

选择免费版将取消当前有效会员。

' + Form().actions('保存', 'adminModalSave') + '
'; Ui().openFormModal('设置会员', form, function () { var planSel = Ui().el('usPlan'); var daysVal = Ui().el('usDays').value.trim(); var body = { plan_id: parseInt(planSel.value, 10) }; if (daysVal) body.days = parseInt(daysVal, 10); return Api().postJson('users/' + userId + '/subscription', body).then(function (r) { if (r) { soonLayerDismiss(); soonToast('会员已更新', 'success'); render(); } }); }); var planEl = Ui().el('usPlan'); if (planEl) { planEl.onchange = function () { var opt = planEl.options[planEl.selectedIndex]; Ui().el('usDays').placeholder = '默认 ' + (opt.getAttribute('data-days') || '0') + ' 天'; }; planEl.onchange(); } }); } function showUserDetail(id, opts) { opts = opts || {}; if (!opts.fromRoute) Router().openDetail(id); Api().get('users/' + id).then(function (j) { if (!j) return; var d = j.data; var u = d.user || {}; var sub = d.subscription; var usage = d.usage || {}; var adminId = State().currentAdminId; var levelLabel = u.role === 'admin' ? (u.admin_level === 'ops' ? '运营管理员' : '超级管理员') : '—'; var account = Ui().detailRow('邮箱', I().esc(u.email)) + Ui().detailRow('角色', I().esc(I().tRole(u.role))) + (u.role === 'admin' ? Ui().detailRow('管理级别', I().esc(levelLabel)) : '') + Ui().detailRow('状态', I().badgeStatus(u.status)) + Ui().detailRow('注册时间', I().esc(I().formatDateTime(u.created_at))); var subHtml; if (sub && sub.plan_name) { subHtml = Ui().detailRow('套餐', I().esc(sub.plan_name)) + Ui().detailRow('状态', I().badgeStatus(sub.status)) + Ui().detailRow('开始时间', I().esc(I().formatDateTime(sub.started_at))) + Ui().detailRow('到期时间', I().esc(I().formatDateTime(sub.expires_at))); } else { subHtml = '

普通用户 / 未激活

'; } var usageHtml = Ui().detailRow('文件数', I().esc(usage.files_count || 0)) + Ui().detailRow('占用空间', I().esc(I().formatBytes(usage.storage_bytes))); var orderRows = (d.recent_orders || []).map(function (o) { return '' + I().esc(o.order_no || o.id) + '' + I().formatCents(o.amount_cents) + '' + I().badgeStatus(o.status) + '' + I().formatDateTime(o.created_at) + ''; }).join(''); var ordersHtml = Ui().dataTable(['订单号', '金额', '状态', '时间'], orderRows, 4); var actions = '
' + '' + '' + '' + (u.id !== adminId ? '' : '') + '
'; Ui().openDrawer('用户 #' + u.id, actions + Ui().detailSection('账号信息', account) + Ui().detailSection('当前会员', subHtml) + Ui().detailSection('云端用量', usageHtml) + Ui().detailSection('最近订单', ordersHtml)); Ui().el('drawerEdit').onclick = function () { Ui().closeDrawer(); showEditModal(u); }; Ui().el('drawerPwd').onclick = function () { showPasswordModal(u.id); }; Ui().el('drawerSub').onclick = function () { showSubscriptionModal(u.id); }; var delBtn = Ui().el('drawerDel'); if (delBtn) { delBtn.onclick = function () { Ui().confirm('确认删除该用户?其云端文件将标记删除且不可恢复。', function () { Api().del('users/' + u.id).then(function (r) { if (r) { Ui().closeDrawer(); soonToast('用户已删除', 'success'); render(); } }); }); }; } }); } function userRowActions(u, adminId) { var isSelf = adminId && u.id === adminId; var editDisabled = State().adminLevel === 'ops' && u.role === 'admin'; var ds = { id: String(u.id) }; var editDs = { id: String(u.id), email: u.email, role: u.role, admin_level: u.admin_level || 'full', }; var inline = [ { label: '详情', action: 'detail', dataset: ds }, { label: '编辑', action: 'edit', dataset: editDs, disabled: editDisabled }, { label: '会员', action: 'sub', dataset: ds }, ]; var more = [ { label: '改密', action: 'pwd', dataset: ds }, ]; if (u.status === 'disabled') { more.push({ label: '启用', action: 'status', dataset: { id: String(u.id), st: 'active' } }); } else if (!isSelf) { more.push({ label: '停用', action: 'status', dataset: { id: String(u.id), st: 'disabled' } }); } else { more.push({ label: '停用', action: 'status', disabled: true }); } if (!isSelf) { more.push({ label: '删除', action: 'delete', className: 'soon-admin-action-menu__item--danger', dataset: ds, }); } return Menu().rowActions('user-' + u.id, inline, more); } function bindUserMenus(panel, adminId) { Menu().bind(panel, function (action, btn) { var id = parseInt(btn.dataset.id, 10); if (action === 'detail') showUserDetail(id); if (action === 'edit') { showEditModal({ id: id, email: btn.dataset.email, role: btn.dataset.role, admin_level: btn.dataset.adminLevel || 'full', }); } if (action === 'pwd') showPasswordModal(id); if (action === 'sub') showSubscriptionModal(id); if (action === 'status' && btn.dataset.st) { Ui().confirm('确认变更用户状态?', function () { Api().postJson('users/' + id + '/status', { status: btn.dataset.st }).then(function (r) { if (r) { soonToast('状态已更新', 'success'); render(); } }); }); } if (action === 'delete') { Ui().confirm('确认删除该用户?其云端文件将标记删除。', function () { Api().del('users/' + id).then(function (r) { if (r) { soonToast('用户已删除', 'success'); render(); } }); }); } }); } function renderFilterBar(st) { return Filter().bar( Filter().field('邮箱', Filter().searchInput('userSearchQ', st.q, '搜索邮箱')), '' + '' ); } function bindFilters(st) { Ui().el('userSearchBtn').onclick = function () { st.q = Ui().el('userSearchQ').value.trim(); st.page = 1; Router().syncQuery(); render(); }; var reset = Ui().el('userSearchReset'); if (reset) { reset.onclick = function () { st.q = ''; st.page = 1; Router().syncQuery(); render(); }; } Ui().el('userSearchQ').onkeydown = function (e) { if (e.key === 'Enter') { st.q = Ui().el('userSearchQ').value.trim(); st.page = 1; Router().syncQuery(); render(); } }; } function render() { var panel = Ui().el('panel-users'); if (!panel) return; if (!Router().hasPendingDetail()) Ui().closeDrawer(); var st = State().users; var pageShell = '
' + Ui().pageHeader('用户管理', '增删改用户、重置密码与设置会员', '') + renderFilterBar(st) + Ui().skeletonTable() + '
'; panel.innerHTML = pageShell; Api().get(buildQuery()).then(function (j) { if (!j) { panel.innerHTML = '
' + Ui().pageHeader('用户管理', '增删改用户、重置密码与设置会员', '') + renderFilterBar(st) + Ui().listError('用户列表加载失败', 'usersListRetry') + '
'; Ui().el('userCreateBtn').onclick = showCreateModal; Ui().el('usersListRetry').onclick = render; bindFilters(st); var errDetailId = Router().consumeDetailId(); if (errDetailId) showUserDetail(errDetailId, { fromRoute: true }); return; } var items = j.data.items || []; var adminId = State().currentAdminId; var rows = items.map(function (u) { var planLabel = u.plan_name ? I().esc(u.plan_name) : '免费版'; return '' + u.id + '' + I().esc(u.email) + '' + I().esc(I().tRole(u.role)) + '' + planLabel + '' + I().badgeStatus(u.status) + '' + I().formatDateTime(u.created_at) + '' + userRowActions(u, adminId) + ''; }).join(''); panel.innerHTML = '
' + Ui().pageHeader('用户管理', '增删改用户、重置密码与设置会员', '') + renderFilterBar(st) + Ui().dataTable(['ID', '邮箱', '角色', '会员', '状态', '注册时间', '操作'], rows) + Ui().pagerHtml(j.data.page, j.data.size, j.data.total) + '
'; Ui().el('userCreateBtn').onclick = showCreateModal; bindFilters(st); Ui().bindPager(panel, j.data.page, j.data.size, j.data.total, function (p, newSize) { st.page = p; if (newSize) st.size = newSize; Router().syncQuery(); render(); }); bindUserMenus(panel, adminId); var detailId = Router().consumeDetailId(); if (detailId) showUserDetail(detailId, { fromRoute: true }); }); } window.AdminViews = window.AdminViews || {}; window.AdminViews.users = { render: render }; })();