206 lines
9.8 KiB
HTML
206 lines
9.8 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="zh-CN">
|
|
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>VideoCall - 录制管理</title>
|
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
|
|
<link rel="stylesheet" href="/styles/style.css">
|
|
</head>
|
|
|
|
<body class="min-h-screen w-screen text-white bg-grid recordings-page">
|
|
<div class="min-h-screen bg-black/70 flex flex-col">
|
|
<header class="glass-strong h-16 flex items-center justify-between px-6 border-b border-white/10">
|
|
<div class="flex items-center gap-3 min-w-0">
|
|
<div class="w-10 h-10 bg-gradient-to-br from-indigo-500 to-purple-600 rounded-xl flex items-center justify-center shadow-lg">
|
|
<i class="fas fa-video text-white text-lg"></i>
|
|
</div>
|
|
<div class="min-w-0">
|
|
<h1 class="font-bold text-lg tracking-tight">录制管理后台</h1>
|
|
<div class="flex items-center gap-3 text-xs text-gray-400">
|
|
<span class="w-2 h-2 bg-green-500 rounded-full"></span>
|
|
<span id="recordingRootText" class="truncate max-w-[60vw]">recordings</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex items-center gap-3">
|
|
<a href="/" class="recordings-icon-btn glass" title="返回视频通话">
|
|
<i class="fas fa-phone"></i>
|
|
</a>
|
|
<button id="refreshBtn" class="recordings-icon-btn glass" title="刷新列表">
|
|
<i class="fas fa-rotate-right"></i>
|
|
</button>
|
|
</div>
|
|
</header>
|
|
|
|
<main class="recordings-shell flex-1 overflow-hidden">
|
|
<section class="recordings-toolbar glass">
|
|
<div class="recordings-stat">
|
|
<span class="recordings-stat-value" id="totalCount">0</span>
|
|
<span class="recordings-stat-label">总录制</span>
|
|
</div>
|
|
<div class="recordings-stat">
|
|
<span class="recordings-stat-value" id="meetingCount">0</span>
|
|
<span class="recordings-stat-label">会议数</span>
|
|
</div>
|
|
<div class="recordings-stat">
|
|
<span class="recordings-stat-value" id="storageSize">0 MB</span>
|
|
<span class="recordings-stat-label">占用空间</span>
|
|
</div>
|
|
|
|
<div class="recordings-search">
|
|
<i class="fas fa-magnifying-glass text-gray-500"></i>
|
|
<input id="searchInput" type="search" placeholder="搜索会议、文件或用户" autocomplete="off">
|
|
</div>
|
|
|
|
<select id="typeFilter" class="recordings-select">
|
|
<option value="all">全部格式</option>
|
|
<option value="mp4">MP4</option>
|
|
<option value="webm">WebM</option>
|
|
</select>
|
|
</section>
|
|
|
|
<section class="recordings-content">
|
|
<aside class="recordings-upload glass">
|
|
<div class="flex items-center justify-between mb-5">
|
|
<div>
|
|
<h2 class="text-base font-semibold">新增录制</h2>
|
|
<p class="text-xs text-gray-500 mt-1">上传到 recordings 目录</p>
|
|
</div>
|
|
<div class="w-10 h-10 rounded-xl bg-indigo-500/20 flex items-center justify-center text-indigo-300">
|
|
<i class="fas fa-cloud-arrow-up"></i>
|
|
</div>
|
|
</div>
|
|
|
|
<form id="uploadForm" class="space-y-4">
|
|
<label class="recordings-dropzone" for="recordingFile">
|
|
<input id="recordingFile" type="file" accept="video/mp4,video/webm" class="hidden" required>
|
|
<i class="fas fa-file-video text-2xl text-indigo-300"></i>
|
|
<span id="fileNameText">选择 MP4 或 WebM 文件</span>
|
|
</label>
|
|
|
|
<div>
|
|
<label class="recordings-label" for="uploadMeetingId">会议 ID</label>
|
|
<input id="uploadMeetingId" class="recordings-input" type="text" placeholder="例如 665-261-326" required>
|
|
</div>
|
|
|
|
<div>
|
|
<label class="recordings-label" for="uploadUserId">用户 ID</label>
|
|
<input id="uploadUserId" class="recordings-input" type="text" placeholder="可选">
|
|
</div>
|
|
|
|
<button id="uploadBtn" class="recordings-primary-btn" type="submit">
|
|
<i class="fas fa-plus"></i>
|
|
<span>上传录制</span>
|
|
</button>
|
|
</form>
|
|
</aside>
|
|
|
|
<section class="recordings-list glass">
|
|
<div class="recordings-list-head">
|
|
<div>
|
|
<h2 class="text-base font-semibold">录制文件</h2>
|
|
<p class="text-xs text-gray-500 mt-1" id="listSummary">等待加载</p>
|
|
</div>
|
|
<button id="clearSearchBtn" class="recordings-text-btn hidden">
|
|
<i class="fas fa-xmark"></i>
|
|
<span>清空筛选</span>
|
|
</button>
|
|
</div>
|
|
|
|
<div id="loadingState" class="recordings-empty">
|
|
<div class="w-10 h-10 border-4 border-indigo-500 border-t-transparent rounded-full animate-spin"></div>
|
|
<span>正在读取 recordings 目录...</span>
|
|
</div>
|
|
|
|
<div id="emptyState" class="recordings-empty hidden">
|
|
<i class="fas fa-folder-open text-3xl text-gray-500"></i>
|
|
<span>还没有录制文件</span>
|
|
</div>
|
|
|
|
<div id="recordingsTableWrap" class="recordings-table-wrap hidden">
|
|
<table class="recordings-table">
|
|
<thead>
|
|
<tr>
|
|
<th>文件</th>
|
|
<th>会议</th>
|
|
<th>大小</th>
|
|
<th>上传时间</th>
|
|
<th>操作</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="recordingsTableBody"></tbody>
|
|
</table>
|
|
</div>
|
|
</section>
|
|
|
|
<aside class="recordings-preview glass">
|
|
<div class="recordings-preview-video">
|
|
<video id="previewVideo" controls playsinline></video>
|
|
<div id="previewPlaceholder" class="recordings-preview-placeholder">
|
|
<i class="fas fa-play text-2xl"></i>
|
|
<span>选择一条录制预览</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="recordings-preview-meta">
|
|
<h2 id="previewTitle">未选择录制</h2>
|
|
<div id="previewDetails" class="space-y-3 text-sm text-gray-400">
|
|
<p>从左侧列表选择文件后,可播放、下载、编辑或删除。</p>
|
|
</div>
|
|
</div>
|
|
</aside>
|
|
</section>
|
|
</main>
|
|
</div>
|
|
|
|
<div id="editDialog" class="fixed inset-0 bg-black/70 hidden items-center justify-center z-50">
|
|
<form id="editForm" class="recordings-dialog glass">
|
|
<div class="flex items-center justify-between mb-5">
|
|
<div>
|
|
<h2 class="text-lg font-semibold">编辑录制信息</h2>
|
|
<p class="text-xs text-gray-500 mt-1" id="editFilenameText"></p>
|
|
</div>
|
|
<button type="button" id="closeEditBtn" class="recordings-icon-btn" title="关闭">
|
|
<i class="fas fa-xmark"></i>
|
|
</button>
|
|
</div>
|
|
|
|
<div class="space-y-4">
|
|
<div>
|
|
<label class="recordings-label" for="editMeetingId">会议 ID</label>
|
|
<input id="editMeetingId" class="recordings-input" type="text" required>
|
|
</div>
|
|
<div>
|
|
<label class="recordings-label" for="editOriginalFilename">显示名称</label>
|
|
<input id="editOriginalFilename" class="recordings-input" type="text" required>
|
|
</div>
|
|
<div>
|
|
<label class="recordings-label" for="editUserId">用户 ID</label>
|
|
<input id="editUserId" class="recordings-input" type="text">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex gap-3 mt-6">
|
|
<button type="button" id="cancelEditBtn" class="recordings-secondary-btn">取消</button>
|
|
<button type="submit" class="recordings-primary-btn">
|
|
<i class="fas fa-floppy-disk"></i>
|
|
<span>保存</span>
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<div id="notification" class="recordings-notification glass">
|
|
<i class="fas fa-info-circle text-indigo-400"></i>
|
|
<span id="notificationText"></span>
|
|
</div>
|
|
|
|
<script type="module" src="/recordings/recordings-admin.js"></script>
|
|
</body>
|
|
|
|
</html>
|