443 lines
24 KiB
PHP
443 lines
24 KiB
PHP
|
|
<?php
|
|||
|
|
// 音乐上传功能(已登录用户自动识别)
|
|||
|
|
require_once 'db_config.php';
|
|||
|
|
|
|||
|
|
$message = '';
|
|||
|
|
$message_type = '';
|
|||
|
|
|
|||
|
|
// 启动会话以检查登录状态
|
|||
|
|
session_start();
|
|||
|
|
|
|||
|
|
// 音乐分类映射
|
|||
|
|
$categories = [
|
|||
|
|
'cantonese' => '粤语歌曲',
|
|||
|
|
'mandarin' => '国语歌曲',
|
|||
|
|
'waiyu' => '外语歌曲',
|
|||
|
|
'classic' => '经典老歌',
|
|||
|
|
'other' => '其他音乐'
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
// 检查用户是否登录
|
|||
|
|
$isLoggedIn = isset($_SESSION['user_logged_in']) && $_SESSION['user_logged_in'] === true;
|
|||
|
|
$uploaderName = $isLoggedIn ? $_SESSION['user_info']['username'] : '匿名用户';
|
|||
|
|
|
|||
|
|
// 处理上传
|
|||
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['upload_music'])) {
|
|||
|
|
// 验证表单数据
|
|||
|
|
$title = trim($_POST['title'] ?? '');
|
|||
|
|
$artist = trim($_POST['artist'] ?? '');
|
|||
|
|
// 如果用户已登录,强制使用会话中的用户名,忽略表单提交的值
|
|||
|
|
$uploader = $isLoggedIn ? $_SESSION['user_info']['username'] : trim($_POST['uploader'] ?? '匿名用户');
|
|||
|
|
$category = $_POST['category'] ?? 'other';
|
|||
|
|
$description = trim($_POST['description'] ?? '');
|
|||
|
|
$bvid = trim($_POST['bvid'] ?? '');
|
|||
|
|
$duration = trim($_POST['duration'] ?? '');
|
|||
|
|
|
|||
|
|
// 验证时长格式
|
|||
|
|
if (!empty($duration) && !preg_match('/^\d+:\d{2}$/', $duration)) {
|
|||
|
|
$message = "时长格式不正确,请使用 MM:SS 格式(例如 3:45 表示3分45秒)";
|
|||
|
|
$message_type = "error";
|
|||
|
|
} elseif (empty($title) || empty($artist)) {
|
|||
|
|
$message = "歌曲名和歌手名不能为空";
|
|||
|
|
$message_type = "error";
|
|||
|
|
} elseif (!isset($_FILES['audio_file']) || $_FILES['audio_file']['error'] !== UPLOAD_ERR_OK) {
|
|||
|
|
$message = "请选择要上传的音频文件";
|
|||
|
|
$message_type = "error";
|
|||
|
|
} else {
|
|||
|
|
// 验证BV号格式
|
|||
|
|
if (!empty($bvid) && !preg_match('/^BV[0-9A-Za-z]+$/', $bvid)) {
|
|||
|
|
$message = "BV号格式不正确,应为以BV开头的字符串(如BV1Va4y1n7HN)";
|
|||
|
|
$message_type = "error";
|
|||
|
|
} else {
|
|||
|
|
// 处理文件上传
|
|||
|
|
$upload_dir = 'uploads/';
|
|||
|
|
if (!is_dir($upload_dir)) {
|
|||
|
|
mkdir($upload_dir, 0755, true);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
$file_ext = pathinfo($_FILES['audio_file']['name'], PATHINFO_EXTENSION);
|
|||
|
|
$allowed_ext = ['mp3', 'wav', 'flac', 'm4a'];
|
|||
|
|
|
|||
|
|
if (!in_array(strtolower($file_ext), $allowed_ext)) {
|
|||
|
|
$message = "不支持的文件格式,仅支持mp3, wav, flac, m4a";
|
|||
|
|
$message_type = "error";
|
|||
|
|
} else {
|
|||
|
|
// 检查文件大小(限制30MB)
|
|||
|
|
$max_file_size = 30 * 1024 * 1024; // 30MB
|
|||
|
|
if ($_FILES['audio_file']['size'] > $max_file_size) {
|
|||
|
|
$message = "文件大小超过限制(30MB)";
|
|||
|
|
$message_type = "error";
|
|||
|
|
} else {
|
|||
|
|
// 生成唯一文件名
|
|||
|
|
$file_name = uniqid('music_') . '.' . $file_ext;
|
|||
|
|
$target_path = $upload_dir . $file_name;
|
|||
|
|
|
|||
|
|
if (move_uploaded_file($_FILES['audio_file']['tmp_name'], $target_path)) {
|
|||
|
|
// 使用用户输入的时长,如果为空则使用默认值
|
|||
|
|
$final_duration = !empty($duration) ? $duration : "0:00";
|
|||
|
|
|
|||
|
|
// 保存到待审核表
|
|||
|
|
try {
|
|||
|
|
$stmt = $conn->prepare("INSERT INTO pending_music
|
|||
|
|
(uploader_name, title, artist, category, description, file_path, duration, upload_time, bvid)
|
|||
|
|
VALUES (?, ?, ?, ?, ?, ?, ?, NOW(), ?)");
|
|||
|
|
$stmt->execute([$uploader, $title, $artist, $category, $description, $target_path, $final_duration, $bvid]);
|
|||
|
|
|
|||
|
|
$message = "上传成功,已进入待审核队列,感谢您的分享!";
|
|||
|
|
$message_type = "success";
|
|||
|
|
// 清空表单
|
|||
|
|
$_POST = [];
|
|||
|
|
} catch (PDOException $e) {
|
|||
|
|
$message = "数据库错误: " . $e->getMessage();
|
|||
|
|
$message_type = "error";
|
|||
|
|
unlink($target_path); // 数据库错误时删除已上传文件
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
$message = "文件上传失败";
|
|||
|
|
$message_type = "error";
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
?>
|
|||
|
|
<!DOCTYPE html>
|
|||
|
|
<html lang="zh-CN">
|
|||
|
|
<head>
|
|||
|
|
<meta charset="UTF-8">
|
|||
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|||
|
|
<title>上传音乐 - 音乐分享平台</title>
|
|||
|
|
<link rel="icon" href="./static/icon/icon.png" type="image/png">
|
|||
|
|
<link rel="alternate icon" href="./static/icon/icon.ico" type="image/x-icon">
|
|||
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
|||
|
|
<style>
|
|||
|
|
@font-face {
|
|||
|
|
font-family: "MyCustomFont";
|
|||
|
|
src: url("./static/font/bbc.ttf") format("truetype");
|
|||
|
|
font-weight: normal;
|
|||
|
|
font-style: normal;
|
|||
|
|
}
|
|||
|
|
/* === 全局变量定义 === */
|
|||
|
|
:root {
|
|||
|
|
--primary-color: #2c3e50;
|
|||
|
|
--primary-hover: #34495e;
|
|||
|
|
--accent-color: #e74c3c;
|
|||
|
|
--bg-color: #f7f9fc;
|
|||
|
|
--text-color: #333;
|
|||
|
|
--muted-color: #7f8c8d;
|
|||
|
|
--card-bg: #ffffff;
|
|||
|
|
--card-shadow: 0 4px 12px rgba(0,0,0,0.08);
|
|||
|
|
--border-color: #dcdfe6;
|
|||
|
|
--main-font: "MyCustomFont", sans-serif; /* 自定义字体变量 */
|
|||
|
|
}
|
|||
|
|
body {
|
|||
|
|
font-family: var(--main-font);
|
|||
|
|
margin: 0;
|
|||
|
|
padding: 0;
|
|||
|
|
background-color: var(--bg-color);
|
|||
|
|
color: var(--text-color);
|
|||
|
|
transition: background-color 0.3s ease, color 0.3s ease;
|
|||
|
|
}
|
|||
|
|
h1, h2, h3 { color: var(--primary-color); }
|
|||
|
|
h1 { font-size: 1.8rem; text-align: center; margin: 1rem 0; }
|
|||
|
|
h2 { font-size: 1.4rem; margin-bottom: 0.5rem; }
|
|||
|
|
.desktop .app-container { display: flex; min-height: 100vh; }
|
|||
|
|
.desktop .main-wrapper { flex: 1; display: flex; flex-direction: column; margin-left: 280px; }
|
|||
|
|
.desktop .main-content { flex: 1; max-width: 1200px; width: 100%; margin: 0 auto; padding: 1rem; box-sizing: border-box; }
|
|||
|
|
.mobile .app-container { display: block; min-height: 100vh; }
|
|||
|
|
.mobile .main-wrapper { margin-left: 0; }
|
|||
|
|
.mobile .main-content { width: 100%; padding: 0.5rem; box-sizing: border-box; }
|
|||
|
|
.top-bar {
|
|||
|
|
display: flex; justify-content: space-between; align-items: center;
|
|||
|
|
padding: 1rem 1.5rem; background-color: var(--card-bg);
|
|||
|
|
box-shadow: 0 2px 8px rgba(0,0,0,0.1); position: sticky; top: 0; z-index: 100;
|
|||
|
|
}
|
|||
|
|
.site-title { margin: 0; font-size: 1.4rem; color: var(--primary-color); }
|
|||
|
|
.theme-toggle, .user-menu-btn {
|
|||
|
|
background: none; border: 1px solid var(--border-color); color: var(--text-color);
|
|||
|
|
padding: 0.5rem 0.8rem; border-radius: 20px; cursor: pointer;
|
|||
|
|
display: flex; align-items: center; gap: 0.5rem; transition: all 0.3s ease; text-decoration: none;
|
|||
|
|
}
|
|||
|
|
.theme-toggle:hover, .user-menu-btn:hover { background-color: var(--primary-color); color: white; border-color: var(--primary-color); }
|
|||
|
|
.form-group { margin-bottom: 1.2rem; text-align: left; }
|
|||
|
|
.form-group label { display: block; margin-bottom: 0.5rem; color: var(--primary-color); font-weight: 500; }
|
|||
|
|
.form-group.required label::after { content: " *"; color: var(--accent-color); }
|
|||
|
|
.form-control {
|
|||
|
|
width: 100%; padding: 0.8rem; border: 1px solid var(--border-color);
|
|||
|
|
border-radius: 8px; font-size: 1rem; box-sizing: border-box;
|
|||
|
|
background-color: var(--bg-color); color: var(--text-color);
|
|||
|
|
transition: border-color 0.3s ease, box-shadow 0.3s ease;
|
|||
|
|
}
|
|||
|
|
.form-control:read-only { background-color: #e9ecef; cursor: not-allowed; color: #495057; }
|
|||
|
|
.form-control:focus { outline: none; border-color: var(--primary-color); box-shadow: 0 0 0 2px rgba(44, 62, 80, 0.1); }
|
|||
|
|
.error-input { border-color: var(--accent-color) !important; box-shadow: 0 0 0 2px rgba(231, 76, 60, 0.1) !important; }
|
|||
|
|
.submit-btn {
|
|||
|
|
background-color: var(--primary-color); color: white; border: none;
|
|||
|
|
padding: 0.8rem 2rem; border-radius: 25px; font-size: 1rem; cursor: pointer;
|
|||
|
|
transition: background-color 0.3s ease, transform 0.1s ease; width: 100%;
|
|||
|
|
box-sizing: border-box; display: flex; align-items: center; justify-content: center; gap: 0.5rem;
|
|||
|
|
}
|
|||
|
|
.submit-btn:hover { background-color: var(--primary-hover); }
|
|||
|
|
.submit-btn:active { transform: translateY(2px); }
|
|||
|
|
.file-info { margin-top: 0.5rem; font-size: 0.85rem; color: var(--muted-color); }
|
|||
|
|
.field-hint { margin-top: 0.3rem; font-size: 0.8rem; color: var(--muted-color); font-style: italic; }
|
|||
|
|
.message { padding: 1rem; border-radius: 8px; margin-bottom: 1rem; text-align: center; font-size: 0.95rem; transition: opacity 0.3s ease, transform 0.3s ease; }
|
|||
|
|
.success { background-color: #d4edda; color: #155724; }
|
|||
|
|
.error { background-color: #f8d7da; color: #721c24; }
|
|||
|
|
.music-item { background-color: var(--card-bg); border-radius: 12px; padding: 1.2rem; box-shadow: var(--card-shadow); margin-bottom: 1.2rem; }
|
|||
|
|
.artist-info { color: var(--muted-color); font-size: 0.9rem; margin-bottom: 1rem; }
|
|||
|
|
.back-to-top {
|
|||
|
|
position: fixed; bottom: 30px; right: 30px; width: 50px; height: 50px;
|
|||
|
|
background-color: var(--primary-color); color: white; border-radius: 50%;
|
|||
|
|
display: flex; align-items: center; justify-content: center; font-size: 1.5rem;
|
|||
|
|
box-shadow: 0 4px 12px rgba(0,0,0,0.2); cursor: pointer;
|
|||
|
|
opacity: 0; visibility: hidden; transition: all 0.3s ease; z-index: 999;
|
|||
|
|
}
|
|||
|
|
.back-to-top.show { opacity: 1; visibility: visible; }
|
|||
|
|
.back-to-top:hover { background-color: var(--primary-hover); transform: translateY(-5px); }
|
|||
|
|
</style>
|
|||
|
|
</head>
|
|||
|
|
<body>
|
|||
|
|
<div class="app-container">
|
|||
|
|
<div class="main-wrapper">
|
|||
|
|
<header class="top-bar">
|
|||
|
|
<h1 class="site-title">
|
|||
|
|
<img src="./static/icon/icon.png" alt="音乐图标" style="width: 24px; height: 24px; vertical-align: middle; margin-right: 8px;">
|
|||
|
|
<a href="./index.php" style="text-decoration: none; color: inherit;">音乐分享平台</a>
|
|||
|
|
</h1>
|
|||
|
|
<?php if ($isLoggedIn): ?>
|
|||
|
|
<a href="user_center.php" class="user-menu-btn"><i class="fas fa-user"></i> <?php echo htmlspecialchars($uploaderName); ?></a>
|
|||
|
|
<?php else: ?>
|
|||
|
|
<a href="login.php" class="user-menu-btn"><i class="fas fa-sign-in-alt"></i> 登录</a>
|
|||
|
|
<?php endif; ?>
|
|||
|
|
</header>
|
|||
|
|
<main class="main-content">
|
|||
|
|
<div class="music-item">
|
|||
|
|
<h2><i class="fas fa-cloud-upload-alt"></i> 上传音乐</h2>
|
|||
|
|
<p class="artist-info">
|
|||
|
|
<?php if ($isLoggedIn): ?>
|
|||
|
|
您好,<strong><?php echo htmlspecialchars($uploaderName); ?></strong>。您已登录,上传将自动记录您的昵称。
|
|||
|
|
<?php else: ?>
|
|||
|
|
您当前未登录,上传后将以“匿名用户”身份显示。<a href="login.php" style="color: var(--primary-color);">登录</a>后可获得更完整的服务。
|
|||
|
|
<?php endif; ?>
|
|||
|
|
</p>
|
|||
|
|
|
|||
|
|
<?php if ($message): ?>
|
|||
|
|
<div class="message <?php echo $message_type; ?>"><?php echo htmlspecialchars($message); ?></div>
|
|||
|
|
<?php endif; ?>
|
|||
|
|
|
|||
|
|
<form id="upload-form" method="post" enctype="multipart/form-data">
|
|||
|
|
<div class="form-group">
|
|||
|
|
<label for="uploader">您的昵称</label>
|
|||
|
|
<input type="text" id="uploader" name="uploader" class="form-control"
|
|||
|
|
value="<?php echo htmlspecialchars($isLoggedIn ? $uploaderName : ($_POST['uploader'] ?? '匿名用户')); ?>"
|
|||
|
|
<?php echo $isLoggedIn ? 'readonly' : ''; ?>>
|
|||
|
|
<?php if ($isLoggedIn): ?>
|
|||
|
|
<div class="field-hint">已为您自动填充昵称,该字段不可修改。</div>
|
|||
|
|
<?php else: ?>
|
|||
|
|
<div class="field-hint">未登录状态下,默认为“匿名用户”。</div>
|
|||
|
|
<?php endif; ?>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="form-group required">
|
|||
|
|
<label for="title">歌曲名称</label>
|
|||
|
|
<input type="text" id="title" name="title" class="form-control" value="<?php echo htmlspecialchars($_POST['title'] ?? ''); ?>" required>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="form-group required">
|
|||
|
|
<label for="artist">歌手/乐队</label>
|
|||
|
|
<input type="text" id="artist" name="artist" class="form-control" value="<?php echo htmlspecialchars($_POST['artist'] ?? ''); ?>" required>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="form-group required">
|
|||
|
|
<label for="category">音乐分类</label>
|
|||
|
|
<select id="category" name="category" class="form-control" required>
|
|||
|
|
<?php foreach ($categories as $key => $name): ?>
|
|||
|
|
<option value="<?php echo $key; ?>" <?php echo (($_POST['category'] ?? '') == $key) ? 'selected' : ''; ?>>
|
|||
|
|
<?php echo $name; ?>
|
|||
|
|
</option>
|
|||
|
|
<?php endforeach; ?>
|
|||
|
|
</select>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="form-group required">
|
|||
|
|
<label for="duration">音频时长</label>
|
|||
|
|
<input type="text" id="duration" name="duration" class="form-control"
|
|||
|
|
value="<?php echo htmlspecialchars($_POST['duration'] ?? ''); ?>"
|
|||
|
|
placeholder="请输入时长,格式为 MM:SS(例如 3:45 表示3分45秒)" required>
|
|||
|
|
<div class="field-hint">请按照实际时长填写,格式为 分钟:秒数(例如 4:30 表示4分30秒)</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="form-group">
|
|||
|
|
<label for="bvid">B站视频BV号 (可选)</label>
|
|||
|
|
<input type="text" id="bvid" name="bvid" class="form-control"
|
|||
|
|
value="<?php echo htmlspecialchars($_POST['bvid'] ?? ''); ?>"
|
|||
|
|
placeholder="例如: BV1Va4y1n7HN">
|
|||
|
|
<div class="field-hint">若该音乐来自B站视频,可填写对应的BV号(以BV开头),方便用户查看视频来源</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="form-group">
|
|||
|
|
<label for="description">歌曲描述 (可选)</label>
|
|||
|
|
<textarea id="description" name="description" class="form-control" rows="3"><?php echo htmlspecialchars($_POST['description'] ?? ''); ?></textarea>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="form-group required">
|
|||
|
|
<label for="audio_file">音频文件</label>
|
|||
|
|
<input type="file" id="audio_file" name="audio_file" class="form-control" accept="audio/*" required>
|
|||
|
|
<small class="file-info">支持格式:mp3, wav, flac, m4a,文件大小不超过30MB</small>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<button type="submit" name="upload_music" class="submit-btn">
|
|||
|
|
<i class="fas fa-upload"></i> 上传音乐
|
|||
|
|
</button>
|
|||
|
|
</form>
|
|||
|
|
</div>
|
|||
|
|
</main>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<script>
|
|||
|
|
// 检测设备类型并添加相应类名
|
|||
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|||
|
|
const isMobile = window.innerWidth < 768;
|
|||
|
|
document.body.classList.add(isMobile ? 'mobile' : 'desktop');
|
|||
|
|
|
|||
|
|
// 表单验证增强
|
|||
|
|
const uploadForm = document.getElementById('upload-form');
|
|||
|
|
if (uploadForm) {
|
|||
|
|
uploadForm.addEventListener('submit', function(e) {
|
|||
|
|
let isValid = true;
|
|||
|
|
const titleInput = document.getElementById('title');
|
|||
|
|
const artistInput = document.getElementById('artist');
|
|||
|
|
const durationInput = document.getElementById('duration');
|
|||
|
|
const bvidInput = document.getElementById('bvid');
|
|||
|
|
|
|||
|
|
// 清除之前的错误状态
|
|||
|
|
titleInput.classList.remove('error-input');
|
|||
|
|
artistInput.classList.remove('error-input');
|
|||
|
|
durationInput.classList.remove('error-input');
|
|||
|
|
bvidInput.classList.remove('error-input');
|
|||
|
|
|
|||
|
|
// 验证必填字段
|
|||
|
|
if (!titleInput.value.trim()) {
|
|||
|
|
titleInput.classList.add('error-input');
|
|||
|
|
isValid = false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!artistInput.value.trim()) {
|
|||
|
|
artistInput.classList.add('error-input');
|
|||
|
|
isValid = false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 验证时长格式
|
|||
|
|
if (durationInput.value.trim() && !/^\d+:\d{2}$/.test(durationInput.value.trim())) {
|
|||
|
|
durationInput.classList.add('error-input');
|
|||
|
|
isValid = false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 验证BV号格式(如果填写了)
|
|||
|
|
if (bvidInput.value.trim() && !/^BV[0-9A-Za-z]+$/.test(bvidInput.value.trim())) {
|
|||
|
|
bvidInput.classList.add('error-input');
|
|||
|
|
isValid = false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!isValid) {
|
|||
|
|
e.preventDefault();
|
|||
|
|
|
|||
|
|
// 清除已有的错误消息
|
|||
|
|
const existingErrors = document.querySelectorAll('.message.error');
|
|||
|
|
existingErrors.forEach(el => el.remove());
|
|||
|
|
|
|||
|
|
// 显示错误消息
|
|||
|
|
const errorMsg = document.createElement('div');
|
|||
|
|
errorMsg.className = 'message error';
|
|||
|
|
|
|||
|
|
if (durationInput.classList.contains('error-input')) {
|
|||
|
|
errorMsg.textContent = '时长格式不正确,请使用 MM:SS 格式(例如 3:45 表示3分45秒)';
|
|||
|
|
} else if (bvidInput.classList.contains('error-input')) {
|
|||
|
|
errorMsg.textContent = 'BV号格式不正确,应为以BV开头的字符串(如BV1Va4y1n7HN)';
|
|||
|
|
} else {
|
|||
|
|
errorMsg.textContent = '请填写所有必填字段';
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
errorMsg.style.marginBottom = '1rem';
|
|||
|
|
uploadForm.parentNode.insertBefore(errorMsg, uploadForm);
|
|||
|
|
|
|||
|
|
// 3秒后自动移除错误消息
|
|||
|
|
setTimeout(() => {
|
|||
|
|
errorMsg.style.opacity = '0';
|
|||
|
|
setTimeout(() => errorMsg.remove(), 300);
|
|||
|
|
}, 3000);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 文件选择预览(大小和名称)
|
|||
|
|
const fileInput = document.getElementById('audio_file');
|
|||
|
|
if (fileInput) {
|
|||
|
|
fileInput.addEventListener('change', function() {
|
|||
|
|
if (this.files && this.files[0]) {
|
|||
|
|
const fileInfo = document.querySelector('.file-info') || document.createElement('div');
|
|||
|
|
fileInfo.className = 'file-info';
|
|||
|
|
|
|||
|
|
// 格式化文件大小
|
|||
|
|
const fileSize = this.files[0].size;
|
|||
|
|
let sizeText;
|
|||
|
|
if (fileSize < 1024 * 1024) {
|
|||
|
|
sizeText = (fileSize / 1024).toFixed(2) + ' KB';
|
|||
|
|
} else {
|
|||
|
|
sizeText = (fileSize / (1024 * 1024)).toFixed(2) + ' MB';
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
fileInfo.innerHTML = `已选择: ${this.files[0].name} (${sizeText})`;
|
|||
|
|
|
|||
|
|
if (!document.querySelector('.file-info')) {
|
|||
|
|
this.parentNode.appendChild(fileInfo);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 回到顶部按钮功能
|
|||
|
|
const backToTopBtn = document.createElement('button');
|
|||
|
|
backToTopBtn.className = 'back-to-top';
|
|||
|
|
backToTopBtn.innerHTML = '<i class="fas fa-chevron-up"></i>';
|
|||
|
|
backToTopBtn.setAttribute('aria-label', '回到顶部');
|
|||
|
|
document.body.appendChild(backToTopBtn);
|
|||
|
|
|
|||
|
|
window.addEventListener('scroll', () => {
|
|||
|
|
if (window.scrollY > 300) {
|
|||
|
|
backToTopBtn.classList.add('show');
|
|||
|
|
} else {
|
|||
|
|
backToTopBtn.classList.remove('show');
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
backToTopBtn.addEventListener('click', () => {
|
|||
|
|
window.scrollTo({
|
|||
|
|
top: 0,
|
|||
|
|
behavior: 'smooth'
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 显示消息动画
|
|||
|
|
const messageEl = document.querySelector('.message');
|
|||
|
|
if (messageEl) {
|
|||
|
|
setTimeout(() => {
|
|||
|
|
messageEl.style.opacity = 1;
|
|||
|
|
}, 100);
|
|||
|
|
|
|||
|
|
// 成功消息5秒后自动消失
|
|||
|
|
if (messageEl.classList.contains('success')) {
|
|||
|
|
setTimeout(() => {
|
|||
|
|
messageEl.style.opacity = 0;
|
|||
|
|
setTimeout(() => messageEl.remove(), 300);
|
|||
|
|
}, 5000);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
</script>
|
|||
|
|
</body>
|
|||
|
|
</html>
|