初始化版本
This commit is contained in:
158
share.php
Normal file
158
share.php
Normal file
@@ -0,0 +1,158 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/config.php';
|
||||
|
||||
function readJson($file) {
|
||||
if (!file_exists($file)) return [];
|
||||
$s = file_get_contents($file);
|
||||
$data = json_decode($s, true);
|
||||
return is_array($data) ? $data : [];
|
||||
}
|
||||
|
||||
function safeId($id) { return preg_match('/^[a-zA-Z0-9_-]+$/', $id); }
|
||||
function writeJson($file, $data) { file_put_contents($file, json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)); }
|
||||
|
||||
$token = $_GET['token'] ?? '';
|
||||
if (!$token) { http_response_code(400); echo 'Bad token'; exit; }
|
||||
|
||||
$baseDir = __DIR__ . DIRECTORY_SEPARATOR . 'data';
|
||||
$docsDir = $baseDir . DIRECTORY_SEPARATOR . 'docs';
|
||||
$indexFile = $baseDir . DIRECTORY_SEPARATOR . 'index.json';
|
||||
$sharesFile = $baseDir . DIRECTORY_SEPARATOR . 'shares.json';
|
||||
|
||||
// 校验令牌
|
||||
$shares = readJson($sharesFile);
|
||||
$found = null;
|
||||
foreach ($shares as $rec) { if (($rec['token'] ?? '') === $token) { $found = $rec; break; } }
|
||||
if (!$found) { http_response_code(403); echo 'Unauthorized'; exit; }
|
||||
if (!empty($found['revoked'])) { http_response_code(403); echo 'Unauthorized'; exit; }
|
||||
if (!empty($found['expires_at']) && time() > $found['expires_at']) { http_response_code(403); echo 'Link expired'; exit; }
|
||||
// 一次性链接已使用则拒绝访问
|
||||
if (!empty($found['single_use']) && !empty($found['used'])) { http_response_code(403); echo 'Link already used'; exit; }
|
||||
$id = $found['id'] ?? '';
|
||||
if (!$id || !safeId($id)) { http_response_code(400); echo 'Bad id'; exit; }
|
||||
|
||||
$file = $docsDir . DIRECTORY_SEPARATOR . $id . '.html';
|
||||
if (!file_exists($file)) { http_response_code(404); echo 'Not found'; exit; }
|
||||
$content = file_get_contents($file);
|
||||
|
||||
$index = readJson($indexFile);
|
||||
$title = $id;
|
||||
foreach ($index as $it) { if (($it['id'] ?? '') === $id) { $title = $it['title'] ?? $id; break; } }
|
||||
?>
|
||||
<!doctype html>
|
||||
<html lang="zh-CN" data-theme="light">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title><?= htmlspecialchars($title) ?> - 分享预览</title>
|
||||
<link rel="stylesheet" href="assets/style.css" />
|
||||
<style>
|
||||
.share-wrap { display:grid; grid-template-columns: 1fr; height:100vh; }
|
||||
.share-toolbar { display:flex; align-items:center; justify-content:space-between; padding:12px; border-bottom:2px solid var(--accent); background: var(--panel); }
|
||||
.share-title { font-size:18px; margin:0; }
|
||||
.theme-toggle { margin-left: 8px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="share-wrap">
|
||||
<div class="share-toolbar">
|
||||
<h1 class="share-title"><?= htmlspecialchars($title) ?></h1>
|
||||
<div style="display:flex; gap:8px; align-items:center;">
|
||||
<button id="share-print" class="btn">打印文档</button>
|
||||
<button id="share-theme" class="btn theme-toggle">切换主题</button>
|
||||
<a class="btn" href="index.php">返回主页</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="editor-area" style="padding-top:12px;">
|
||||
<?= $content ?>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
// 初始化主题
|
||||
(function(){
|
||||
var t = localStorage.getItem('theme');
|
||||
if (t === 'dark' || t === 'light') {
|
||||
document.documentElement.setAttribute('data-theme', t);
|
||||
}
|
||||
})();
|
||||
document.getElementById('share-theme').addEventListener('click', function(){
|
||||
var root = document.documentElement;
|
||||
var cur = root.getAttribute('data-theme') || 'light';
|
||||
var next = cur === 'light' ? 'dark' : 'light';
|
||||
root.setAttribute('data-theme', next);
|
||||
try { localStorage.setItem('theme', next); } catch (e) {}
|
||||
});
|
||||
|
||||
// 打印功能
|
||||
document.getElementById('share-print').addEventListener('click', function() {
|
||||
try {
|
||||
// 获取文档标题和内容
|
||||
var title = document.querySelector('.share-title').textContent;
|
||||
var content = document.querySelector('.editor-area').innerHTML;
|
||||
|
||||
// 创建打印内容容器
|
||||
var printContainer = document.createElement('div');
|
||||
printContainer.id = 'print-container';
|
||||
printContainer.style.position = 'absolute';
|
||||
printContainer.style.left = '-9999px';
|
||||
printContainer.style.width = '800px'; // 设置合适的打印宽度
|
||||
|
||||
// 设置打印内容
|
||||
printContainer.innerHTML = '<h1 style="text-align:center; font-family:Arial, sans-serif;">' +
|
||||
title +
|
||||
'</h1><div style="font-family:Arial, sans-serif; line-height:1.6;">' +
|
||||
content +
|
||||
'</div>';
|
||||
|
||||
// 添加到页面
|
||||
document.body.appendChild(printContainer);
|
||||
|
||||
// 创建打印样式
|
||||
var printStyle = document.createElement('style');
|
||||
printStyle.media = 'print';
|
||||
printStyle.innerHTML =
|
||||
'#print-container { position: static !important; width: 100% !important; } ' +
|
||||
'body > *:not(#print-container) { display: none !important; } ' +
|
||||
'body { margin: 2cm; }';
|
||||
document.head.appendChild(printStyle);
|
||||
|
||||
// 保存原始样式引用,以便稍后移除
|
||||
var originalPrintStyle = printStyle;
|
||||
|
||||
// 当打印对话框关闭后恢复页面
|
||||
window.onafterprint = function() {
|
||||
// 移除打印容器和样式
|
||||
document.body.removeChild(printContainer);
|
||||
document.head.removeChild(originalPrintStyle);
|
||||
window.onafterprint = null; // 清除事件处理
|
||||
};
|
||||
|
||||
// 调用浏览器打印功能
|
||||
window.print();
|
||||
} catch (e) {
|
||||
// 打印错误时恢复页面
|
||||
try {
|
||||
var printContainer = document.getElementById('print-container');
|
||||
if (printContainer) document.body.removeChild(printContainer);
|
||||
var printStyles = document.querySelectorAll('style[media="print"]');
|
||||
printStyles.forEach(function(style) { document.head.removeChild(style); });
|
||||
} catch (cleanupError) {
|
||||
console.error('清理打印元素时出错:', cleanupError);
|
||||
}
|
||||
|
||||
console.error('打印失败:', e);
|
||||
alert('打印失败,请重试');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
<?php
|
||||
// 标记一次性链接为已使用
|
||||
if (!empty($found['single_use']) && empty($found['used'])) {
|
||||
foreach ($shares as &$rec) {
|
||||
if (($rec['token'] ?? '') === $token) { $rec['used'] = true; break; }
|
||||
}
|
||||
writeJson($sharesFile, $shares);
|
||||
}
|
||||
?>
|
||||
Reference in New Issue
Block a user