Add roles/ACL so admin and users can issue activation codes; exe opens review login.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,10 +1,12 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}账户 · {{ app_name }}{% endblock %}
|
||||
{% block content %}
|
||||
<h2 style="margin:0 0 14px">账户标注</h2>
|
||||
<h2 style="margin:0 0 14px">账户{% if can_create %}(仅管理员可创建){% else %}(只读自己的账户){% endif %}</h2>
|
||||
<div class="grid cols-2">
|
||||
{% if can_create %}
|
||||
<div class="card">
|
||||
<h3>新增账户</h3>
|
||||
<p class="muted">账户禁止自助注册,创建后在「用户」中绑定给唯一操作员。</p>
|
||||
<form method="post" action="{{ url_for('accounts_create') }}">
|
||||
<div class="form-row"><label>名称</label><input name="name" required placeholder="如:模拟盘-A"></div>
|
||||
<div class="form-row"><label>券商</label><input name="broker" placeholder="MT5 券商名"></div>
|
||||
@@ -21,8 +23,9 @@
|
||||
<button class="btn" type="submit">添加</button>
|
||||
</form>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="card">
|
||||
<h3>已有账户</h3>
|
||||
<h3>账户列表</h3>
|
||||
<table>
|
||||
<thead><tr><th>名称</th><th>类型</th><th>标注</th><th></th></tr></thead>
|
||||
<tbody>
|
||||
|
||||
@@ -14,11 +14,16 @@
|
||||
<a href="{{ url_for('dashboard') }}" class="{% if request.endpoint=='dashboard' %}active{% endif %}">总览</a>
|
||||
<a href="{{ url_for('records_page') }}" class="{% if request.endpoint and request.endpoint.startswith('record') %}active{% endif %}">交易复盘</a>
|
||||
<a href="{{ url_for('download_page') }}" class="{% if request.endpoint and 'download' in request.endpoint %}active{% endif %}">下载中心</a>
|
||||
{% if is_admin %}
|
||||
<a href="{{ url_for('accounts_page') }}" class="{% if request.endpoint and 'account' in request.endpoint %}active{% endif %}">账户</a>
|
||||
<a href="{{ url_for('users_page') }}" class="{% if request.endpoint and 'users' in request.endpoint %}active{% endif %}">用户</a>
|
||||
<a href="{{ url_for('machines_page') }}" class="{% if request.endpoint and 'machine' in request.endpoint %}active{% endif %}">机器</a>
|
||||
{% else %}
|
||||
<a href="{{ url_for('accounts_page') }}" class="{% if request.endpoint and 'account' in request.endpoint %}active{% endif %}">我的账户</a>
|
||||
{% endif %}
|
||||
<a href="{{ url_for('settings_page') }}" class="{% if request.endpoint and 'settings' in request.endpoint %}active{% endif %}">系统设置</a>
|
||||
</nav>
|
||||
<div class="right">{{ session.get('user') }} · <a href="{{ url_for('logout') }}">退出</a></div>
|
||||
<div class="right">{{ current_user.username }}({{ current_user.role }}) · <a href="{{ url_for('logout') }}">退出</a></div>
|
||||
</header>
|
||||
{% endif %}
|
||||
<main class="wrap">
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
</div>
|
||||
<div class="card">
|
||||
<h3>生成激活码</h3>
|
||||
<p class="muted">管理员与普通用户均可发放;普通用户只能发给自己的账户。</p>
|
||||
<form method="post" action="{{ url_for('download_create_activation') }}">
|
||||
<div class="form-row">
|
||||
<label>绑定账户</label>
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}机器 · {{ app_name }}{% endblock %}
|
||||
{% block content %}
|
||||
<h2 style="margin:0 0 14px">机器标注</h2>
|
||||
<h2 style="margin:0 0 14px">机器{% if is_admin %}(管理员可预登记){% else %}(与本账户相关){% endif %}</h2>
|
||||
<div class="grid cols-2">
|
||||
{% if is_admin %}
|
||||
<div class="card">
|
||||
<h3>预登记机器</h3>
|
||||
<p class="muted">也可不预登记:激活时自动创建机器并绑定指纹。</p>
|
||||
@@ -12,6 +13,7 @@
|
||||
<button class="btn" type="submit">添加</button>
|
||||
</form>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="card">
|
||||
<h3>已有机器</h3>
|
||||
<table>
|
||||
@@ -20,12 +22,18 @@
|
||||
{% for m in items %}
|
||||
<tr>
|
||||
<td>
|
||||
{% if is_admin %}
|
||||
<form method="post" action="{{ url_for('machines_note', mid=m.id) }}">
|
||||
<input name="name" value="{{ m.name }}" style="margin-bottom:6px">
|
||||
<div class="muted">{{ m.device_fingerprint or '未绑定' }}</div>
|
||||
<textarea name="note" rows="2" style="margin-top:6px">{{ m.note or '' }}</textarea>
|
||||
<button class="btn secondary" style="margin-top:6px" type="submit">保存</button>
|
||||
</form>
|
||||
{% else %}
|
||||
<div>{{ m.name }}</div>
|
||||
<div class="muted">{{ m.device_fingerprint or '未绑定' }}</div>
|
||||
{% if m.note %}<div class="muted" style="margin-top:6px">{{ m.note }}</div>{% endif %}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="muted">{{ m.last_seen_at or '—' }}</td>
|
||||
<td>#{{ m.id }}</td>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<div class="grid cols-2">
|
||||
<div class="card">
|
||||
<h3>修改登录密码</h3>
|
||||
<p class="muted">修改后立即生效,无需重启服务。请使用足够强度的密码。</p>
|
||||
<p class="muted">修改当前登录用户密码,立即生效。管理员请在「用户」页创建普通用户。</p>
|
||||
<form method="post" action="{{ url_for('settings_password') }}" style="margin-top:12px">
|
||||
<div class="form-row">
|
||||
<label>当前密码</label>
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}用户管理 · {{ app_name }}{% endblock %}
|
||||
{% block content %}
|
||||
<h2 style="margin:0 0 6px">用户管理</h2>
|
||||
<p class="muted" style="margin:0 0 14px">仅管理员可创建。普通用户必须绑定唯一交易账户(一人一账户,账户不可自助注册)。</p>
|
||||
<div class="grid cols-2">
|
||||
<div class="card">
|
||||
<h3>创建用户</h3>
|
||||
<form method="post" action="{{ url_for('users_create') }}">
|
||||
<div class="form-row"><label>用户名</label><input name="username" required></div>
|
||||
<div class="form-row"><label>初始密码</label><input name="password" type="password" required minlength="6"></div>
|
||||
<div class="form-row">
|
||||
<label>角色</label>
|
||||
<select name="role" id="roleSel">
|
||||
<option value="user">普通用户</option>
|
||||
<option value="admin">管理员</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-row" id="accountRow">
|
||||
<label>绑定交易账户(普通用户必选,且未被占用)</label>
|
||||
<select name="account_id">
|
||||
<option value="">—</option>
|
||||
{% for a in free_accounts %}
|
||||
<option value="{{ a.id }}">#{{ a.id }} {{ a.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<button class="btn" type="submit">创建</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h3>已有用户</h3>
|
||||
<table>
|
||||
<thead><tr><th>用户名</th><th>角色</th><th>账户</th><th>状态</th></tr></thead>
|
||||
<tbody>
|
||||
{% for u in users %}
|
||||
<tr>
|
||||
<td>{{ u.username }}</td>
|
||||
<td><span class="tag {% if u.role=='admin' %}green{% else %}gray{% endif %}">{{ u.role }}</span></td>
|
||||
<td>{{ u.account_name or (u.account_id or '—') }}</td>
|
||||
<td>{{ '启用' if u.enabled else '停用' }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block scripts %}
|
||||
<script>
|
||||
const sel = document.getElementById('roleSel');
|
||||
const row = document.getElementById('accountRow');
|
||||
function sync(){ row.style.display = sel.value === 'admin' ? 'none' : 'block'; }
|
||||
sel.addEventListener('change', sync); sync();
|
||||
</script>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user