Files
aitsc/src/flask_prompt_master/templates/base.html
rjb 1a87798b8a
Some checks failed
Flask 提示词大师 - CI/CD 流水线 / 代码质量检查 (push) Has been cancelled
Flask 提示词大师 - CI/CD 流水线 / 单元测试 (push) Has been cancelled
Flask 提示词大师 - CI/CD 流水线 / 集成测试 (push) Has been cancelled
Flask 提示词大师 - CI/CD 流水线 / 构建Docker镜像 (push) Has been cancelled
Flask 提示词大师 - CI/CD 流水线 / 部署到测试环境 (push) Has been cancelled
Flask 提示词大师 - CI/CD 流水线 / 部署到生产环境 (push) Has been cancelled
Flask 提示词大师 - CI/CD 流水线 / 部署监控系统 (push) Has been cancelled
temp
2026-02-23 17:50:22 +08:00

629 lines
20 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>提示词大师 - {% block title %}{% endblock %}</title>
<!-- 添加 Google Fonts - Inter字体 -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<!-- Font Awesome -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- jQuery -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<!-- Bootstrap JS -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
<style>
/* 全局样式 - 深蓝色科技感主题 */
:root {
/* 主色调 - 深蓝色系 */
--primary-color: #1E3A8A; /* 深蓝主色 */
--primary-light: #3B82F6; /* 浅蓝 */
--primary-dark: #1E40AF; /* 深蓝 */
--primary-lighter: #60A5FA; /* 更浅蓝 */
/* 辅助色 - 渐变蓝紫 */
--secondary-color: #6366F1; /* 紫蓝 */
--accent-color: #8B5CF6; /* 紫色 */
--gradient-primary: linear-gradient(135deg, #6366F1, #8B5CF6);
--gradient-secondary: linear-gradient(135deg, #1E3A8A, #3B82F6);
/* 功能色 */
--success-color: #10B981; /* 绿色 */
--warning-color: #F59E0B; /* 橙色 */
--error-color: #EF4444; /* 红色 */
--info-color: #06B6D4; /* 青色 */
/* 中性色 */
--background-color: #F8FAFC; /* 中性背景 */
--background-secondary: #F1F5F9; /* 次要背景 */
--border-color: #E2E8F0; /* 边框色 */
--border-light: #F1F5F9; /* 浅边框 */
/* 文字色 */
--text-color: #0F172A; /* 深色文字 */
--text-secondary: #475569; /* 次要文字 */
--text-light: #64748B; /* 浅色文字 */
--text-muted: #94A3B8; /* 静音文字 */
/* 阴影 */
--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
--shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
line-height: 1.6;
color: var(--text-color);
background-color: var(--background-color);
font-weight: 400;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/* 字体层次系统 */
h1, h2, h3, h4, h5, h6 {
font-family: 'Inter', sans-serif;
font-weight: 600;
line-height: 1.3;
color: var(--text-color);
}
.font-display {
font-family: 'Inter', sans-serif;
font-weight: 700;
}
.font-mono {
font-family: 'SF Mono', 'Monaco', 'Consolas', 'Liberation Mono', 'Courier New', monospace;
}
/* 导航栏样式 - 科技感设计 */
header {
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px);
border-bottom: 1px solid var(--border-light);
box-shadow: var(--shadow-sm);
position: sticky;
top: 0;
z-index: 100;
}
nav {
max-width: 1200px;
margin: 0 auto;
padding: 1rem;
display: flex;
justify-content: space-between;
align-items: center;
}
.nav-brand {
font-size: 1.5rem;
font-weight: 700;
background: var(--gradient-primary);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
text-decoration: none;
display: flex;
align-items: center;
gap: 0.75rem;
transition: all 0.3s ease;
}
.nav-brand:hover {
transform: scale(1.05);
}
.nav-brand i {
font-size: 1.5rem;
}
.nav-links {
display: flex;
gap: 1rem;
align-items: center;
}
.nav-link {
color: var(--text-secondary);
text-decoration: none;
padding: 0.75rem 1rem;
border-radius: 8px;
transition: all 0.3s ease;
display: flex;
align-items: center;
gap: 0.5rem;
white-space: nowrap;
min-width: fit-content;
font-weight: 500;
position: relative;
overflow: hidden;
}
.nav-link::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: var(--gradient-primary);
opacity: 0.1;
transition: left 0.3s ease;
z-index: -1;
}
.nav-link:hover {
color: var(--primary-color);
transform: translateY(-1px);
box-shadow: var(--shadow-md);
}
.nav-link:hover::before {
left: 0;
}
.nav-link i {
font-size: 1rem;
}
/* 响应式导航栏 */
@media (max-width: 1200px) {
.nav-links {
gap: 0.5rem;
}
.nav-link {
padding: 0.5rem 0.75rem;
font-size: 0.9rem;
}
}
@media (max-width: 992px) {
.nav-links {
gap: 0.25rem;
}
.nav-link {
padding: 0.5rem 0.5rem;
font-size: 0.85rem;
position: relative;
}
.nav-link span {
display: none;
}
.nav-link i {
font-size: 1.1rem;
}
/* 工具提示 */
.nav-link::after {
content: attr(data-tooltip);
position: absolute;
bottom: -35px;
left: 50%;
transform: translateX(-50%);
background: rgba(0, 0, 0, 0.8);
color: white;
padding: 0.5rem 0.75rem;
border-radius: 4px;
font-size: 0.75rem;
white-space: nowrap;
opacity: 0;
visibility: hidden;
transition: all 0.3s ease;
z-index: 1000;
pointer-events: none;
}
.nav-link:hover::after {
opacity: 1;
visibility: visible;
}
}
@media (max-width: 768px) {
nav {
flex-direction: column;
gap: 1rem;
padding: 1rem;
}
.nav-links {
flex-wrap: wrap;
justify-content: center;
gap: 0.5rem;
}
.nav-link {
padding: 0.5rem 1rem;
font-size: 0.9rem;
}
.nav-link span {
display: inline;
}
}
.user-menu {
display: flex;
align-items: center;
}
/* 导航栏分类样式 */
.nav-primary {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
font-weight: 600;
}
.nav-primary:hover {
background: linear-gradient(135deg, #5a6fd8 0%, #6a4190 100%);
color: white;
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
}
.nav-featured {
background: white;
border: 1px solid var(--border-light);
color: var(--text-primary);
position: relative;
}
.nav-featured:hover {
background: var(--background-light);
border-color: var(--primary-color);
color: var(--primary-color);
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
.nav-badge {
position: absolute;
top: -4px;
right: -4px;
background: #ff6b6b;
color: white;
font-size: 0.625rem;
font-weight: 600;
padding: 0.125rem 0.375rem;
border-radius: 10px;
text-transform: uppercase;
letter-spacing: 0.5px;
box-shadow: 0 2px 4px rgba(255, 107, 107, 0.3);
}
.nav-featured:nth-child(5) .nav-badge {
background: #4ecdc4;
}
.nav-featured:nth-child(6) .nav-badge {
background: #f093fb;
}
.user-menu .dropdown-toggle {
color: var(--text-color);
text-decoration: none;
padding: 0.5rem 1rem;
border-radius: 4px;
transition: all 0.3s ease;
display: flex;
align-items: center;
gap: 0.5rem;
}
.user-menu .dropdown-toggle:hover {
background: var(--background-color);
color: var(--primary-color);
}
.user-menu .dropdown-menu {
min-width: 220px;
border: none;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
border-radius: 8px;
padding: 0.5rem 0;
}
.user-menu .dropdown-toggle {
background: var(--gradient-primary);
border: none;
color: white;
text-decoration: none;
padding: 0.75rem 1.25rem;
border-radius: 12px;
transition: all 0.3s ease;
display: flex;
align-items: center;
gap: 0.5rem;
font-weight: 600;
box-shadow: var(--shadow-md);
position: relative;
}
.user-menu .dropdown-toggle::after {
content: '';
border: none;
width: 0;
height: 0;
border-left: 4px solid transparent;
border-right: 4px solid transparent;
border-top: 4px solid white;
margin-left: 0.5rem;
}
.user-menu .dropdown-toggle:hover {
transform: translateY(-2px);
box-shadow: var(--shadow-lg);
background: var(--gradient-secondary);
}
.user-menu .dropdown-toggle:focus {
box-shadow: 0 0 0 2px rgba(33, 150, 243, 0.2);
}
.user-menu .user-name {
max-width: 120px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.user-menu .dropdown-item {
padding: 0.75rem 1rem;
display: flex;
align-items: center;
transition: all 0.2s ease;
}
.user-menu .dropdown-item:hover {
background: var(--background-color);
color: var(--primary-color);
}
.user-menu .dropdown-item i {
width: 16px;
text-align: center;
}
.user-menu .dropdown-header {
padding: 0.5rem 1rem;
font-size: 0.75rem;
font-weight: 600;
color: var(--text-light);
text-transform: uppercase;
letter-spacing: 0.5px;
}
.user-menu .dropdown-divider {
margin: 0.5rem 0;
border-color: var(--border-color);
}
/* 响应式用户菜单 */
@media (max-width: 992px) {
.user-menu .dropdown-toggle .user-name {
display: none;
}
.user-menu .dropdown-toggle {
padding: 0.5rem;
}
}
/* 主要内容区域 */
main {
min-height: calc(100vh - 120px);
}
/* 闪现消息样式 */
.flash-messages {
position: fixed;
top: 1rem;
right: 1rem;
z-index: 1000;
}
.flash-message {
background: white;
padding: 1rem;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
margin-bottom: 0.5rem;
animation: slideIn 0.3s ease-out;
}
@keyframes slideIn {
from {
transform: translateX(100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
/* 页脚样式 */
footer {
background: white;
padding: 2rem 1rem;
text-align: center;
color: var(--text-light);
margin-top: 3rem;
}
/* 响应式设计 */
@media (max-width: 768px) {
nav {
padding: 1rem;
}
}
</style>
{% block extra_css %}{% endblock %}
<script>
// 检查登录状态并更新用户菜单
function updateUserMenu() {
fetch('/api/check-login')
.then(response => response.json())
.then(data => {
const userMenu = document.getElementById('userMenu');
if (data.logged_in) {
userMenu.innerHTML = `
<div class="dropdown">
<a class="dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
<i class="fas fa-user-circle"></i>
<span class="user-name">${data.user.nickname}</span>
</a>
<ul class="dropdown-menu dropdown-menu-end">
<li><h6 class="dropdown-header">用户中心</h6></li>
<li><a class="dropdown-item" href="/profile">
<i class="fas fa-user me-2"></i>个人资料
</a></li>
<li><a class="dropdown-item" href="/history">
<i class="fas fa-history me-2"></i>优化历史
</a></li>
<li><a class="dropdown-item" href="/favorites">
<i class="fas fa-heart me-2"></i>我的收藏
</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item text-danger" href="#" onclick="logout()">
<i class="fas fa-sign-out-alt me-2"></i>退出登录
</a></li>
</ul>
</div>
`;
} else {
userMenu.innerHTML = `
<a href="/login" class="nav-link" data-tooltip="登录">
<i class="fas fa-sign-in-alt"></i>
<span>登录</span>
</a>
<a href="/register" class="nav-link" data-tooltip="注册">
<i class="fas fa-user-plus"></i>
<span>注册</span>
</a>
`;
}
})
.catch(error => {
console.error('检查登录状态失败:', error);
// 如果API调用失败显示登录/注册按钮
const userMenu = document.getElementById('userMenu');
userMenu.innerHTML = `
<a href="/login" class="nav-link" data-tooltip="登录">
<i class="fas fa-sign-in-alt"></i>
<span>登录</span>
</a>
<a href="/register" class="nav-link" data-tooltip="注册">
<i class="fas fa-user-plus"></i>
<span>注册</span>
</a>
`;
});
}
function logout() {
fetch('/api/logout', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
}
})
.then(response => response.json())
.then(data => {
if (data.success) {
alert('退出登录成功');
window.location.reload();
} else {
alert(data.message || '退出登录失败');
}
})
.catch(error => {
console.error('退出登录失败:', error);
alert('退出登录失败,请稍后重试');
});
}
// 页面加载时更新用户菜单
document.addEventListener('DOMContentLoaded', function() {
updateUserMenu();
});
</script>
</head>
<body>
<header>
<nav>
<div class="nav-brand">
<i class="fas fa-robot"></i>
AI应用
</div>
<div class="nav-links">
<!-- 核心功能 -->
<a href="{{ url_for('main.index') }}" class="nav-link nav-primary" data-tooltip="首页">
<i class="fas fa-home"></i>
<span>首页</span>
</a>
<!-- 用户功能 -->
<div class="user-menu" id="userMenu">
<!-- 用户菜单将通过JavaScript动态加载 -->
</div>
</div>
</nav>
</header>
<main>
{% with messages = get_flashed_messages() %}
{% if messages %}
<div class="flash-messages">
{% for message in messages %}
<div class="flash-message">{{ message }}</div>
{% endfor %}
</div>
{% endif %}
{% endwith %}
{% block content %}{% endblock %}
</main>
<footer>
<p>&copy; 2025 提示词大师 - 让AI更好地理解您的需求</p>
</footer>
{% block scripts %}{% endblock %}
{% block extra_js %}{% endblock %}
<script>
// 自动隐藏闪现消息
document.addEventListener('DOMContentLoaded', function() {
const messages = document.querySelectorAll('.flash-message');
messages.forEach(message => {
setTimeout(() => {
message.style.opacity = '0';
message.style.transform = 'translateX(100%)';
setTimeout(() => message.remove(), 300);
}, 3000);
});
});
</script>
<!-- 交互增强脚本 -->
<script src="{{ url_for('static', filename='js/interactions.js') }}"></script>
</body>
</html>