04-25-周六_15-46-07
This commit is contained in:
1102
课堂代码/01-blog开发/v3/article.php
Normal file
1102
课堂代码/01-blog开发/v3/article.php
Normal file
File diff suppressed because it is too large
Load Diff
65
课堂代码/01-blog开发/v3/article_add.php
Normal file
65
课堂代码/01-blog开发/v3/article_add.php
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
<?php
|
||||||
|
$pageTitle = '网站后台管理 - 添加文章';
|
||||||
|
$page = 'articles';
|
||||||
|
include("header.php");
|
||||||
|
?>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
if (isset($_REQUEST["title"])) {
|
||||||
|
// 连接数据库
|
||||||
|
include("db.php");
|
||||||
|
|
||||||
|
// 接收标题,作者,内容等数据
|
||||||
|
$title = $_REQUEST["title"];
|
||||||
|
$author = $_REQUEST["author"];
|
||||||
|
$content = $_REQUEST["content"];
|
||||||
|
|
||||||
|
// 设置为+8时区,读取系统时间
|
||||||
|
date_default_timezone_set('PRC');
|
||||||
|
$time = date("Y-m-d H:i:s");
|
||||||
|
|
||||||
|
|
||||||
|
// 插入数据库
|
||||||
|
$sql = "INSERT INTO articles (title, author, content, time) VALUES ('$title', '$author', '$content', '$time')";
|
||||||
|
if (mysqli_query($conn, $sql) === TRUE) {
|
||||||
|
echo "<script>alert('文章添加成功');location.href='articles_list.php'</script>";
|
||||||
|
} else {
|
||||||
|
echo "Error: " . $sql . "<br>" . $conn->error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<main class="main-content">
|
||||||
|
<div class="page-header">
|
||||||
|
<h2>添加文章</h2>
|
||||||
|
<p>编写博客的文章</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-card">
|
||||||
|
<form action="" method="post">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="title">文章标题</label>
|
||||||
|
<input type="text" id="title" name="title" placeholder="请输入文章标题" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="author">文章作者</label>
|
||||||
|
<input type="text" id="author" name="author" placeholder="请输入文章作者" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="content">文章内容</label>
|
||||||
|
<textarea id="content" name="content" placeholder="请输入文章内容" required></textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="btn-group">
|
||||||
|
<button type="submit" class="btn btn-primary">提交</button>
|
||||||
|
<a href="articles_list.php" class="btn btn-secondary">返回文章列表</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
73
课堂代码/01-blog开发/v3/article_edit.php
Normal file
73
课堂代码/01-blog开发/v3/article_edit.php
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
<?php
|
||||||
|
$pageTitle = '网站后台管理 - 修改文章';
|
||||||
|
$page = 'articles';
|
||||||
|
include("header.php");
|
||||||
|
?>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
// 连接数据库
|
||||||
|
include("db.php");
|
||||||
|
|
||||||
|
// 接收文章ID
|
||||||
|
$id = $_REQUEST["id"];
|
||||||
|
|
||||||
|
if (isset($_POST["title"])) {
|
||||||
|
// 接收标题,作者,内容等数据
|
||||||
|
$title = $_POST["title"];
|
||||||
|
$author = $_POST["author"];
|
||||||
|
$content = $_POST["content"];
|
||||||
|
|
||||||
|
// 设置为+8时区,读取系统时间
|
||||||
|
date_default_timezone_set('PRC');
|
||||||
|
$time = date("Y-m-d H:i:s");
|
||||||
|
|
||||||
|
|
||||||
|
// 插入数据库
|
||||||
|
$sql = "update articles set title='$title', author='$author', content='$content', time='$time' where id='$id'";
|
||||||
|
if (mysqli_query($conn, $sql) === TRUE) {
|
||||||
|
echo "<script>alert('文章添加成功');location.href='articles_list.php'</script>";
|
||||||
|
} else {
|
||||||
|
echo "Error: " . $sql . "<br>" . $conn->error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<main class="main-content">
|
||||||
|
<div class="page-header">
|
||||||
|
<h2>修改文章</h2>
|
||||||
|
<p>修改博客的文章</p>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
// 以及对应的内容
|
||||||
|
$sql = "select * from articles where id = $id";
|
||||||
|
$result = mysqli_query($conn, $sql);
|
||||||
|
$row = mysqli_fetch_assoc($result);
|
||||||
|
?>
|
||||||
|
<div class="form-card">
|
||||||
|
<form action="" method="post">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="title">文章标题</label>
|
||||||
|
<input type="text" id="title" name="title" placeholder="请输入文章标题" value="<?php echo $row["title"]; ?>" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="author">文章作者</label>
|
||||||
|
<input type="text" id="author" name="author" placeholder="请输入文章作者" value="<?php echo $row["author"]; ?>" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="content">文章内容</label>
|
||||||
|
<textarea id="content" name="content" placeholder="请输入文章内容" required><?php echo $row["content"]; ?></textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="btn-group">
|
||||||
|
<button type="submit" class="btn btn-primary">提交</button>
|
||||||
|
<a href="articles_list.php" class="btn btn-secondary">返回文章列表</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
73
课堂代码/01-blog开发/v3/articles_list.php
Normal file
73
课堂代码/01-blog开发/v3/articles_list.php
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
<?php
|
||||||
|
$pageTitle = '网站后台管理 - 文章列表';
|
||||||
|
$page = 'articles';
|
||||||
|
include("header.php");
|
||||||
|
?>
|
||||||
|
|
||||||
|
<main class="main-content">
|
||||||
|
<div class="page-header page-header-bar">
|
||||||
|
<div>
|
||||||
|
<h2>文章管理</h2>
|
||||||
|
<p>管理博客的文章</p>
|
||||||
|
</div>
|
||||||
|
<a href="article_add.php" class="btn-add">
|
||||||
|
<span>+</span>
|
||||||
|
<span>添加文章</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="table-container">
|
||||||
|
<table class="articles-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>序号</th>
|
||||||
|
<th>标题</th>
|
||||||
|
<th>作者</th>
|
||||||
|
<th>发布时间</th>
|
||||||
|
<th>操作</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php
|
||||||
|
// 连接数据库
|
||||||
|
include("db.php");
|
||||||
|
|
||||||
|
// 删除文章的功能
|
||||||
|
if(isset($_REQUEST["del"])){
|
||||||
|
$id = $_REQUEST["id"];
|
||||||
|
$sql = "delete from articles where id = '$id'";
|
||||||
|
if (mysqli_query($conn, $sql) === TRUE) {
|
||||||
|
echo "<script>alert('文章删除成功');location.href='articles_list.php'</script>";
|
||||||
|
} else {
|
||||||
|
echo "Error: " . $sql . "<br>" . $conn->error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询所有文章
|
||||||
|
$sql = "select * from articles";
|
||||||
|
$result = mysqli_query($conn, $sql);
|
||||||
|
while ($row = mysqli_fetch_assoc($result)) {
|
||||||
|
// 标题超过10个字,就加省略号
|
||||||
|
$title = strlen($row["title"]) > 45 ? substr($row["title"], 0, 45) . "..." : $row["title"];
|
||||||
|
?>
|
||||||
|
<tr>
|
||||||
|
<td><?php echo $row["id"];?></td>
|
||||||
|
<td><?php echo $title;?></td>
|
||||||
|
<td><?php echo $row["author"];?></td>
|
||||||
|
<td><?php echo $row["time"];?></td>
|
||||||
|
<td>
|
||||||
|
<div class="action-btns">
|
||||||
|
<a href="article_edit.php?id=<?php echo $row["id"];?>" class="btn btn-edit">✏️ 编辑</a>
|
||||||
|
<a href="?del&id=<?php echo $row["id"];?>" class="btn btn-delete" onclick="return confirm('确定要删除该文章吗?')">🗑️ 删除</a>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
73
课堂代码/01-blog开发/v3/comment_list.php
Normal file
73
课堂代码/01-blog开发/v3/comment_list.php
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
<?php
|
||||||
|
$pageTitle = '网站后台管理 - 文章列表';
|
||||||
|
$page = 'commonts';
|
||||||
|
include("header.php");
|
||||||
|
?>
|
||||||
|
|
||||||
|
<main class="main-content">
|
||||||
|
<div class="page-header page-header-bar">
|
||||||
|
<div>
|
||||||
|
<h2>评论管理</h2>
|
||||||
|
<p>管理博客的评论</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="table-container">
|
||||||
|
<table class="articles-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>序号</th>
|
||||||
|
<th>文章</th>
|
||||||
|
<th>昵称</th>
|
||||||
|
<th>发布时间</th>
|
||||||
|
<th>内容</th>
|
||||||
|
<th>操作</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php
|
||||||
|
// 连接数据库
|
||||||
|
include("db.php");
|
||||||
|
|
||||||
|
// 删除文章的功能
|
||||||
|
if(isset($_REQUEST["del"])){
|
||||||
|
$id = $_REQUEST["id"];
|
||||||
|
$sql = "delete from comments where id = '$id'";
|
||||||
|
if (mysqli_query($conn, $sql) === TRUE) {
|
||||||
|
echo "<script>location.href='comment_list.php'</script>";
|
||||||
|
} else {
|
||||||
|
echo "Error: " . $sql . "<br>" . $conn->error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询所有评论
|
||||||
|
$sql = "select * from comments order by id desc";
|
||||||
|
$result = mysqli_query($conn, $sql);
|
||||||
|
while ($row = mysqli_fetch_assoc($result)) {
|
||||||
|
$sql = "select * from articles where id = '". $row['article_id']. "'";
|
||||||
|
$article_result = mysqli_query($conn, $sql);
|
||||||
|
$article_row = mysqli_fetch_assoc($article_result);
|
||||||
|
$article_title = $article_row["title"];
|
||||||
|
|
||||||
|
?>
|
||||||
|
<tr>
|
||||||
|
<td><?php echo $row["id"];?></td>
|
||||||
|
<td><?php echo $article_title;?></td>
|
||||||
|
<td><?php echo $row["nick"];?></td>
|
||||||
|
<td><?php echo $row["time"];?></td>
|
||||||
|
<td><?php echo $row["content"];?></td>
|
||||||
|
<td>
|
||||||
|
<div class="action-btns">
|
||||||
|
<a href="?del&id=<?php echo $row["id"];?>" class="btn btn-delete" onclick="return confirm('确定要删除该文章吗?')">🗑️ 删除</a>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
16
课堂代码/01-blog开发/v3/db.php
Normal file
16
课堂代码/01-blog开发/v3/db.php
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
// 连接数据库
|
||||||
|
$host = "127.0.0.1";
|
||||||
|
$dbname = "root";
|
||||||
|
$dbpassword = "usbw";
|
||||||
|
$database = "blog";
|
||||||
|
$port = 3307;
|
||||||
|
$conn = mysqli_connect($host, $dbname, $dbpassword, $database, $port);
|
||||||
|
if (!$conn) {
|
||||||
|
echo "连接失败";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置连接的字符集为utf8
|
||||||
|
mysqli_query($conn,"set names utf8");
|
||||||
|
|
||||||
708
课堂代码/01-blog开发/v3/header.php
Normal file
708
课堂代码/01-blog开发/v3/header.php
Normal file
@@ -0,0 +1,708 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<?php
|
||||||
|
session_start();
|
||||||
|
if (!isset($_SESSION["username"])) {
|
||||||
|
echo "<script>alert('请先登录');location.href='login.php'</script>";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
$page = isset($page) ? $page : '';
|
||||||
|
$pageTitle = isset($pageTitle) ? $pageTitle : '网站后台管理';
|
||||||
|
|
||||||
|
if (isset($_GET["logout"])) {
|
||||||
|
session_destroy();
|
||||||
|
echo "<script>alert('退出成功');location.href='login.php'</script>";
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title><?php echo $pageTitle; ?></title>
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: 'PingFang SC', 'Microsoft YaHei', 'Segoe UI', Arial, sans-serif;
|
||||||
|
background: #fafbfc;
|
||||||
|
color: #374151;
|
||||||
|
min-height: 100vh;
|
||||||
|
letter-spacing: 0.3px;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 顶部导航 */
|
||||||
|
.header {
|
||||||
|
background: #ffffff;
|
||||||
|
height: 60px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 0 32px;
|
||||||
|
border-bottom: 1px solid #e5e7eb;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header h1 {
|
||||||
|
font-size: 18px;
|
||||||
|
color: #1f2937;
|
||||||
|
font-weight: 600;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header .user-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
color: #6b7280;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header .user-avatar {
|
||||||
|
width: 34px;
|
||||||
|
height: 34px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: #3b82f6;
|
||||||
|
color: #fff;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 侧边栏 */
|
||||||
|
.sidebar {
|
||||||
|
width: 220px;
|
||||||
|
background: #ffffff;
|
||||||
|
color: #374151;
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
top: 60px;
|
||||||
|
bottom: 0;
|
||||||
|
padding: 20px 0;
|
||||||
|
border-right: 1px solid #e5e7eb;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar a {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 14px;
|
||||||
|
color: #6b7280;
|
||||||
|
text-decoration: none;
|
||||||
|
padding: 12px 24px;
|
||||||
|
font-size: 14px;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
margin: 4px 12px;
|
||||||
|
border-radius: 8px;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar a:hover {
|
||||||
|
background: #f3f4f6;
|
||||||
|
color: #374151;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar a.active {
|
||||||
|
background: #eff6ff;
|
||||||
|
color: #3b82f6;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar a .icon {
|
||||||
|
font-size: 17px;
|
||||||
|
width: 22px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 退出登录 */
|
||||||
|
.sidebar .logout {
|
||||||
|
margin-top: auto;
|
||||||
|
border-top: 1px solid #e5e7eb;
|
||||||
|
padding-top: 16px;
|
||||||
|
margin-left: 0;
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar .logout:hover {
|
||||||
|
background: #fef2f2;
|
||||||
|
color: #ef4444;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 主内容区 */
|
||||||
|
.main-content {
|
||||||
|
margin-left: 220px;
|
||||||
|
margin-top: 60px;
|
||||||
|
padding: 32px 40px;
|
||||||
|
min-height: calc(100vh - 60px);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 欢迎区域(main.php) */
|
||||||
|
.welcome-section {
|
||||||
|
margin-bottom: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.welcome-section h2 {
|
||||||
|
font-size: 24px;
|
||||||
|
color: #111827;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
font-weight: 600;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.welcome-section p {
|
||||||
|
color: #9ca3af;
|
||||||
|
font-size: 14px;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 统计卡片(main.php) */
|
||||||
|
.stats-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
|
||||||
|
gap: 20px;
|
||||||
|
margin-bottom: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card {
|
||||||
|
background: #ffffff;
|
||||||
|
border: 1px solid #e5e7eb;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 24px;
|
||||||
|
transition: all 0.25s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card:hover {
|
||||||
|
border-color: #d1d5db;
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.04);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card .card-icon {
|
||||||
|
width: 44px;
|
||||||
|
height: 44px;
|
||||||
|
border-radius: 10px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 20px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card.visitors .card-icon {
|
||||||
|
background: #eff6ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card.memory .card-icon {
|
||||||
|
background: #ecfdf5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card.cpu .card-icon {
|
||||||
|
background: #fef3c7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card.site .card-icon {
|
||||||
|
background: #fef2f2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card .stat-label {
|
||||||
|
font-size: 13px;
|
||||||
|
color: #9ca3af;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card .stat-value {
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #111827;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card .stat-unit {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #6b7280;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 内容卡片(main.php) */
|
||||||
|
.content-card {
|
||||||
|
background: #ffffff;
|
||||||
|
border: 1px solid #e5e7eb;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 28px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-card h3 {
|
||||||
|
font-size: 16px;
|
||||||
|
color: #111827;
|
||||||
|
margin-bottom: 18px;
|
||||||
|
padding-bottom: 14px;
|
||||||
|
border-bottom: 1px solid #f3f4f6;
|
||||||
|
font-weight: 600;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-list {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 14px;
|
||||||
|
padding: 16px;
|
||||||
|
background: #f9fafb;
|
||||||
|
border-radius: 10px;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-item:hover {
|
||||||
|
background: #f3f4f6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-item .info-icon {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
border-radius: 10px;
|
||||||
|
background: #eff6ff;
|
||||||
|
color: #3b82f6;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-item .info-text h4 {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #374151;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
font-weight: 500;
|
||||||
|
letter-spacing: 0.3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-item .info-text p {
|
||||||
|
font-size: 13px;
|
||||||
|
color: #9ca3af;
|
||||||
|
letter-spacing: 0.3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 页面头部 */
|
||||||
|
.page-header {
|
||||||
|
margin-bottom: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header h2 {
|
||||||
|
font-size: 24px;
|
||||||
|
color: #111827;
|
||||||
|
font-weight: 600;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header p {
|
||||||
|
color: #9ca3af;
|
||||||
|
font-size: 14px;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header-bar {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-add {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
background: #3b82f6;
|
||||||
|
color: #fff;
|
||||||
|
padding: 10px 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
text-decoration: none;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-add:hover {
|
||||||
|
background: #2563eb;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 表格容器 */
|
||||||
|
.table-container {
|
||||||
|
background: #ffffff;
|
||||||
|
border: 1px solid #e5e7eb;
|
||||||
|
border-radius: 12px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
table-layout: fixed;
|
||||||
|
}
|
||||||
|
|
||||||
|
thead {
|
||||||
|
background: #f9fafb;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
text-align: left;
|
||||||
|
padding: 16px 20px;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #6b7280;
|
||||||
|
letter-spacing: 0.8px;
|
||||||
|
border-bottom: 1px solid #e5e7eb;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
padding: 14px 16px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #374151;
|
||||||
|
border-bottom: 1px solid #f3f4f6;
|
||||||
|
vertical-align: middle;
|
||||||
|
letter-spacing: 0.3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody tr {
|
||||||
|
transition: background 0.15s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody tr:hover {
|
||||||
|
background: #f9fafb;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody tr:last-child td {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 文章列表表格列宽 */
|
||||||
|
.articles-table th:nth-child(1) {
|
||||||
|
width: 10%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.articles-table th:nth-child(2) {
|
||||||
|
width: 30%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.articles-table th:nth-child(3) {
|
||||||
|
width: 15%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.articles-table th:nth-child(4) {
|
||||||
|
width: 20%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.articles-table th:nth-child(5) {
|
||||||
|
width: 25%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.articles-table th:nth-child(6) {
|
||||||
|
width: 10%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 用户列表表格列宽 */
|
||||||
|
.users-table th:nth-child(1) {
|
||||||
|
width: 8%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.users-table th:nth-child(2) {
|
||||||
|
width: 15%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.users-table th:nth-child(3) {
|
||||||
|
width: 18%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.users-table th:nth-child(4) {
|
||||||
|
width: 34%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.users-table th:nth-child(5) {
|
||||||
|
width: 30%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.users-table td:nth-child(1),
|
||||||
|
.users-table td:nth-child(2),
|
||||||
|
.users-table td:nth-child(3),
|
||||||
|
.users-table td:nth-child(4) {
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.users-table td:nth-child(5) {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 操作按钮 */
|
||||||
|
.action-btns {
|
||||||
|
display: flex;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
padding: 6px 10px;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 500;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: all 0.15s ease;
|
||||||
|
letter-spacing: 0.3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-edit {
|
||||||
|
background: #eff6ff;
|
||||||
|
color: #3b82f6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-edit:hover {
|
||||||
|
background: #3b82f6;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-delete {
|
||||||
|
background: #fef2f2;
|
||||||
|
color: #ef4444;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-delete:hover {
|
||||||
|
background: #ef4444;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 表单卡片 */
|
||||||
|
.form-card {
|
||||||
|
background: #ffffff;
|
||||||
|
border: 1px solid #e5e7eb;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 32px;
|
||||||
|
max-width: 720px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-card-sm {
|
||||||
|
max-width: 520px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group {
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group label {
|
||||||
|
display: block;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #374151;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
letter-spacing: 0.3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group input,
|
||||||
|
.form-group textarea {
|
||||||
|
width: 100%;
|
||||||
|
padding: 12px 16px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: inherit;
|
||||||
|
color: #374151;
|
||||||
|
background: #ffffff;
|
||||||
|
border: 1px solid #d1d5db;
|
||||||
|
border-radius: 8px;
|
||||||
|
outline: none;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
letter-spacing: 0.3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group input:focus,
|
||||||
|
.form-group textarea:focus {
|
||||||
|
border-color: #3b82f6;
|
||||||
|
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group input::placeholder,
|
||||||
|
.form-group textarea::placeholder {
|
||||||
|
color: #9ca3af;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group textarea {
|
||||||
|
min-height: 240px;
|
||||||
|
resize: vertical;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-hint {
|
||||||
|
font-size: 13px;
|
||||||
|
color: #9ca3af;
|
||||||
|
margin-top: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-group {
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
margin-top: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-group .btn {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 12px 24px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
font-family: inherit;
|
||||||
|
border-radius: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary {
|
||||||
|
background: #3b82f6;
|
||||||
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary:hover {
|
||||||
|
background: #2563eb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-secondary {
|
||||||
|
background: #ffffff;
|
||||||
|
color: #374151;
|
||||||
|
border: 1px solid #d1d5db;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-secondary:hover {
|
||||||
|
background: #f9fafb;
|
||||||
|
border-color: #9ca3af;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 密码显示 */
|
||||||
|
.password-masked {
|
||||||
|
font-family: inherit;
|
||||||
|
color: #374151;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 响应式 */
|
||||||
|
@media (max-width: 900px) {
|
||||||
|
.sidebar {
|
||||||
|
width: 64px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar .nav-text {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar a {
|
||||||
|
justify-content: center;
|
||||||
|
padding: 12px;
|
||||||
|
margin: 4px 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-content {
|
||||||
|
margin-left: 64px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
.sidebar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-content {
|
||||||
|
margin-left: 0;
|
||||||
|
padding: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
padding: 0 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header h1 {
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header-bar {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
th,
|
||||||
|
td {
|
||||||
|
padding: 12px 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btns {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-card {
|
||||||
|
padding: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-group {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<header class="header">
|
||||||
|
<h1>网站后台管理</h1>
|
||||||
|
<div class="user-info">
|
||||||
|
<span>欢迎回来</span>
|
||||||
|
<div class="user-avatar">管</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<nav class="sidebar">
|
||||||
|
<a href="main.php" class="<?php echo $page == 'main' ? 'active' : ''; ?>">
|
||||||
|
<span class="icon">📊</span>
|
||||||
|
<span class="nav-text">网站信息</span>
|
||||||
|
</a>
|
||||||
|
<a href="articles_list.php" class="<?php echo $page == 'articles' ? 'active' : ''; ?>">
|
||||||
|
<span class="icon">📝</span>
|
||||||
|
<span class="nav-text">文章管理</span>
|
||||||
|
</a>
|
||||||
|
<a href="comment_list.php" class="<?php echo $page == 'commonts' ? 'active' : ''; ?>">
|
||||||
|
<span class="icon">💬</span>
|
||||||
|
<span class="nav-text">评论管理</span>
|
||||||
|
</a>
|
||||||
|
<a href="users_list.php" class="<?php echo $page == 'users' ? 'active' : ''; ?>">
|
||||||
|
<span class="icon">👥</span>
|
||||||
|
<span class="nav-text">用户管理</span>
|
||||||
|
</a>
|
||||||
|
<a href="?logout" class="logout">
|
||||||
|
<span class="icon">🚪</span>
|
||||||
|
<span class="nav-text">退出登录</span>
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
BIN
课堂代码/01-blog开发/v3/images/avatar/2026042515340236840.jpg
Normal file
BIN
课堂代码/01-blog开发/v3/images/avatar/2026042515340236840.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 180 KiB |
BIN
课堂代码/01-blog开发/v3/images/avatar/2026042515374976790.png
Normal file
BIN
课堂代码/01-blog开发/v3/images/avatar/2026042515374976790.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 86 KiB |
BIN
课堂代码/01-blog开发/v3/images/avatar/2026042515413160538.jpg
Normal file
BIN
课堂代码/01-blog开发/v3/images/avatar/2026042515413160538.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 180 KiB |
BIN
课堂代码/01-blog开发/v3/images/avatar/default.jpg
Normal file
BIN
课堂代码/01-blog开发/v3/images/avatar/default.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 63 KiB |
719
课堂代码/01-blog开发/v3/index.php
Normal file
719
课堂代码/01-blog开发/v3/index.php
Normal file
@@ -0,0 +1,719 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>许老师的小站 — 笔记与随笔</title>
|
||||||
|
<style>
|
||||||
|
/* ========== 基础重置 ========== */
|
||||||
|
*, *::before, *::after {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--primary: #6366f1;
|
||||||
|
--primary-dark: #4f46e5;
|
||||||
|
--primary-light: #818cf8;
|
||||||
|
--accent: #f59e0b;
|
||||||
|
--bg-page: #f8f9fc;
|
||||||
|
--bg-card: #ffffff;
|
||||||
|
--bg-card-hover: #f5f7ff;
|
||||||
|
--text-primary: #1e293b;
|
||||||
|
--text-secondary: #64748b;
|
||||||
|
--text-muted: #94a3b8;
|
||||||
|
--border: #e2e8f0;
|
||||||
|
--border-light: #f1f5f9;
|
||||||
|
--gradient-1: linear-gradient(135deg, #6366f1, #8b5cf6, #ec4899);
|
||||||
|
--gradient-2: linear-gradient(135deg, #f59e0b, #ef4444, #ec4899);
|
||||||
|
--shadow: 0 4px 24px rgba(99, 102, 241, 0.08);
|
||||||
|
--shadow-hover: 0 12px 40px rgba(99, 102, 241, 0.14);
|
||||||
|
--radius: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
html { scroll-behavior: smooth; }
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: 'Inter', 'PingFang SC', 'Microsoft YaHei', -apple-system, BlinkMacSystemFont, sans-serif;
|
||||||
|
background-color: var(--bg-page);
|
||||||
|
color: var(--text-primary);
|
||||||
|
min-height: 100vh;
|
||||||
|
overflow-x: hidden;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar { width: 6px; }
|
||||||
|
::-webkit-scrollbar-track { background: var(--bg-page); }
|
||||||
|
::-webkit-scrollbar-thumb { background: var(--primary); border-radius: 3px; }
|
||||||
|
|
||||||
|
/* ========== 装饰背景 ========== */
|
||||||
|
.bg-decoration {
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
z-index: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-circle {
|
||||||
|
position: absolute;
|
||||||
|
border-radius: 50%;
|
||||||
|
filter: blur(80px);
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-circle-1 {
|
||||||
|
width: 500px; height: 500px;
|
||||||
|
background: rgba(99, 102, 241, 0.08);
|
||||||
|
top: -150px; right: -100px;
|
||||||
|
animation: floatBg 25s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-circle-2 {
|
||||||
|
width: 400px; height: 400px;
|
||||||
|
background: rgba(236, 72, 153, 0.05);
|
||||||
|
bottom: 10%; left: -80px;
|
||||||
|
animation: floatBg 20s ease-in-out infinite reverse;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-circle-3 {
|
||||||
|
width: 300px; height: 300px;
|
||||||
|
background: rgba(245, 158, 11, 0.05);
|
||||||
|
top: 50%; right: 10%;
|
||||||
|
animation: floatBg 18s ease-in-out infinite;
|
||||||
|
animation-delay: -8s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes floatBg {
|
||||||
|
0%, 100% { transform: translate(0, 0) scale(1); }
|
||||||
|
33% { transform: translate(30px, -40px) scale(1.08); }
|
||||||
|
66% { transform: translate(-20px, 30px) scale(0.96); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========== 导航栏 ========== */
|
||||||
|
.navbar {
|
||||||
|
position: fixed;
|
||||||
|
top: 0; left: 0; right: 0;
|
||||||
|
z-index: 100;
|
||||||
|
padding: 0 48px;
|
||||||
|
height: 72px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
background: rgba(248, 249, 252, 0.82);
|
||||||
|
backdrop-filter: blur(20px) saturate(180%);
|
||||||
|
-webkit-backdrop-filter: blur(20px) saturate(180%);
|
||||||
|
border-bottom: 1px solid var(--border);
|
||||||
|
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar.scrolled {
|
||||||
|
height: 62px;
|
||||||
|
background: rgba(248, 249, 252, 0.96);
|
||||||
|
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-brand {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
text-decoration: none;
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-brand-icon {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
border-radius: 12px;
|
||||||
|
background: var(--gradient-1);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 18px;
|
||||||
|
box-shadow: 0 4px 15px rgba(99, 102, 241, 0.3);
|
||||||
|
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-brand:hover .nav-brand-icon {
|
||||||
|
transform: rotate(-8deg) scale(1.08);
|
||||||
|
box-shadow: 0 8px 25px rgba(99, 102, 241, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-brand-text {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: -0.3px;
|
||||||
|
background: var(--gradient-1);
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
background-clip: text;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-links { display: flex; align-items: center; gap: 8px; }
|
||||||
|
|
||||||
|
.nav-link {
|
||||||
|
padding: 8px 18px;
|
||||||
|
border-radius: 10px;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
text-decoration: none;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-link:hover { color: var(--primary); background: rgba(99, 102, 241, 0.06); }
|
||||||
|
.nav-link.active { color: var(--primary); background: rgba(99, 102, 241, 0.1); }
|
||||||
|
|
||||||
|
.nav-link-admin {
|
||||||
|
padding: 8px 20px;
|
||||||
|
background: var(--gradient-1);
|
||||||
|
color: #fff !important;
|
||||||
|
border-radius: 10px;
|
||||||
|
font-weight: 600;
|
||||||
|
box-shadow: 0 4px 15px rgba(99, 102, 241, 0.3);
|
||||||
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-link-admin:hover {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 8px 25px rgba(99, 102, 241, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========== Hero ========== */
|
||||||
|
.hero {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
min-height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
text-align: center;
|
||||||
|
padding: 120px 24px 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-badge {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 8px 20px;
|
||||||
|
background: rgba(99, 102, 241, 0.08);
|
||||||
|
border: 1px solid rgba(99, 102, 241, 0.15);
|
||||||
|
border-radius: 50px;
|
||||||
|
font-size: 13px;
|
||||||
|
color: var(--primary);
|
||||||
|
font-weight: 500;
|
||||||
|
margin-bottom: 32px;
|
||||||
|
animation: fadeInUp 0.8s ease forwards;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-badge-dot {
|
||||||
|
width: 6px;
|
||||||
|
height: 6px;
|
||||||
|
background: var(--primary);
|
||||||
|
border-radius: 50%;
|
||||||
|
animation: pulse 2s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes pulse {
|
||||||
|
0%, 100% { opacity: 1; transform: scale(1); }
|
||||||
|
50% { opacity: 0.4; transform: scale(1.6); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-title {
|
||||||
|
font-size: clamp(44px, 7vw, 82px);
|
||||||
|
font-weight: 800;
|
||||||
|
line-height: 1.1;
|
||||||
|
letter-spacing: -2px;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
animation: fadeInUp 0.8s ease 0.15s forwards;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-title-line { display: block; }
|
||||||
|
|
||||||
|
.hero-title-gradient {
|
||||||
|
background: var(--gradient-1);
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
background-clip: text;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-subtitle {
|
||||||
|
font-size: clamp(16px, 2vw, 20px);
|
||||||
|
color: var(--text-secondary);
|
||||||
|
max-width: 520px;
|
||||||
|
line-height: 1.8;
|
||||||
|
margin-bottom: 48px;
|
||||||
|
animation: fadeInUp 0.8s ease 0.3s forwards;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 16px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
animation: fadeInUp 0.8s ease 0.45s forwards;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 14px 32px;
|
||||||
|
background: var(--gradient-1);
|
||||||
|
color: #fff;
|
||||||
|
border-radius: 14px;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 600;
|
||||||
|
text-decoration: none;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
box-shadow: 0 8px 30px rgba(99, 102, 241, 0.3);
|
||||||
|
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
background: linear-gradient(135deg, rgba(255,255,255,0.2), transparent);
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary:hover {
|
||||||
|
transform: translateY(-3px) scale(1.02);
|
||||||
|
box-shadow: 0 16px 40px rgba(99, 102, 241, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary:hover::before { opacity: 1; }
|
||||||
|
|
||||||
|
.btn-ghost {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 14px 28px;
|
||||||
|
background: var(--bg-card);
|
||||||
|
color: var(--text-primary);
|
||||||
|
border: 1.5px solid var(--border);
|
||||||
|
border-radius: 14px;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 500;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-ghost:hover {
|
||||||
|
border-color: var(--primary);
|
||||||
|
color: var(--primary);
|
||||||
|
background: rgba(99, 102, 241, 0.04);
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 6px 20px rgba(99, 102, 241, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-scroll {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 40px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
color: var(--text-muted);
|
||||||
|
font-size: 12px;
|
||||||
|
letter-spacing: 2px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
animation: fadeInUp 1s ease 1s forwards, float 3s ease-in-out infinite 1.5s;
|
||||||
|
opacity: 0;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll-line {
|
||||||
|
width: 1px;
|
||||||
|
height: 40px;
|
||||||
|
background: linear-gradient(to bottom, var(--primary), transparent);
|
||||||
|
animation: scrollLine 2s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes scrollLine {
|
||||||
|
0% { transform: scaleY(0); transform-origin: top; }
|
||||||
|
50% { transform: scaleY(1); transform-origin: top; }
|
||||||
|
51% { transform: scaleY(1); transform-origin: bottom; }
|
||||||
|
100% { transform: scaleY(0); transform-origin: bottom; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========== 文章列表 ========== */
|
||||||
|
.articles-section {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
max-width: 1100px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 40px 24px 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 48px;
|
||||||
|
animation: fadeInUp 0.8s ease forwards;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: -0.5px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title-icon {
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
border-radius: 10px;
|
||||||
|
background: var(--gradient-1);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 16px;
|
||||||
|
box-shadow: 0 4px 12px rgba(99, 102, 241, 0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-count {
|
||||||
|
padding: 6px 16px;
|
||||||
|
background: rgba(99, 102, 241, 0.08);
|
||||||
|
border: 1px solid rgba(99, 102, 241, 0.12);
|
||||||
|
border-radius: 50px;
|
||||||
|
font-size: 13px;
|
||||||
|
color: var(--primary);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.articles-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
|
||||||
|
gap: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.article-card {
|
||||||
|
position: relative;
|
||||||
|
background: var(--bg-card);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: var(--radius);
|
||||||
|
padding: 32px;
|
||||||
|
text-decoration: none;
|
||||||
|
color: inherit;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
transition: all 0.5s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
cursor: pointer;
|
||||||
|
overflow: hidden;
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(30px);
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.02);
|
||||||
|
}
|
||||||
|
|
||||||
|
.article-card.visible {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.article-card:hover {
|
||||||
|
transform: translateY(-8px);
|
||||||
|
border-color: rgba(99, 102, 241, 0.2);
|
||||||
|
box-shadow: var(--shadow-hover);
|
||||||
|
background: var(--bg-card-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-top {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-tag {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 5px;
|
||||||
|
padding: 5px 12px;
|
||||||
|
background: rgba(99, 102, 241, 0.08);
|
||||||
|
border-radius: 8px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--primary);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-date { font-size: 12px; color: var(--text-muted); }
|
||||||
|
|
||||||
|
.card-title {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 1.45;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
color: var(--text-primary);
|
||||||
|
transition: color 0.3s;
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: 2;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.article-card:hover .card-title { color: var(--primary); }
|
||||||
|
|
||||||
|
.card-excerpt {
|
||||||
|
font-size: 14px;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
line-height: 1.75;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
flex-grow: 1;
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: 3;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-footer {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding-top: 20px;
|
||||||
|
border-top: 1px solid var(--border-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-author { display: flex; align-items: center; gap: 10px; }
|
||||||
|
|
||||||
|
.card-author-avatar {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: var(--gradient-2);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-author-name { font-size: 13px; font-weight: 500; color: var(--text-secondary); }
|
||||||
|
|
||||||
|
.card-read-more {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
font-size: 13px;
|
||||||
|
color: var(--primary);
|
||||||
|
font-weight: 500;
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateX(-10px);
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.article-card:hover .card-read-more {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-state {
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
text-align: center;
|
||||||
|
padding: 80px 20px;
|
||||||
|
animation: fadeIn 0.6s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-icon { font-size: 64px; margin-bottom: 24px; opacity: 0.25; }
|
||||||
|
.empty-state h3 { font-size: 20px; color: var(--text-secondary); margin-bottom: 8px; }
|
||||||
|
.empty-state p { color: var(--text-muted); font-size: 14px; }
|
||||||
|
|
||||||
|
/* ========== 底部 ========== */
|
||||||
|
.footer {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
text-align: center;
|
||||||
|
padding: 40px 24px 60px;
|
||||||
|
border-top: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-text { font-size: 14px; color: var(--text-muted); }
|
||||||
|
.footer-text span { color: var(--primary); font-weight: 600; }
|
||||||
|
|
||||||
|
/* ========== 动画 ========== */
|
||||||
|
@keyframes fadeInUp {
|
||||||
|
from { opacity: 0; transform: translateY(30px); }
|
||||||
|
to { opacity: 1; transform: translateY(0); }
|
||||||
|
}
|
||||||
|
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
|
||||||
|
@keyframes float {
|
||||||
|
0%, 100% { transform: translateX(-50%) translateY(0); }
|
||||||
|
50% { transform: translateX(-50%) translateY(-10px); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========== 响应式 ========== */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.navbar { padding: 0 20px; }
|
||||||
|
.nav-links { gap: 4px; }
|
||||||
|
.nav-link { padding: 8px 12px; font-size: 13px; }
|
||||||
|
.nav-link-admin { padding: 8px 14px; }
|
||||||
|
.articles-grid { grid-template-columns: 1fr; }
|
||||||
|
.hero { padding: 100px 20px 80px; }
|
||||||
|
.hero-actions { flex-direction: column; align-items: center; }
|
||||||
|
.section-header { flex-direction: column; align-items: flex-start; gap: 16px; }
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<!-- 装饰背景 -->
|
||||||
|
<div class="bg-decoration">
|
||||||
|
<div class="bg-circle bg-circle-1"></div>
|
||||||
|
<div class="bg-circle bg-circle-2"></div>
|
||||||
|
<div class="bg-circle bg-circle-3"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 导航栏 -->
|
||||||
|
<nav class="navbar" id="navbar">
|
||||||
|
<a href="index.php" class="nav-brand">
|
||||||
|
<div class="nav-brand-icon">✦</div>
|
||||||
|
<span class="nav-brand-text">许老师的小站</span>
|
||||||
|
</a>
|
||||||
|
<div class="nav-links">
|
||||||
|
<a href="index.php" class="nav-link active">首页</a>
|
||||||
|
<a href="main.php" class="nav-link nav-link-admin" target="_blank">后台管理</a>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<!-- Hero -->
|
||||||
|
<section class="hero">
|
||||||
|
<div class="hero-badge">
|
||||||
|
<span class="hero-badge-dot"></span>
|
||||||
|
<span>笔记与随笔</span>
|
||||||
|
</div>
|
||||||
|
<h1 class="hero-title">
|
||||||
|
<span class="hero-title-line">记录思考,</span>
|
||||||
|
<span class="hero-title-line hero-title-gradient">沉淀成长</span>
|
||||||
|
</h1>
|
||||||
|
<p class="hero-subtitle">
|
||||||
|
在这里,每一次敲击键盘都是一次思维的碰撞,每一篇文章都是对知识的重新梳理。
|
||||||
|
</p>
|
||||||
|
<div class="hero-actions">
|
||||||
|
<a href="#articles" class="btn-primary">
|
||||||
|
<span>探索文章</span>
|
||||||
|
<span>↓</span>
|
||||||
|
</a>
|
||||||
|
<a href="main.php" class="btn-ghost" target="_blank">后台管理</a>
|
||||||
|
</div>
|
||||||
|
<a href="#articles" class="hero-scroll">
|
||||||
|
<span>向下滚动</span>
|
||||||
|
<div class="scroll-line"></div>
|
||||||
|
</a>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- 文章列表 -->
|
||||||
|
<section class="articles-section" id="articles">
|
||||||
|
<div class="section-header">
|
||||||
|
<h2 class="section-title">
|
||||||
|
<div class="section-title-icon">📝</div>
|
||||||
|
全部文章
|
||||||
|
</h2>
|
||||||
|
<?php
|
||||||
|
include("db.php");
|
||||||
|
$sql = "SELECT COUNT(*) as total FROM articles";
|
||||||
|
$countResult = mysqli_query($conn, $sql);
|
||||||
|
$countRow = mysqli_fetch_assoc($countResult);
|
||||||
|
?>
|
||||||
|
<span class="section-count"><?php echo $countRow['total']; ?> 篇</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="articles-grid">
|
||||||
|
<?php
|
||||||
|
$sql = "SELECT * FROM articles ORDER BY id DESC";
|
||||||
|
$result = mysqli_query($conn, $sql);
|
||||||
|
|
||||||
|
if (mysqli_num_rows($result) === 0) {
|
||||||
|
echo '<div class="empty-state">
|
||||||
|
<div class="empty-icon">🙃</div>
|
||||||
|
<h3>暂无文章</h3>
|
||||||
|
<p>点击右上角「后台管理」添加你的第一篇文章吧</p>
|
||||||
|
</div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
while ($row = mysqli_fetch_assoc($result)) {
|
||||||
|
$excerpt = mb_substr(strip_tags($row["content"]), 0, 80, 'utf-8');
|
||||||
|
if (mb_strlen(strip_tags($row["content"]), 'utf-8') > 80) $excerpt .= '…';
|
||||||
|
$authorInitial = mb_substr($row["author"], 0, 1, 'utf-8');
|
||||||
|
?>
|
||||||
|
<a href="article.php?id=<?php echo $row["id"]; ?>" class="article-card">
|
||||||
|
<div class="card-top">
|
||||||
|
<span class="card-tag">📄 笔记</span>
|
||||||
|
<span class="card-date"><?php echo date('m/d', strtotime($row["time"])); ?></span>
|
||||||
|
</div>
|
||||||
|
<h3 class="card-title"><?php echo $row["title"]; ?></h3>
|
||||||
|
<p class="card-excerpt"><?php echo $excerpt; ?></p>
|
||||||
|
<div class="card-footer">
|
||||||
|
<div class="card-author">
|
||||||
|
<div class="card-author-avatar"><?php echo $authorInitial; ?></div>
|
||||||
|
<span class="card-author-name"><?php echo $row["author"]; ?></span>
|
||||||
|
</div>
|
||||||
|
<span class="card-read-more">阅读全文 →</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<?php } ?>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- 底部 -->
|
||||||
|
<footer class="footer">
|
||||||
|
<p class="footer-text">
|
||||||
|
© <?php echo date('Y'); ?> <span>许老师的小站</span> · 用心记录每一天
|
||||||
|
</p>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const navbar = document.getElementById('navbar');
|
||||||
|
window.addEventListener('scroll', () => {
|
||||||
|
navbar.classList.toggle('scrolled', window.scrollY > 50);
|
||||||
|
}, { passive: true });
|
||||||
|
|
||||||
|
const cards = document.querySelectorAll('.article-card');
|
||||||
|
const observer = new IntersectionObserver((entries) => {
|
||||||
|
entries.forEach((entry, index) => {
|
||||||
|
if (entry.isIntersecting) {
|
||||||
|
setTimeout(() => entry.target.classList.add('visible'), index * 80);
|
||||||
|
observer.unobserve(entry.target);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, { threshold: 0.1, rootMargin: '0px 0px -50px 0px' });
|
||||||
|
cards.forEach(card => observer.observe(card));
|
||||||
|
|
||||||
|
cards.forEach(card => {
|
||||||
|
card.addEventListener('click', function(e) {
|
||||||
|
const ripple = document.createElement('div');
|
||||||
|
ripple.style.cssText = 'position:absolute;border-radius:50%;background:rgba(99,102,241,0.1);transform:scale(0);animation:rippleOut 0.6s ease-out forwards;pointer-events:none;';
|
||||||
|
const rect = this.getBoundingClientRect();
|
||||||
|
const size = Math.max(rect.width, rect.height);
|
||||||
|
ripple.style.width = ripple.style.height = size + 'px';
|
||||||
|
ripple.style.left = (e.clientX - rect.left - size / 2) + 'px';
|
||||||
|
ripple.style.top = (e.clientY - rect.top - size / 2) + 'px';
|
||||||
|
this.appendChild(ripple);
|
||||||
|
setTimeout(() => ripple.remove(), 600);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const s = document.createElement('style');
|
||||||
|
s.textContent = '@keyframes rippleOut { to { transform:scale(4); opacity:0; } }';
|
||||||
|
document.head.appendChild(s);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
415
课堂代码/01-blog开发/v3/login.php
Normal file
415
课堂代码/01-blog开发/v3/login.php
Normal file
@@ -0,0 +1,415 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>欢迎登录</title>
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
min-height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 50%, #f093fb 100%);
|
||||||
|
font-family: 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', sans-serif;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 装饰背景 */
|
||||||
|
.bg-decoration {
|
||||||
|
position: fixed;
|
||||||
|
border-radius: 50%;
|
||||||
|
filter: blur(80px);
|
||||||
|
opacity: 0.5;
|
||||||
|
z-index: 0;
|
||||||
|
animation: float 8s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-decoration:nth-child(1) {
|
||||||
|
width: 400px;
|
||||||
|
height: 400px;
|
||||||
|
background: rgba(102, 126, 234, 0.6);
|
||||||
|
top: -100px;
|
||||||
|
left: -100px;
|
||||||
|
animation-delay: 0s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-decoration:nth-child(2) {
|
||||||
|
width: 300px;
|
||||||
|
height: 300px;
|
||||||
|
background: rgba(240, 147, 251, 0.5);
|
||||||
|
bottom: -50px;
|
||||||
|
right: -50px;
|
||||||
|
animation-delay: -2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-decoration:nth-child(3) {
|
||||||
|
width: 200px;
|
||||||
|
height: 200px;
|
||||||
|
background: rgba(255, 255, 255, 0.3);
|
||||||
|
top: 50%;
|
||||||
|
right: 10%;
|
||||||
|
animation-delay: -4s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes float {
|
||||||
|
|
||||||
|
0%,
|
||||||
|
100% {
|
||||||
|
transform: translate(0, 0) scale(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
25% {
|
||||||
|
transform: translate(20px, -20px) scale(1.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
transform: translate(0, -30px) scale(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
75% {
|
||||||
|
transform: translate(-20px, -10px) scale(1.03);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 登录卡片 */
|
||||||
|
.login-card {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
background: rgba(255, 255, 255, 0.95);
|
||||||
|
backdrop-filter: blur(20px);
|
||||||
|
border-radius: 24px;
|
||||||
|
padding: 48px 40px;
|
||||||
|
width: 420px;
|
||||||
|
max-width: 90vw;
|
||||||
|
box-shadow:
|
||||||
|
0 25px 50px -12px rgba(0, 0, 0, 0.25),
|
||||||
|
0 0 0 1px rgba(255, 255, 255, 0.5) inset;
|
||||||
|
animation: slideUp 0.8s cubic-bezier(0.16, 1, 0.3, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideUp {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(40px) scale(0.95);
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0) scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 标题 */
|
||||||
|
.login-title {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-title h1 {
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: 600;
|
||||||
|
background: linear-gradient(135deg, #667eea, #764ba2);
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
background-clip: text;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-title p {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #6b7280;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 输入框容器 */
|
||||||
|
.input-group {
|
||||||
|
position: relative;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group input {
|
||||||
|
width: 100%;
|
||||||
|
padding: 16px 20px;
|
||||||
|
font-size: 16px;
|
||||||
|
border: 2px solid #e5e7eb;
|
||||||
|
border-radius: 12px;
|
||||||
|
outline: none;
|
||||||
|
background: #f9fafb;
|
||||||
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group input::placeholder {
|
||||||
|
color: #9ca3af;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group input:focus {
|
||||||
|
border-color: #667eea;
|
||||||
|
background: #ffffff;
|
||||||
|
box-shadow: 0 0 0 4px rgba(102, 126, 234, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group input:focus::placeholder {
|
||||||
|
opacity: 0.5;
|
||||||
|
transform: translateX(4px);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 输入框图标 */
|
||||||
|
.input-icon {
|
||||||
|
position: absolute;
|
||||||
|
left: 16px;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
font-size: 18px;
|
||||||
|
color: #9ca3af;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group input:focus~.input-icon {
|
||||||
|
color: #667eea;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group input {
|
||||||
|
padding-left: 48px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 记住我 & 忘记密码 */
|
||||||
|
.form-options {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remember-me {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remember-me input[type="checkbox"] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkmark {
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
border: 2px solid #d1d5db;
|
||||||
|
border-radius: 5px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remember-me:hover .checkmark {
|
||||||
|
border-color: #667eea;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remember-me input:checked+.checkmark {
|
||||||
|
background: #667eea;
|
||||||
|
border-color: #667eea;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkmark::after {
|
||||||
|
content: '✓';
|
||||||
|
font-size: 12px;
|
||||||
|
color: white;
|
||||||
|
opacity: 0;
|
||||||
|
transform: scale(0);
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remember-me input:checked+.checkmark::after {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.remember-me span {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #6b7280;
|
||||||
|
}
|
||||||
|
|
||||||
|
.forgot-password {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #667eea;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.forgot-password:hover {
|
||||||
|
color: #764ba2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 登录按钮 */
|
||||||
|
.login-btn {
|
||||||
|
width: 100%;
|
||||||
|
padding: 16px;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: white;
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
border: none;
|
||||||
|
border-radius: 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-btn::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: -100%;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
|
||||||
|
transition: left 0.5s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-btn:hover {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 10px 30px -5px rgba(102, 126, 234, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-btn:hover::before {
|
||||||
|
left: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-btn:active {
|
||||||
|
transform: translateY(0);
|
||||||
|
box-shadow: 0 5px 15px -3px rgba(102, 126, 234, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 注册链接 */
|
||||||
|
.signup-link {
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 28px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #6b7280;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signup-link a {
|
||||||
|
color: #667eea;
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: 500;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signup-link a:hover {
|
||||||
|
color: #764ba2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 分隔线 */
|
||||||
|
.divider {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin: 28px 0;
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.divider::before,
|
||||||
|
.divider::after {
|
||||||
|
content: '';
|
||||||
|
flex: 1;
|
||||||
|
height: 1px;
|
||||||
|
background: linear-gradient(90deg, transparent, #e5e7eb, transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.divider span {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #9ca3af;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 社交登录 */
|
||||||
|
.social-login {
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.social-btn {
|
||||||
|
flex: 1;
|
||||||
|
padding: 12px;
|
||||||
|
border: 2px solid #e5e7eb;
|
||||||
|
border-radius: 10px;
|
||||||
|
background: white;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 8px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #6b7280;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.social-btn:hover {
|
||||||
|
border-color: #667eea;
|
||||||
|
background: #f9fafb;
|
||||||
|
transform: translateY(-2px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.social-btn svg {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<!-- 装饰背景 -->
|
||||||
|
<div class="bg-decoration"></div>
|
||||||
|
<div class="bg-decoration"></div>
|
||||||
|
<div class="bg-decoration"></div>
|
||||||
|
|
||||||
|
<div class="login-card">
|
||||||
|
<div class="login-title">
|
||||||
|
<h1>欢迎登录</h1>
|
||||||
|
<p>请输入您的账号信息</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form action="users.php" method="POST">
|
||||||
|
<!-- GET提交方式,所有的信息都在网址中 -->
|
||||||
|
<!-- POST提交方式,所有的信息都在请求体中 -->
|
||||||
|
<div class="input-group">
|
||||||
|
<input type="text" placeholder="用户名" name="username" required>
|
||||||
|
<span class="input-icon">👤</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="input-group">
|
||||||
|
<input type="text" placeholder="密码" name="password" required>
|
||||||
|
<span class="input-icon">🔒</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-options">
|
||||||
|
<label class="remember-me">
|
||||||
|
<input type="checkbox" name="remember">
|
||||||
|
<span class="checkmark"></span>
|
||||||
|
<span>记住我</span>
|
||||||
|
</label>
|
||||||
|
<a href="#" class="forgot-password">忘记密码?</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input type="submit" class="login-btn" name="login" value="登 录">
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div class="signup-link">
|
||||||
|
还没有账号?<a href="register.php">立即注册</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
87
课堂代码/01-blog开发/v3/main.php
Normal file
87
课堂代码/01-blog开发/v3/main.php
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
<?php
|
||||||
|
$pageTitle = '网站后台管理 - 网站信息';
|
||||||
|
$page = 'main';
|
||||||
|
include("header.php");
|
||||||
|
?>
|
||||||
|
|
||||||
|
<main class="main-content">
|
||||||
|
<div class="welcome-section">
|
||||||
|
<h2>仪表盘</h2>
|
||||||
|
<p>实时监控网站运行状态</p>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
// 获取服务器的内存占用
|
||||||
|
//$memoryUsage = exec('powershell -c "$os=Get-CimInstance Win32_OperatingSystem;$pct=[math]::Round(($os.TotalVisibleMemorySize-$os.FreePhysicalMemory)*100/$os.TotalVisibleMemorySize,1);echo $pct"');
|
||||||
|
// 目前用随机数代替
|
||||||
|
$memoryUsage = mt_rand(30, 60);
|
||||||
|
|
||||||
|
// 获取服务器的CPU占用
|
||||||
|
//$cpuUsage = exec('powershell -c "(Get-CimInstance Win32_Processor).LoadPercentage"');
|
||||||
|
$cpuUsage = mt_rand(30, 60);
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="stats-grid">
|
||||||
|
<div class="stat-card visitors">
|
||||||
|
<div class="card-icon">👥</div>
|
||||||
|
<div class="stat-label">今日访客</div>
|
||||||
|
<div class="stat-value">1000</div>
|
||||||
|
</div>
|
||||||
|
<div class="stat-card memory">
|
||||||
|
<div class="card-icon">💾</div>
|
||||||
|
<div class="stat-label">服务内存占用</div>
|
||||||
|
<div class="stat-value"><?php echo $memoryUsage; ?><span class="stat-unit">%</span></div>
|
||||||
|
</div>
|
||||||
|
<div class="stat-card cpu">
|
||||||
|
<div class="card-icon">⚙️</div>
|
||||||
|
<div class="stat-label">服务器 CPU 占用</div>
|
||||||
|
<div class="stat-value"><?php echo $cpuUsage; ?><span class="stat-unit">%</span></div>
|
||||||
|
</div>
|
||||||
|
<div class="stat-card site">
|
||||||
|
<div class="card-icon">🌐</div>
|
||||||
|
<div class="stat-label">站点名称</div>
|
||||||
|
<div class="stat-value" style="font-size: 20px;">许老师的小站</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content-card">
|
||||||
|
<h3>快速信息</h3>
|
||||||
|
<div class="info-list">
|
||||||
|
<div class="info-item">
|
||||||
|
<div class="info-icon">🏠</div>
|
||||||
|
<div class="info-text">
|
||||||
|
<h4>站点状态</h4>
|
||||||
|
<p>运行正常</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="info-item">
|
||||||
|
<div class="info-icon">🕐</div>
|
||||||
|
<div class="info-text">
|
||||||
|
<h4>系统时间</h4>
|
||||||
|
<p id="current-time">加载中...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="info-item">
|
||||||
|
<div class="info-icon">📅</div>
|
||||||
|
<div class="info-text">
|
||||||
|
<h4>系统日期</h4>
|
||||||
|
<p id="current-date">加载中...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function updateTime() {
|
||||||
|
const now = new Date();
|
||||||
|
const timeStr = now.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit', second: '2-digit' });
|
||||||
|
const dateStr = now.toLocaleDateString('zh-CN', { year: 'numeric', month: 'long', day: 'numeric', weekday: 'long' });
|
||||||
|
document.getElementById('current-time').textContent = timeStr;
|
||||||
|
document.getElementById('current-date').textContent = dateStr;
|
||||||
|
}
|
||||||
|
updateTime();
|
||||||
|
setInterval(updateTime, 1000);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
416
课堂代码/01-blog开发/v3/register.php
Normal file
416
课堂代码/01-blog开发/v3/register.php
Normal file
@@ -0,0 +1,416 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>欢迎注册</title>
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
min-height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 50%, #f093fb 100%);
|
||||||
|
font-family: 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', sans-serif;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 装饰背景 */
|
||||||
|
.bg-decoration {
|
||||||
|
position: fixed;
|
||||||
|
border-radius: 50%;
|
||||||
|
filter: blur(80px);
|
||||||
|
opacity: 0.5;
|
||||||
|
z-index: 0;
|
||||||
|
animation: float 8s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-decoration:nth-child(1) {
|
||||||
|
width: 400px;
|
||||||
|
height: 400px;
|
||||||
|
background: rgba(102, 126, 234, 0.6);
|
||||||
|
top: -100px;
|
||||||
|
left: -100px;
|
||||||
|
animation-delay: 0s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-decoration:nth-child(2) {
|
||||||
|
width: 300px;
|
||||||
|
height: 300px;
|
||||||
|
background: rgba(240, 147, 251, 0.5);
|
||||||
|
bottom: -50px;
|
||||||
|
right: -50px;
|
||||||
|
animation-delay: -2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-decoration:nth-child(3) {
|
||||||
|
width: 200px;
|
||||||
|
height: 200px;
|
||||||
|
background: rgba(255, 255, 255, 0.3);
|
||||||
|
top: 50%;
|
||||||
|
right: 10%;
|
||||||
|
animation-delay: -4s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes float {
|
||||||
|
|
||||||
|
0%,
|
||||||
|
100% {
|
||||||
|
transform: translate(0, 0) scale(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
25% {
|
||||||
|
transform: translate(20px, -20px) scale(1.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
transform: translate(0, -30px) scale(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
75% {
|
||||||
|
transform: translate(-20px, -10px) scale(1.03);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 登录卡片 */
|
||||||
|
.login-card {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
background: rgba(255, 255, 255, 0.95);
|
||||||
|
backdrop-filter: blur(20px);
|
||||||
|
border-radius: 24px;
|
||||||
|
padding: 48px 40px;
|
||||||
|
width: 420px;
|
||||||
|
max-width: 90vw;
|
||||||
|
box-shadow:
|
||||||
|
0 25px 50px -12px rgba(0, 0, 0, 0.25),
|
||||||
|
0 0 0 1px rgba(255, 255, 255, 0.5) inset;
|
||||||
|
animation: slideUp 0.8s cubic-bezier(0.16, 1, 0.3, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideUp {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(40px) scale(0.95);
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0) scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 标题 */
|
||||||
|
.login-title {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-title h1 {
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: 600;
|
||||||
|
background: linear-gradient(135deg, #667eea, #764ba2);
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
background-clip: text;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-title p {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #6b7280;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 输入框容器 */
|
||||||
|
.input-group {
|
||||||
|
position: relative;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group input {
|
||||||
|
width: 100%;
|
||||||
|
padding: 16px 20px;
|
||||||
|
font-size: 16px;
|
||||||
|
border: 2px solid #e5e7eb;
|
||||||
|
border-radius: 12px;
|
||||||
|
outline: none;
|
||||||
|
background: #f9fafb;
|
||||||
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group input::placeholder {
|
||||||
|
color: #9ca3af;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group input:focus {
|
||||||
|
border-color: #667eea;
|
||||||
|
background: #ffffff;
|
||||||
|
box-shadow: 0 0 0 4px rgba(102, 126, 234, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group input:focus::placeholder {
|
||||||
|
opacity: 0.5;
|
||||||
|
transform: translateX(4px);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 输入框图标 */
|
||||||
|
.input-icon {
|
||||||
|
position: absolute;
|
||||||
|
left: 16px;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
font-size: 18px;
|
||||||
|
color: #9ca3af;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group input:focus~.input-icon {
|
||||||
|
color: #667eea;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group input {
|
||||||
|
padding-left: 48px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 记住我 & 忘记密码 */
|
||||||
|
.form-options {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remember-me {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remember-me input[type="checkbox"] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkmark {
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
border: 2px solid #d1d5db;
|
||||||
|
border-radius: 5px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remember-me:hover .checkmark {
|
||||||
|
border-color: #667eea;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remember-me input:checked+.checkmark {
|
||||||
|
background: #667eea;
|
||||||
|
border-color: #667eea;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkmark::after {
|
||||||
|
content: '✓';
|
||||||
|
font-size: 12px;
|
||||||
|
color: white;
|
||||||
|
opacity: 0;
|
||||||
|
transform: scale(0);
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remember-me input:checked+.checkmark::after {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.remember-me span {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #6b7280;
|
||||||
|
}
|
||||||
|
|
||||||
|
.forgot-password {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #667eea;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.forgot-password:hover {
|
||||||
|
color: #764ba2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 登录按钮 */
|
||||||
|
.login-btn {
|
||||||
|
width: 100%;
|
||||||
|
padding: 16px;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: white;
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
border: none;
|
||||||
|
border-radius: 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-btn::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: -100%;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
|
||||||
|
transition: left 0.5s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-btn:hover {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 10px 30px -5px rgba(102, 126, 234, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-btn:hover::before {
|
||||||
|
left: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-btn:active {
|
||||||
|
transform: translateY(0);
|
||||||
|
box-shadow: 0 5px 15px -3px rgba(102, 126, 234, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 注册链接 */
|
||||||
|
.signup-link {
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 28px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #6b7280;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signup-link a {
|
||||||
|
color: #667eea;
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: 500;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signup-link a:hover {
|
||||||
|
color: #764ba2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 分隔线 */
|
||||||
|
.divider {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin: 28px 0;
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.divider::before,
|
||||||
|
.divider::after {
|
||||||
|
content: '';
|
||||||
|
flex: 1;
|
||||||
|
height: 1px;
|
||||||
|
background: linear-gradient(90deg, transparent, #e5e7eb, transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.divider span {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #9ca3af;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 社交登录 */
|
||||||
|
.social-login {
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.social-btn {
|
||||||
|
flex: 1;
|
||||||
|
padding: 12px;
|
||||||
|
border: 2px solid #e5e7eb;
|
||||||
|
border-radius: 10px;
|
||||||
|
background: white;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 8px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #6b7280;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.social-btn:hover {
|
||||||
|
border-color: #667eea;
|
||||||
|
background: #f9fafb;
|
||||||
|
transform: translateY(-2px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.social-btn svg {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<!-- 装饰背景 -->
|
||||||
|
<div class="bg-decoration"></div>
|
||||||
|
<div class="bg-decoration"></div>
|
||||||
|
<div class="bg-decoration"></div>
|
||||||
|
|
||||||
|
<div class="login-card">
|
||||||
|
<div class="login-title">
|
||||||
|
<h1>欢迎注册</h1>
|
||||||
|
<p>请创建您的账号信息</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form action="users.php" method="POST">
|
||||||
|
<!-- GET提交方式,所有的信息都在网址中 -->
|
||||||
|
<!-- POST提交方式,所有的信息都在请求体中 -->
|
||||||
|
<div class="input-group">
|
||||||
|
<input type="text" placeholder="用户名" name="username" required>
|
||||||
|
<span class="input-icon">👤</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="input-group">
|
||||||
|
<input type="text" placeholder="密码" name="password" required>
|
||||||
|
<span class="input-icon">🔒</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="input-group">
|
||||||
|
<input type="text" placeholder="确认密码" name="password2" required>
|
||||||
|
<span class="input-icon">🔒</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="input-group">
|
||||||
|
<input type="text" placeholder="邮箱" name="email" required>
|
||||||
|
<span class="input-icon">📧</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input type="submit" class="login-btn" value="注 册" name="register">
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div class="signup-link">
|
||||||
|
已有账号?<a href="login.php">立即登录</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
29
课堂代码/01-blog开发/v3/test.php
Normal file
29
课堂代码/01-blog开发/v3/test.php
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
// 字符集设置为utf-8
|
||||||
|
header("Content-Type: text/html; charset=UTF-8");
|
||||||
|
|
||||||
|
// 连接mysql数据库
|
||||||
|
$host = "127.0.0.1";
|
||||||
|
$dbname = "root";
|
||||||
|
$dbpassword = "usbw";
|
||||||
|
$database = "blog";
|
||||||
|
$port = 3307;
|
||||||
|
$conn = mysqli_connect($host, $dbname, $dbpassword, $database, $port);
|
||||||
|
if (!$conn) {
|
||||||
|
echo "连接失败";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取users表中的所有数据
|
||||||
|
$sql = "select * from users";
|
||||||
|
$result = mysqli_query($conn, $sql);
|
||||||
|
if (!$result) {
|
||||||
|
echo "查询失败";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将查询的数据一行行输出
|
||||||
|
// mysqli_fetch_assoc函数是将查询的数据以关联数组的形式返回,数组的key是字段名,value是字段值
|
||||||
|
while ($row = mysqli_fetch_assoc($result)) {
|
||||||
|
echo "<p>" . $row["username"] . ":" . $row["email"] . ":" . $row["password"] . "</p>";
|
||||||
|
}
|
||||||
54
课堂代码/01-blog开发/v3/user_add.php
Normal file
54
课堂代码/01-blog开发/v3/user_add.php
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
$pageTitle = '网站后台管理 - 用户添加';
|
||||||
|
$page = 'users';
|
||||||
|
include("header.php");
|
||||||
|
?>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
// 根据传递的id,获取表中的各个信息
|
||||||
|
// 连接mysql数据库
|
||||||
|
include("db.php");
|
||||||
|
|
||||||
|
$userid = $_REQUEST["id"];
|
||||||
|
$sql = "select * from users where id='$userid'";
|
||||||
|
$result = mysqli_query($conn, $sql);
|
||||||
|
$user = mysqli_fetch_assoc($result);
|
||||||
|
?>
|
||||||
|
|
||||||
|
<main class="main-content">
|
||||||
|
<div class="page-header">
|
||||||
|
<h2>添加用户</h2>
|
||||||
|
<p>添加用户信息</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-card form-card-sm">
|
||||||
|
<form action="users.php" method="post">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="username">用户名</label>
|
||||||
|
<input type="text" id="username" name="username" placeholder="请输入用户名" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="password">密码</label>
|
||||||
|
<input type="password" id="password" name="password" placeholder="请输入新密码" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="password2">确认密码</label>
|
||||||
|
<input type="password" id="password2" name="password2" placeholder="请再次输入新密码" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="email">邮箱</label>
|
||||||
|
<input type="email" id="email" name="email" placeholder="请输入邮箱地址" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="btn-group">
|
||||||
|
<input type="submit" class="btn btn-primary" value="添加" name="add">
|
||||||
|
<a href="users_list.php" class="btn btn-secondary">取消</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
136
课堂代码/01-blog开发/v3/user_avatar.php
Normal file
136
课堂代码/01-blog开发/v3/user_avatar.php
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
<?php
|
||||||
|
$pageTitle = '网站后台管理 - 头像修改';
|
||||||
|
$page = 'users';
|
||||||
|
include("header.php");
|
||||||
|
?>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
include("db.php");
|
||||||
|
if (count($_FILES) > 0) {
|
||||||
|
// php传图片会默认放在临时目录下,在程序执行结束后就会自动删除
|
||||||
|
// php上传图片,本质上就是从临时目录中将文件及时移动到指定目录下
|
||||||
|
// 先获取图片的格式
|
||||||
|
$ext = pathinfo($_FILES["avatar"]["name"], PATHINFO_EXTENSION);
|
||||||
|
$img_path = "images/avatar/" . date("YmdHis") . mt_rand(10000, 99999) . "." . $ext;
|
||||||
|
move_uploaded_file($_FILES["avatar"]["tmp_name"], $img_path);
|
||||||
|
|
||||||
|
// 写入数据库中
|
||||||
|
$id = $_GET["id"];
|
||||||
|
$sql = "UPDATE users SET avatar = '$img_path' WHERE id = $id";
|
||||||
|
if (mysqli_query($conn, $sql) === TRUE) {
|
||||||
|
echo "<script>alert('头像修改成功');location.href='users_list.php'</script>";
|
||||||
|
} else {
|
||||||
|
echo "Error: " . $sql . "<br>" . $conn->error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 获取当前的头像
|
||||||
|
$sql = "select * from users where id = '" . $_GET["id"] . "'";
|
||||||
|
$result = mysqli_query($conn, $sql);
|
||||||
|
$row = mysqli_fetch_assoc($result);
|
||||||
|
$avatar = $row["avatar"];
|
||||||
|
?>
|
||||||
|
|
||||||
|
<main class="main-content">
|
||||||
|
<div class="page-header page-header-bar">
|
||||||
|
<div>
|
||||||
|
<h2>头像修改</h2>
|
||||||
|
<p>更新用户头像</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-card">
|
||||||
|
<div class="avatar-preview">
|
||||||
|
<div class="avatar-current">
|
||||||
|
<p class="avatar-label">当前头像</p>
|
||||||
|
<div class="avatar-img-wrap">
|
||||||
|
<?php if ($avatar): ?>
|
||||||
|
<img src="<?php echo $avatar; ?>" alt="当前头像">
|
||||||
|
<?php else: ?>
|
||||||
|
<div class="avatar-placeholder">👤</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form action="" method="post" enctype="multipart/form-data">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="avatar">上传新头像</label>
|
||||||
|
<div class="file-upload-wrap">
|
||||||
|
<input type="file" name="avatar" id="avatar" accept="image/*" required>
|
||||||
|
</div>
|
||||||
|
<p class="form-hint">支持 JPG、PNG、GIF 格式,文件大小不超过 2MB</p>
|
||||||
|
</div>
|
||||||
|
<div class="btn-group">
|
||||||
|
<button type="submit" class="btn btn-primary">
|
||||||
|
<span>💾</span>
|
||||||
|
<span>上传头像</span>
|
||||||
|
</button>
|
||||||
|
<a href="users_list.php" class="btn btn-secondary">取消</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.avatar-preview {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin-bottom: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-current {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-label {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #6b7280;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-img-wrap {
|
||||||
|
width: 120px;
|
||||||
|
height: 120px;
|
||||||
|
border-radius: 50%;
|
||||||
|
overflow: hidden;
|
||||||
|
border: 3px solid #e5e7eb;
|
||||||
|
background: #f9fafb;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin: 0 auto;
|
||||||
|
transition: border-color 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-img-wrap:hover {
|
||||||
|
border-color: #3b82f6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-img-wrap img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-placeholder {
|
||||||
|
font-size: 48px;
|
||||||
|
color: #9ca3af;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-upload-wrap input[type="file"] {
|
||||||
|
padding: 10px 16px;
|
||||||
|
background: #f9fafb;
|
||||||
|
border: 2px dashed #d1d5db;
|
||||||
|
border-radius: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-upload-wrap input[type="file"]:hover {
|
||||||
|
border-color: #3b82f6;
|
||||||
|
background: #eff6ff;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
56
课堂代码/01-blog开发/v3/user_edit.php
Normal file
56
课堂代码/01-blog开发/v3/user_edit.php
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
<?php
|
||||||
|
$pageTitle = '网站后台管理 - 用户编辑';
|
||||||
|
$page = 'users';
|
||||||
|
include("header.php");
|
||||||
|
?>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
// 根据传递的id,获取表中的各个信息
|
||||||
|
// 连接mysql数据库
|
||||||
|
include("db.php");
|
||||||
|
|
||||||
|
$userid = $_REQUEST["id"];
|
||||||
|
$sql = "select * from users where id='$userid'";
|
||||||
|
$result = mysqli_query($conn, $sql);
|
||||||
|
$user = mysqli_fetch_assoc($result);
|
||||||
|
?>
|
||||||
|
|
||||||
|
<main class="main-content">
|
||||||
|
<div class="page-header">
|
||||||
|
<h2>编辑用户</h2>
|
||||||
|
<p>修改用户信息</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-card form-card-sm">
|
||||||
|
<form action="users.php" method="post">
|
||||||
|
<input type="hidden" value="<?php echo $user["id"]; ?>" name="id">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="username">用户名</label>
|
||||||
|
<input type="text" id="username" name="username" placeholder="请输入用户名" value="<?php echo $user["username"]; ?>">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="password">密码</label>
|
||||||
|
<input type="password" id="password" name="password" placeholder="请输入新密码">
|
||||||
|
<p class="form-hint">密码留空则不修改</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="password2">确认密码</label>
|
||||||
|
<input type="password" id="password2" name="password2" placeholder="请再次输入新密码">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="email">邮箱</label>
|
||||||
|
<input type="email" id="email" name="email" placeholder="请输入邮箱地址" value="<?php echo $user["email"]; ?>">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="btn-group">
|
||||||
|
<input type="submit" class="btn btn-primary" value="保存" name="change">
|
||||||
|
<a href="users_list.php" class="btn btn-secondary">取消</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
116
课堂代码/01-blog开发/v3/users.php
Normal file
116
课堂代码/01-blog开发/v3/users.php
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
<?php
|
||||||
|
// 处理用户登录、注册、修改、退出、删除相关的代码
|
||||||
|
// 设置页面的字符编码为UTF-8
|
||||||
|
header("Content-Type: text/html; charset=UTF-8");
|
||||||
|
|
||||||
|
// 连接mysql数据库
|
||||||
|
// include函数相当于将db.php文件中的代码复制到这里,就不用在每个页面中都写一遍了
|
||||||
|
include("db.php");
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
// 先判断$_REQUEST中是否存在'login'或'register'参数,如果存在,则执行对应的操作,否则返回错误信息
|
||||||
|
// isset 判断变量是否存在
|
||||||
|
if (isset($_REQUEST["login"])) {
|
||||||
|
// 从前端接受用户名和密码,并且去数据库中验证
|
||||||
|
$username = $_REQUEST["username"];
|
||||||
|
$password = $_REQUEST["password"];
|
||||||
|
|
||||||
|
// 写sql语句
|
||||||
|
$sql = "select * from users where username='$username' and password='$password'";
|
||||||
|
$result = mysqli_query($conn, $sql);
|
||||||
|
|
||||||
|
if (mysqli_num_rows($result) > 0) {
|
||||||
|
$_SESSION["username"] = $username;
|
||||||
|
echo "<script>alert('登录成功');location.href='main.php'</script>";
|
||||||
|
} else {
|
||||||
|
echo "<script>alert('登录失败');location.href='login.php'</script>";
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (isset($_REQUEST["register"]) or isset( $_REQUEST["add"])) {
|
||||||
|
// 从前端获取用户名,以及两次密码输入,以及邮箱
|
||||||
|
$username = $_REQUEST["username"];
|
||||||
|
$password = $_REQUEST["password"];
|
||||||
|
$password2 = $_REQUEST["password2"];
|
||||||
|
$email = $_REQUEST["email"];
|
||||||
|
|
||||||
|
// 判断两次密码是否一致
|
||||||
|
if ($password != $password2) {
|
||||||
|
echo "两次密码不一致";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断用户名或邮箱是否已存在
|
||||||
|
$sql = "select * from users where username='$username' or email='$email'";
|
||||||
|
$result = mysqli_query($conn, $sql);
|
||||||
|
if (mysqli_num_rows($result) > 0) {
|
||||||
|
echo "用户名或邮箱已存在";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 写sql语句,插入一条新的用户记录
|
||||||
|
$sql = "insert into users(username, password, email) values('$username', '$password', '$email')";
|
||||||
|
$result = mysqli_query($conn, $sql);
|
||||||
|
|
||||||
|
// 插入成功后,返回注册成功信息
|
||||||
|
if ($result) {
|
||||||
|
if(isset($_REQUEST["add"])) {
|
||||||
|
echo "<script>alert('添加成功');location.href='users_list.php'</script>";
|
||||||
|
} else {
|
||||||
|
echo "<script>alert('注册成功');location.href='login.php'</script>";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(isset($_REQUEST["add"])) {
|
||||||
|
echo "<script>alert('添加失败');location.href='users_list.php'</script>";
|
||||||
|
} else {
|
||||||
|
echo "<script>alert('注册失败');location.href='login.php'</script>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (isset($_REQUEST["change"])) {
|
||||||
|
// 修改用户信息的操作
|
||||||
|
$userid = $_REQUEST["id"];
|
||||||
|
$username = $_REQUEST["username"];
|
||||||
|
$email = $_REQUEST["email"];
|
||||||
|
|
||||||
|
// 判断是否需要修改密码,判断密码的长度
|
||||||
|
if (strlen($_REQUEST["password"]) > 0) {
|
||||||
|
$password = $_REQUEST["password"];
|
||||||
|
$password2 = $_REQUEST["password2"];
|
||||||
|
if ($password != $password2) {
|
||||||
|
echo "<script>alert('两次密码不一致');location.href='users_list.php'</script>";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
// 更新用户名,密码,邮箱
|
||||||
|
// 存在逻辑漏洞,没有判断用户名是否存在,可以修改别人的用户名
|
||||||
|
$sql = "update users set username='$username', password='$password', email='$email' where id='$userid'";
|
||||||
|
$result = mysqli_query($conn, $sql);
|
||||||
|
if ($result) {
|
||||||
|
echo "<script>alert('修改成功');location.href='users_list.php'</script>";
|
||||||
|
} else {
|
||||||
|
echo "<script>alert('修改失败');location.href='users_list.php'</script>";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 更新用户名和邮箱
|
||||||
|
$sql = "update users set username='$username', email='$email' where id='$userid'";
|
||||||
|
$result = mysqli_query($conn, $sql);
|
||||||
|
if ($result) {
|
||||||
|
echo "<script>alert('修改成功');location.href='users_list.php'</script>";
|
||||||
|
} else {
|
||||||
|
echo "<script>alert('修改失败');location.href='users_list.php'</script>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (isset($_REQUEST["del"])) {
|
||||||
|
// 删除用户
|
||||||
|
$userid = $_REQUEST["id"];
|
||||||
|
$sql = "delete from users where id='$userid'";
|
||||||
|
$result = mysqli_query($conn, $sql);
|
||||||
|
if ($result) {
|
||||||
|
echo "<script>alert('删除成功');location.href='users_list.php'</script>";
|
||||||
|
} else {
|
||||||
|
echo "<script>alert('删除失败');location.href='users_list.php'</script>";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
echo "错误操作";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
?>
|
||||||
181
课堂代码/01-blog开发/v3/users_list.php
Normal file
181
课堂代码/01-blog开发/v3/users_list.php
Normal file
@@ -0,0 +1,181 @@
|
|||||||
|
<?php
|
||||||
|
$pageTitle = '网站后台管理 - 用户列表';
|
||||||
|
$page = 'users';
|
||||||
|
include("header.php");
|
||||||
|
?>
|
||||||
|
|
||||||
|
<main class="main-content">
|
||||||
|
<div class="page-header page-header-bar">
|
||||||
|
<div>
|
||||||
|
<h2>用户管理</h2>
|
||||||
|
<p>管理系统用户账号</p>
|
||||||
|
</div>
|
||||||
|
<a href="user_add.php" class="btn-add">
|
||||||
|
<span>+</span>
|
||||||
|
<span>添加用户</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="table-container">
|
||||||
|
<table class="users-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>ID</th>
|
||||||
|
<th>用户名</th>
|
||||||
|
<th>密码</th>
|
||||||
|
<th>邮箱</th>
|
||||||
|
<th>操作</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php
|
||||||
|
// 连接mysql数据库
|
||||||
|
include("db.php");
|
||||||
|
|
||||||
|
// 获取users表中的所有数据
|
||||||
|
$sql = "select * from users";
|
||||||
|
$result = mysqli_query($conn, $sql);
|
||||||
|
if (!$result) {
|
||||||
|
echo "查询失败";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将查询的数据一行行输出
|
||||||
|
// mysqli_fetch_assoc函数是将查询的数据以关联数组的形式返回,数组的key是字段名,value是字段值
|
||||||
|
while ($row = mysqli_fetch_assoc($result)) {
|
||||||
|
?>
|
||||||
|
<tr>
|
||||||
|
<td><?php echo $row["id"];?></td>
|
||||||
|
<td>
|
||||||
|
<span class="username-tooltip">
|
||||||
|
<?php echo $row["username"];?>
|
||||||
|
<span class="tooltip-content">
|
||||||
|
<?php if ($row["avatar"]): ?>
|
||||||
|
<img src="<?php echo $row["avatar"];?>" alt="头像">
|
||||||
|
<?php else: ?>
|
||||||
|
<div class="tooltip-avatar-placeholder">👤</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td><span class="password-masked"><?php echo $row["password"];?></span></td>
|
||||||
|
<td><?php echo $row["email"];?></td>
|
||||||
|
<td>
|
||||||
|
<div class="action-btns">
|
||||||
|
<a href="user_edit.php?id=<?php echo $row["id"];?>" class="btn btn-edit">✏️ 编辑</a>
|
||||||
|
<a href="users.php?del&id=<?php echo $row["id"];?>" class="btn btn-delete"
|
||||||
|
onclick="return confirm('确定要删除该用户吗?')">🗑️ 删除</a>
|
||||||
|
<a href="user_avatar.php?id=<?php echo $row["id"];?>" class="btn btn-edit">👤 修改头像</a>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.username-tooltip {
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
color: #3b82f6;
|
||||||
|
font-weight: 500;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.users-table td:nth-child(2) {
|
||||||
|
position: relative;
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-container {
|
||||||
|
overflow: visible !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.users-table {
|
||||||
|
overflow: visible !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.username-tooltip:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip-content {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
bottom: calc(100% + 10px);
|
||||||
|
transform: translateX(-50%);
|
||||||
|
background: #ffffff;
|
||||||
|
border: 1px solid #e5e7eb;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 8px;
|
||||||
|
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
|
||||||
|
z-index: 9999;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip-content::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
bottom: -6px;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
border-left: 6px solid transparent;
|
||||||
|
border-right: 6px solid transparent;
|
||||||
|
border-top: 6px solid #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip-content::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
bottom: -7px;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
border-left: 6px solid transparent;
|
||||||
|
border-right: 6px solid transparent;
|
||||||
|
border-top: 6px solid #e5e7eb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.username-tooltip:hover .tooltip-content {
|
||||||
|
display: block;
|
||||||
|
animation: tooltipFadeIn 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip-content img {
|
||||||
|
width: 80px;
|
||||||
|
height: 80px;
|
||||||
|
border-radius: 50%;
|
||||||
|
object-fit: cover;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip-avatar-placeholder {
|
||||||
|
width: 80px;
|
||||||
|
height: 80px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: #f3f4f6;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 36px;
|
||||||
|
color: #9ca3af;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes tooltipFadeIn {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateX(-50%) translateY(4px);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateX(-50%) translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user