OneBot: Leantime 改造版源码(BOM/Univer 表格/AI 接管/品牌替换等)

This commit is contained in:
wangruiguo
2026-09-03 18:49:20 +08:00
commit d647428529
3501 changed files with 1988906 additions and 0 deletions

67
dev/library.php Normal file
View File

@@ -0,0 +1,67 @@
<?php
/**
* 2D/3D 数模库 - 元数据接口(首页库表用)
* GET 无参 → 返回 library.json 的全部记录(静态 JSON 也行,这里统一走接口)
* POST {"records":[...]} → 清洗后整体保存(客户端把编辑后的数组传回)
*
* 只允许本站页面调用Sec-Fetch-Site 优先、Referer 兜底,与 api/token.php 同一策略)。
* 注意这只是防顺手篡改的弱校验:库表只存名称/备注等元数据,不含文件内容。
*/
header('Content-Type: application/json; charset=utf-8');
header('Cache-Control: no-store');
$fetchSite = $_SERVER['HTTP_SEC_FETCH_SITE'] ?? '';
$referer = $_SERVER['HTTP_REFERER'] ?? '';
$host = $_SERVER['HTTP_HOST'] ?? '';
if ($fetchSite !== '') {
if ($fetchSite !== 'same-origin' && $fetchSite !== 'same-site') json_out(403, ['error' => 'forbidden']);
} elseif (!$host || strpos($referer, $host) === false) {
json_out(403, ['error' => 'forbidden']);
}
function json_out($code, $obj) {
http_response_code($code);
echo json_encode($obj, JSON_UNESCAPED_UNICODE);
exit;
}
$file = __DIR__ . '/library.json';
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
if (is_file($file)) { readfile($file); exit; }
json_out(200, ['records' => []]);
}
if ($_SERVER['REQUEST_METHOD'] !== 'POST') json_out(405, ['error' => 'method not allowed']);
$in = json_decode((string)file_get_contents('php://input'), true);
if (!is_array($in) || !isset($in['records']) || !is_array($in['records'])) {
json_out(400, ['error' => 'bad body']);
}
// 清洗path 是链接核心(拒绝 ..、限制字符与长度name/note 纯文本截断
$records = [];
$seen = [];
foreach ($in['records'] as $r) {
if (!is_array($r)) continue;
$path = is_string($r['path'] ?? null) ? trim($r['path']) : '';
$name = is_string($r['name'] ?? null) ? trim($r['name']) : '';
$note = is_string($r['note'] ?? null) ? trim($r['note']) : '';
$type = ($r['type'] ?? '') === '2d' ? '2d' : '3d';
if ($path === '' || strpos($path, '..') !== false || strlen($path) > 300) continue;
if (!preg_match('/^[\x20-\x7e\x{4e00}-\x{9fff}\/\\\\]+$/u', $path)) continue;
if (isset($seen[$path])) continue;
$seen[$path] = true;
$records[] = [
'path' => $path,
'name' => mb_substr($name, 0, 100),
'type' => $type,
'note' => mb_substr($note, 0, 200),
'time' => is_numeric($r['time'] ?? null) ? (int)$r['time'] : time(),
];
}
// 带锁写文件,防止两个查看器上传时并发写坏
$json = json_encode(['records' => $records], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
if (file_put_contents($file, $json, LOCK_EX) === false) json_out(500, ['error' => 'write failed']);
json_out(200, ['ok' => true, 'count' => count($records)]);