first commit

This commit is contained in:
JiXieShi
2024-11-14 22:55:43 +08:00
commit 421cfb8cfa
98 changed files with 12617 additions and 0 deletions

View File

@@ -0,0 +1,103 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>修改密码</title>
<link rel="stylesheet" href="/static/layui/css/layui.css">
<link rel="stylesheet" href="/static/css/style.css">
</head>
<body>
<div class="layui-fluid">
<div class="layui-card">
<div class="layui-card-body">
<form class="layui-form" lay-filter="changePasswordForm">
<div class="layui-form-item">
<label class="layui-form-label">原密码</label>
<div class="layui-input-block">
<input type="password" name="old_password" required lay-verify="required"
placeholder="请输入原密码" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">新密码</label>
<div class="layui-input-block">
<input type="password" name="newPassword" required lay-verify="required|password"
placeholder="请输入新密码" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">确认密码</label>
<div class="layui-input-block">
<input type="password" name="confirmPassword" required lay-verify="required|confirmPassword"
placeholder="请再次输入新密码" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit lay-filter="passwordSubmit">修改</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
</div>
</div>
<script src="/static/layui/layui.js"></script>
<script>
layui.use(['form', 'layer'], function(){
var form = layui.form;
var layer = layui.layer;
// 自定义验证规则
form.verify({
password: [
/^[\S]{6,12}$/,
'密码必须6到12位且不能出现空格'
],
confirmPassword: function(value) {
var password = $('input[name=newPassword]').val();
if (value !== password) {
return '两次输入的密码不一致';
}
}
});
// 表单提交
form.on('submit(passwordSubmit)', function(data){
fetch('/api/users/change-password', {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + localStorage.getItem('token'),
'Content-Type': 'application/json'
},
body: JSON.stringify({
old_password: data.field.oldPassword,
new_password: data.field.newPassword
})
})
.then(response => response.json())
.then(result => {
if (result.error) {
layer.msg(result.error);
return;
}
layer.msg('密码修改成功,请重新登录');
setTimeout(function(){
localStorage.removeItem('token');
top.location.href = '/login.html';
}, 1500);
})
.catch(error => {
layer.msg('修改失败:' + error.message);
});
return false;
});
});
</script>
</body>
</html>

View File

@@ -0,0 +1,54 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>控制台</title>
<link rel="stylesheet" href="/static/layui/css/layui.css">
<link rel="stylesheet" href="/static/css/style.css">
</head>
<body>
<div class="layui-fluid">
<div class="layui-row layui-col-space15">
<div class="layui-col-md3">
<div class="layui-card">
<div class="layui-card-header">设备总数</div>
<div class="layui-card-body big-font" id="total-devices">0</div>
</div>
</div>
<div class="layui-col-md3">
<div class="layui-card">
<div class="layui-card-header">授权码总数</div>
<div class="layui-card-body big-font" id="total-licenses">0</div>
</div>
</div>
<div class="layui-col-md3">
<div class="layui-card">
<div class="layui-card-header">今日新增</div>
<div class="layui-card-body big-font" id="today-new">0</div>
</div>
</div>
<div class="layui-col-md3">
<div class="layui-card">
<div class="layui-card-header">在线设备</div>
<div class="layui-card-body big-font" id="online-devices">0</div>
</div>
</div>
<div class="layui-col-md3">
<div class="layui-card">
<div class="layui-card-header">激活设备</div>
<div class="layui-card-body big-font" id="active-devices">0</div>
</div>
</div>
<div class="layui-col-md3">
<div class="layui-card">
<div class="layui-card-header">过期设备</div>
<div class="layui-card-body big-font" id="expired-devices">0</div>
</div>
</div>
</div>
</div>
<script src="/static/layui/layui.js"></script>
<script src="/static/js/dashboard.js"></script>
</body>
</html>

View File

@@ -0,0 +1,119 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>设备文件管理</title>
<link rel="stylesheet" href="/static/layui/css/layui.css">
<link rel="stylesheet" href="/static/css/style.css">
</head>
<body>
<div class="layui-fluid">
<div class="layui-card">
<div class="layui-card-header">
<span>设备文件管理</span>
<div class="layui-btn-group">
<button class="layui-btn layui-btn-sm" id="uploadFile">
<i class="layui-icon">&#xe67c;</i>上传文件
</button>
<button class="layui-btn layui-btn-sm layui-btn-normal" id="uploadUpdate">
<i class="layui-icon">&#xe67c;</i>上传更新
</button>
</div>
</div>
<div class="layui-card-body">
<!-- 搜索表单 -->
<form class="layui-form layui-form-pane" action="">
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">设备型号</label>
<div class="layui-input-inline">
<select name="deviceModel" lay-search>
<option value="">全部</option>
</select>
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">文件类型</label>
<div class="layui-input-inline">
<select name="fileType">
<option value="">全部</option>
<option value="update">更新文件</option>
<option value="normal">普通文件</option>
</select>
</div>
</div>
<div class="layui-inline">
<button class="layui-btn" lay-submit lay-filter="search">
<i class="layui-icon">&#xe615;</i> 搜索
</button>
</div>
</div>
</form>
<!-- 文件列表 -->
<table class="layui-table">
<thead>
<tr>
<th>文件名</th>
<th>设备型号</th>
<th>版本</th>
<th>类型</th>
<th>大小</th>
<th>下载次数</th>
<th>上传时间</th>
<th>操作</th>
</tr>
</thead>
<tbody id="fileList"></tbody>
</table>
</div>
</div>
</div>
<!-- 上传表单模板 -->
<script type="text/html" id="uploadFormTpl">
<form class="layui-form" style="padding: 20px;">
<div class="layui-form-item">
<label class="layui-form-label">设备型号</label>
<div class="layui-input-block">
<select name="deviceModel" lay-verify="required" lay-search>
<option value="">请选择设备型号</option>
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">文件版本</label>
<div class="layui-input-block">
<input type="text" name="version" required lay-verify="required"
placeholder="请输入文件版本" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">文件描述</label>
<div class="layui-input-block">
<textarea name="description" placeholder="请输入文件描述"
class="layui-textarea"></textarea>
</div>
</div>
<div class="layui-form-item" id="updateOptions" style="display:none;">
<label class="layui-form-label">更新选项</label>
<div class="layui-input-block">
<input type="checkbox" name="forceUpdate" title="强制更新">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">选择文件</label>
<div class="layui-input-block">
<button type="button" class="layui-btn" id="selectFile">
<i class="layui-icon">&#xe67c;</i>
</button>
<div class="layui-inline layui-word-aux" id="selectedFile"></div>
</div>
</div>
</form>
</script>
<script src="/static/layui/layui.js"></script>
<script src="/static/js/upload.js"></script>
</body>
</html>

