diff --git a/TODO.md b/TODO.md
deleted file mode 100644
index a4484ba..0000000
--- a/TODO.md
+++ /dev/null
@@ -1,155 +0,0 @@
-# Database Render Application - 后续任务清单
-
-## 已完成 ✅
-
-### 核心系统
-
-- [x] 项目基础结构和 go.mod 配置
-- [x] 配置管理系统 (Viper + YAML)
-- [x] 数据库连接和 ORM 层 (GORM + 多数据库支持)
-- [x] HTTP 处理器层 (Fiber 框架)
-- [x] 模板渲染系统 (Go templates)
-- [x] 前端模板和静态资源 (TailwindCSS + 响应式设计)
-- [x] 主应用入口点
-- [x] Makefile 和构建脚本
-- [x] Docker 配置
-- [x] 开发工具脚本
-
-### 文档和配置
-
-- [x] Makefile (包含所有常用命令)
-- [x] Docker 配置 (Dockerfile + docker-compose.yml)
-- [x] 示例配置文件
-- [x] 示例数据库 schema
-- [x] 构建脚本 (scripts/build.sh)
-- [x] 开发脚本 (scripts/dev.sh)
-- [x] Air 热重载配置
-
-## 待完成 📋
-
-### 测试相关
-
-- [ ] 单元测试 (repository 层)
-- [ ] 单元测试 (service 层)
-- [ ] 单元测试 (handler 层)
-- [ ] 集成测试 (API 端点)
-- [ ] 端到端测试 (UI 测试)
-- [ ] 测试数据工厂
-- [ ] Mock 数据生成器
-
-### 功能增强
-
-- [ ] 导出功能 (CSV, JSON, Excel)
-- [ ] 批量操作 (删除, 状态更新)
-- [ ] 高级搜索 (过滤器, 排序)
-- [ ] 数据可视化图表
-- [ ] 用户认证系统
-- [ ] 权限管理
-- [ ] 审计日志
-- [ ] 数据备份/恢复
-
-### 性能优化
-
-- [ ] 数据库连接池配置优化
-- [ ] 缓存层 (Redis)
-- [ ] 分页性能优化
-- [ ] 静态资源缓存
-- [ ] 数据库索引优化
-- [ ] 查询性能分析
-
-### 前端增强
-
-- [ ] 暗黑模式切换
-- [ ] 移动端优化
-- [ ] 表格视图 (可选)
-- [ ] 数据编辑界面
-- [ ] 图片上传和预览
-- [ ] 富文本编辑器
-
-### 部署和运维
-
-- [ ] CI/CD 配置 (GitHub Actions)
-- [ ] 生产环境配置模板
-- [ ] 监控和告警
-- [ ] 日志轮转配置
-- [ ] 健康检查增强
-- [ ] 容器编排 (K8s manifests)
-
-### 文档完善
-
-- [ ] 项目 README
-- [ ] API 文档 (OpenAPI/Swagger)
-- [ ] 部署指南
-- [ ] 配置说明文档
-- [ ] 开发指南
-- [ ] 故障排除指南
-
-### 安全增强
-
-- [ ] 输入验证和清理
-- [ ] SQL 注入防护检查
-- [ ] XSS 防护
-- [ ] CSRF 保护
-- [ ] 安全头部配置
-- [ ] 依赖安全扫描
-
-## 立即行动项 🚀
-
-### 启动应用测试
-
-```bash
-# 初始化项目
-./scripts/dev.sh init-db
-./scripts/build.sh build
-./scripts/dev.sh start
-
-# 或者使用Makefile
-make init
-make run
-```
-
-### 测试验证
-
-1. 访问 http://localhost:8080
-2. 验证数据库连接
-3. 测试数据展示
-4. 检查搜索功能
-5. 验证分页功能
-
-### 下一步开发建议
-
-1. **优先完成测试**:为现有功能添加测试覆盖
-2. **功能增强**:从导出功能开始,逐步增加实用性功能
-3. **性能优化**:添加 Redis 缓存提升查询性能
-4. **安全加固**:实施基本的输入验证和安全防护
-
-### 快速开始命令
-
-```bash
-# 完整开发环境启动
-./scripts/dev.sh start
-
-# 热重载开发
-./scripts/dev.sh watch
-
-# 多平台构建
-./scripts/build.sh build-all
-
-# Docker环境
-make docker-compose-up
-```
-
-## 技术债务
-
-- [ ] 代码注释完善
-- [ ] 错误处理统一
-- [ ] 日志格式标准化
-- [ ] 配置验证增强
-- [ ] 代码重构优化
-
-## 版本规划
-
-- **v1.0.0**: 基础功能完成,稳定运行
-- **v1.1.0**: 增加导出和批量操作
-- **v1.2.0**: 添加用户认证和权限
-- **v2.0.0**: 架构优化,性能提升
diff --git a/UI.md b/UI.md
deleted file mode 100644
index 1dbb597..0000000
--- a/UI.md
+++ /dev/null
@@ -1,1610 +0,0 @@
-# UI 左右布局优化方案
-
-## 当前问题分析
-- **布局问题**: 当前为单栏垂直布局,所有内容堆叠在页面中央
-- **空间利用率**: 屏幕宽度利用率低,特别是宽屏显示器
-- **导航效率**: 表格切换和数据筛选都在顶部,操作路径长
-- **用户体验**: 缺乏现代化的应用布局,更像传统网页
-
-## 优化目标
-- **左右分栏**: 左侧固定宽度导航栏,右侧主内容区
-- **响应式设计**: 适配不同屏幕尺寸
-- **操作便捷**: 减少用户操作路径,提高数据访问效率
-- **现代化UI**: 采用现代Web应用设计语言
-
-## 具体优化步骤
-
-### 🎨 配色系统优化
-
-**专业配色方案**
-```css
-:root {
- /* 主色调 - 中性专业 */
- --primary-50: #f8fafc;
- --primary-100: #f1f5f9;
- --primary-200: #e2e8f0;
- --primary-300: #cbd5e1;
- --primary-400: #94a3b8;
- --primary-500: #64748b;
- --primary-600: #475569;
- --primary-700: #334155;
- --primary-800: #1e293b;
- --primary-900: #0f172a;
-
- /* 强调色 - 蓝色系 */
- --accent-50: #eff6ff;
- --accent-100: #dbeafe;
- --accent-200: #bfdbfe;
- --accent-300: #93c5fd;
- --accent-400: #60a5fa;
- --accent-500: #3b82f6;
- --accent-600: #2563eb;
- --accent-700: #1d4ed8;
- --accent-800: #1e40af;
- --accent-900: #1e3a8a;
-
- /* 状态色 */
- --success: #10b981;
- --warning: #f59e0b;
- --error: #ef4444;
- --info: #06b6d4;
-
- /* 背景色 */
- --bg-primary: #ffffff;
- --bg-secondary: #f8fafc;
- --bg-tertiary: #f1f5f9;
-
- /* 文字色 */
- --text-primary: #0f172a;
- --text-secondary: #475569;
- --text-tertiary: #64748b;
- --text-muted: #94a3b8;
-
- /* 边框色 */
- --border-light: #e2e8f0;
- --border-medium: #cbd5e1;
- --border-dark: #94a3b8;
-}
-
-/* 暗色主题支持 */
-[data-theme="dark"] {
- --bg-primary: #0f172a;
- --bg-secondary: #1e293b;
- --bg-tertiary: #334155;
- --text-primary: #f8fafc;
- --text-secondary: #e2e8f0;
- --text-tertiary: #cbd5e1;
- --border-light: #334155;
- --border-medium: #475569;
- --border-dark: #64748b;
-}
-```
-
-### 🎯 交互易用性增强
-
-**无障碍设计原则**
-- **键盘导航**: 所有交互元素支持Tab键导航
-- **焦点指示**: 清晰的焦点样式,符合WCAG 2.1标准
-- **屏幕阅读器**: 适当的ARIA标签和语义化HTML
-- **色彩对比**: 所有文本满足4.5:1的对比度要求
-
-### 阶段1: 基础布局重构
-
-**1.1 HTML结构调整**
-```html
-
-
-
-
-
-
-
-
-
-
-```
-
-**1.2 现代化CSS Grid布局**
-```css
-.app-container {
- display: grid;
- grid-template-columns: 260px 1fr;
- height: 100vh;
- overflow: hidden;
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
- background: var(--bg-secondary);
-}
-
-.sidebar {
- background: var(--bg-primary);
- border-right: 1px solid var(--border-light);
- overflow-y: auto;
- position: relative;
- box-shadow: 0 0 20px rgba(0, 0, 0, 0.05);
-}
-
-.main-content {
- overflow-y: auto;
- background: var(--bg-secondary);
- position: relative;
-}
-
-/* 响应式设计 - 更智能的断点 */
-@media (max-width: 1024px) {
- .app-container {
- grid-template-columns: 240px 1fr;
- }
-}
-
-@media (max-width: 768px) {
- .app-container {
- grid-template-columns: 1fr;
- }
-
- .sidebar {
- position: fixed;
- top: 0;
- left: -260px;
- height: 100vh;
- z-index: 1000;
- transition: left 0.3s cubic-bezier(0.4, 0, 0.2, 1);
- box-shadow: 2px 0 20px rgba(0, 0, 0, 0.1);
- }
-
- .sidebar.open {
- left: 0;
- }
-
- .sidebar-backdrop {
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background: rgba(0, 0, 0, 0.5);
- z-index: 999;
- opacity: 0;
- visibility: hidden;
- transition: all 0.3s ease;
- }
-
- .sidebar.open + .sidebar-backdrop {
- opacity: 1;
- visibility: visible;
- }
-}
-```
-
-### 阶段2: 左侧导航栏设计
-
-**2.1 无障碍导航栏结构**
-```html
-
-
-
-
-```
-
-**2.2 无障碍导航栏样式**
-```css
-.sidebar-header {
- padding: 16px 20px;
- border-bottom: 1px solid var(--border-light);
- background: var(--bg-primary);
-}
-
-.brand {
- display: flex;
- align-items: center;
- gap: 12px;
- margin-bottom: 16px;
-}
-
-.brand-icon {
- color: var(--accent-600);
- flex-shrink: 0;
-}
-
-.brand-title {
- font-size: 16px;
- font-weight: 700;
- color: var(--text-primary);
- margin: 0;
- line-height: 1.2;
-}
-
-.brand-subtitle {
- font-size: 13px;
- color: var(--text-secondary);
- margin: 0;
-}
-
-.theme-toggle {
- position: absolute;
- top: 16px;
- right: 16px;
- background: none;
- border: none;
- padding: 8px;
- border-radius: 6px;
- color: var(--text-secondary);
- cursor: pointer;
- transition: all 0.2s ease;
-}
-
-.theme-toggle:hover {
- background: var(--bg-tertiary);
- color: var(--text-primary);
-}
-
-.theme-toggle .moon-icon {
- display: none;
-}
-
-[data-theme="dark"] .theme-toggle .sun-icon {
- display: none;
-}
-
-[data-theme="dark"] .theme-toggle .moon-icon {
- display: block;
-}
-
-.sidebar-search {
- padding: 12px 16px;
- border-bottom: 1px solid var(--border-light);
-}
-
-.search-container {
- position: relative;
- display: flex;
- align-items: center;
-}
-
-.search-icon {
- position: absolute;
- left: 12px;
- color: var(--text-muted);
- pointer-events: none;
-}
-
-.sidebar-search-input {
- width: 100%;
- padding: 8px 12px 8px 36px;
- border: 1px solid var(--border-medium);
- border-radius: 6px;
- font-size: 14px;
- background: var(--bg-secondary);
- color: var(--text-primary);
- transition: all 0.2s ease;
-}
-
-.sidebar-search-input:focus {
- outline: none;
- border-color: var(--accent-500);
- box-shadow: 0 0 0 3px var(--accent-100);
-}
-
-.sidebar-search-input::placeholder {
- color: var(--text-muted);
-}
-
-.sidebar-nav {
- padding: 8px 0;
- flex: 1;
- overflow-y: auto;
-}
-
-.nav-section-title {
- padding: 12px 20px 8px;
- font-size: 11px;
- font-weight: 600;
- color: var(--text-muted);
- text-transform: uppercase;
- letter-spacing: 0.5px;
- margin: 0;
-}
-
-.nav-list {
- list-style: none;
- padding: 0;
- margin: 0;
-}
-
-.nav-item {
- margin: 2px 8px;
-}
-
-.nav-link {
- display: block;
- padding: 8px 12px;
- color: var(--text-secondary);
- text-decoration: none;
- border-radius: 6px;
- transition: all 0.2s ease;
- position: relative;
-}
-
-.nav-link:hover {
- background: var(--bg-tertiary);
- color: var(--text-primary);
-}
-
-.nav-link:focus {
- outline: none;
- box-shadow: 0 0 0 2px var(--accent-200);
-}
-
-.nav-link.active {
- background: var(--accent-50);
- color: var(--accent-700);
- font-weight: 500;
-}
-
-.nav-link.active .nav-icon {
- color: var(--accent-600);
-}
-
-.nav-link-content {
- display: flex;
- align-items: center;
- gap: 12px;
- position: relative;
-}
-
-.nav-icon {
- color: var(--text-muted);
- flex-shrink: 0;
- transition: color 0.2s ease;
-}
-
-.nav-text-content {
- flex: 1;
- min-width: 0;
-}
-
-.nav-title {
- display: block;
- font-size: 14px;
- line-height: 1.3;
-}
-
-.nav-description {
- display: block;
- font-size: 12px;
- color: var(--text-muted);
- margin-top: 1px;
-}
-
-.nav-indicator {
- position: absolute;
- right: -12px;
- top: 50%;
- transform: translateY(-50%);
- width: 3px;
- height: 20px;
- background: var(--accent-600);
- border-radius: 2px;
-}
-
-.sidebar-footer {
- padding: 16px 20px;
- border-top: 1px solid var(--border-light);
- background: var(--bg-tertiary);
-}
-
-.system-info {
- margin-bottom: 12px;
-}
-
-.info-item {
- display: flex;
- justify-content: space-between;
- align-items: center;
- font-size: 12px;
- color: var(--text-secondary);
- margin-bottom: 4px;
-}
-
-.info-label {
- font-weight: 500;
-}
-
-.info-value {
- color: var(--text-primary);
- font-weight: 600;
-}
-
-.settings-button {
- width: 100%;
- padding: 8px 12px;
- background: none;
- border: 1px solid var(--border-medium);
- border-radius: 6px;
- color: var(--text-secondary);
- font-size: 13px;
- cursor: pointer;
- transition: all 0.2s ease;
- display: flex;
- align-items: center;
- justify-content: center;
- gap: 6px;
-}
-
-.settings-button:hover {
- background: var(--bg-primary);
- color: var(--text-primary);
- border-color: var(--border-dark);
-}
-
-.settings-button:focus {
- outline: none;
- box-shadow: 0 0 0 2px var(--accent-200);
-}
-
-/* 滚动条优化 */
-.sidebar::-webkit-scrollbar {
- width: 6px;
-}
-
-.sidebar::-webkit-scrollbar-track {
- background: transparent;
-}
-
-.sidebar::-webkit-scrollbar-thumb {
- background: var(--border-medium);
- border-radius: 3px;
-}
-
-.sidebar::-webkit-scrollbar-thumb:hover {
- background: var(--border-dark);
-}
-```
-
-### 阶段3: 右侧内容区优化
-
-**3.1 智能头部区域重构**
-```html
-
-
-```
-
-**3.2 智能数据表格优化**
-```css
-.content-header {
- background: var(--bg-primary);
- border-bottom: 1px solid var(--border-light);
- padding: 0;
-}
-
-.header-toolbar {
- display: flex;
- align-items: center;
- justify-content: space-between;
- gap: 16px;
- padding: 16px 24px;
- flex-wrap: wrap;
-}
-
-.mobile-menu-toggle {
- display: none;
- background: none;
- border: none;
- padding: 8px;
- border-radius: 6px;
- color: var(--text-secondary);
- cursor: pointer;
- transition: all 0.2s ease;
-}
-
-.mobile-menu-toggle:hover {
- background: var(--bg-tertiary);
- color: var(--text-primary);
-}
-
-.breadcrumb {
- flex: 1;
- min-width: 200px;
-}
-
-.breadcrumb-list {
- display: flex;
- align-items: center;
- list-style: none;
- padding: 0;
- margin: 0;
- gap: 8px;
-}
-
-.breadcrumb-item:not(:last-child)::after {
- content: '/';
- color: var(--text-muted);
- margin-left: 8px;
-}
-
-.breadcrumb-link {
- color: var(--text-secondary);
- text-decoration: none;
- font-size: 14px;
- transition: color 0.2s ease;
-}
-
-.breadcrumb-link:hover {
- color: var(--accent-600);
-}
-
-.breadcrumb-current {
- color: var(--text-primary);
- font-weight: 500;
- font-size: 14px;
-}
-
-.header-tools {
- display: flex;
- align-items: center;
- gap: 12px;
- flex-wrap: wrap;
-}
-
-.search-container {
- display: flex;
- align-items: center;
- gap: 8px;
-}
-
-.search-box {
- position: relative;
- display: flex;
- align-items: center;
-}
-
-.search-icon {
- position: absolute;
- left: 12px;
- color: var(--text-muted);
- pointer-events: none;
- z-index: 1;
-}
-
-.search-input {
- width: 300px;
- max-width: 100%;
- padding: 8px 12px 8px 36px;
- border: 1px solid var(--border-medium);
- border-radius: 6px;
- font-size: 14px;
- background: var(--bg-secondary);
- color: var(--text-primary);
- transition: all 0.2s ease;
-}
-
-.search-input:focus {
- outline: none;
- border-color: var(--accent-500);
- box-shadow: 0 0 0 3px var(--accent-100);
-}
-
-.search-clear {
- position: absolute;
- right: 8px;
- background: none;
- border: none;
- padding: 4px;
- color: var(--text-muted);
- cursor: pointer;
- border-radius: 3px;
- transition: all 0.2s ease;
-}
-
-.search-clear:hover {
- background: var(--bg-tertiary);
- color: var(--text-primary);
-}
-
-.search-button {
- padding: 8px 12px;
- background: var(--accent-600);
- color: white;
- border: none;
- border-radius: 6px;
- font-size: 14px;
- cursor: pointer;
- transition: all 0.2s ease;
-}
-
-.search-button:hover {
- background: var(--accent-700);
-}
-
-.search-button:focus {
- outline: none;
- box-shadow: 0 0 0 3px var(--accent-200);
-}
-
-.view-controls {
- display: flex;
- align-items: center;
- background: var(--bg-secondary);
- border: 1px solid var(--border-medium);
- border-radius: 6px;
- overflow: hidden;
-}
-
-.view-button {
- padding: 8px;
- background: none;
- border: none;
- color: var(--text-secondary);
- cursor: pointer;
- transition: all 0.2s ease;
-}
-
-.view-button:hover {
- background: var(--bg-tertiary);
- color: var(--text-primary);
-}
-
-.view-button.active {
- background: var(--accent-100);
- color: var(--accent-700);
-}
-
-.export-dropdown {
- position: relative;
-}
-
-.export-button {
- padding: 8px 12px;
- background: var(--bg-secondary);
- border: 1px solid var(--border-medium);
- border-radius: 6px;
- color: var(--text-secondary);
- cursor: pointer;
- transition: all 0.2s ease;
-}
-
-.export-button:hover {
- background: var(--bg-tertiary);
- color: var(--text-primary);
-}
-
-.export-menu {
- position: absolute;
- top: 100%;
- right: 0;
- margin-top: 4px;
- background: var(--bg-primary);
- border: 1px solid var(--border-light);
- border-radius: 6px;
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
- min-width: 120px;
- z-index: 1000;
- display: none;
-}
-
-.export-menu.show {
- display: block;
-}
-
-.export-option {
- width: 100%;
- padding: 8px 12px;
- background: none;
- border: none;
- text-align: left;
- font-size: 14px;
- color: var(--text-secondary);
- cursor: pointer;
- transition: all 0.2s ease;
-}
-
-.export-option:hover {
- background: var(--bg-secondary);
- color: var(--text-primary);
-}
-
-.export-option:first-child {
- border-top-left-radius: 6px;
- border-top-right-radius: 6px;
-}
-
-.export-option:last-child {
- border-bottom-left-radius: 6px;
- border-bottom-right-radius: 6px;
-}
-
-.pagination-info {
- display: flex;
- align-items: center;
- justify-content: space-between;
- gap: 16px;
- padding: 12px 24px;
- background: var(--bg-tertiary);
- border-top: 1px solid var(--border-light);
-}
-
-.pagination-text {
- font-size: 14px;
- color: var(--text-secondary);
-}
-
-.per-page-select {
- padding: 4px 8px;
- border: 1px solid var(--border-medium);
- border-radius: 4px;
- font-size: 14px;
- background: var(--bg-primary);
- color: var(--text-primary);
- cursor: pointer;
-}
-
-.per-page-select:focus {
- outline: none;
- border-color: var(--accent-500);
- box-shadow: 0 0 0 2px var(--accent-100);
-}
-
-@media (max-width: 768px) {
- .mobile-menu-toggle {
- display: block;
- }
-
- .header-toolbar {
- flex-direction: column;
- align-items: stretch;
- gap: 12px;
- }
-
- .search-input {
- width: 100%;
- }
-
- .header-tools {
- justify-content: center;
- }
-
- .pagination-info {
- flex-direction: column;
- align-items: stretch;
- gap: 8px;
- }
-}
-```
-
-### 阶段4: 响应式交互增强
-
-**4.1 现代化JavaScript交互**
-```javascript
-// 应用状态管理
-class AppState {
- constructor() {
- this.searchTimeout = null;
- this.currentView = 'table';
- this.exportMenuOpen = false;
- this.init();
- }
-
- init() {
- this.setupThemeToggle();
- this.setupSidebarToggle();
- this.setupSearch();
- this.setupKeyboardShortcuts();
- this.setupAccessibility();
- }
-
- // 主题切换
- setupThemeToggle() {
- const themeToggle = document.querySelector('.theme-toggle');
- if (themeToggle) {
- themeToggle.addEventListener('click', () => this.toggleTheme());
- }
-
- // 初始化主题
- const savedTheme = localStorage.getItem('theme') || 'light';
- this.setTheme(savedTheme);
- }
-
- toggleTheme() {
- const currentTheme = document.documentElement.getAttribute('data-theme') || 'light';
- const newTheme = currentTheme === 'light' ? 'dark' : 'light';
- this.setTheme(newTheme);
- }
-
- setTheme(theme) {
- document.documentElement.setAttribute('data-theme', theme);
- localStorage.setItem('theme', theme);
- }
-
- // 侧边栏管理
- setupSidebarToggle() {
- const toggle = document.querySelector('.mobile-menu-toggle');
- const sidebar = document.querySelector('.sidebar');
- const backdrop = document.querySelector('.sidebar-backdrop');
-
- if (toggle) {
- toggle.addEventListener('click', () => this.toggleSidebar());
- }
-
- if (backdrop) {
- backdrop.addEventListener('click', () => this.closeSidebar());
- }
-
- // 响应式处理
- window.addEventListener('resize', () => {
- if (window.innerWidth > 768) {
- this.closeSidebar();
- }
- });
- }
-
- toggleSidebar() {
- const sidebar = document.querySelector('.sidebar');
- const toggle = document.querySelector('.mobile-menu-toggle');
- const isOpen = sidebar.classList.contains('open');
-
- if (isOpen) {
- this.closeSidebar();
- } else {
- this.openSidebar();
- }
- }
-
- openSidebar() {
- const sidebar = document.querySelector('.sidebar');
- const toggle = document.querySelector('.mobile-menu-toggle');
- const backdrop = document.querySelector('.sidebar-backdrop');
-
- sidebar.classList.add('open');
- if (toggle) toggle.setAttribute('aria-expanded', 'true');
- if (backdrop) backdrop.style.display = 'block';
- document.body.style.overflow = 'hidden';
- }
-
- closeSidebar() {
- const sidebar = document.querySelector('.sidebar');
- const toggle = document.querySelector('.mobile-menu-toggle');
- const backdrop = document.querySelector('.sidebar-backdrop');
-
- sidebar.classList.remove('open');
- if (toggle) toggle.setAttribute('aria-expanded', 'false');
- if (backdrop) backdrop.style.display = 'none';
- document.body.style.overflow = '';
- }
-
- // 智能搜索
- setupSearch() {
- const searchInput = document.getElementById('searchInput');
- const searchClear = document.querySelector('.search-clear');
-
- if (searchInput) {
- searchInput.addEventListener('input', (e) => {
- this.debounceSearch(e.target.value);
- });
- }
-
- if (searchClear) {
- searchClear.addEventListener('click', () => this.clearSearch());
- }
- }
-
- debounceSearch(query) {
- clearTimeout(this.searchTimeout);
- this.searchTimeout = setTimeout(() => {
- this.performSearch(query);
- }, 300);
- }
-
- performSearch(query) {
- const table = new URLSearchParams(window.location.search).get('table') || '{{.Table}}';
- const params = new URLSearchParams(window.location.search);
-
- if (query.trim()) {
- params.set('search', query);
- } else {
- params.delete('search');
- }
- params.set('page', '1');
-
- window.location.href = `/?${params.toString()}`;
- }
-
- clearSearch() {
- const searchInput = document.getElementById('searchInput');
- const searchClear = document.querySelector('.search-clear');
-
- if (searchInput) searchInput.value = '';
- if (searchClear) searchClear.style.display = 'none';
-
- this.performSearch('');
- }
-
- // 表格筛选
- filterTables(query) {
- const navLinks = document.querySelectorAll('.nav-link');
- const searchTerm = query.toLowerCase();
-
- navLinks.forEach(link => {
- const title = link.querySelector('.nav-title').textContent.toLowerCase();
- const description = link.querySelector('.nav-description').textContent.toLowerCase();
-
- if (title.includes(searchTerm) || description.includes(searchTerm)) {
- link.style.display = 'block';
- link.parentElement.style.display = 'block';
- } else {
- link.style.display = 'none';
- link.parentElement.style.display = 'none';
- }
- });
- }
-
- // 视图切换
- setViewMode(mode) {
- this.currentView = mode;
-
- // 更新按钮状态
- document.querySelectorAll('.view-button').forEach(btn => {
- btn.classList.remove('active');
- });
- document.querySelector(`[onclick="setViewMode('${mode}')"]`).classList.add('active');
-
- // 保存用户偏好
- localStorage.setItem('viewMode', mode);
-
- // 切换视图
- const content = document.querySelector('.main-content');
- content.setAttribute('data-view', mode);
- }
-
- // 导出功能
- toggleExportMenu() {
- const menu = document.querySelector('.export-menu');
- const button = document.querySelector('.export-button');
-
- if (menu.classList.contains('show')) {
- menu.classList.remove('show');
- button.setAttribute('aria-expanded', 'false');
- } else {
- menu.classList.add('show');
- button.setAttribute('aria-expanded', 'true');
-
- // 点击外部关闭
- setTimeout(() => {
- document.addEventListener('click', this.closeExportMenu, { once: true });
- }, 0);
- }
- }
-
- closeExportMenu = (e) => {
- const menu = document.querySelector('.export-menu');
- const button = document.querySelector('.export-button');
-
- if (!button.contains(e.target)) {
- menu.classList.remove('show');
- button.setAttribute('aria-expanded', 'false');
- }
- }
-
- exportData(format) {
- const table = new URLSearchParams(window.location.search).get('table') || '{{.Table}}';
- const params = new URLSearchParams(window.location.search);
- params.set('format', format);
-
- window.location.href = `/api/export/${table}?${params.toString()}`;
- this.toggleExportMenu();
- }
-
- // 键盘快捷键
- setupKeyboardShortcuts() {
- document.addEventListener('keydown', (e) => {
- // Ctrl/Cmd + K 聚焦搜索
- if ((e.ctrlKey || e.metaKey) && e.key === 'k') {
- e.preventDefault();
- const searchInput = document.getElementById('searchInput');
- if (searchInput) searchInput.focus();
- }
-
- // Esc 关闭侧边栏/菜单
- if (e.key === 'Escape') {
- this.closeSidebar();
- this.closeExportMenu({ target: document });
- }
-
- // Ctrl/Cmd + , 打开设置
- if ((e.ctrlKey || e.metaKey) && e.key === ',') {
- e.preventDefault();
- this.openSettings();
- }
- });
- }
-
- // 无障碍支持
- setupAccessibility() {
- // 焦点管理
- document.addEventListener('focusin', (e) => {
- const sidebar = document.querySelector('.sidebar');
- const isInSidebar = sidebar.contains(e.target);
- const isMobile = window.innerWidth <= 768;
-
- if (isMobile && !isInSidebar && sidebar.classList.contains('open')) {
- this.closeSidebar();
- }
- });
-
- // 实时搜索反馈
- const searchInput = document.getElementById('searchInput');
- if (searchInput) {
- searchInput.addEventListener('input', (e) => {
- const clearButton = document.querySelector('.search-clear');
- if (clearButton) {
- clearButton.style.display = e.target.value ? 'block' : 'none';
- }
- });
- }
- }
-
- // 设置面板
- openSettings() {
- // 可以扩展为模态框
- console.log('打开设置面板');
- }
-
- changePerPage(perPage) {
- const params = new URLSearchParams(window.location.search);
- params.set('per_page', perPage);
- params.set('page', '1');
- window.location.href = `/?${params.toString()}`;
- }
-}
-
-// 初始化应用
-const app = new AppState();
-
-// 全局函数
-function toggleSidebar() { app.toggleSidebar(); }
-function closeSidebar() { app.closeSidebar(); }
-function debounceSearch(query) { app.debounceSearch(query); }
-function performSearch() { app.performSearch(document.getElementById('searchInput').value); }
-function clearSearch() { app.clearSearch(); }
-function filterTables(query) { app.filterTables(query); }
-function setViewMode(mode) { app.setViewMode(mode); }
-function toggleExportMenu() { app.toggleExportMenu(); }
-function exportData(format) { app.exportData(format); }
-function changePerPage(perPage) { app.changePerPage(perPage); }
-
-// 页面加载完成后恢复用户偏好
-document.addEventListener('DOMContentLoaded', () => {
- const savedViewMode = localStorage.getItem('viewMode') || 'table';
- app.setViewMode(savedViewMode);
-});
-```
-
-### 阶段5: 性能优化与无障碍设计
-
-**5.1 性能优化策略**
-```css
-/* 渐进式加载动画 */
-@keyframes shimmer {
- 0% { background-position: -200px 0; }
- 100% { background-position: calc(200px + 100%) 0; }
-}
-
-.loading-shimmer {
- background: linear-gradient(90deg,
- var(--bg-tertiary) 0%,
- var(--bg-secondary) 50%,
- var(--bg-tertiary) 100%);
- background-size: 200px 100%;
- animation: shimmer 1.5s infinite linear;
-}
-
-/* 硬件加速 */
-.sidebar,
-.content-header,
-.nav-link {
- will-change: transform, opacity;
- transform: translateZ(0);
-}
-
-/* 延迟加载 */
-.lazy-image {
- opacity: 0;
- transition: opacity 0.3s ease;
-}
-
-.lazy-image.loaded {
- opacity: 1;
-}
-
-/* 减少重绘 */
-.nav-link,
-.view-button {
- backface-visibility: hidden;
-}
-```
-
-**5.2 无障碍设计增强**
-```css
-/* 焦点指示器 */
-:focus-visible {
- outline: 2px solid var(--accent-600);
- outline-offset: 2px;
-}
-
-/* 减少动画偏好 */
-@media (prefers-reduced-motion: reduce) {
- .sidebar,
- .nav-link,
- .content-header {
- transition: none;
- }
-
- .loading-shimmer {
- animation: none;
- }
-}
-
-/* 高对比度模式 */
-@media (prefers-contrast: high) {
- :root {
- --border-light: #000;
- --border-medium: #000;
- --border-dark: #000;
- }
-}
-
-/* 语义化颜色 */
-.sr-only {
- position: absolute;
- width: 1px;
- height: 1px;
- padding: 0;
- margin: -1px;
- overflow: hidden;
- clip: rect(0, 0, 0, 0);
- white-space: nowrap;
- border: 0;
-}
-
-/* 键盘导航支持 */
-.nav-link:focus-visible,
-.view-button:focus-visible,
-.export-button:focus-visible {
- outline: 2px solid var(--accent-600);
- outline-offset: 2px;
-}
-
-/* 屏幕阅读器支持 */
-.aria-live {
- position: absolute;
- left: -10000px;
- top: auto;
- width: 1px;
- height: 1px;
- overflow: hidden;
-}
-```
-
-**5.3 用户体验增强**
-```javascript
-// 加载状态管理
-class LoadingManager {
- constructor() {
- this.loadingStates = new Map();
- }
-
- showLoading(selector, message = '加载中...') {
- const element = document.querySelector(selector);
- if (element) {
- element.classList.add('loading-shimmer');
- element.setAttribute('aria-busy', 'true');
- element.setAttribute('aria-label', message);
- }
- }
-
- hideLoading(selector) {
- const element = document.querySelector(selector);
- if (element) {
- element.classList.remove('loading-shimmer');
- element.setAttribute('aria-busy', 'false');
- element.removeAttribute('aria-label');
- }
- }
-}
-
-// 错误处理
-class ErrorHandler {
- static show(message, type = 'error') {
- const notification = document.createElement('div');
- notification.className = `notification notification-${type}`;
- notification.setAttribute('role', 'alert');
- notification.setAttribute('aria-live', 'polite');
- notification.textContent = message;
-
- document.body.appendChild(notification);
-
- setTimeout(() => {
- notification.remove();
- }, 5000);
- }
-}
-
-// 响应式断点检测
-class ResponsiveManager {
- constructor() {
- this.breakpoints = {
- mobile: 768,
- tablet: 1024,
- desktop: 1440
- };
- this.currentBreakpoint = this.getCurrentBreakpoint();
- this.setupListeners();
- }
-
- getCurrentBreakpoint() {
- const width = window.innerWidth;
- if (width <= this.breakpoints.mobile) return 'mobile';
- if (width <= this.breakpoints.tablet) return 'tablet';
- return 'desktop';
- }
-
- setupListeners() {
- window.addEventListener('resize', () => {
- const newBreakpoint = this.getCurrentBreakpoint();
- if (newBreakpoint !== this.currentBreakpoint) {
- this.currentBreakpoint = newBreakpoint;
- this.onBreakpointChange(newBreakpoint);
- }
- });
- }
-
- onBreakpointChange(breakpoint) {
- document.documentElement.setAttribute('data-breakpoint', breakpoint);
- }
-}
-
-// 初始化
-const responsiveManager = new ResponsiveManager();
-```
-
-**5.4 国际化支持**
-```javascript
-// 多语言支持
-const i18n = {
- zh: {
- search: '搜索',
- clear: '清除',
- loading: '加载中...',
- noResults: '没有找到结果',
- export: '导出',
- settings: '设置'
- },
- en: {
- search: 'Search',
- clear: 'Clear',
- loading: 'Loading...',
- noResults: 'No results found',
- export: 'Export',
- settings: 'Settings'
- }
-};
-
-// 语言检测
-function detectLanguage() {
- return navigator.language.startsWith('zh') ? 'zh' : 'en';
-}
-
-// 获取翻译
-function t(key) {
- const lang = detectLanguage();
- return i18n[lang][key] || key;
-}
-```
-
-## 实施优先级
-
-### 高优先级 (立即实施)
-1. ✅ 专业配色系统设计
-2. ✅ 无障碍导航栏重构
-3. ✅ 智能搜索功能
-4. ✅ 响应式布局实现
-5. ✅ 暗色主题支持
-
-### 中优先级 (1-2天内)
-1. ✅ 键盘快捷键支持
-2. ✅ 导出功能实现
-3. ✅ 视图模式切换
-4. ✅ 性能优化
-5. ✅ 无障碍设计增强
-
-### 低优先级 (后续迭代)
-1. 国际化支持
-2. 高级筛选器
-3. 数据可视化
-4. 个性化设置面板
-5. 实时通知系统
-
-## 用户体验指标
-
-### 可访问性 (WCAG 2.1 标准)
-- ✅ 键盘导航支持
-- ✅ 屏幕阅读器兼容
-- ✅ 色彩对比度 4.5:1
-- ✅ 焦点指示器清晰
-- ✅ 语义化HTML结构
-
-### 性能指标
-- ✅ 首屏加载 < 2秒
-- ✅ 交互响应 < 100ms
-- ✅ 动画流畅 60fps
-- ✅ 内存占用优化
-- ✅ 渐进式增强
-
-### 交互体验
-- ✅ 智能搜索 (300ms防抖)
-- ✅ 一键清除搜索
-- ✅ 快捷键支持 (Ctrl+K)
-- ✅ 移动端手势支持
-- ✅ 实时状态反馈
-
-## 设计验证
-
-### 用户体验测试
-- [ ] 用户任务完成率 > 90%
-- [ ] 用户满意度评分 > 4.5/5
-- [ ] 平均操作时间减少 50%
-- [ ] 错误率降低 80%
-
-### 技术验证
-- [ ] Lighthouse评分 > 95
-- [ ] 可访问性评分 > 100
-- [ ] 性能评分 > 90
-- [ ] SEO评分 > 100
-
-## 总结
-
-本次优化从配色和交互易用性角度出发,实现了:
-
-🎨 **专业配色系统**: 基于中性色+强调色的现代配色方案,支持明暗主题
-🎯 **无障碍设计**: 符合WCAG 2.1标准,支持键盘导航和屏幕阅读器
-⚡ **智能交互**: 防抖搜索、快捷键、响应式断点检测
-📱 **多端适配**: 桌面、平板、手机完美适配
-🔧 **扩展性强**: 模块化设计,支持后续功能扩展
-
-所有代码遵循KISS、YAGNI、DRY原则,确保简洁高效且易于维护。
-
-## 测试验证
-
-### 功能测试
-- [ ] 表格切换功能正常
-- [ ] 搜索功能正常工作
-- [ ] 分页功能正常
-- [ ] 详情弹窗正常显示
-
-### 响应式测试
-- [ ] 桌面端 (>1024px) 显示正常
-- [ ] 平板端 (768px-1024px) 显示正常
-- [ ] 移动端 (<768px) 侧边栏可正常开关
-
-### 性能测试
-- [ ] 初始加载时间 < 2秒
-- [ ] 侧边栏切换流畅无卡顿
-- [ ] 响应式切换无闪烁
-
-## 文件变更清单
-
-### 需要修改的文件
-- `web/templates/list.html` - 主要布局重构
-- `web/static/css/app.css` - 新增样式文件
-- `web/static/js/app.js` - 新增交互逻辑
-
-### 新增文件
-- `web/static/css/components/sidebar.css` - 侧边栏专用样式
-- `web/static/css/components/content.css` - 内容区样式
-- `web/static/css/responsive.css` - 响应式样式
-
-## 回滚方案
-保留原始文件备份,如出现问题可快速回滚到垂直布局版本。
\ No newline at end of file
diff --git a/database_render/.gitignore b/database_render/.gitignore
deleted file mode 100644
index 5b90e79..0000000
--- a/database_render/.gitignore
+++ /dev/null
@@ -1,27 +0,0 @@
-# ---> Go
-# If you prefer the allow list template instead of the deny list, see community template:
-# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
-#
-# Binaries for programs and plugins
-*.exe
-*.exe~
-*.dll
-*.so
-*.dylib
-
-# Test binary, built with `go test -c`
-*.test
-
-# Output of the go coverage tool, specifically when used with LiteIDE
-*.out
-
-# Dependency directories (remove the comment below to include it)
-# vendor/
-
-# Go workspace file
-go.work
-go.work.sum
-
-# env file
-.env
-
diff --git a/database_render/README.md b/database_render/README.md
deleted file mode 100644
index a1e4f4f..0000000
--- a/database_render/README.md
+++ /dev/null
@@ -1,2 +0,0 @@
-# database_render
-
diff --git a/errors.md b/errors.md
deleted file mode 100644
index fc51f60..0000000
--- a/errors.md
+++ /dev/null
@@ -1,11 +0,0 @@
-## 待修复问题
-
-1. 左侧表展示排序会随机变化,需要固定排序
-2. 左侧表搜索无法支持原始表名搜索,需要同时展示原始表名并支持搜索
-3. 详情弹出层内容无 CSS 样式,展示混乱。且弹出层关闭按钮 icon 肉眼不可见
-4. toggleTheme 报错
- ```
- 应用错误: ReferenceError: toggleTheme is not defined
- at HTMLButtonElement.onclick (?table=posts:32:40)
- ```
-5. 文章表多写入些数据,方便测试分页功能。