增加配置文件
This commit is contained in:
@@ -92,6 +92,12 @@ function showPage(pageName) {
|
||||
case 'comments':
|
||||
loadComments();
|
||||
break;
|
||||
case 'themes':
|
||||
loadThemes();
|
||||
break;
|
||||
case 'theme-editor':
|
||||
// 主题编辑器由 editTheme() 函数加载
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -614,3 +620,369 @@ function getStatusText(status) {
|
||||
};
|
||||
return map[status] || status;
|
||||
}
|
||||
|
||||
// ==================== 主题管理 ====================
|
||||
|
||||
// 加载主题列表
|
||||
let currentTheme = null;
|
||||
async function loadThemes() {
|
||||
try {
|
||||
// 获取当前主题
|
||||
const currentRes = await fetch(`${API_BASE}/theme`, {
|
||||
headers: getHeaders()
|
||||
});
|
||||
const currentData = await currentRes.json();
|
||||
currentTheme = currentData.theme;
|
||||
|
||||
// 获取所有可用主题
|
||||
const themesRes = await fetch(`${API_BASE}/themes`, {
|
||||
headers: getHeaders()
|
||||
});
|
||||
const themesData = await themesRes.json();
|
||||
|
||||
// 填充下拉列表
|
||||
const themeSelect = document.getElementById('theme-select');
|
||||
themeSelect.innerHTML = '';
|
||||
|
||||
themesData.themes.forEach(theme => {
|
||||
const option = document.createElement('option');
|
||||
option.value = theme;
|
||||
option.textContent = theme;
|
||||
if (theme === currentTheme) {
|
||||
option.selected = true;
|
||||
}
|
||||
themeSelect.appendChild(option);
|
||||
});
|
||||
|
||||
// 显示主题列表
|
||||
displayThemeList(themesData.themes, currentTheme);
|
||||
|
||||
} catch (error) {
|
||||
console.error('加载主题失败:', error);
|
||||
showThemeMessage('加载主题失败', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
// 显示主题列表
|
||||
function displayThemeList(themes, currentTheme) {
|
||||
const themeList = document.getElementById('theme-list');
|
||||
themeList.innerHTML = '';
|
||||
|
||||
themes.forEach(theme => {
|
||||
const themeCard = document.createElement('div');
|
||||
themeCard.className = `theme-card ${theme === currentTheme ? 'active' : ''}`;
|
||||
|
||||
themeCard.innerHTML = `
|
||||
<div class="theme-card-header">
|
||||
<h3>${theme}</h3>
|
||||
${theme === currentTheme ? '<span class="theme-badge">当前使用</span>' : ''}
|
||||
</div>
|
||||
<div class="theme-card-body">
|
||||
<p>主题名称: ${theme}</p>
|
||||
<p>状态: ${theme === currentTheme ? '使用中' : '未使用'}</p>
|
||||
</div>
|
||||
<div class="theme-card-actions">
|
||||
<button class="btn-small btn-secondary" onclick="editTheme('${theme}')">编辑</button>
|
||||
${theme !== currentTheme ? `<button class="btn-small btn-primary" onclick="quickSwitch('${theme}')">切换</button>` : ''}
|
||||
</div>
|
||||
`;
|
||||
|
||||
themeList.appendChild(themeCard);
|
||||
});
|
||||
}
|
||||
|
||||
// 切换主题
|
||||
async function switchTheme() {
|
||||
const themeSelect = document.getElementById('theme-select');
|
||||
const selectedTheme = themeSelect.value;
|
||||
|
||||
if (!selectedTheme) {
|
||||
showThemeMessage('请选择一个主题', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
if (selectedTheme === currentTheme) {
|
||||
showThemeMessage('当前已经是该主题', 'warning');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(`${API_BASE}/theme`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
...getHeaders(),
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({ theme: selectedTheme })
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (response.ok) {
|
||||
showThemeMessage(data.message || '主题切换成功', 'success');
|
||||
currentTheme = selectedTheme;
|
||||
|
||||
// 刷新主题列表显示
|
||||
loadThemes();
|
||||
} else {
|
||||
showThemeMessage(data.error || '主题切换失败', 'error');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('切换主题失败:', error);
|
||||
showThemeMessage('切换主题失败', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
// 显示主题消息
|
||||
function showThemeMessage(message, type = 'info') {
|
||||
const messageEl = document.getElementById('theme-message');
|
||||
messageEl.textContent = message;
|
||||
messageEl.className = `theme-message ${type}`;
|
||||
messageEl.style.display = 'block';
|
||||
|
||||
// 3秒后自动隐藏
|
||||
setTimeout(() => {
|
||||
messageEl.style.display = 'none';
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
// 显示创建主题弹窗
|
||||
function showCreateThemeModal() {
|
||||
document.getElementById('theme-modal').classList.remove('hidden');
|
||||
document.getElementById('new-theme-name').value = '';
|
||||
document.getElementById('theme-template').value = 'default';
|
||||
document.getElementById('create-css').checked = true;
|
||||
}
|
||||
|
||||
// 隐藏创建主题弹窗
|
||||
function hideThemeModal() {
|
||||
document.getElementById('theme-modal').classList.add('hidden');
|
||||
}
|
||||
|
||||
// 创建主题表单提交
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const createThemeForm = document.getElementById('create-theme-form');
|
||||
if (createThemeForm) {
|
||||
createThemeForm.addEventListener('submit', handleCreateTheme);
|
||||
}
|
||||
});
|
||||
|
||||
async function handleCreateTheme(e) {
|
||||
e.preventDefault();
|
||||
|
||||
const themeName = document.getElementById('new-theme-name').value.trim();
|
||||
const template = document.getElementById('theme-template').value;
|
||||
const createCSS = document.getElementById('create-css').checked;
|
||||
|
||||
if (!themeName) {
|
||||
showThemeMessage('请输入主题名称', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(`${API_BASE}/themes/create`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
...getHeaders(),
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
name: themeName,
|
||||
template: template,
|
||||
create_css: createCSS
|
||||
})
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (response.ok) {
|
||||
showThemeMessage(data.message || '主题创建成功', 'success');
|
||||
hideThemeModal();
|
||||
|
||||
// 刷新主题列表
|
||||
setTimeout(() => {
|
||||
loadThemes();
|
||||
}, 500);
|
||||
} else {
|
||||
showThemeMessage(data.error || '主题创建失败', 'error');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('创建主题失败:', error);
|
||||
showThemeMessage('创建主题失败', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
// 快速切换主题
|
||||
async function quickSwitch(theme) {
|
||||
try {
|
||||
const response = await fetch(`${API_BASE}/theme`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
...getHeaders(),
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({ theme: theme })
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (response.ok) {
|
||||
showThemeMessage(data.message || '主题切换成功', 'success');
|
||||
currentTheme = theme;
|
||||
loadThemes();
|
||||
} else {
|
||||
showThemeMessage(data.error || '主题切换失败', 'error');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('切换主题失败:', error);
|
||||
showThemeMessage('切换主题失败', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 主题编辑器 ====================
|
||||
|
||||
let currentEditingTheme = null;
|
||||
let currentEditingFile = null;
|
||||
let themeFiles = [];
|
||||
|
||||
// 编辑主题
|
||||
async function editTheme(themeName) {
|
||||
currentEditingTheme = themeName;
|
||||
currentEditingFile = null;
|
||||
|
||||
document.getElementById('editor-theme-name').textContent = themeName;
|
||||
document.getElementById('current-file-name').textContent = '选择文件进行编辑';
|
||||
document.getElementById('theme-file-editor').value = '';
|
||||
|
||||
showPage('theme-editor');
|
||||
|
||||
// 加载主题文件列表
|
||||
await loadThemeFiles(themeName);
|
||||
}
|
||||
|
||||
// 加载主题文件列表
|
||||
async function loadThemeFiles(themeName) {
|
||||
try {
|
||||
const response = await fetch(`${API_BASE}/themes/${themeName}/files`, {
|
||||
headers: getHeaders()
|
||||
});
|
||||
const data = await response.json();
|
||||
|
||||
if (response.ok) {
|
||||
themeFiles = data.files || [];
|
||||
displayThemeFiles(themeFiles);
|
||||
} else {
|
||||
showThemeMessage(data.error || '加载文件列表失败', 'error');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载文件列表失败:', error);
|
||||
showThemeMessage('加载文件列表失败', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
// 显示主题文件列表
|
||||
function displayThemeFiles(files) {
|
||||
const filesContainer = document.getElementById('theme-files');
|
||||
filesContainer.innerHTML = '';
|
||||
|
||||
if (files.length === 0) {
|
||||
filesContainer.innerHTML = '<p class="no-files">暂无文件</p>';
|
||||
return;
|
||||
}
|
||||
|
||||
files.forEach(file => {
|
||||
const fileItem = document.createElement('div');
|
||||
fileItem.className = 'theme-file-item';
|
||||
fileItem.innerHTML = `
|
||||
<span class="file-icon">${getFileIcon(file)}</span>
|
||||
<span class="file-name">${file}</span>
|
||||
`;
|
||||
fileItem.onclick = () => loadFileContent(file);
|
||||
filesContainer.appendChild(fileItem);
|
||||
});
|
||||
}
|
||||
|
||||
// 获取文件图标
|
||||
function getFileIcon(filename) {
|
||||
if (filename.endsWith('.html')) return '📄';
|
||||
if (filename.endsWith('.css')) return '🎨';
|
||||
if (filename.endsWith('.js')) return '📜';
|
||||
return '📁';
|
||||
}
|
||||
|
||||
// 加载文件内容
|
||||
async function loadFileContent(filename) {
|
||||
try {
|
||||
currentEditingFile = filename;
|
||||
|
||||
const response = await fetch(`${API_BASE}/themes/${currentEditingTheme}/files/${filename}`, {
|
||||
headers: getHeaders()
|
||||
});
|
||||
const data = await response.json();
|
||||
|
||||
if (response.ok) {
|
||||
document.getElementById('current-file-name').textContent = filename;
|
||||
document.getElementById('theme-file-editor').value = data.content || '';
|
||||
|
||||
// 高亮当前文件
|
||||
document.querySelectorAll('.theme-file-item').forEach(item => {
|
||||
item.classList.remove('active');
|
||||
});
|
||||
event.currentTarget.classList.add('active');
|
||||
} else {
|
||||
showThemeMessage(data.error || '加载文件失败', 'error');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载文件失败:', error);
|
||||
showThemeMessage('加载文件失败', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
// 保存当前文件
|
||||
async function saveCurrentFile() {
|
||||
if (!currentEditingTheme || !currentEditingFile) {
|
||||
showThemeMessage('请先选择文件', 'warning');
|
||||
return;
|
||||
}
|
||||
|
||||
const content = document.getElementById('theme-file-editor').value;
|
||||
|
||||
try {
|
||||
const response = await fetch(`${API_BASE}/themes/${currentEditingTheme}/files/${currentEditingFile}`, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
...getHeaders(),
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({ content: content })
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (response.ok) {
|
||||
showThemeMessage(data.message || '文件保存成功', 'success');
|
||||
|
||||
// 如果是模板文件,重新加载主题
|
||||
if (currentEditingFile.endsWith('.html')) {
|
||||
const renderer = await fetch(`${API_BASE}/theme`, { headers: getHeaders() });
|
||||
const rendererData = await renderer.json();
|
||||
if (rendererData.theme === currentEditingTheme) {
|
||||
// 重新加载当前主题以应用更改
|
||||
await fetch(`${API_BASE}/theme`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
...getHeaders(),
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({ theme: currentEditingTheme })
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
showThemeMessage(data.error || '保存文件失败', 'error');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('保存文件失败:', error);
|
||||
showThemeMessage('保存文件失败', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
+79
-1
@@ -4,6 +4,7 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>后台管理 - GoBlog</title>
|
||||
<link rel="icon" href="/static/images/favicon.ico" type="image/x-icon">
|
||||
<link rel="stylesheet" href="/static/admin/style.css">
|
||||
</head>
|
||||
<body>
|
||||
@@ -20,6 +21,7 @@
|
||||
<a href="#tags" class="menu-item" data-page="tags">标签管理</a>
|
||||
<a href="#pages" class="menu-item" data-page="pages">页面管理</a>
|
||||
<a href="#comments" class="menu-item" data-page="comments">评论管理</a>
|
||||
<a href="#themes" class="menu-item" data-page="themes">主题管理</a>
|
||||
</nav>
|
||||
<div class="user-info">
|
||||
<span id="username">Admin</span>
|
||||
@@ -218,6 +220,50 @@
|
||||
<tbody id="comments-list"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- 主题管理 -->
|
||||
<div id="themes-page" class="page hidden">
|
||||
<div class="page-header">
|
||||
<h1>主题管理</h1>
|
||||
<button class="btn-primary" onclick="showCreateThemeModal()">新建主题</button>
|
||||
</div>
|
||||
<div class="theme-settings">
|
||||
<div class="form-group">
|
||||
<label>当前主题</label>
|
||||
<select id="theme-select" class="theme-selector">
|
||||
<option value="">加载中...</option>
|
||||
</select>
|
||||
</div>
|
||||
<button class="btn-primary" onclick="switchTheme()">切换主题</button>
|
||||
<div id="theme-message" class="theme-message"></div>
|
||||
</div>
|
||||
<div class="theme-list" id="theme-list">
|
||||
<!-- 主题列表将动态加载 -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 主题编辑器 -->
|
||||
<div id="theme-editor-page" class="page hidden">
|
||||
<div class="page-header">
|
||||
<h1>编辑主题: <span id="editor-theme-name"></span></h1>
|
||||
<div>
|
||||
<button class="btn-secondary" onclick="showPage('themes')">返回</button>
|
||||
<button class="btn-primary" onclick="saveCurrentFile()">保存文件</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="theme-editor-container">
|
||||
<div class="theme-file-list">
|
||||
<h3>文件列表</h3>
|
||||
<div id="theme-files"></div>
|
||||
</div>
|
||||
<div class="theme-editor-content">
|
||||
<div class="editor-header">
|
||||
<h3 id="current-file-name">选择文件进行编辑</h3>
|
||||
</div>
|
||||
<textarea id="theme-file-editor" class="code-editor" placeholder="选择左侧文件进行编辑..."></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
@@ -247,6 +293,38 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/static/admin/app.js?v=6"></script>
|
||||
<!-- 创建主题弹窗 -->
|
||||
<div id="theme-modal" class="modal hidden">
|
||||
<div class="modal-content modal-large">
|
||||
<h3>新建主题</h3>
|
||||
<form id="create-theme-form">
|
||||
<div class="form-group">
|
||||
<label>主题名称 *</label>
|
||||
<input type="text" id="new-theme-name" required placeholder="例如: mytheme">
|
||||
<small>只能包含字母、数字和下划线</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>基于模板创建</label>
|
||||
<select id="theme-template">
|
||||
<option value="default">default(默认主题)</option>
|
||||
<option value="minimal">minimal(极简主题)</option>
|
||||
<option value="blank">blank(空白主题)</option>
|
||||
</select>
|
||||
<small>选择新主题的初始模板</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<input type="checkbox" id="create-css" checked> 创建样式文件
|
||||
</label>
|
||||
</div>
|
||||
<div class="modal-actions">
|
||||
<button type="button" class="btn-secondary" onclick="hideThemeModal()">取消</button>
|
||||
<button type="submit" class="btn-primary">创建主题</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/static/admin/app.js?v=9"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -358,3 +358,307 @@ body {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
/* 主题管理 */
|
||||
.theme-settings {
|
||||
background: #fff;
|
||||
padding: 24px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.theme-settings .form-group {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.theme-settings label {
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.theme-selector {
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
padding: 10px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
background: #fff;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.theme-selector:focus {
|
||||
outline: none;
|
||||
border-color: #1890ff;
|
||||
}
|
||||
|
||||
.theme-settings .btn-primary {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.theme-message {
|
||||
margin-top: 15px;
|
||||
padding: 10px 15px;
|
||||
border-radius: 4px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.theme-message.success {
|
||||
background: #f6ffed;
|
||||
border: 1px solid #b7eb8f;
|
||||
color: #52c41a;
|
||||
}
|
||||
|
||||
.theme-message.error {
|
||||
background: #fff2f0;
|
||||
border: 1px solid #ffccc7;
|
||||
color: #ff4d4f;
|
||||
}
|
||||
|
||||
.theme-message.warning {
|
||||
background: #fffbe6;
|
||||
border: 1px solid #ffe58f;
|
||||
color: #faad14;
|
||||
}
|
||||
|
||||
.theme-list {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.theme-card {
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
||||
border: 2px solid transparent;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.theme-card:hover {
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.theme-card.active {
|
||||
border-color: #1890ff;
|
||||
background: #f0f9ff;
|
||||
}
|
||||
|
||||
.theme-card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 15px;
|
||||
padding-bottom: 15px;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.theme-card-header h3 {
|
||||
font-size: 18px;
|
||||
color: #333;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.theme-badge {
|
||||
background: #1890ff;
|
||||
color: #fff;
|
||||
padding: 4px 12px;
|
||||
border-radius: 12px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.theme-card-body p {
|
||||
margin: 8px 0;
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.theme-list {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.theme-settings {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.theme-selector {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
/* 大尺寸模态框 */
|
||||
.modal-large {
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
.modal-large .form-group small {
|
||||
display: block;
|
||||
margin-top: 5px;
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.modal-large input[type="text"] {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.modal-large input[type="checkbox"] {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
/* 主题卡片操作按钮 */
|
||||
.theme-card-actions {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
margin-top: 15px;
|
||||
padding-top: 15px;
|
||||
border-top: 1px solid #eee;
|
||||
}
|
||||
|
||||
.btn-small {
|
||||
padding: 6px 12px;
|
||||
font-size: 13px;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.btn-small.btn-secondary {
|
||||
background: #f5f5f5;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.btn-small.btn-secondary:hover {
|
||||
background: #e8e8e8;
|
||||
}
|
||||
|
||||
.btn-small.btn-primary {
|
||||
background: #1890ff;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.btn-small.btn-primary:hover {
|
||||
background: #40a9ff;
|
||||
}
|
||||
|
||||
/* 主题编辑器 */
|
||||
.theme-editor-container {
|
||||
display: grid;
|
||||
grid-template-columns: 280px 1fr;
|
||||
gap: 20px;
|
||||
height: calc(100vh - 200px);
|
||||
}
|
||||
|
||||
.theme-file-list {
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.theme-file-list h3 {
|
||||
margin: 0 0 15px;
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.theme-file-item {
|
||||
padding: 12px;
|
||||
margin-bottom: 8px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.theme-file-item:hover {
|
||||
background: #e6f7ff;
|
||||
}
|
||||
|
||||
.theme-file-item.active {
|
||||
background: #1890ff;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.theme-file-item .file-icon {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.theme-file-item .file-name {
|
||||
flex: 1;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.theme-editor-content {
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.editor-header {
|
||||
margin-bottom: 15px;
|
||||
padding-bottom: 15px;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.editor-header h3 {
|
||||
margin: 0;
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.code-editor {
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
padding: 15px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 6px;
|
||||
font-family: 'Courier New', monospace;
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
resize: none;
|
||||
background: #f9f9f9;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.code-editor:focus {
|
||||
outline: none;
|
||||
border-color: #1890ff;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.no-files {
|
||||
text-align: center;
|
||||
color: #999;
|
||||
padding: 40px 20px;
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
.theme-editor-container {
|
||||
grid-template-columns: 1fr;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.theme-file-list {
|
||||
max-height: 300px;
|
||||
}
|
||||
|
||||
.code-editor {
|
||||
min-height: 500px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,542 @@
|
||||
/* 极简主题 - Minimal Theme */
|
||||
/* 基础样式重置 */
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Georgia', 'Times New Roman', serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.8;
|
||||
color: #e0e0e0;
|
||||
background-color: #121212;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #64b5f6;
|
||||
text-decoration: none;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #90caf9;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 0 25px;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* 头部样式 */
|
||||
.header {
|
||||
background: #1e1e1e;
|
||||
padding: 40px 0;
|
||||
border-bottom: 1px solid #333;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.site-title {
|
||||
font-size: 32px;
|
||||
font-weight: 400;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
.site-title a {
|
||||
color: #e0e0e0;
|
||||
}
|
||||
|
||||
.site-title a:hover {
|
||||
color: #64b5f6;
|
||||
}
|
||||
|
||||
.site-desc {
|
||||
color: #9e9e9e;
|
||||
margin-top: 10px;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.main-nav {
|
||||
margin-top: 25px;
|
||||
padding-top: 25px;
|
||||
border-top: 1px solid #333;
|
||||
}
|
||||
|
||||
.main-nav a {
|
||||
margin-right: 25px;
|
||||
color: #9e9e9e;
|
||||
font-size: 15px;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.main-nav a:hover {
|
||||
color: #64b5f6;
|
||||
}
|
||||
|
||||
/* 主内容区 */
|
||||
.main {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
/* 文章列表 */
|
||||
.post-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 40px;
|
||||
}
|
||||
|
||||
.post-item {
|
||||
padding-bottom: 40px;
|
||||
border-bottom: 1px solid #333;
|
||||
}
|
||||
|
||||
.post-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.post-title {
|
||||
font-size: 26px;
|
||||
margin-bottom: 15px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.post-title a {
|
||||
color: #e0e0e0;
|
||||
}
|
||||
|
||||
.post-title a:hover {
|
||||
color: #64b5f6;
|
||||
}
|
||||
|
||||
.top-badge {
|
||||
display: inline-block;
|
||||
background: #d32f2f;
|
||||
color: #fff;
|
||||
font-size: 11px;
|
||||
padding: 3px 10px;
|
||||
border-radius: 3px;
|
||||
margin-left: 10px;
|
||||
vertical-align: middle;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.post-meta {
|
||||
color: #757575;
|
||||
font-size: 14px;
|
||||
margin-bottom: 20px;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.post-meta span {
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.post-meta a {
|
||||
color: #9e9e9e;
|
||||
}
|
||||
|
||||
.tag {
|
||||
display: inline-block;
|
||||
background: #2c2c2c;
|
||||
padding: 3px 10px;
|
||||
border-radius: 3px;
|
||||
font-size: 12px;
|
||||
margin-right: 8px;
|
||||
color: #9e9e9e;
|
||||
}
|
||||
|
||||
.tag:hover {
|
||||
background: #383838;
|
||||
color: #64b5f6;
|
||||
}
|
||||
|
||||
.post-summary {
|
||||
color: #b0b0b0;
|
||||
line-height: 1.9;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.read-more {
|
||||
display: inline-block;
|
||||
color: #64b5f6;
|
||||
font-weight: 400;
|
||||
border-bottom: 1px solid transparent;
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
|
||||
.read-more:hover {
|
||||
border-bottom-color: #64b5f6;
|
||||
}
|
||||
|
||||
/* 文章详情 */
|
||||
.post-detail {
|
||||
background: #1e1e1e;
|
||||
padding: 45px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #333;
|
||||
}
|
||||
|
||||
.post-header {
|
||||
margin-bottom: 35px;
|
||||
padding-bottom: 25px;
|
||||
border-bottom: 1px solid #333;
|
||||
}
|
||||
|
||||
.post-detail .post-title {
|
||||
font-size: 32px;
|
||||
margin-bottom: 20px;
|
||||
font-weight: 400;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.post-body {
|
||||
line-height: 1.9;
|
||||
color: #d0d0d0;
|
||||
}
|
||||
|
||||
.post-body h2,
|
||||
.post-body h3,
|
||||
.post-body h4 {
|
||||
margin: 35px 0 20px;
|
||||
color: #e0e0e0;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.post-body h2 {
|
||||
font-size: 26px;
|
||||
border-bottom: 1px solid #333;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.post-body h3 {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.post-body p {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.post-body img {
|
||||
max-width: 100%;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #333;
|
||||
}
|
||||
|
||||
.post-body pre {
|
||||
background: #252525;
|
||||
padding: 20px;
|
||||
border-radius: 4px;
|
||||
overflow-x: auto;
|
||||
border: 1px solid #333;
|
||||
margin: 25px 0;
|
||||
}
|
||||
|
||||
.post-body code {
|
||||
background: #252525;
|
||||
padding: 3px 8px;
|
||||
border-radius: 3px;
|
||||
font-family: 'Courier New', monospace;
|
||||
font-size: 14px;
|
||||
border: 1px solid #333;
|
||||
}
|
||||
|
||||
.post-body blockquote {
|
||||
border-left: 3px solid #64b5f6;
|
||||
padding-left: 20px;
|
||||
margin: 25px 0;
|
||||
color: #9e9e9e;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.post-body ul,
|
||||
.post-body ol {
|
||||
margin: 20px 0;
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
||||
.post-body li {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
/* 页面 */
|
||||
.page-detail {
|
||||
background: #1e1e1e;
|
||||
padding: 45px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #333;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-size: 32px;
|
||||
margin-bottom: 25px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.page-body {
|
||||
line-height: 1.9;
|
||||
color: #d0d0d0;
|
||||
}
|
||||
|
||||
/* 分页 */
|
||||
.pagination {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 25px;
|
||||
margin-top: 50px;
|
||||
padding: 25px;
|
||||
}
|
||||
|
||||
.pagination a {
|
||||
padding: 10px 20px;
|
||||
background: #1e1e1e;
|
||||
border: 1px solid #333;
|
||||
border-radius: 4px;
|
||||
color: #9e9e9e;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.pagination a:hover {
|
||||
background: #2c2c2c;
|
||||
border-color: #64b5f6;
|
||||
color: #64b5f6;
|
||||
}
|
||||
|
||||
.page-info {
|
||||
color: #757575;
|
||||
}
|
||||
|
||||
/* 评论区 */
|
||||
.comments-section {
|
||||
background: #1e1e1e;
|
||||
padding: 35px;
|
||||
margin-top: 40px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #333;
|
||||
}
|
||||
|
||||
.comments-section h3 {
|
||||
margin-bottom: 25px;
|
||||
font-weight: 400;
|
||||
font-size: 22px;
|
||||
color: #e0e0e0;
|
||||
}
|
||||
|
||||
.comment-form {
|
||||
margin-bottom: 35px;
|
||||
padding-bottom: 35px;
|
||||
border-bottom: 1px solid #333;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.form-group input,
|
||||
.form-group textarea {
|
||||
width: 100%;
|
||||
padding: 12px;
|
||||
background: #252525;
|
||||
border: 1px solid #333;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
color: #e0e0e0;
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
.form-group input:focus,
|
||||
.form-group textarea:focus {
|
||||
outline: none;
|
||||
border-color: #64b5f6;
|
||||
}
|
||||
|
||||
.form-group textarea {
|
||||
min-height: 120px;
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
.comment-form button {
|
||||
background: #64b5f6;
|
||||
color: #121212;
|
||||
border: none;
|
||||
padding: 12px 30px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
transition: background 0.3s ease;
|
||||
}
|
||||
|
||||
.comment-form button:hover {
|
||||
background: #90caf9;
|
||||
}
|
||||
|
||||
.comments-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 25px;
|
||||
}
|
||||
|
||||
.comment-item {
|
||||
padding: 20px;
|
||||
background: #252525;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #333;
|
||||
}
|
||||
|
||||
.comment-item.child {
|
||||
margin-left: 35px;
|
||||
margin-top: 15px;
|
||||
background: #2a2a2a;
|
||||
}
|
||||
|
||||
.comment-header {
|
||||
margin-bottom: 12px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.comment-author {
|
||||
font-weight: 500;
|
||||
color: #e0e0e0;
|
||||
}
|
||||
|
||||
.comment-author a {
|
||||
color: #64b5f6;
|
||||
}
|
||||
|
||||
.comment-date {
|
||||
color: #757575;
|
||||
margin-left: 12px;
|
||||
}
|
||||
|
||||
.comment-content {
|
||||
color: #b0b0b0;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.no-comments {
|
||||
color: #757575;
|
||||
text-align: center;
|
||||
padding: 40px;
|
||||
}
|
||||
|
||||
/* 空状态 */
|
||||
.empty {
|
||||
text-align: center;
|
||||
padding: 80px;
|
||||
color: #757575;
|
||||
background: #1e1e1e;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #333;
|
||||
}
|
||||
|
||||
/* 底部 */
|
||||
.footer {
|
||||
background: #1e1e1e;
|
||||
padding: 35px 0;
|
||||
margin-top: 60px;
|
||||
text-align: center;
|
||||
color: #757575;
|
||||
border-top: 1px solid #333;
|
||||
}
|
||||
|
||||
/* 文章导航 - 上一篇/下一篇 */
|
||||
.post-navigation {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 25px;
|
||||
margin: 35px 0;
|
||||
padding: 25px;
|
||||
background: #1e1e1e;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #333;
|
||||
}
|
||||
|
||||
.nav-prev,
|
||||
.nav-next {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.nav-next {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 15px;
|
||||
border-radius: 4px;
|
||||
transition: background-color 0.3s;
|
||||
}
|
||||
|
||||
.nav-link:hover {
|
||||
background-color: #252525;
|
||||
}
|
||||
|
||||
.nav-link.disabled {
|
||||
color: #757575;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.nav-link.disabled:hover {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.nav-label {
|
||||
font-size: 13px;
|
||||
color: #757575;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.nav-title {
|
||||
font-size: 15px;
|
||||
font-weight: 400;
|
||||
color: #e0e0e0;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.nav-link:hover .nav-title {
|
||||
color: #64b5f6;
|
||||
}
|
||||
|
||||
/* 响应式 */
|
||||
@media (max-width: 768px) {
|
||||
.site-title {
|
||||
font-size: 26px;
|
||||
}
|
||||
|
||||
.post-detail,
|
||||
.page-detail {
|
||||
padding: 25px;
|
||||
}
|
||||
|
||||
.post-detail .post-title {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.post-meta span {
|
||||
display: block;
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
.post-navigation {
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.nav-next {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.comment-item.child {
|
||||
margin-left: 20px;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/* mytheme Theme */
|
||||
/* 在此添加你的样式 */
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
.header {
|
||||
background: #fff;
|
||||
padding: 20px 0;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.site-title {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.site-title a {
|
||||
color: #333;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.site-desc {
|
||||
color: #666;
|
||||
margin: 10px 0 0;
|
||||
}
|
||||
|
||||
.main-nav {
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.main-nav a {
|
||||
margin-right: 15px;
|
||||
color: #666;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.main {
|
||||
padding: 30px 0;
|
||||
min-height: 500px;
|
||||
}
|
||||
|
||||
.footer {
|
||||
background: #f5f5f5;
|
||||
padding: 20px 0;
|
||||
text-align: center;
|
||||
color: #999;
|
||||
}
|
||||
+207
-1
@@ -23,11 +23,208 @@ a:hover {
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 900px;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
/* 内容区域布局 */
|
||||
.content-wrapper {
|
||||
display: flex;
|
||||
gap: 30px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
/* 侧边栏 */
|
||||
.sidebar {
|
||||
width: 300px;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.sidebar-widget {
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.08);
|
||||
}
|
||||
|
||||
.widget-title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 15px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 2px solid #1890ff;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
/* 博客信息 */
|
||||
.blog-info {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.blog-avatar {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border-radius: 50%;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.blog-name {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.blog-description {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.blog-stats {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
margin-top: 15px;
|
||||
padding-top: 15px;
|
||||
border-top: 1px solid #eee;
|
||||
}
|
||||
|
||||
.stat-item {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.stat-number {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: #1890ff;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
/* 搜索框 */
|
||||
.search-form {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.search-input {
|
||||
flex: 1;
|
||||
padding: 8px 12px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
outline: none;
|
||||
transition: border-color 0.2s;
|
||||
}
|
||||
|
||||
.search-input:focus {
|
||||
border-color: #1890ff;
|
||||
}
|
||||
|
||||
.search-btn {
|
||||
padding: 8px 16px;
|
||||
background: #1890ff;
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
transition: background 0.2s;
|
||||
}
|
||||
|
||||
.search-btn:hover {
|
||||
background: #40a9ff;
|
||||
}
|
||||
|
||||
/* 分类列表 */
|
||||
.category-list {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.category-item {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.category-link {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 8px 12px;
|
||||
color: #666;
|
||||
border-radius: 4px;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.category-link:hover {
|
||||
background: #f0f9ff;
|
||||
color: #1890ff;
|
||||
}
|
||||
|
||||
.category-count {
|
||||
background: #f0f0f0;
|
||||
padding: 2px 8px;
|
||||
border-radius: 12px;
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
/* 标签云 */
|
||||
.tag-cloud {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.tag-item {
|
||||
display: inline-block;
|
||||
padding: 4px 12px;
|
||||
background: #f0f0f0;
|
||||
color: #666;
|
||||
border-radius: 4px;
|
||||
font-size: 13px;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.tag-item:hover {
|
||||
background: #1890ff;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* 系统菜单 */
|
||||
.system-menu {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.system-menu-item {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.system-menu-link {
|
||||
display: block;
|
||||
padding: 8px 12px;
|
||||
color: #666;
|
||||
border-radius: 4px;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.system-menu-link:hover {
|
||||
background: #f0f9ff;
|
||||
color: #1890ff;
|
||||
}
|
||||
|
||||
/* 头部样式 */
|
||||
.header {
|
||||
background: #fff;
|
||||
@@ -441,4 +638,13 @@ a:hover {
|
||||
.nav-next {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
/* 移动端 sidebar 隐藏或置底 */
|
||||
.content-wrapper {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user