页面优化

This commit is contained in:
rjb
2025-10-07 02:00:17 +08:00
parent 3ebcb77ca9
commit fb693e91a6
8 changed files with 1941 additions and 83 deletions

View File

@@ -11,9 +11,68 @@
</div>
</div>
<div class="container mt-4">
<div class="row">
<div class="col-md-8 offset-md-2">
<div class="main-layout">
<!-- 侧边栏切换按钮 -->
<button class="sidebar-toggle" id="sidebarToggle">
<i class="fas fa-filter"></i>
<span>筛选</span>
</button>
<!-- 侧边栏 -->
<div class="sidebar" id="sidebar">
<div class="sidebar-header">
<h3>选择场景</h3>
<button class="sidebar-close" id="sidebarClose">
<i class="fas fa-times"></i>
</button>
</div>
<!-- 筛选控制 -->
<div class="sidebar-filters">
<div class="filter-group">
<label for="industryFilter">行业</label>
<select id="industryFilter" class="custom-select">
<option value="all">全部行业</option>
{% for industry in industries %}
<option value="{{ industry }}">{{ industry }}</option>
{% endfor %}
</select>
</div>
<div class="filter-group">
<label for="professionFilter">职业</label>
<select id="professionFilter" class="custom-select">
<option value="all">全部职业</option>
{% for profession in professions %}
<option value="{{ profession }}">{{ profession }}</option>
{% endfor %}
</select>
</div>
<div class="filter-group">
<label for="subCategoryFilter">领域</label>
<select id="subCategoryFilter" class="custom-select">
<option value="all">全部领域</option>
{% for sub_category in sub_categories %}
<option value="{{ sub_category }}">{{ sub_category }}</option>
{% endfor %}
</select>
</div>
</div>
<!-- 场景分类 -->
<div class="sidebar-categories">
<div class="category-tabs">
<div class="tab active" data-category="all">全部</div>
{% for category in categories %}
<div class="tab" data-category="{{ category }}">{{ category }}</div>
{% endfor %}
</div>
</div>
</div>
<!-- 主内容区域 -->
<div class="main-content">
<div class="d-flex justify-content-between align-items-center mb-4">
<h2>提示词生成器</h2>
<a href="{{ url_for('main.expert_generate') }}" class="btn btn-primary">
@@ -37,36 +96,6 @@
</div>
<div class="templates-section">
<div class="section-header">
<h2>选择场景</h2>
<div class="filter-controls">
<select id="industryFilter" class="custom-select">
<option value="all">全部行业</option>
{% for industry in industries %}
<option value="{{ industry }}">{{ industry }}</option>
{% endfor %}
</select>
<select id="professionFilter" class="custom-select">
<option value="all">全部职业</option>
{% for profession in professions %}
<option value="{{ profession }}">{{ profession }}</option>
{% endfor %}
</select>
<select id="subCategoryFilter" class="custom-select">
<option value="all">全部领域</option>
{% for sub_category in sub_categories %}
<option value="{{ sub_category }}">{{ sub_category }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="category-tabs">
<div class="tab active" data-category="all">全部</div>
{% for category in categories %}
<div class="tab" data-category="{{ category }}">{{ category }}</div>
{% endfor %}
</div>
<div class="template-grid">
{% for template in templates %}
@@ -189,14 +218,89 @@
<style>
:root {
--primary-color: #4a90e2;
--primary-dark: #357abd;
--secondary-color: #f5f7fa;
--text-color: #2c3e50;
--border-color: #e0e0e0;
--hover-color: #e8f0fe;
--success-color: #4CAF50;
--success-dark: #45a049;
/* 间距系统 - 基于4px基准 */
--spacing-unit: 0.25rem; /* 4px基准 */
--spacing-xs: calc(var(--spacing-unit) * 1); /* 4px */
--spacing-sm: calc(var(--spacing-unit) * 2); /* 8px */
--spacing-md: calc(var(--spacing-unit) * 4); /* 16px */
--spacing-lg: calc(var(--spacing-unit) * 6); /* 24px */
--spacing-xl: calc(var(--spacing-unit) * 8); /* 32px */
--spacing-2xl: calc(var(--spacing-unit) * 12); /* 48px */
--spacing-3xl: calc(var(--spacing-unit) * 16); /* 64px */
/* 容器与布局 */
--container-max-width: 1400px;
--section-padding: clamp(2rem, 5vw, 4rem);
--border-radius: 12px;
--border-radius-sm: 8px;
--border-radius-lg: 16px;
/* 色彩系统 - 层级化设计 */
--color-primary: #2563eb;
--color-primary-light: #3b82f6;
--color-primary-dark: #1d4ed8;
--color-secondary: #64748b;
--color-secondary-light: #94a3b8;
--color-secondary-dark: #475569;
--color-success: #10b981;
--color-warning: #f59e0b;
--color-error: #ef4444;
--color-info: #06b6d4;
/* 中性色系 */
--color-white: #ffffff;
--color-gray-50: #f8fafc;
--color-gray-100: #f1f5f9;
--color-gray-200: #e2e8f0;
--color-gray-300: #cbd5e1;
--color-gray-400: #94a3b8;
--color-gray-500: #64748b;
--color-gray-600: #475569;
--color-gray-700: #334155;
--color-gray-800: #1e293b;
--color-gray-900: #0f172a;
/* 字体系统 */
--text-xs: 0.75rem; /* 12px */
--text-sm: 0.875rem; /* 14px */
--text-base: 1rem; /* 16px */
--text-lg: 1.125rem; /* 18px */
--text-xl: 1.25rem; /* 20px */
--text-2xl: 1.5rem; /* 24px */
--text-3xl: 1.875rem; /* 30px */
--text-4xl: 2.25rem; /* 36px */
/* 字重系统 */
--font-weight-normal: 400;
--font-weight-medium: 500;
--font-weight-semibold: 600;
--font-weight-bold: 700;
/* 行高系统 */
--line-height-tight: 1.25;
--line-height-normal: 1.5;
--line-height-relaxed: 1.75;
/* 阴影系统 */
--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
--shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
/* 过渡动画 */
--transition-fast: 150ms ease-in-out;
--transition-normal: 300ms ease-in-out;
--transition-slow: 500ms ease-in-out;
/* 兼容性变量 */
--primary-color: var(--color-primary);
--primary-dark: var(--color-primary-dark);
--secondary-color: var(--color-gray-100);
--text-color: var(--color-gray-800);
--border-color: var(--color-gray-200);
--hover-color: var(--color-gray-50);
--success-color: var(--color-success);
--success-dark: #059669;
}
.hero {
@@ -238,10 +342,164 @@
opacity: 0.1;
}
.main-container {
max-width: 1200px;
/* 主布局 */
.main-layout {
display: flex;
max-width: var(--container-max-width);
margin: 0 auto;
padding: 0 2rem;
gap: var(--spacing-xl);
padding: 0 var(--spacing-lg);
min-height: calc(100vh - 200px);
}
/* 侧边栏切换按钮 */
.sidebar-toggle {
display: none;
position: fixed;
top: 50%;
left: var(--spacing-md);
transform: translateY(-50%);
background: var(--primary-color);
color: var(--color-white);
border: none;
border-radius: var(--border-radius);
padding: var(--spacing-md);
cursor: pointer;
box-shadow: var(--shadow-lg);
z-index: 1000;
transition: var(--transition-normal);
}
.sidebar-toggle:hover {
background: var(--color-primary-dark);
transform: translateY(-50%) scale(1.05);
}
.sidebar-toggle i {
margin-right: var(--spacing-xs);
}
/* 侧边栏 */
.sidebar {
width: 280px;
background: var(--color-white);
border-radius: var(--border-radius);
box-shadow: var(--shadow-md);
padding: var(--spacing-lg);
height: fit-content;
position: sticky;
top: var(--spacing-lg);
transition: var(--transition-normal);
}
.sidebar-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: var(--spacing-lg);
padding-bottom: var(--spacing-md);
border-bottom: 1px solid var(--border-color);
}
.sidebar-header h3 {
margin: 0;
font-size: var(--text-lg);
font-weight: var(--font-weight-semibold);
color: var(--text-color);
}
.sidebar-close {
display: none;
background: none;
border: none;
color: var(--color-gray-500);
cursor: pointer;
padding: var(--spacing-xs);
border-radius: var(--border-radius-sm);
transition: var(--transition-fast);
}
.sidebar-close:hover {
background: var(--color-gray-100);
color: var(--color-gray-700);
}
/* 侧边栏筛选 */
.sidebar-filters {
margin-bottom: var(--spacing-lg);
}
.sidebar-filters .filter-group {
margin-bottom: var(--spacing-md);
}
.sidebar-filters label {
display: block;
margin-bottom: var(--spacing-xs);
font-size: var(--text-sm);
font-weight: var(--font-weight-medium);
color: var(--color-gray-700);
}
.sidebar-filters .custom-select {
width: 100%;
padding: var(--spacing-sm) var(--spacing-md);
border: 1px solid var(--border-color);
border-radius: var(--border-radius-sm);
font-size: var(--text-sm);
background: var(--color-white);
transition: var(--transition-fast);
}
.sidebar-filters .custom-select:focus {
outline: none;
border-color: var(--primary-color);
box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);
}
/* 侧边栏分类 */
.sidebar-categories {
margin-top: var(--spacing-lg);
}
.sidebar-categories .category-tabs {
display: flex;
flex-direction: column;
gap: var(--spacing-xs);
}
.sidebar-categories .tab {
padding: var(--spacing-sm) var(--spacing-md);
background: var(--color-gray-50);
border: 1px solid var(--border-color);
border-radius: var(--border-radius-sm);
cursor: pointer;
transition: var(--transition-fast);
font-size: var(--text-sm);
text-align: left;
}
.sidebar-categories .tab:hover {
background: var(--color-gray-100);
border-color: var(--primary-color);
}
.sidebar-categories .tab.active {
background: var(--primary-color);
color: var(--color-white);
border-color: var(--primary-color);
}
/* 主内容区域 */
.main-content {
flex: 1;
min-width: 0;
}
.main-container {
max-width: var(--container-max-width);
margin: 0 auto;
padding: 0 var(--spacing-lg);
}
.section-header {
@@ -293,30 +551,34 @@
.template-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 1.5rem;
margin-bottom: 2rem;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: var(--spacing-md);
margin-bottom: var(--spacing-2xl);
padding: var(--spacing-sm);
}
.template-card {
position: relative;
transition: transform 0.2s, box-shadow 0.2s;
min-height: 160px;
}
.template-content {
display: flex;
padding: 1.5rem;
background: white;
padding: var(--spacing-md);
background: var(--color-white);
border: 1px solid var(--border-color);
border-radius: 12px;
border-radius: var(--border-radius);
cursor: pointer;
transition: all 0.3s ease;
transition: var(--transition-normal);
height: 100%;
flex-direction: column;
gap: var(--spacing-sm);
}
.template-content:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
box-shadow: var(--shadow-lg);
border-color: var(--primary-color);
}
@@ -338,16 +600,18 @@
}
.template-info h3 {
margin: 0 0 0.5rem;
font-size: 1.1rem;
margin: 0 0 var(--spacing-sm);
font-size: var(--text-sm);
font-weight: var(--font-weight-semibold);
color: var(--text-color);
line-height: var(--line-height-tight);
}
.template-info p {
margin: 0 0 1rem;
font-size: 0.9rem;
color: #666;
line-height: 1.5;
margin: 0 0 var(--spacing-sm);
font-size: var(--text-xs);
color: var(--color-gray-600);
line-height: var(--line-height-normal);
}
.template-header {
@@ -496,31 +760,31 @@
.template-categories {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-bottom: 12px;
padding: 8px;
background: #f8f9fa;
border-radius: 6px;
gap: var(--spacing-xs);
margin-bottom: var(--spacing-sm);
padding: var(--spacing-xs);
background: var(--color-gray-50);
border-radius: var(--border-radius-sm);
}
.category-group {
display: flex;
align-items: center;
gap: 4px;
padding: 4px 8px;
background: white;
border-radius: 4px;
font-size: 0.85rem;
gap: var(--spacing-xs);
padding: var(--spacing-xs) var(--spacing-sm);
background: var(--color-white);
border-radius: var(--border-radius-sm);
font-size: var(--text-xs);
}
.category-label {
color: #666;
font-weight: 500;
color: var(--color-gray-600);
font-weight: var(--font-weight-medium);
}
.category-value {
color: var(--primary-color);
font-weight: 600;
font-weight: var(--font-weight-semibold);
}
.template-card {
@@ -567,6 +831,16 @@
color: white;
}
/* 快速筛选标签样式 */
.quick-filters {
display: flex;
gap: var(--spacing-md);
margin: var(--spacing-lg) 0 var(--spacing-xl) 0;
flex-wrap: wrap;
justify-content: flex-start;
padding: 0 var(--spacing-sm);
}
@media (max-width: 768px) {
.hero {
padding: 3rem 1rem;
@@ -576,12 +850,66 @@
font-size: 2rem;
}
.main-container {
padding: 0 1rem;
.main-layout {
flex-direction: column;
gap: var(--spacing-md);
padding: 0 var(--spacing-md);
}
.sidebar-toggle {
display: flex;
align-items: center;
}
.sidebar {
position: fixed;
top: 0;
left: -100%;
width: 280px;
height: 100vh;
z-index: 1001;
transition: left var(--transition-normal);
overflow-y: auto;
}
.sidebar.show {
left: 0;
}
.sidebar-close {
display: block;
}
.main-content {
width: 100%;
}
.template-grid {
grid-template-columns: 1fr;
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
gap: var(--spacing-sm);
}
.quick-filters {
gap: 6px;
margin: 10px 0;
justify-content: center;
}
.filter-tab {
padding: 6px 12px;
font-size: 0.8rem;
}
.sidebar-categories .category-tabs {
flex-direction: row;
flex-wrap: wrap;
gap: var(--spacing-xs);
}
.sidebar-categories .tab {
flex: 1;
min-width: 120px;
text-align: center;
}
.section-header {
@@ -697,12 +1025,15 @@
}
.search-section {
margin-bottom: 1.5rem;
margin-bottom: 1.2rem;
max-width: 800px;
margin-left: auto;
margin-right: auto;
}
.search-box {
position: relative;
max-width: 600px;
max-width: 700px;
margin: 0 auto;
}
@@ -751,10 +1082,12 @@
.template-actions {
position: absolute;
top: 1rem;
right: 1rem;
top: var(--spacing-sm);
right: var(--spacing-sm);
opacity: 0;
transition: opacity 0.3s ease;
display: flex;
gap: var(--spacing-xs);
}
.template-card:hover .template-actions {
@@ -762,12 +1095,13 @@
}
.btn-delete {
padding: 0.5rem;
padding: var(--spacing-xs);
background: none;
border: none;
color: #dc3545;
cursor: pointer;
transition: all 0.3s ease;
font-size: var(--text-xs);
}
.btn-delete:hover {
@@ -1382,14 +1716,15 @@ style.textContent = `
}
.btn-favorite {
padding: 8px 16px;
padding: var(--spacing-xs) var(--spacing-sm);
background: #ff6b6b;
color: white;
border: none;
border-radius: 4px;
border-radius: var(--border-radius-sm);
cursor: pointer;
transition: all 0.3s ease;
margin-left: 8px;
margin-left: var(--spacing-sm);
font-size: var(--text-xs);
}
.btn-favorite:hover {
@@ -1959,6 +2294,9 @@ function initializeAnimations() {
document.addEventListener('DOMContentLoaded', function() {
// 延迟初始化动画,确保页面完全加载
setTimeout(initializeAnimations, 100);
// 初始化现代交互功能
initializeModernInteractions();
});
// 收藏功能
@@ -2028,5 +2366,257 @@ function addToFavorites() {
alert('收藏失败,请稍后重试');
});
}
// ==================== 现代交互功能系统 ====================
// 初始化现代交互功能
function initializeModernInteractions() {
// 初始化平滑滚动
initializeSmoothScroll();
// 初始化焦点管理
initializeFocusManagement();
// 初始化悬停效果
initializeHoverEffects();
// 初始化键盘导航
initializeKeyboardNavigation();
// 初始化性能优化
initializePerformanceOptimizations();
console.log('现代交互功能初始化完成');
}
// 平滑滚动与焦点管理
function initializeSmoothScroll() {
// 平滑滚动到目标元素
window.smoothScroll = (target) => {
if (typeof target === 'string') {
target = document.querySelector(target);
}
if (target) {
target.scrollIntoView({
behavior: 'smooth',
block: 'nearest'
});
}
};
// 为所有内部链接添加平滑滚动
document.querySelectorAll('a[href^="#"]').forEach(link => {
link.addEventListener('click', function(e) {
e.preventDefault();
const targetId = this.getAttribute('href').substring(1);
const target = document.getElementById(targetId);
if (target) {
smoothScroll(target);
}
});
});
}
// 焦点管理系统
function initializeFocusManagement() {
// 焦点可见性管理
const focusVisibleClass = 'focus-visible';
// 添加焦点样式
const style = document.createElement('style');
style.textContent = `
.focus-visible {
outline: 2px solid var(--color-primary);
outline-offset: 2px;
}
.focus-visible:focus {
outline: 2px solid var(--color-primary);
outline-offset: 2px;
}
`;
document.head.appendChild(style);
// 键盘焦点管理
document.addEventListener('keydown', function(e) {
if (e.key === 'Tab') {
document.body.classList.add('keyboard-navigation');
}
});
document.addEventListener('mousedown', function() {
document.body.classList.remove('keyboard-navigation');
});
}
// 悬停效果统一管理
function initializeHoverEffects() {
// 为模板卡片添加悬停效果
document.querySelectorAll('.template-card').forEach(card => {
card.style.transition = 'var(--transition-normal)';
card.addEventListener('mouseenter', function() {
this.style.transform = 'translateY(-2px)';
this.style.boxShadow = 'var(--shadow-lg)';
});
card.addEventListener('mouseleave', function() {
this.style.transform = 'translateY(0)';
this.style.boxShadow = 'var(--shadow-sm)';
});
});
// 为按钮添加悬停效果
document.querySelectorAll('button, .btn').forEach(button => {
button.style.transition = 'var(--transition-fast)';
});
}
// 键盘导航支持
function initializeKeyboardNavigation() {
// 模板卡片键盘导航
document.querySelectorAll('.template-card').forEach((card, index) => {
card.setAttribute('tabindex', '0');
card.setAttribute('role', 'button');
card.setAttribute('aria-label', `选择模板 ${index + 1}`);
card.addEventListener('keydown', function(e) {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
const radio = this.querySelector('input[type="radio"]');
if (radio) {
radio.checked = true;
radio.dispatchEvent(new Event('change'));
}
}
});
});
// 筛选标签键盘导航
document.querySelectorAll('.filter-tab').forEach(tab => {
tab.setAttribute('tabindex', '0');
tab.setAttribute('role', 'button');
tab.addEventListener('keydown', function(e) {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
this.click();
}
});
});
}
// 性能优化功能
function initializePerformanceOptimizations() {
// 图片懒加载
if ('IntersectionObserver' in window) {
const imageObserver = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
if (img.dataset.src) {
img.src = img.dataset.src;
img.removeAttribute('data-src');
observer.unobserve(img);
}
}
});
});
document.querySelectorAll('img[data-src]').forEach(img => {
imageObserver.observe(img);
});
}
// 防抖搜索
let searchTimeout;
const searchInput = document.getElementById('templateSearch');
if (searchInput) {
searchInput.addEventListener('input', function() {
clearTimeout(searchTimeout);
searchTimeout = setTimeout(() => {
performSearchAndFilter();
}, 300);
});
}
}
// 现代CSS类工具函数
const modernUtils = {
// 添加CSS类
addClass: (element, className) => {
if (element && element.classList) {
element.classList.add(className);
}
},
// 移除CSS类
removeClass: (element, className) => {
if (element && element.classList) {
element.classList.remove(className);
}
},
// 切换CSS类
toggleClass: (element, className) => {
if (element && element.classList) {
element.classList.toggle(className);
}
},
// 检查是否有CSS类
hasClass: (element, className) => {
return element && element.classList && element.classList.contains(className);
}
};
// 导出工具函数到全局
window.modernUtils = modernUtils;
window.smoothScroll = window.smoothScroll || smoothScroll;
// ==================== 侧边栏功能 ====================
// 初始化侧边栏功能
function initializeSidebar() {
const sidebarToggle = document.getElementById('sidebarToggle');
const sidebarClose = document.getElementById('sidebarClose');
const sidebar = document.getElementById('sidebar');
if (sidebarToggle && sidebarClose && sidebar) {
// 切换侧边栏显示
sidebarToggle.addEventListener('click', function() {
sidebar.classList.add('show');
document.body.style.overflow = 'hidden';
});
// 关闭侧边栏
sidebarClose.addEventListener('click', function() {
sidebar.classList.remove('show');
document.body.style.overflow = '';
});
// 点击侧边栏外部关闭
document.addEventListener('click', function(e) {
if (window.innerWidth <= 768 &&
sidebar.classList.contains('show') &&
!sidebar.contains(e.target) &&
!sidebarToggle.contains(e.target)) {
sidebar.classList.remove('show');
document.body.style.overflow = '';
}
});
// 窗口大小改变时重置侧边栏状态
window.addEventListener('resize', function() {
if (window.innerWidth > 768) {
sidebar.classList.remove('show');
document.body.style.overflow = '';
}
});
}
}
// 在页面加载时初始化侧边栏
document.addEventListener('DOMContentLoaded', function() {
initializeSidebar();
});
</script>
{% endblock %}