Files
jiu/web/profile.njk
T
wangjia c7de728c18 feat(site): 导航登录态下拉菜单 + 个人信息/退出登录页,登录不再直跳 App
- 导航「进入系统 · 名字」改为下拉:个人信息 / 进入系统 / 退出登录,导航可重入刷新(window.jiuNavRender)
- 新增 /profile/(账号 / 门店 / 授权三卡,authFetch 实时拉取)与 /logout/(撤销会话 + 清本地凭证)
- 登录成功默认落地 /profile/(?next= 站内白名单不变),不再直跳 /app/
- auth.js 增加 jiuAuth.clear();site.css 含本轮下拉 / profile / 特惠卡样式

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JJ1g8XV1YhhmHRzhwWEW7o
2026-07-03 22:24:55 +08:00

93 lines
4.5 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
layout: base.njk
title: 个人信息
description: 查看当前登录账号、门店与授权状态。
permalink: /profile/
---
{# 个人信息(需登录):账号信息来自 localStorage;门店与授权实时拉
GET /api/v1/shop/info(原样 JSON)与 GET /api/v1/license/info{data}包裹)。 #}
<div class="container" style="padding:40px 24px 72px; max-width:720px">
<div class="crumb"><a href="/">首页</a><span>/</span><span>个人信息</span></div>
<h1 class="co-title">个人信息</h1>
<div class="co-card">
<h2>账号</h2>
<div class="pf-row"><span class="k">姓名</span><span class="v" id="pfName">—</span></div>
<div class="pf-row"><span class="k">登录账号</span><span class="v mono" id="pfUser">—</span></div>
<div class="pf-row"><span class="k">角色</span><span class="v" id="pfRole">—</span></div>
<div class="pf-row"><span class="k">门店编号</span><span class="v mono" id="pfShopNo">—</span></div>
</div>
<div class="co-card">
<h2>门店</h2>
<div class="pf-row"><span class="k">门店名称</span><span class="v" id="pfShopName">加载中…</span></div>
<div class="pf-row"><span class="k">负责人</span><span class="v" id="pfManager">—</span></div>
<div class="pf-row"><span class="k">联系电话</span><span class="v mono" id="pfPhone">—</span></div>
<div class="pf-row"><span class="k">门店地址</span><span class="v" id="pfAddr">—</span></div>
</div>
<div class="co-card">
<h2>授权</h2>
<div class="pf-row"><span class="k">状态</span><span class="v" id="pfPhase">加载中…</span></div>
<div class="pf-row"><span class="k">授权类型</span><span class="v" id="pfType">—</span></div>
<div class="pf-row"><span class="k">到期时间</span><span class="v mono" id="pfExpire">—</span></div>
<div class="pf-row"><span class="k">已绑定设备</span><span class="v mono" id="pfDev">—</span></div>
<div class="pf-acts" style="margin-top:14px">
<a class="btn primary" href="/checkout/">购买 / 续费</a>
</div>
</div>
<div class="pf-acts">
<a class="btn primary" href="/app/">进入系统</a>
<a class="btn ghost" href="/logout/">退出登录</a>
</div>
</div>
<script>
(function () {
var API = '{{ site.appBaseUrl }}';
function $(id) { return document.getElementById(id); }
function gotoLogin() { location.href = '/login/?next=/profile/'; }
if (!window.jiuAuth || !jiuAuth.loggedIn()) { gotoLogin(); return; }
var ROLE = { superadmin: '超级管理员', super_admin: '超级管理员', admin: '管理员', operator: '操作员', readonly: '只读' };
var TYPE = { trial: '试用', monthly: '包月', annual: '包年', lifetime: '永久' };
$('pfName').textContent = jiuAuth.get('real_name') || '—';
$('pfUser').textContent = jiuAuth.get('username') || '—';
var role = jiuAuth.get('role') || '';
$('pfRole').textContent = ROLE[role] || role || '—';
$('pfShopNo').textContent = jiuAuth.get('shop_no') || '—';
function guard(r) {
if (r.status === 401) { gotoLogin(); return null; }
return r.ok ? r.json() : null;
}
// 门店信息(GetInfo 直接返回 shop JSON,无 {data} 包裹)
jiuAuth.authFetch(API, '/api/v1/shop/info').then(guard).then(function (s) {
if (!s) return;
$('pfShopName').textContent = s.name || '—';
$('pfManager').textContent = s.manager_name || '—';
$('pfPhone').textContent = s.phone || '—';
$('pfAddr').textContent = s.address || '—';
}).catch(function () { $('pfShopName').textContent = '加载失败'; });
// 授权信息({data} 包裹;data:null = 无有效授权)
jiuAuth.authFetch(API, '/api/v1/license/info').then(guard).then(function (j) {
if (!j) return;
var d = j.data;
if (!d) { $('pfPhase').innerHTML = '<span class="pf-badge bad">无有效授权</span>'; return; }
var badge =
d.phase === 'normal' ? '<span class="pf-badge ok">正常</span>' :
d.phase === 'grace' ? '<span class="pf-badge warn">已到期 · 宽限期内</span>' :
d.phase === 'readonly' ? '<span class="pf-badge warn">已到期 · 只读</span>' :
'<span class="pf-badge bad">已锁定</span>';
$('pfPhase').innerHTML = badge;
$('pfType').textContent = TYPE[d.type] || d.type || '—';
$('pfExpire').textContent = d.expires_at ? String(d.expires_at).slice(0, 10) : '—';
$('pfDev').textContent = (d.device_count != null ? d.device_count : '—') + ' / ' + (d.max_devices || '—');
}).catch(function () { $('pfPhase').textContent = '加载失败'; });
})();
</script>