136 lines
7.5 KiB
HTML
136 lines
7.5 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>历史记录</title>
|
||
<style>
|
||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||
body { font-family: "Microsoft YaHei", sans-serif; background: #EDEFF3; height: 100vh; overflow: hidden; display: flex; }
|
||
.sidebar { width: 220px; height: 100vh; background: #FAFBFC; border-right: 1px solid #E4E7EB; display: flex; flex-direction: column; flex-shrink: 0; }
|
||
.sidebar-brand { display: flex; align-items: center; gap: 8px; padding: 20px 16px; font-size: 15px; font-weight: 700; color: #1565C0; }
|
||
.sidebar-nav { flex: 1; padding: 8px 0; }
|
||
.nav-item { display: flex; align-items: center; height: 48px; padding: 0 16px; margin: 2px 8px; border-radius: 8px; cursor: pointer; font-size: 14px; color: #555; }
|
||
.nav-item:hover { background: #EEF2F7; color: #333; }
|
||
.nav-item.active { background: #E3F2FD; color: #1565C0; font-weight: 600; }
|
||
.nav-icon { margin-right: 10px; }
|
||
.sidebar-footer { padding: 16px; border-top: 1px solid #E8ECF0; }
|
||
.btn-logout { width: 100%; height: 36px; border: 1px solid #E0E0E0; border-radius: 8px; background: #fff; color: #666; cursor: pointer; font-family: inherit; }
|
||
.btn-logout:hover { border-color: #E53935; color: #E53935; }
|
||
.main { flex: 1; overflow-y: auto; padding: 32px 48px; }
|
||
.page-title { font-size: 22px; font-weight: 700; color: #1A1A1A; margin-bottom: 20px; }
|
||
.search-row { display: flex; gap: 12px; margin-bottom: 20px; }
|
||
.search-input { flex: 1; height: 40px; border: 1px solid #E0E0E0; border-radius: 8px; padding: 0 14px; font-size: 14px; font-family: inherit; outline: none; }
|
||
.search-input:focus { border-color: #1565C0; }
|
||
.filter-select { width: 130px; height: 40px; border: 1px solid #E0E0E0; border-radius: 8px; padding: 0 10px; font-size: 14px; font-family: inherit; outline: none; background: #fff; flex-shrink: 0; }
|
||
.filter-select:focus { border-color: #1565C0; }
|
||
.btn-back { height: 40px; padding: 0 18px; border: 1px solid #E0E0E0; border-radius: 8px; background: #fff; color: #666; cursor: pointer; font-family: inherit; }
|
||
.btn-back:hover { border-color: #1565C0; color: #1565C0; }
|
||
.list-empty { text-align: center; color: #999; padding: 80px 0; }
|
||
.record-item { background: #fff; border-radius: 10px; padding: 18px 22px; margin-bottom: 12px; box-shadow: 0 1px 3px rgba(0,0,0,0.05); display: flex; align-items: center; justify-content: space-between; }
|
||
.record-title { font-size: 15px; font-weight: 600; color: #333; margin-bottom: 4px; }
|
||
.record-meta { font-size: 12px; color: #999; }
|
||
.record-actions { display: flex; gap: 8px; }
|
||
.btn-dl { height: 32px; padding: 0 14px; border: none; border-radius: 6px; background: #1565C0; color: #fff; font-size: 13px; cursor: pointer; font-family: inherit; }
|
||
.btn-del { height: 32px; padding: 0 14px; border: 1px solid #E53935; border-radius: 6px; background: #fff; color: #E53935; font-size: 13px; cursor: pointer; font-family: inherit; }
|
||
.lang-row { display: flex; gap: 8px; margin-bottom: 10px; }
|
||
.lang-btn { flex: 1; height: 32px; border: 1px solid #E0E0E0; border-radius: 8px; background: #fff; color: #666; font-size: 13px; cursor: pointer; font-family: inherit; }
|
||
.lang-btn.active { border-color: #1565C0; color: #1565C0; font-weight: 600; }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<aside class="sidebar">
|
||
<div class="sidebar-brand">📊 <span data-i18n="app_name">演示文稿智能生成</span></div>
|
||
<nav class="sidebar-nav">
|
||
<div class="nav-item" onclick="location.href='/workspace'"><span class="nav-icon">📄</span><span data-i18n="nav_generate">PPT 生成</span></div>
|
||
<div class="nav-item active"><span class="nav-icon">🕐</span><span data-i18n="nav_history">历史记录</span></div>
|
||
<div class="nav-item" onclick="location.href='/settings'"><span class="nav-icon">⚙️</span><span data-i18n="nav_settings">个人设置</span></div>
|
||
</nav>
|
||
<div class="sidebar-footer">
|
||
<div class="lang-row">
|
||
<button class="lang-btn" id="langZh" onclick="setLang('zh')">中文</button>
|
||
<button class="lang-btn" id="langJa" onclick="setLang('ja')">日本語</button>
|
||
</div>
|
||
<button class="btn-logout" onclick="doLogout()" data-i18n="btn_logout">退出登录</button>
|
||
</div>
|
||
</aside>
|
||
<main class="main">
|
||
<div class="page-title" data-i18n="nav_history">历史记录</div>
|
||
<div class="search-row">
|
||
<input class="search-input" id="searchInput" data-i18n-ph="history_search_ph" placeholder="搜索标题…" oninput="loadRecords()">
|
||
<select class="filter-select" id="langFilter" onchange="loadRecords()">
|
||
<option value="" data-i18n="filter_all_lang">全部语言</option>
|
||
<option value="zh" data-i18n="lang_zh">中文</option>
|
||
<option value="ja" data-i18n="lang_ja">日本語</option>
|
||
</select>
|
||
<button class="btn-back" onclick="location.href='/workspace'" data-i18n="btn_new_doc">+ 新建</button>
|
||
</div>
|
||
<div id="recordList"></div>
|
||
</main>
|
||
<script>
|
||
let I18N = {};
|
||
|
||
async function loadLang(lang) {
|
||
try {
|
||
const res = await fetch('/static/lang/' + lang + '.json');
|
||
I18N = await res.json();
|
||
} catch (e) { I18N = {}; }
|
||
document.querySelectorAll('[data-i18n]').forEach(el => {
|
||
el.textContent = I18N[el.dataset.i18n] || el.textContent;
|
||
});
|
||
document.querySelectorAll('[data-i18n-ph]').forEach(el => {
|
||
el.placeholder = I18N[el.dataset.i18nPh] || el.placeholder;
|
||
});
|
||
document.getElementById('langZh').classList.toggle('active', lang === 'zh');
|
||
document.getElementById('langJa').classList.toggle('active', lang === 'ja');
|
||
}
|
||
|
||
function setLang(lang) {
|
||
loadLang(lang).then(loadRecords);
|
||
localStorage.setItem('ui_lang', lang);
|
||
}
|
||
|
||
async function loadRecords() {
|
||
const kw = document.getElementById('searchInput').value.trim();
|
||
const lang = document.getElementById('langFilter').value;
|
||
try {
|
||
const res = await fetch('/api/records?keyword=' + encodeURIComponent(kw) + '&language=' + encodeURIComponent(lang));
|
||
const data = await res.json();
|
||
if (data.code !== 0) { window.location.href = '/login'; return; }
|
||
render(data.data.records);
|
||
} catch (e) { window.location.href = '/login'; }
|
||
}
|
||
function render(records) {
|
||
const list = document.getElementById('recordList');
|
||
if (!records || records.length === 0) {
|
||
list.innerHTML = '<div class="list-empty">' + (I18N.history_empty || '暂无历史记录,去工作台生成一个吧') + '</div>';
|
||
return;
|
||
}
|
||
list.innerHTML = records.map(r => `
|
||
<div class="record-item">
|
||
<div>
|
||
<div class="record-title">${r.title || I18N.unnamed_title || '未命名'}</div>
|
||
<div class="record-meta">${r.scene === 'report' ? (I18N.scene_report || '社内汇报') : (I18N.scene_training || '社内培训')} · ${r.language === 'ja' ? (I18N.lang_ja || '日本語') : (I18N.lang_zh || '中文')} · ${r.page_count || '-'} ${I18N.preview_pages || '页'} · ${r.created_at}</div>
|
||
</div>
|
||
<div class="record-actions">
|
||
<button class="btn-dl" onclick="download(${r.id})">${I18N.btn_download || '下载'}</button>
|
||
<button class="btn-del" onclick="del(${r.id})">${I18N.btn_delete || '删除'}</button>
|
||
</div>
|
||
</div>`).join('');
|
||
}
|
||
function download(id) { window.location.href = '/api/files/' + id + '/download'; }
|
||
async function del(id) {
|
||
if (!confirm(I18N.confirm_del_record || '确认删除该记录?')) return;
|
||
await fetch('/api/records/' + id, { method: 'DELETE' });
|
||
loadRecords();
|
||
}
|
||
async function doLogout() { await fetch('/api/logout', { method: 'POST' }); window.location.href = '/login'; }
|
||
|
||
(async function init() {
|
||
const saved = localStorage.getItem('ui_lang');
|
||
await loadLang(saved === 'ja' ? 'ja' : 'zh');
|
||
loadRecords();
|
||
})();
|
||
</script>
|
||
</body>
|
||
</html> |