View File

@@ -0,0 +1,129 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>设备授权管理</title>
<link rel="stylesheet" href="/static/layui/css/layui.css">
<link rel="stylesheet" href="/static/css/style.css">
</head>
<body>
<div class="layui-fluid">
<div class="layui-card">
<div class="layui-card-header">
<span>设备授权管理</span>
</div>
<div class="layui-card-body">
<!-- 搜索表单 -->
<form class="layui-form layui-form-pane" action="">
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">设备UID</label>
<div class="layui-input-inline">
<input type="text" name="uid" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">设备型号</label>
<div class="layui-input-inline">
<select name="device_model" lay-search>
<option value="">全部</option>
</select>
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">授权状态</label>
<div class="layui-input-inline">
<select name="status">
<option value="">全部</option>
<option value="active">正常</option>
<option value="expired">已过期</option>
<option value="inactive">未激活</option>
</select>
</div>
</div>
<div class="layui-inline">
<button class="layui-btn" lay-submit lay-filter="search">
<i class="layui-icon">&#xe615;</i> 搜索
</button>
<button type="button" class="layui-btn layui-btn-primary" id="export-devices">
<i class="layui-icon">&#xe67d;</i> 导出
</button>
</div>
</div>
</form>
<!-- 数据表格 -->
<table id="device-table" lay-filter="device-table"></table>
</div>
</div>
</div>
<!-- 表格工具栏模板 -->
<script type="text/html" id="tableToolbar">
<div class="layui-btn-container">
<button class="layui-btn layui-btn-sm" lay-event="refresh">
<i class="layui-icon">&#xe669;</i>
</button>
</div>
</script>
<!-- 行工具栏模板 -->
<script type="text/html" id="tableRowBar">
<a class="layui-btn layui-btn-xs" lay-event="view">查看</a>
<a class="layui-btn layui-btn-xs layui-btn-normal" lay-event="bind">绑定授权</a>
<a class="layui-btn layui-btn-xs layui-btn-warm" lay-event="logs">日志</a>
{{# if(d.status !== 'expired'){ }}
<a class="layui-btn layui-btn-xs layui-btn-danger" lay-event="revoke">撤销</a>
{{# } }}
</script>
<!-- 设备详情模板 -->
<script type="text/html" id="deviceDetailTpl">
<div style="padding: 20px;">
<table class="layui-table" lay-skin="line">
<colgroup>
<col width="150">
<col>
</colgroup>
<tbody>
<tr>
<td>设备UID</td>
<td>{{ d.uid }}</td>
</tr>
<tr>
<td>设备型号</td>
<td>{{ d.device_model }}</td>
</tr>
<tr>
<td>授权码</td>
<td>{{ d.license_code || '-' }}</td>
</tr>
<tr>
<td>授权类型</td>
<td>{{ d.license_type || '-' }}</td>
</tr>
<tr>
<td>过期时间</td>
<td>{{ d.expire_time ? new Date(d.expire_time).toLocaleString() : '-' }}</td>
</tr>
<tr>
<td>启动次数</td>
<td>{{ d.start_count }}</td>
</tr>
<tr>
<td>最后活跃</td>
<td>{{ d.last_active_at ? new Date(d.last_active_at).toLocaleString() : '-' }}</td>
</tr>
<tr>
<td>注册时间</td>
<td>{{ new Date(d.register_time).toLocaleString() }}</td>
</tr>
</tbody>
</table>
</div>
</script>
<script src="/static/layui/layui.js"></script>
<script src="/static/js/device-license.js"></script>
</body>
</html>

View File

@@ -0,0 +1,213 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>设备管理</title>
<link rel="stylesheet" href="/static/layui/css/layui.css" />
<link rel="stylesheet" href="/static/css/style.css" />
</head>
<body>
<div class="layui-fluid">
<div class="layui-card">
<div class="layui-card-header">
<span>设备型号管理</span>
<button
class="layui-btn layui-btn-sm layui-btn-normal"
id="add-device"
>
<i class="layui-icon">&#xe654;</i> 添加设备型号
</button>
</div>
<div class="layui-card-body">
<!-- 搜索表单 -->
<form class="layui-form layui-form-pane" action="">
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">设备型号</label>
<div class="layui-input-inline">
<input
type="text"
name="deviceModel"
autocomplete="off"
class="layui-input"
/>
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">设备类型</label>
<div class="layui-input-inline">
<select name="deviceType">
<option value="">全部</option>
<option value="软件">软件</option>
<option value="网站">网站</option>
<option value="嵌入式设备">嵌入式设备</option>
<option value="单片机设备">单片机设备</option>
</select>
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">所属公司</label>
<div class="layui-input-inline">
<input
type="text"
name="company"
autocomplete="off"
class="layui-input"
/>
</div>
</div>
<div class="layui-inline">
<button class="layui-btn" lay-submit lay-filter="search">
<i class="layui-icon">&#xe615;</i> 搜索
</button>
<button
type="button"
class="layui-btn layui-btn-primary"
id="export-devices"
>
<i class="layui-icon">&#xe67d;</i> 导出
</button>
</div>
</div>
</form>
<!-- 数据表格 -->
<table id="device-table" lay-filter="device-table"></table>
</div>
</div>
</div>
<!-- 表格工具栏模板 -->
<script type="text/html" id="tableToolbar">
<div class="layui-btn-container">
<button class="layui-btn layui-btn-sm" lay-event="refresh">
<i class="layui-icon">&#xe669;</i>
</button>
<button
class="layui-btn layui-btn-sm layui-btn-danger"
lay-event="batchDel"
>
<i class="layui-icon">&#xe640;</i>
</button>
</div>
</script>
<!-- 行工具栏模板 -->
<script type="text/html" id="tableRowBar">
<a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>
<a class="layui-btn layui-btn-xs layui-btn-warm" lay-event="files"
>文件</a
>
<a class="layui-btn layui-btn-xs layui-btn-danger" lay-event="del"
>删除</a
>
</script>
<!-- 设备表单模板 -->
<script type="text/html" id="deviceFormTpl">
<form class="layui-form" style="padding: 20px;" lay-filter="deviceForm">
<input type="hidden" name="id" />
<div class="layui-form-item">
<label class="layui-form-label">设备型号</label>
<div class="layui-input-block">
<input
type="text"
name="model_name"
required
lay-verify="required"
placeholder="请输入设备型号"
autocomplete="off"
class="layui-input"
/>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">设备类型</label>
<div class="layui-input-block">
<select name="device_type" required lay-verify="required">
<option value="software">软件</option>
<option value="website">网站</option>
<option value="embedded">嵌入式设备</option>
<option value="mcu">单片机设备</option>
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">所属公司</label>
<div class="layui-input-block">
<input
type="text"
name="company"
placeholder="请输入所属公司"
autocomplete="off"
class="layui-input"
/>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">备注说明</label>
<div class="layui-input-block">
<textarea
name="remark"
placeholder="请输入备注说明"
class="layui-textarea"
></textarea>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit lay-filter="deviceSubmit">
提交
</button>
<button type="reset" class="layui-btn layui-btn-primary">
重置
</button>
</div>
</div>
</form>
</script>
<script src="/static/layui/layui.js"></script>
<script src="/static/js/devices.js"></script>
</body>
</html>

View File

@@ -0,0 +1,172 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>授权码操作日志</title>
<link rel="stylesheet" href="/static/layui/css/layui.css">
<link rel="stylesheet" href="/static/css/style.css">
</head>
<body>
<div class="layui-fluid">
<div class="layui-card">
<div class="layui-card-header">
<span>授权码操作日志</span>
<div class="layui-btn-group">
<button class="layui-btn layui-btn-sm" id="refresh-logs">
<i class="layui-icon">&#xe669;</i> 刷新
</button>
<button class="layui-btn layui-btn-sm layui-btn-normal" id="export-logs">
<i class="layui-icon">&#xe67d;</i> 导出
</button>
</div>
</div>
<div class="layui-card-body">
<!-- 搜索表单 -->
<form class="layui-form layui-form-pane" action="">
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">操作类型</label>
<div class="layui-input-inline">
<select name="action">
<option value="">全部</option>
<option value="create">创建</option>
<option value="use">使用</option>
<option value="verify">验证</option>
<option value="revoke">撤销</option>
</select>
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">状态</label>
<div class="layui-input-inline">
<select name="status">
<option value="">全部</option>
<option value="success">成功</option>
<option value="failed">失败</option>
</select>
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">设备UID</label>
<div class="layui-input-inline">
<input type="text" name="device_uid" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-inline">
<button class="layui-btn" lay-submit lay-filter="search">
<i class="layui-icon">&#xe615;</i> 搜索
</button>
</div>
</div>
</form>
<!-- 数据表格 -->
<table id="log-table" lay-filter="log-table"></table>
</div>
</div>
</div>
<!-- 操作类型模板 -->
<script type="text/html" id="actionTpl">
{{# var types = {
'create': '<span class="layui-badge layui-bg-blue">创建</span>',
'use': '<span class="layui-badge layui-bg-green">使用</span>',
'verify': '<span class="layui-badge layui-bg-orange">验证</span>',
'revoke': '<span class="layui-badge layui-bg-red">撤销</span>'
}; }}
{{# return types[d.action] || d.action; }}
</script>
<!-- 状态模板 -->
<script type="text/html" id="statusTpl">
{{# if(d.status === 'success'){ }}
<span class="layui-badge layui-bg-green">成功</span>
{{# } else { }}
<span class="layui-badge layui-bg-red">失败</span>
{{# } }}
</script>
<script src="/static/layui/layui.js"></script>
<script>
layui.use(['table', 'layer', 'form'], function(){
var table = layui.table;
var layer = layui.layer;
var form = layui.form;
var $ = layui.$;
// 获取授权码ID
var licenseId = location.search.match(/id=(\d+)/)[1];
// 初始化表格
var tableIns = table.render({
elem: '#log-table',
url: '/api/licenses/' + licenseId + '/logs',
headers: {
'Authorization': 'Bearer ' + localStorage.getItem('token')
},
cols: [[
{field: 'action', title: '操作类型', width: 100, templet: '#actionTpl', sort: true},
{field: 'device_uid', title: '设备UID', width: 180},
{field: 'ip', title: 'IP地址', width: 150},
{field: 'status', title: '状态', width: 100, templet: '#statusTpl'},
{field: 'message', title: '详细信息'},
{field: 'created_at', title: '操作时间', width: 180, sort: true, templet: function(d){
return new Date(d.created_at).toLocaleString();
}}
]],
page: true,
parseData: function(res) {
if (res.code === 401) {
window.location.href = '/login';
return;
}
return res;
}
});
// 搜索表单提交
form.on('submit(search)', function(data){
tableIns.reload({
where: data.field,
page: {
curr: 1
}
});
return false;
});
// 刷新按钮点击事件
$('#refresh-logs').on('click', function(){
tableIns.reload();
});
// 导出按钮点击事件
$('#export-logs').on('click', function(){
var loadIndex = layer.load(2);
fetch('/api/licenses/' + licenseId + '/logs?export=1', {
headers: {
'Authorization': 'Bearer ' + localStorage.getItem('token')
}
})
.then(response => response.blob())
.then(blob => {
layer.close(loadIndex);
var url = window.URL.createObjectURL(blob);
var a = document.createElement('a');
a.href = url;
a.download = 'license_logs_' + licenseId + '_' +
new Date().toISOString().slice(0,19).replace(/[-:]/g, '') + '.csv';
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
document.body.removeChild(a);
})
.catch(error => {
layer.close(loadIndex);
layer.msg('导出失败:' + error.message);
});
});
});
</script>
</body>
</html>

View File

@@ -0,0 +1,263 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>授权码管理</title>
<link rel="stylesheet" href="/static/layui/css/layui.css" />
<link rel="stylesheet" href="/static/css/style.css" />
</head>
<body>
<div class="layui-fluid">
<div class="layui-card">
<div class="layui-card-header">
<span>授权码管理</span>
<button
class="layui-btn layui-btn-sm layui-btn-normal"
id="create-license"
>
<i class="layui-icon">&#xe654;</i> 生成授权码
</button>
</div>
<div class="layui-card-body">
<!-- 搜索表单 -->
<form class="layui-form layui-form-pane" action="">
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">授权码</label>
<div class="layui-input-inline">
<input
type="text"
name="code"
autocomplete="off"
class="layui-input"
/>
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">授权类型</label>
<div class="layui-input-inline">
<select name="license_type">
<option value="">全部</option>
<option value="time">时间授权</option>
<option value="count">次数授权</option>
<option value="permanent">永久授权</option>
</select>
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">状态</label>
<div class="layui-input-inline">
<select name="status">
<option value="">全部</option>
<option value="unused">未使用</option>
<option value="used">已使用</option>
<option value="expired">已过期</option>
<option value="revoked">已撤销</option>
</select>
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">批次号</label>
<div class="layui-input-inline">
<input
type="text"
name="batch_no"
autocomplete="off"
class="layui-input"
/>
</div>
</div>
<div class="layui-inline">
<button class="layui-btn" lay-submit lay-filter="search">
<i class="layui-icon">&#xe615;</i> 搜索
</button>
<button
type="button"
class="layui-btn layui-btn-primary"
id="export-licenses"
>
<i class="layui-icon">&#xe67d;</i> 导出
</button>
</div>
</div>
</form>
<!-- 数据表格 -->
<table id="license-table" lay-filter="license-table"></table>
</div>
</div>
</div>
<!-- Layui 表格工具栏模板 -->
<script type="text/html" id="tableToolbar">
<div class="layui-btn-container">
<button class="layui-btn layui-btn-sm" lay-event="refresh">
<i class="layui-icon">&#xe669;</i>
</button>
<button
class="layui-btn layui-btn-sm layui-btn-normal"
lay-event="copySelected"
>
<i class="layui-icon">&#xe64c;</i>
</button>
<button
class="layui-btn layui-btn-sm layui-btn-danger"
lay-event="batchDel"
>
<i class="layui-icon">&#xe640;</i>
</button>
</div>
</script>
<!-- 行工具栏模板 -->
<script id="tableRowBar" type="text/html">
<a class="layui-btn layui-btn-xs" lay-event="view">查看</a>
<a class="layui-btn layui-btn-xs layui-btn-warm" lay-event="logs">日志</a>
{{# if(d.status === 'unused'){ }}
<a class="layui-btn layui-btn-xs layui-btn-danger" lay-event="revoke"
>撤销</a
>
{{# } }}
</script>
<script src="/static/layui/layui.js"></script>
<script src="/static/js/licenses.js"></script>
<!-- 在页面底部添加创建授权码表单模板 -->
<script type="text/html" id="createLicenseTpl">
<form class="layui-form" style="padding: 20px;" lay-filter="licenseForm">
<div class="layui-form-item">
<label class="layui-form-label">授权类型</label>
<div class="layui-input-block">
<select
name="license_type"
lay-verify="required"
lay-filter="licenseType"
>
<option value="time">时间授权</option>
<option value="count">次数授权</option>
<option value="permanent">永久授权</option>
</select>
</div>
</div>
<div class="layui-form-item" id="durationItem">
<label class="layui-form-label">有效期</label>
<div class="layui-input-inline" style="width: 150px;">
<input
type="number"
name="duration"
class="layui-input"
placeholder="请输入数值"
/>
</div>
<div class="layui-input-inline" style="width: 100px;">
<select name="duration_unit">
<option value="1">分钟</option>
<option value="60">小时</option>
<option value="1440"></option>
<option value="43200"></option>
<option value="525600"></option>
</select>
</div>
</div>
<div class="layui-form-item" id="maxUsesItem" style="display:none;">
<label class="layui-form-label">使用次数</label>
<div class="layui-input-block">
<input
type="number"
name="max_uses"
class="layui-input"
placeholder="请输入最大使用次数"
/>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">生成数量</label>
<div class="layui-input-block">
<input
type="number"
name="count"
required
lay-verify="required|number|min1"
value="1"
class="layui-input"
/>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">备注</label>
<div class="layui-input-block">
<textarea
name="remark"
placeholder="请输入备注信息"
class="layui-textarea"
></textarea>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit lay-filter="licenseSubmit">
生成
</button>
<button type="reset" class="layui-btn layui-btn-primary">
重置
</button>
</div>
</div>
</form>
</script>
</body>
</html>

View File

@@ -0,0 +1,325 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>系统监控</title>
<link rel="stylesheet" href="/static/layui/css/layui.css">
<link rel="stylesheet" href="/static/css/style.css">
</head>
<body>
<div class="layui-fluid">
<!-- 系统概览 -->
<div class="layui-row layui-col-space15">
<div class="layui-col-md3">
<div class="layui-card">
<div class="layui-card-header">运行时间</div>
<div class="layui-card-body big-font" id="uptime">
0天0小时0分钟
</div>
</div>
</div>
<div class="layui-col-md3">
<div class="layui-card">
<div class="layui-card-header">活跃用户</div>
<div class="layui-card-body big-font" id="active-users">
0
</div>
</div>
</div>
<div class="layui-col-md3">
<div class="layui-card">
<div class="layui-card-header">设备总数</div>
<div class="layui-card-body big-font" id="total-devices">
0
</div>
</div>
</div>
<div class="layui-col-md3">
<div class="layui-card">
<div class="layui-card-header">系统负载</div>
<div class="layui-card-body big-font" id="load-avg">
0.00
</div>
</div>
</div>
</div>
<!-- 资源监控 -->
<div class="layui-row layui-col-space15">
<div class="layui-col-md6">
<div class="layui-card">
<div class="layui-card-header">CPU使用率</div>
<div class="layui-card-body">
<div id="cpu-chart" style="height: 300px;"></div>
</div>
</div>
</div>
<div class="layui-col-md6">
<div class="layui-card">
<div class="layui-card-header">内存使用情况</div>
<div class="layui-card-body">
<div id="memory-chart" style="height: 300px;"></div>
</div>
</div>
</div>
</div>
<!-- 磁盘和网络 -->
<div class="layui-row layui-col-space15">
<div class="layui-col-md6">
<div class="layui-card">
<div class="layui-card-header">磁盘使用情况</div>
<div class="layui-card-body">
<div id="disk-chart" style="height: 300px;"></div>
</div>
</div>
</div>
<div class="layui-col-md6">
<div class="layui-card">
<div class="layui-card-header">网络流量</div>
<div class="layui-card-body">
<div id="network-chart" style="height: 300px;"></div>
</div>
</div>
</div>
</div>
<!-- 进程和系统信息 -->
<div class="layui-row layui-col-space15">
<div class="layui-col-md6">
<div class="layui-card">
<div class="layui-card-header">
<span>进程列表Top 10</span>
<span class="layui-badge layui-bg-blue" id="total-processes">0</span>
</div>
<div class="layui-card-body">
<table class="layui-table" lay-skin="line">
<thead>
<tr>
<th>PID</th>
<th>名称</th>
<th>CPU使用率</th>
<th>内存使用率</th>
<th>运行时间</th>
</tr>
</thead>
<tbody id="process-list"></tbody>
</table>
</div>
</div>
</div>
<div class="layui-col-md6">
<div class="layui-card">
<div class="layui-card-header">系统信息</div>
<div class="layui-card-body">
<table class="layui-table" lay-skin="nob">
<tbody>
<tr>
<td>主机名</td>
<td id="hostname"></td>
</tr>
<tr>
<td>操作系统</td>
<td id="os"></td>
</tr>
<tr>
<td>平台</td>
<td id="platform"></td>
</tr>
<tr>
<td>内核版本</td>
<td id="kernel"></td>
</tr>
<tr>
<td>CPU型号</td>
<td id="cpu-model"></td>
</tr>
<tr>
<td>CPU核心数</td>
<td id="cpu-cores"></td>
</tr>
<tr>
<td>启动时间</td>
<td id="boot-time"></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<script src="/static/layui/layui.js"></script>
<script src="/static/lib/echarts.min.js"></script>
<script src="/static/js/monitor.js"></script>
<script type="text/html" id="processListTpl">
{{# layui.each(d, function(index, item){ }}
<tr>
<td>{{item.pid}}</td>
<td>{{item.name}}</td>
<td>{{item.cpu.toFixed(1)}}%</td>
<td>{{item.memory.toFixed(1)}}%</td>
<td>{{formatDuration(Math.floor((Date.now() - item.created) / 1000))}}</td>
</tr>
{{# }); }}
</script>
</body>
</html>

View File

@@ -0,0 +1,185 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>站点设置</title>
<link rel="stylesheet" href="/static/layui/css/layui.css">
<link rel="stylesheet" href="/static/css/style.css">
</head>
<body>
<div class="layui-fluid">
<div class="layui-card">
<div class="layui-card-header">站点设置</div>
<div class="layui-card-body">
<form class="layui-form" lay-filter="siteSettingsForm">
<div class="layui-form-item">
<label class="layui-form-label">站点标题</label>
<div class="layui-input-block">
<input type="text" name="title" required lay-verify="required"
placeholder="请输入站点标题" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">站点描述</label>
<div class="layui-input-block">
<textarea name="description" placeholder="请输入站点描述"
class="layui-textarea"></textarea>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">基础URL</label>
<div class="layui-input-block">
<input type="text" name="baseUrl" required lay-verify="required"
placeholder="请输入基础URL" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">ICP备案号</label>
<div class="layui-input-block">
<input type="text" name="icp" placeholder="请输入ICP备案号"
autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">版权信息</label>
<div class="layui-input-block">
<input type="text" name="copyright" required lay-verify="required"
placeholder="请输入版权信息" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">Logo</label>
<div class="layui-input-inline">
<input type="text" name="logo" placeholder="Logo路径"
autocomplete="off" class="layui-input">
</div>
<div class="layui-input-inline" style="width: auto;">
<button type="button" class="layui-btn" id="uploadLogo">
<i class="layui-icon">&#xe67c;</i>上传Logo
</button>
</div>
<div class="layui-input-inline" style="width: auto;">
<img id="currentLogo" src="" style="display:none;max-height:38px;margin-left:10px;">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">Favicon</label>
<div class="layui-input-inline">
<input type="text" name="favicon" placeholder="Favicon路径"
autocomplete="off" class="layui-input">
</div>
<div class="layui-input-inline" style="width: auto;">
<button type="button" class="layui-btn" id="uploadFavicon">
<i class="layui-icon">&#xe67c;</i>上传Favicon
</button>
</div>
<div class="layui-input-inline" style="width: auto;">
<img id="currentFavicon" src="" style="display:none;max-height:38px;margin-left:10px;">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit lay-filter="siteSubmit">保存设置</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
</div>
</div>
<script src="/static/layui/layui.js"></script>
<script>
layui.use(['form', 'upload', 'layer'], function(){
var form = layui.form;
var upload = layui.upload;
var layer = layui.layer;
var $ = layui.$;
// 加载当前配置
fetch('/api/site/settings', {
headers: {
'Authorization': 'Bearer ' + localStorage.getItem('token')
}
})
.then(response => response.json())
.then(data => {
if (data.error) {
layer.msg(data.error);
return;
}
form.val('siteForm', data);
})
.catch(error => {
layer.msg('加载配置失败:' + error.message);
});
// 上传Logo
upload.render({
elem: '#uploadLogo',
url: '/api/uploads/site',
headers: {
'Authorization': 'Bearer ' + localStorage.getItem('token')
},
accept: 'images',
done: function(res){
if (res.error) {
layer.msg(res.error);
return;
}
$('input[name=logo]').val(res.url);
}
});
// 上传Favicon
upload.render({
elem: '#uploadFavicon',
url: '/api/uploads/site',
headers: {
'Authorization': 'Bearer ' + localStorage.getItem('token')
},
accept: 'images',
done: function(res){
if (res.error) {
layer.msg(res.error);
return;
}
$('input[name=favicon]').val(res.url);
}
});
// 表单提交
form.on('submit(siteSubmit)', function(data){
fetch('/api/site/settings', {
method: 'PUT',
headers: {
'Authorization': 'Bearer ' + localStorage.getItem('token'),
'Content-Type': 'application/json'
},
body: JSON.stringify(data.field)
})
.then(response => response.json())
.then(result => {
if (result.error) {
layer.msg(result.error);
return;
}
layer.msg('保存成功');
})
.catch(error => {
layer.msg('保存失败:' + error.message);
});
return false;
});
});
</script>
</body>
</html>

View File

@@ -0,0 +1,69 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>令牌使用日志</title>
<link rel="stylesheet" href="/static/layui/css/layui.css">
<link rel="stylesheet" href="/static/css/style.css">
</head>
<body>
<div class="layui-fluid">
<div class="layui-card">
<div class="layui-card-header">令牌使用日志</div>
<div class="layui-card-body">
<table id="log-table" lay-filter="log-table"></table>
</div>
</div>
</div>
<!-- 状态模板 -->
<script type="text/html" id="statusTpl">
{{# if(d.status === 'success'){ }}
<span class="layui-badge layui-bg-green">成功</span>
{{# } else { }}
<span class="layui-badge layui-bg-red">失败</span>
{{# } }}
</script>
<!-- 操作类型模板 -->
<script type="text/html" id="actionTpl">
{{# var types = {
'create': '创建',
'use': '使用',
'revoke': '撤销'
}; }}
{{# var type = types[d.action] || d.action; }}
<span>{{type}}</span>
</script>
<script src="/static/layui/layui.js"></script>
<script>
layui.use(['table', 'layer'], function(){
var table = layui.table;
var layer = layui.layer;
var $ = layui.$;
// 获取令牌ID
var tokenId = location.search.match(/id=(\d+)/)[1];
// 初始化表格
table.render({
elem: '#log-table',
url: '/api/tokens/' + tokenId + '/logs',
headers: {
'Authorization': 'Bearer ' + localStorage.getItem('token')
},
cols: [[
{field: 'action', title: '操作类型', width: 100, templet: '#actionTpl'},
{field: 'ip', title: 'IP地址', width: 150},
{field: 'userAgent', title: 'User-Agent', width: 300},
{field: 'status', title: '状态', width: 100, templet: '#statusTpl'},
{field: 'message', title: '详细信息'},
{field: 'createdAt', title: '时间', width: 160}
]],
page: true
});
});
</script>
</body>
</html>

View File

@@ -0,0 +1,130 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>访问令牌管理</title>
<link rel="stylesheet" href="/static/layui/css/layui.css">
<link rel="stylesheet" href="/static/css/style.css">
</head>
<body>
<div class="layui-fluid">
<div class="layui-card">
<div class="layui-card-header">
<span>访问令牌管理</span>
<button class="layui-btn layui-btn-sm layui-btn-normal" id="create-token">
<i class="layui-icon">&#xe654;</i> 创建令牌
</button>
</div>
<div class="layui-card-body">
<!-- 搜索表单 -->
<form class="layui-form layui-form-pane" action="">
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">设备UID</label>
<div class="layui-input-inline">
<input type="text" name="device_uid" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">令牌类型</label>
<div class="layui-input-inline">
<select name="token_type">
<option value="">全部</option>
<option value="api">API</option>
<option value="device">设备</option>
</select>
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">状态</label>
<div class="layui-input-inline">
<select name="status">
<option value="">全部</option>
<option value="active">有效</option>
<option value="revoked">已撤销</option>
<option value="expired">已过期</option>
</select>
</div>
</div>
<div class="layui-inline">
<button class="layui-btn" lay-submit lay-filter="search">
<i class="layui-icon">&#xe615;</i> 搜索
</button>
</div>
</div>
</form>
<!-- 数据表格 -->
<table id="token-table" lay-filter="token-table"></table>
</div>
</div>
</div>
<!-- 表格工具栏模板 -->
<script type="text/html" id="tableToolbar">
<div class="layui-btn-container">
<button class="layui-btn layui-btn-sm" lay-event="refresh">
<i class="layui-icon">&#xe669;</i>
</button>
<button class="layui-btn layui-btn-sm layui-btn-danger" lay-event="batchRevoke">
<i class="layui-icon">&#xe640;</i>
</button>
</div>
</script>
<!-- 行工具栏模板 -->
<script type="text/html" id="tableRowBar">
<a class="layui-btn layui-btn-xs" lay-event="view">查看</a>
<a class="layui-btn layui-btn-xs layui-btn-warm" lay-event="logs">日志</a>
[[# if(d.status === 'active'){ ]]
<a class="layui-btn layui-btn-xs layui-btn-danger" lay-event="revoke">撤销</a>
[[# } ]]
</script>
<!-- 创建令牌表单模板 -->
<script type="text/html" id="createTokenTpl">
<form class="layui-form" style="padding: 20px;" lay-filter="tokenForm">
<div class="layui-form-item">
<label class="layui-form-label">设备UID</label>
<div class="layui-input-block">
<select name="device_uid" lay-verify="required" lay-search>
<option value="">请选择设备</option>
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">令牌类型</label>
<div class="layui-input-block">
<select name="token_type" lay-verify="required">
<option value="api">API</option>
<option value="device">设备</option>
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">有效期</label>
<div class="layui-input-block">
<input type="number" name="expire_days" required lay-verify="required|number"
placeholder="请输入有效期天数" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">IP限制</label>
<div class="layui-input-block">
<textarea name="ip_list" placeholder="请输入允许访问的IP地址多个IP用逗号分隔"
class="layui-textarea"></textarea>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit lay-filter="tokenSubmit">创建</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</script>
<script src="/static/layui/layui.js"></script>
<script src="/static/js/tokens.js"></script>
</body>
</html>

View File

@@ -0,0 +1,126 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>编辑用户</title>
<link rel="stylesheet" href="/static/layui/css/layui.css">
<link rel="stylesheet" href="/static/css/style.css">
</head>
<body>
<div class="layui-fluid">
<div class="layui-card">
<div class="layui-card-body">
<form class="layui-form" lay-filter="userForm">
<input type="hidden" name="id">
<div class="layui-form-item">
<label class="layui-form-label">用户名</label>
<div class="layui-input-block">
<input type="text" name="username" required lay-verify="required"
placeholder="请输入用户名" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">邮箱</label>
<div class="layui-input-block">
<input type="text" name="email" required lay-verify="required|email"
placeholder="请输入邮箱" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">角色</label>
<div class="layui-input-block">
<select name="role" required lay-verify="required">
<option value="user">普通用户</option>
<option value="admin">管理员</option>
</select>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit lay-filter="userSubmit">保存</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
</div>
</div>
<script src="/static/layui/layui.js"></script>
<script>
layui.use(['form', 'layer'], function(){
var form = layui.form;
var layer = layui.layer;
var $ = layui.$;
// 获取用户ID
var userId = location.search.match(/id=(\d+)/);
if (userId) {
userId = userId[1];
// 加载用户数据
fetch('/api/users/' + userId, {
headers: {
'Authorization': 'Bearer ' + localStorage.getItem('token')
}
})
.then(response => response.json())
.then(data => {
if (data.error) {
layer.msg(data.error);
return;
}
// 填充表单
form.val('userForm', {
'id': data.id,
'username': data.username,
'email': data.email,
'role': data.role
});
})
.catch(error => {
layer.msg('加载用户数据失败:' + error.message);
});
}
// 表单提交
form.on('submit(userSubmit)', function(data){
var field = data.field;
var url = userId ? '/api/users/' + userId : '/api/users';
var method = userId ? 'PUT' : 'POST';
fetch(url, {
method: method,
headers: {
'Authorization': 'Bearer ' + localStorage.getItem('token'),
'Content-Type': 'application/json'
},
body: JSON.stringify(field)
})
.then(response => response.json())
.then(result => {
if (result.error) {
layer.msg(result.error);
return;
}
layer.msg('保存成功');
// 如果是在弹窗中,则关闭弹窗并刷新父页面的表格
var index = parent.layer.getFrameIndex(window.name);
if (index) {
parent.layui.table.reload('user-table');
parent.layer.close(index);
}
})
.catch(error => {
layer.msg('保存失败:' + error.message);
});
return false;
});
});
</script>
</body>
</html>

View File

@@ -0,0 +1,124 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>用户管理</title>
<link rel="stylesheet" href="/static/layui/css/layui.css">
<link rel="stylesheet" href="/static/css/style.css">
</head>
<body>
<div class="layui-fluid">
<div class="layui-card">
<div class="layui-card-header">
<span>用户管理</span>
<button class="layui-btn layui-btn-sm layui-btn-normal" id="add-user">
<i class="layui-icon">&#xe654;</i> 添加用户
</button>
</div>
<div class="layui-card-body">
<!-- 搜索表单 -->
<form class="layui-form layui-form-pane" action="">
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">用户名</label>
<div class="layui-input-inline">
<input type="text" name="username" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">角色</label>
<div class="layui-input-inline">
<select name="role">
<option value="">全部</option>
<option value="admin">管理员</option>
<option value="user">普通用户</option>
</select>
</div>
</div>
<div class="layui-inline">
<button class="layui-btn" lay-submit lay-filter="search">
<i class="layui-icon">&#xe615;</i> 搜索
</button>
</div>
</div>
</form>
<!-- 数据表格 -->
<table id="user-table" lay-filter="user-table"></table>
</div>
</div>
</div>
<!-- 表格工具栏模板 -->
<script type="text/html" id="tableToolbar">
<div class="layui-btn-container">
<button class="layui-btn layui-btn-sm" lay-event="refresh">
<i class="layui-icon">&#xe669;</i>
</button>
</div>
</script>
<!-- 角色模板 -->
<script type="text/html" id="roleTpl">
{{# if(d.role === 'admin'){ }}
<span class="layui-badge layui-bg-blue">管理员</span>
{{# } else { }}
<span class="layui-badge layui-bg-gray">普通用户</span>
{{# } }}
</script>
<!-- 行工具栏模板 -->
<script type="text/html" id="tableRowBar">
<a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>
{{# if(d.role !== 'admin'){ }}
<a class="layui-btn layui-btn-xs layui-btn-danger" lay-event="del">删除</a>
{{# } }}
</script>
<!-- 用户表单模板 -->
<script type="text/html" id="userFormTpl">
<form class="layui-form" style="padding: 20px;" lay-filter="userForm">
<input type="hidden" name="id">
<div class="layui-form-item">
<label class="layui-form-label">用户名</label>
<div class="layui-input-block">
<input type="text" name="username" required lay-verify="required"
placeholder="请输入用户名" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">密码</label>
<div class="layui-input-block">
<input type="password" name="password" required lay-verify="required"
placeholder="请输入密码" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">邮箱</label>
<div class="layui-input-block">
<input type="text" name="email" required lay-verify="required|email"
placeholder="请输入邮箱" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">角色</label>
<div class="layui-input-block">
<select name="role" required lay-verify="required">
<option value="user">普通用户</option>
<option value="admin">管理员</option>
</select>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit lay-filter="userSubmit">提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</script>
<script src="/static/layui/layui.js"></script>
<script src="/static/js/users.js"></script>
</body>
</html>

111
web/templates/index.html Normal file
View File

@@ -0,0 +1,111 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>授权验证管理平台</title>
<link rel="stylesheet" href="/static/layui/css/layui.css">
<link rel="stylesheet" href="/static/css/style.css">
</head>
<body class="layui-layout-body">
<div class="layui-layout layui-layout-admin">
<!-- 头部 -->
<div class="layui-header">
<div class="layui-logo">
<img src="/static/images/logo.png" alt="logo" id="site-logo">
<span id="site-name">授权验证管理平台</span>
</div>
<ul class="layui-nav layui-layout-right">
<li class="layui-nav-item">
<a href="javascript:;">
<span id="current-user"></span>
</a>
<dl class="layui-nav-child">
<dd><a href="javascript:;" class="change-password">修改密码</a></dd>
<dd><a href="javascript:;" class="logout">退出登录</a></dd>
</dl>
</li>
</ul>
</div>
<!-- 左侧导航 -->
<div class="layui-side layui-bg-black">
<div class="layui-side-scroll">
<ul class="layui-nav layui-nav-tree">
<li class="layui-nav-item layui-this">
<a href="javascript:;" data-url="/admin/dashboard">
<i class="layui-icon">&#xe68e;</i> 控制台
</a>
</li>
<li class="layui-nav-item">
<a href="javascript:;">
<i class="layui-icon">&#xe665;</i> 设备管理
</a>
<dl class="layui-nav-child">
<dd><a href="javascript:;" data-url="/admin/devices">设备型号管理</a></dd>
<dd><a href="javascript:;" data-url="/admin/device-files">设备文件管理</a></dd>
<dd><a href="javascript:;" data-url="/admin/device-license">设备授权管理</a></dd>
</dl>
</li>
<li class="layui-nav-item">
<a href="javascript:;">
<i class="layui-icon">&#xe672;</i> 授权管理
</a>
<dl class="layui-nav-child">
<dd><a href="javascript:;" data-url="/admin/licenses">授权码管理</a></dd>
<dd><a href="javascript:;" data-url="/admin/license-logs">授权日志</a></dd>
</dl>
</li>
<li class="layui-nav-item">
<a href="javascript:;">
<i class="layui-icon">&#xe674;</i> 令牌管理
</a>
<dl class="layui-nav-child">
<dd><a href="javascript:;" data-url="/admin/tokens">访问令牌</a></dd>
<dd><a href="javascript:;" data-url="/admin/token-logs">令牌日志</a></dd>
</dl>
</li>
<li class="layui-nav-item admin-only">
<a href="javascript:;" data-url="/admin/users">
<i class="layui-icon">&#xe770;</i> 用户管理
</a>
</li>
<li class="layui-nav-item">
<a href="javascript:;" data-url="/admin/monitor">
<i class="layui-icon">&#xe665;</i> 系统监控
</a>
</li>
<li class="layui-nav-item admin-only">
<a href="javascript:;" data-url="/admin/site-settings">
<i class="layui-icon">&#xe716;</i> 站点设置
</a>
</li>
</ul>
</div>
</div>
<!-- 内容主体 -->
<div class="layui-body">
<div class="layui-breadcrumb" lay-separator="/">
<a href="javascript:;">首页</a>
<a><cite>控制台</cite></a>
</div>
<div class="content-container">
<iframe id="content-frame" frameborder="0" class="layadmin-iframe"></iframe>
</div>
</div>
<!-- 底部 -->
<div class="layui-footer">
<div class="footer-left">
<span id="site-copyright"></span>
</div>
<div class="footer-right">
<span id="site-icp"></span>
</div>
</div>
</div>
<script src="/static/layui/layui.js"></script>
<script src="/static/js/main.js"></script>
</body>
</html>

49
web/templates/login.html Normal file
View File

@@ -0,0 +1,49 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>登录 - 授权验证管理平台</title>
<link rel="stylesheet" href="/static/layui/css/layui.css">
<link rel="stylesheet" href="/static/css/style.css">
</head>
<body class="login-body">
<div class="layui-container">
<div class="layui-row">
<div class="layui-col-md4 layui-col-md-offset4">
<div class="login-box">
<h2>授权验证管理平台</h2>
<form class="layui-form" action="">
<div class="layui-form-item">
<input type="text" name="username" required lay-verify="required"
placeholder="用户名" autocomplete="off" class="layui-input">
</div>
<div class="layui-form-item">
<input type="password" name="password" required lay-verify="required"
placeholder="密码" autocomplete="off" class="layui-input">
</div>
<div class="layui-form-item">
<div class="layui-input-inline" style="width: 200px;">
<input type="text" name="captcha" required lay-verify="required"
placeholder="请输入验证码" autocomplete="off" class="layui-input">
</div>
<div class="layui-input-inline" style="width: 120px;">
<img src="" id="captchaImg" style="height:38px;cursor:pointer;" alt="点击刷新">
<input type="hidden" name="captchaId">
</div>
</div>
<div class="layui-form-item">
<button class="layui-btn layui-btn-fluid" lay-submit lay-filter="login">登录</button>
</div>
<div class="layui-form-item">
<a href="javascript:;" class="forget-pwd">忘记密码?</a>
<a href="javascript:;" class="register">注册账号</a>
</div>
</form>
</div>
</div>
</div>
</div>
<script src="/static/layui/layui.js"></script>
<script src="/static/js/login.js"></script>
</body>
</html>