更新 Go 版本至 1.23.0,添加管理员功能,包括管理员登录、用户和客户端管理,新增相应的模板和中间件,优化数据库模型以支持管理员管理。

This commit is contained in:
2025-04-17 01:47:10 +08:00
parent a3f3cc17cf
commit 83c82f7135
18 changed files with 686 additions and 21 deletions

View File

@@ -0,0 +1,38 @@
{{template "header" .}}
<div class="container mt-4">
<h2>客户端管理</h2>
<table class="table">
<thead>
<tr>
<th>ID</th>
<th>客户端ID</th>
<th>名称</th>
<th>创建时间</th>
</tr>
</thead>
<tbody>
{{range .clients}}
<tr>
<td>{{.ID}}</td>
<td>{{.ClientID}}</td>
<td>{{.Name}}</td>
<td>{{.CreatedAt.Format "2006-01-02 15:04:05"}}</td>
</tr>
{{end}}
</tbody>
</table>
<nav>
<ul class="pagination">
{{if gt .page 1}}
<li class="page-item">
<a class="page-link" href="?page={{subtract .page 1}}&page_size={{.pageSize}}">上一页</a>
</li>
{{end}}
<li class="page-item">
<a class="page-link" href="?page={{add .page 1}}&page_size={{.pageSize}}">下一页</a>
</li>
</ul>
</nav>
</div>
{{template "footer" .}}

View File

@@ -0,0 +1,24 @@
{{template "header" .}}
<div class="container mt-4">
<div class="row">
<div class="col-md-4">
<div class="card">
<div class="card-body">
<h5 class="card-title">用户管理</h5>
<p class="card-text">管理系统用户账号</p>
<a href="/admin/users" class="btn btn-primary">查看用户</a>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card">
<div class="card-body">
<h5 class="card-title">客户端管理</h5>
<p class="card-text">管理 OAuth2 客户端</p>
<a href="/admin/clients" class="btn btn-primary">查看客户端</a>
</div>
</div>
</div>
</div>
</div>
{{template "footer" .}}

View File

@@ -0,0 +1,29 @@
{{template "header" .}}
<div class="container mt-5">
<div class="row justify-content-center">
<div class="col-md-6">
<div class="card">
<div class="card-header">
<h3 class="text-center">管理员登录</h3>
</div>
<div class="card-body">
{{if .error}}
<div class="alert alert-danger">{{.error}}</div>
{{end}}
<form method="POST" action="/admin/login">
<div class="form-group mb-3">
<label for="username">用户名</label>
<input type="text" class="form-control" id="username" name="username" required>
</div>
<div class="form-group mb-3">
<label for="password">密码</label>
<input type="password" class="form-control" id="password" name="password" required>
</div>
<button type="submit" class="btn btn-primary w-100">登录</button>
</form>
</div>
</div>
</div>
</div>
</div>
{{template "footer" .}}

View File

@@ -0,0 +1,38 @@
{{template "header" .}}
<div class="container mt-4">
<h2>用户管理</h2>
<table class="table">
<thead>
<tr>
<th>ID</th>
<th>用户名</th>
<th>邮箱</th>
<th>创建时间</th>
</tr>
</thead>
<tbody>
{{range .users}}
<tr>
<td>{{.ID}}</td>
<td>{{.Username}}</td>
<td>{{.Email}}</td>
<td>{{.CreatedAt.Format "2006-01-02 15:04:05"}}</td>
</tr>
{{end}}
</tbody>
</table>
<nav>
<ul class="pagination">
{{if gt .page 1}}
<li class="page-item">
<a class="page-link" href="?page={{subtract .page 1}}&page_size={{.pageSize}}">上一页</a>
</li>
{{end}}
<li class="page-item">
<a class="page-link" href="?page={{add .page 1}}&page_size={{.pageSize}}">下一页</a>
</li>
</ul>
</nav>
</div>
{{template "footer" .}}

5
templates/footer.html Normal file
View File

@@ -0,0 +1,5 @@
{{define "footer"}}
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
{{end}}

27
templates/header.html Normal file
View File

@@ -0,0 +1,27 @@
{{define "header"}}
<!DOCTYPE html>
<html>
<head>
<title>OIDC OAuth2 管理系统</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container">
<a class="navbar-brand" href="/admin/dashboard">OIDC OAuth2 管理系统</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="/admin/users">用户管理</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/admin/clients">客户端管理</a>
</li>
</ul>
</div>
</div>
</nav>
{{end}}

View File

@@ -55,6 +55,19 @@
color: #dc3545;
margin-bottom: 15px;
}
.signup-link {
text-align: center;
margin-top: 20px;
padding-top: 20px;
border-top: 1px solid #eee;
}
.signup-link a {
color: #007bff;
text-decoration: none;
}
.signup-link a:hover {
text-decoration: underline;
}
</style>
</head>
<body>
@@ -82,6 +95,9 @@
<button type="submit">登录</button>
</form>
<div class="signup-link">
还没有账号?<a href="/signup">立即注册</a>
</div>
</div>
</body>
</html>

87
templates/signup.html Normal file
View File

@@ -0,0 +1,87 @@
<!DOCTYPE html>
<html>
<head>
<title>{{.title}}</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body {
font-family: Arial, sans-serif;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: #f5f5f5;
}
.signup-container {
background: white;
padding: 2rem;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
width: 100%;
max-width: 400px;
}
.form-group {
margin-bottom: 1rem;
}
label {
display: block;
margin-bottom: 0.5rem;
}
input {
width: 100%;
padding: 0.5rem;
border: 1px solid #ddd;
border-radius: 4px;
box-sizing: border-box;
}
button {
width: 100%;
padding: 0.75rem;
background-color: #007bff;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background-color: #0056b3;
}
.error {
color: red;
margin-bottom: 1rem;
}
.login-link {
text-align: center;
margin-top: 1rem;
}
</style>
</head>
<body>
<div class="signup-container">
<h2>注册</h2>
{{if .error}}
<div class="error">{{.error}}</div>
{{end}}
<form method="POST" action="/signup">
<div class="form-group">
<label for="username">用户名</label>
<input type="text" id="username" name="username" required>
</div>
<div class="form-group">
<label for="email">邮箱</label>
<input type="email" id="email" name="email" required>
</div>
<div class="form-group">
<label for="password">密码</label>
<input type="password" id="password" name="password" required>
</div>
<button type="submit">注册</button>
</form>
<div class="login-link">
已有账号?<a href="/login">立即登录</a>
</div>
</div>
</body>
</html>