706849ff7f
- 实现APK文件上传功能,包括版本验证和自动更新最新版本 - 添加访问令牌验证机制保障安全性 - 创建README文档说明项目结构和使用方法 - 添加图片资源和日志记录功能
217 lines
7.7 KiB
PHP
217 lines
7.7 KiB
PHP
<?php
|
|
|
|
// 生成随机16位访问字符串
|
|
$accessToken = substr(md5(uniqid(mt_rand(), true)), 0, 32);
|
|
$accessFile = 'access_token.txt';
|
|
|
|
// 检查或生成访问令牌
|
|
if (!file_exists($accessFile)) {
|
|
file_put_contents($accessFile, $accessToken);
|
|
} else {
|
|
$accessToken = trim(file_get_contents($accessFile));
|
|
}
|
|
|
|
// 验证访问令牌
|
|
if (!isset($_GET['token']) || $_GET['token'] !== $accessToken) {
|
|
die('无效访问令牌');
|
|
}
|
|
|
|
$message = '';
|
|
if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_FILES['apk'])) {
|
|
$targetDir = 'uploads/';
|
|
$apkFile = $_FILES['apk'];
|
|
$fileName = basename($apkFile['name']);
|
|
$targetPath = $targetDir . $fileName;
|
|
|
|
// 检查文件类型
|
|
$fileType = strtolower(pathinfo($targetPath, PATHINFO_EXTENSION));
|
|
if ($fileType != 'apk') {
|
|
$message = '只允许上传APK文件';
|
|
} else {
|
|
// 检查包名
|
|
$tempPath = $apkFile['tmp_name'];
|
|
$packageName = shell_exec("aapt dump badging \"$tempPath\" | grep package | awk -F\"'\" '{print $2}'");
|
|
$packageName = trim($packageName);
|
|
|
|
if ($packageName !== 'com.f8com.f8laike') {
|
|
$message = '非法的APK';
|
|
} else {
|
|
// 获取版本号
|
|
$versionInfo = shell_exec("aapt dump badging \"$tempPath\" | grep -E 'versionName|versionCode'");
|
|
$versionName = preg_match("/versionName='([^']*)'/", $versionInfo, $matches) ? $matches[1] : '';
|
|
$versionName = trim($versionName);
|
|
|
|
// 创建上传目录
|
|
if (!file_exists($targetDir)) {
|
|
mkdir($targetDir, 0755, true);
|
|
}
|
|
|
|
// 移动文件
|
|
if (move_uploaded_file($tempPath, $targetPath)) {
|
|
// 获取客户端IP
|
|
$ip = $_SERVER['HTTP_CLIENT_IP'] ??
|
|
$_SERVER['HTTP_X_FORWARDED_FOR'] ??
|
|
$_SERVER['REMOTE_ADDR'] ??
|
|
'unknown';
|
|
|
|
// 记录日志
|
|
$log = date('Y-m-d H:i:s') . " - IP: $ip, 上传文件: $fileName, 版本号: $versionName\n";
|
|
file_put_contents($targetDir . 'upload.log', $log, FILE_APPEND);
|
|
|
|
// 更新最新版本
|
|
$latestPath = $targetDir . 'F8来客_latest.apk';
|
|
|
|
// 获取当前上传APK的版本号
|
|
$newVersion = $versionName;
|
|
|
|
// 获取现有最新APK的版本号
|
|
$currentLatestVersion = '0';
|
|
if (file_exists($latestPath)) {
|
|
$versionInfo = shell_exec("aapt dump badging \"$latestPath\" | grep -E 'versionName|versionCode'");
|
|
$currentLatestVersion = preg_match("/versionName='([^']*)'/", $versionInfo, $matches) ? $matches[1] : '0';
|
|
$currentLatestVersion = trim($currentLatestVersion);
|
|
}
|
|
|
|
// 比较版本号,只有当新版本更高时才覆盖
|
|
if (version_compare($newVersion, $currentLatestVersion) > 0) {
|
|
if (file_exists($latestPath)) {
|
|
unlink($latestPath);
|
|
}
|
|
if (!copy($targetPath, $latestPath)) {
|
|
$message = '更新最新版本失败';
|
|
}
|
|
$message = '上传成功! 已更新为最新版本: ' . $versionName;
|
|
} else {
|
|
$message = '上传成功! 当前版本: ' . $versionName . ' (未更新,已有更高版本: ' . $currentLatestVersion . ')';
|
|
}
|
|
} else {
|
|
$message = '上传失败';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function getLatestVersionName($dir) {
|
|
$files = glob($dir . '*.apk');
|
|
$maxVersion = '0';
|
|
foreach ($files as $file) {
|
|
if (basename($file) === 'F8来客_latest.apk') continue;
|
|
$version = shell_exec("aapt dump badging \"$file\" | grep versionName | awk -F\"'\" '{print $2}'");
|
|
$version = trim($version);
|
|
if (version_compare($version, $maxVersion) > 0) {
|
|
$maxVersion = $version;
|
|
}
|
|
}
|
|
return $maxVersion;
|
|
}
|
|
?>
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">
|
|
<title>F8来客 - APK上传</title>
|
|
<style>
|
|
* { box-sizing: border-box; }
|
|
body {
|
|
font-family: -apple-system, BlinkMacSystemFont, sans-serif;
|
|
margin: 0; padding: 20px; background-color: #fff;
|
|
}
|
|
.container {
|
|
max-width: 600px; margin: 0 auto;
|
|
}
|
|
.logo {
|
|
width: 60px; height: 60px; border-radius: 5px;
|
|
margin-bottom: 15px;
|
|
}
|
|
h1 {
|
|
font-size: 18px; color: #2a2a2a; font-weight: 700;
|
|
margin-bottom: 30px;
|
|
}
|
|
.message {
|
|
padding: 10px; margin-bottom: 20px;
|
|
border-radius: 5px; text-align: center;
|
|
}
|
|
.success { background-color: #d4edda; color: #155724; }
|
|
.error { background-color: #f8d7da; color: #721c24; }
|
|
.upload-form {
|
|
border: 1px dashed #007aff; padding: 30px;
|
|
text-align: center; border-radius: 5px;
|
|
margin-bottom: 20px;
|
|
}
|
|
.file-input {
|
|
display: none;
|
|
}
|
|
.file-label {
|
|
display: inline-block;
|
|
padding: 12px 24px;
|
|
background-color: #007aff;
|
|
color: white;
|
|
border-radius: 5px;
|
|
cursor: pointer;
|
|
font-size: 16px;
|
|
}
|
|
.submit-btn {
|
|
padding: 12px 24px;
|
|
background-color: #28a745;
|
|
color: white;
|
|
border: none;
|
|
border-radius: 5px;
|
|
cursor: pointer;
|
|
font-size: 16px;
|
|
margin-top: 15px;
|
|
}
|
|
.logout {
|
|
color: #007aff; text-decoration: none;
|
|
display: inline-block; margin-top: 20px;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<img src="https://www.bltcxj.cn/f8img/logo.jpg" class="logo">
|
|
<h1>APK上传</h1>
|
|
|
|
<?php if ($message): ?>
|
|
<div class="message <?php echo strpos($message, '成功') !== false ? 'success' : 'error'; ?>">
|
|
<?php echo htmlspecialchars($message); ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<form method="post" enctype="multipart/form-data" class="upload-form">
|
|
<input type="file" name="apk" id="apk" accept=".apk" class="file-input">
|
|
<label for="apk" class="file-label">选择APK文件</label>
|
|
<div id="fileName" style="margin-top: 10px;"></div>
|
|
<button type="submit" class="submit-btn">上传APK</button>
|
|
</form>
|
|
|
|
|
|
|
|
<h2>最近上传记录</h2>
|
|
<div class="upload-history">
|
|
<?php
|
|
$logFile = 'uploads/upload.log';
|
|
if (file_exists($logFile)) {
|
|
$lines = file($logFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
|
$recentLines = array_slice(array_reverse($lines), 0, 5);
|
|
echo '<ul>';
|
|
foreach ($recentLines as $line) {
|
|
echo '<li>' . htmlspecialchars($line) . '</li>';
|
|
}
|
|
echo '</ul>';
|
|
} else {
|
|
echo '<p>暂无上传记录</p>';
|
|
}
|
|
?>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
document.getElementById('apk').addEventListener('change', function(e) {
|
|
var fileName = e.target.files[0] ? e.target.files[0].name : '未选择文件';
|
|
document.getElementById('fileName').textContent = fileName;
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|