整理一下,分出前端后端public
This commit is contained in:
156
README.md
156
README.md
@@ -1,156 +0,0 @@
|
||||
<!-- ...existing code... -->
|
||||
# astro-jiao77.cn
|
||||
|
||||
一个基于 Astro 5、TypeScript 与 Tailwind CSS 打造的现代静态网站,融合玻璃质感设计、莫兰蒂配色与定制动画系统,适合构建专题站点、数据报告与导航中心。
|
||||
|
||||
## 项目简介
|
||||
|
||||
- 使用 Astro 的岛屿架构实现快速加载与细粒度交互。
|
||||
- Tailwind CSS 提供统一的设计令牌与主题扩展,支持深浅配色切换。
|
||||
- 组件库涵盖导航、报告、通用 UI 与动画包装器,降低页面搭建成本。
|
||||
- 内置部署脚本与检查流程,支持快速上线与质量验证。
|
||||
|
||||
## 环境要求
|
||||
|
||||
| 工具 | 建议版本 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| Node.js | ≥ 18.17.0 | 可用 nvm 管理不同版本 |
|
||||
| npm / pnpm | npm ≥ 9 / pnpm ≥ 8 | 根据团队习惯选择包管理器 |
|
||||
| Git | 最新版本 | 代码管理与部署同步 |
|
||||
|
||||
## 快速开始
|
||||
|
||||
1. 安装依赖
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
2. 启动开发服务器(默认端口 4321)
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
3. 构建与预览产物
|
||||
```bash
|
||||
npm run build
|
||||
npm run preview
|
||||
```
|
||||
4. 类型与模板检查
|
||||
```bash
|
||||
npm run astro check
|
||||
```
|
||||
|
||||
## 目录结构
|
||||
|
||||
```text
|
||||
.
|
||||
├─ src/
|
||||
│ ├─ components/
|
||||
│ │ ├─ common/ # 通用组件(按钮、动画包装、图像查看器等)
|
||||
│ │ ├─ navigation/ # 导航页面组件 (NavigationCard、NavigationGrid)
|
||||
│ │ └─ report/ # 报告组件 (ReportSection、MetricCard、MetricsGrid)
|
||||
│ ├─ layouts/ # 布局组件 (BaseLayout 等)
|
||||
│ ├─ pages/ # Astro 页面 (首页、报告模板、专题页)
|
||||
│ └─ scripts/ # 浏览器交互脚本 (滚动、头部动画等)
|
||||
├─ docs/ # 说明文档与部署指南
|
||||
├─ public/ # 静态资源 (图片、图标、字体等)
|
||||
├─ tailwind.config.mjs # 主题与配色扩展
|
||||
├─ deploy.sh / deploy-full.sh # 部署脚本
|
||||
└─ astro.config.mjs # Astro 全局配置
|
||||
```
|
||||
|
||||
## 常用命令
|
||||
|
||||
| 命令 | 功能 |
|
||||
| --- | --- |
|
||||
| `npm run dev` | 本地开发,支持热更新 |
|
||||
| `npm run build` | 产出静态文件到 `dist/` |
|
||||
| `npm run preview` | 使用 Astro 内置服务器预览构建结果 |
|
||||
| `npm run astro check` | 运行 TypeScript + Astro 模板检查 |
|
||||
| `npm run lighthouse` | (如配置)执行性能与可访问性检测 |
|
||||
|
||||
## 核心模块与文件
|
||||
|
||||
- 报告模板:`src/pages/report/template/index.astro`,配合 `docs/REPORT_TEMPLATE_SUMMARY.md` 快速复用结构。
|
||||
- 导航模板:`src/pages/navigation-template.astro`,搭配 `docs/NAVIGATION_TEMPLATE_GUIDE.md` 定制导航入口。
|
||||
- 交互脚本:`src/scripts/scroll-progress.ts`、`src/scripts/header.ts` 管理滚动进度条与动态头部。
|
||||
- 通用组件:`src/components/common/AnimatedElement.astro`、`GlowButton.astro`、`ImageViewer.astro` 提供动画与图片交互。
|
||||
- 配色定义:`tailwind.config.mjs` 中的 `morandi` 调色盘,实现统一的莫兰蒂主题。
|
||||
|
||||
## 页面与组件使用
|
||||
|
||||
### 导航页面
|
||||
|
||||
- 组合 `NavigationGrid` 与 `NavigationCard` 构建入口矩阵。
|
||||
- 支持自定义列数、动画延迟与卡片主题,适用于首页、功能导航等场景。
|
||||
|
||||
### 报告页面
|
||||
|
||||
- 使用 `ReportSection` 划分章节,搭配 `MetricCard`、`MetricsGrid` 展示核心指标。
|
||||
- 支持深色渐变背景与滚动触发动画,适合数据报告、分析仪表盘。
|
||||
|
||||
### 通用组件
|
||||
|
||||
- `Container`:多种视觉变体(glass、solid、outline)与尺寸可选。
|
||||
- `AnimatedElement`:封装 8 种滚动动画,支持延迟与持续时间配置。
|
||||
- `Header`:响应滚动的智能页眉,移动端自适应。
|
||||
|
||||
## 设计与交互
|
||||
|
||||
- **玻璃质感**:半透明背景 + 模糊滤镜,营造层次感。
|
||||
- **莫兰蒂配色**:柔和雅致,适用于深浅背景。定义示例:
|
||||
```css
|
||||
morandi: {
|
||||
cream: '#F4F1E8',
|
||||
beige: '#E8DCC0',
|
||||
sage: '#C8D5B9',
|
||||
dusty: '#D4B5A0',
|
||||
mauve: '#B8A5A5',
|
||||
clay: '#A68B7B',
|
||||
mist: '#C7B8A1',
|
||||
stone: '#9B8B7A',
|
||||
deep: '#7A6B5D'
|
||||
}
|
||||
```
|
||||
- **动画系统**:加载、滚动、悬浮多种动效,增强反馈与沉浸感。
|
||||
- **响应式布局**:针对桌面、平板、移动端优化栅格与交互。
|
||||
|
||||
## 开发流程
|
||||
|
||||
1. 基于模板创建页面:复制 `pages/report/template` 或现有导航页。
|
||||
2. 在 `src/components/` 中组合组件,必要时拓展新变体。
|
||||
3. Tailwind 实现局部样式,注意复用 `@apply` 与设计令牌。
|
||||
4. 若需脚本交互,将逻辑放入 `src/scripts/` 并在页面中按需引入。
|
||||
5. 执行 `npm run astro check` 与 `npm run build` 确保质量。
|
||||
|
||||
## 部署流程
|
||||
|
||||
1. 本地构建:`npm run build`
|
||||
2. 根据上线需求选择:
|
||||
- `./deploy.sh`:快速增量部署
|
||||
- `./deploy-full.sh`:完整部署,包含权限校验、压缩检测
|
||||
3. 部署验证请参考 `docs/DEPLOYMENT.md` 与 `docs/DEPLOY_FULL_VERIFICATION.md`
|
||||
4. 上线后建议检查服务器日志与浏览器控制台,确保资源加载正常。
|
||||
|
||||
## 调试技巧
|
||||
|
||||
- 利用浏览器 DevTools 观察 CSS 变量与动画帧率。
|
||||
- Astro CLI 支持 `--open`、`--host`,例如 `npm run dev -- --host` 供局域网调试。
|
||||
- 对滚动行为可在控制台监听 `scroll-progress` 脚本的状态输出。
|
||||
- 若遇到类型问题,运行 `npm run astro check -- --watch` 进行持续监控。
|
||||
|
||||
## 技术栈
|
||||
|
||||
- **Astro**:静态站点生成 + 部分组件岛屿渲染。
|
||||
- **Tailwind CSS**:实用类样式与主题扩展。
|
||||
- **TypeScript**:类型安全与更佳的开发体验。
|
||||
- **Font Awesome / 自定义图标**:图标资源。
|
||||
- **Vite**:开发服务器与构建工具。
|
||||
|
||||
## 贡献指南
|
||||
|
||||
欢迎提交 Issue 或 Pull Request 改进项目。建议遵循以下流程:
|
||||
|
||||
1. Fork 仓库并创建新分支。
|
||||
2. 完成改动后运行 `npm run build` 与相关检查。
|
||||
3. 提交 PR 并在描述中说明变更内容及影响范围。
|
||||
|
||||
<!-- ...existing code... -->
|
||||
@@ -1,59 +0,0 @@
|
||||
# Apache 虚拟主机配置文件
|
||||
# 请将此配置添加到您的 Apache 配置中
|
||||
|
||||
<VirtualHost *:80>
|
||||
ServerName jiao77.cn
|
||||
ServerAlias www.jiao77.cn
|
||||
DocumentRoot /var/www/jiao77.cn
|
||||
|
||||
# 启用压缩以提高性能
|
||||
<IfModule mod_deflate.c>
|
||||
AddOutputFilterByType DEFLATE text/plain
|
||||
AddOutputFilterByType DEFLATE text/html
|
||||
AddOutputFilterByType DEFLATE text/xml
|
||||
AddOutputFilterByType DEFLATE text/css
|
||||
AddOutputFilterByType DEFLATE application/xml
|
||||
AddOutputFilterByType DEFLATE application/xhtml+xml
|
||||
AddOutputFilterByType DEFLATE application/rss+xml
|
||||
AddOutputFilterByType DEFLATE application/javascript
|
||||
AddOutputFilterByType DEFLATE application/x-javascript
|
||||
</IfModule>
|
||||
|
||||
# 设置缓存头以提高性能
|
||||
<IfModule mod_expires.c>
|
||||
ExpiresActive On
|
||||
ExpiresByType text/css "access plus 1 month"
|
||||
ExpiresByType application/javascript "access plus 1 month"
|
||||
ExpiresByType image/png "access plus 1 year"
|
||||
ExpiresByType image/jpg "access plus 1 year"
|
||||
ExpiresByType image/jpeg "access plus 1 year"
|
||||
ExpiresByType image/gif "access plus 1 year"
|
||||
ExpiresByType image/svg+xml "access plus 1 year"
|
||||
ExpiresByType font/woff "access plus 1 year"
|
||||
ExpiresByType font/woff2 "access plus 1 year"
|
||||
</IfModule>
|
||||
|
||||
# 安全头设置
|
||||
<IfModule mod_headers.c>
|
||||
Header always set X-Frame-Options "SAMEORIGIN"
|
||||
Header always set X-Content-Type-Options "nosniff"
|
||||
Header always set Referrer-Policy "strict-origin-when-cross-origin"
|
||||
</IfModule>
|
||||
|
||||
# 错误和访问日志
|
||||
ErrorLog ${APACHE_LOG_DIR}/jiao77_error.log
|
||||
CustomLog ${APACHE_LOG_DIR}/jiao77_access.log combined
|
||||
</VirtualHost>
|
||||
|
||||
# HTTPS 配置 (如果您有 SSL 证书)
|
||||
# <VirtualHost *:443>
|
||||
# ServerName jiao77.cn
|
||||
# ServerAlias www.jiao77.cn
|
||||
# DocumentRoot /var/www/html
|
||||
#
|
||||
# SSLEngine on
|
||||
# SSLCertificateFile /path/to/your/certificate.crt
|
||||
# SSLCertificateKeyFile /path/to/your/private.key
|
||||
#
|
||||
# # 包括上面相同的配置...
|
||||
# </VirtualHost>
|
||||
620
dashboard.html
Normal file
620
dashboard.html
Normal file
@@ -0,0 +1,620 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>jiao77.cn 部署仪表板</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
min-height: 100vh;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
header {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
border-radius: 10px;
|
||||
padding: 30px;
|
||||
margin-bottom: 30px;
|
||||
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: #333;
|
||||
font-size: 32px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
color: #666;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.status-badge {
|
||||
display: inline-block;
|
||||
background: #10b981;
|
||||
color: white;
|
||||
padding: 6px 16px;
|
||||
border-radius: 20px;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
||||
gap: 20px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.card {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
border-radius: 10px;
|
||||
padding: 20px;
|
||||
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.1);
|
||||
transition: transform 0.3s, box-shadow 0.3s;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
transform: translateY(-5px);
|
||||
box-shadow: 0 15px 50px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.card-content {
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
width: 100%;
|
||||
height: 8px;
|
||||
background: #e5e7eb;
|
||||
border-radius: 4px;
|
||||
margin-top: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.progress-fill {
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, #10b981, #059669);
|
||||
transition: width 0.3s;
|
||||
}
|
||||
|
||||
.icon {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.section {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
border-radius: 10px;
|
||||
padding: 30px;
|
||||
margin-bottom: 30px;
|
||||
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 20px;
|
||||
padding-bottom: 15px;
|
||||
border-bottom: 2px solid #667eea;
|
||||
}
|
||||
|
||||
.checklist {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.checklist li {
|
||||
padding: 12px 0;
|
||||
color: #333;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.checklist li:before {
|
||||
content: '✓';
|
||||
color: #10b981;
|
||||
font-weight: bold;
|
||||
font-size: 18px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.checklist li.pending:before {
|
||||
content: '⏳';
|
||||
color: #f59e0b;
|
||||
}
|
||||
|
||||
.checklist li.pending {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.code-block {
|
||||
background: #f3f4f6;
|
||||
border-left: 4px solid #667eea;
|
||||
padding: 15px;
|
||||
margin: 15px 0;
|
||||
border-radius: 4px;
|
||||
font-family: 'Courier New', monospace;
|
||||
font-size: 13px;
|
||||
color: #333;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.button-group {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
flex-wrap: wrap;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.button {
|
||||
display: inline-block;
|
||||
padding: 10px 20px;
|
||||
background: #667eea;
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
border-radius: 6px;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
transition: background 0.3s;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
background: #764ba2;
|
||||
}
|
||||
|
||||
.button-secondary {
|
||||
background: #e5e7eb;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.button-secondary:hover {
|
||||
background: #d1d5db;
|
||||
}
|
||||
|
||||
.metric {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 10px 0;
|
||||
border-bottom: 1px solid #e5e7eb;
|
||||
}
|
||||
|
||||
.metric:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.metric-label {
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.metric-value {
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.timeline {
|
||||
position: relative;
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
||||
.timeline-item {
|
||||
margin-bottom: 20px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.timeline-item:before {
|
||||
content: '';
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
background: #667eea;
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
left: -25px;
|
||||
top: 3px;
|
||||
}
|
||||
|
||||
.timeline-item.completed:before {
|
||||
background: #10b981;
|
||||
}
|
||||
|
||||
.timeline-item.current:before {
|
||||
animation: pulse 1.5s infinite;
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0%, 100% { transform: scale(1); }
|
||||
50% { transform: scale(1.3); }
|
||||
}
|
||||
|
||||
.timeline-title {
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.timeline-subtitle {
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.footer {
|
||||
text-align: center;
|
||||
color: white;
|
||||
margin-top: 40px;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.alert {
|
||||
background: #fef3c7;
|
||||
border-left: 4px solid #f59e0b;
|
||||
padding: 15px;
|
||||
border-radius: 4px;
|
||||
margin: 15px 0;
|
||||
color: #92400e;
|
||||
}
|
||||
|
||||
.success {
|
||||
background: #dcfce7;
|
||||
border-left: 4px solid #10b981;
|
||||
color: #166534;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
h1 {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.section {
|
||||
padding: 20px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<!-- 页眉 -->
|
||||
<header>
|
||||
<h1>🚀 jiao77.cn 部署仪表板</h1>
|
||||
<p class="subtitle">Phase 1 P0 自动化完成 • 等待执行部署</p>
|
||||
<span class="status-badge">✅ 自动化就绪</span>
|
||||
</header>
|
||||
|
||||
<!-- 关键指标 -->
|
||||
<div class="grid">
|
||||
<div class="card">
|
||||
<div class="card-title"><span class="icon">⚡</span>自动化脚本</div>
|
||||
<div class="card-content">3 个完整脚本<br>800+ 行代码<br>生产就绪</div>
|
||||
<div class="progress-bar">
|
||||
<div class="progress-fill" style="width: 100%"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-title"><span class="icon">📚</span>部署文档</div>
|
||||
<div class="card-content">5 份详细指南<br>1,300+ 行文档<br>完整参考</div>
|
||||
<div class="progress-bar">
|
||||
<div class="progress-fill" style="width: 100%"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-title"><span class="icon">⏱️</span>时间节省</div>
|
||||
<div class="card-content">从 90 分钟<br>→ 18 分钟<br>节省 80%</div>
|
||||
<div class="progress-bar">
|
||||
<div class="progress-fill" style="width: 80%"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-title"><span class="icon">✅</span>自动化覆盖</div>
|
||||
<div class="card-content">92% 任务自动化<br>8% 手工配置<br>一键部署</div>
|
||||
<div class="progress-bar">
|
||||
<div class="progress-fill" style="width: 92%"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 快速开始 -->
|
||||
<div class="section">
|
||||
<h2 class="section-title">🎯 立即开始</h2>
|
||||
|
||||
<div class="alert success">
|
||||
<strong>✨ 好消息</strong><br>
|
||||
所有脚本已准备就绪,只需一条命令启动整个部署流程!
|
||||
</div>
|
||||
|
||||
<h3 style="margin-top: 20px; color: #333; margin-bottom: 10px;">第 1 步:一键部署到 VPS</h3>
|
||||
<div class="code-block">bash scripts/deploy-to-vps.sh</div>
|
||||
<p style="color: #666; font-size: 14px; margin-bottom: 15px;">
|
||||
预计时间:25-30 分钟(完全自动化)
|
||||
</p>
|
||||
|
||||
<h3 style="margin-top: 20px; color: #333; margin-bottom: 10px;">第 2 步:配置 DNS</h3>
|
||||
<p style="color: #666; font-size: 14px; margin-bottom: 10px;">
|
||||
在域名注册商添加 A 记录,将 jiao77.cn 指向 VPS IP(从脚本输出获得)
|
||||
</p>
|
||||
<p style="color: #666; font-size: 14px; margin-bottom: 15px;">
|
||||
预计时间:5 分钟配置 + 15-60 分钟 DNS 传播
|
||||
</p>
|
||||
|
||||
<h3 style="margin-top: 20px; color: #333; margin-bottom: 10px;">第 3 步:申请 SSL 证书</h3>
|
||||
<div class="code-block">ssh root@jiao77.cn "cd /home/app/astro-jiao77.cn && bash scripts/init-ssl.sh"</div>
|
||||
<p style="color: #666; font-size: 14px;">
|
||||
预计时间:3-5 分钟(需要 DNS 已生效)
|
||||
</p>
|
||||
|
||||
<div class="button-group">
|
||||
<button class="button" onclick="copyToClipboard('bash scripts/deploy-to-vps.sh')">
|
||||
📋 复制部署命令
|
||||
</button>
|
||||
<a href="QUICK_START.md" class="button button-secondary">
|
||||
📖 查看快速指南
|
||||
</a>
|
||||
<a href="DEPLOYMENT_CHECKLIST.md" class="button button-secondary">
|
||||
✅ 查看检查清单
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 项目进度 -->
|
||||
<div class="section">
|
||||
<h2 class="section-title">📊 项目进度</h2>
|
||||
|
||||
<div class="timeline">
|
||||
<div class="timeline-item completed">
|
||||
<div class="timeline-title">✅ SSH 连接验证</div>
|
||||
<div class="timeline-subtitle">已完成</div>
|
||||
</div>
|
||||
|
||||
<div class="timeline-item completed">
|
||||
<div class="timeline-title">✅ 自动化脚本创建</div>
|
||||
<div class="timeline-subtitle">3 个脚本 (800+ 行)</div>
|
||||
</div>
|
||||
|
||||
<div class="timeline-item completed">
|
||||
<div class="timeline-title">✅ 部署文档编写</div>
|
||||
<div class="timeline-subtitle">5 份指南 (1,300+ 行)</div>
|
||||
</div>
|
||||
|
||||
<div class="timeline-item current">
|
||||
<div class="timeline-title">⏳ VPS 初始化</div>
|
||||
<div class="timeline-subtitle">等待执行 (25-30 分钟)</div>
|
||||
</div>
|
||||
|
||||
<div class="timeline-item pending">
|
||||
<div class="timeline-title">⏳ DNS 配置</div>
|
||||
<div class="timeline-subtitle">手工配置 + 等待传播 (15-60 分钟)</div>
|
||||
</div>
|
||||
|
||||
<div class="timeline-item pending">
|
||||
<div class="timeline-title">⏳ SSL 证书申请</div>
|
||||
<div class="timeline-subtitle">自动化脚本 (3-5 分钟)</div>
|
||||
</div>
|
||||
|
||||
<div class="timeline-item pending">
|
||||
<div class="timeline-title">📅 Phase 2 后端开发</div>
|
||||
<div class="timeline-subtitle">60 小时计划</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Phase 1 P0 检查清单 -->
|
||||
<div class="section">
|
||||
<h2 class="section-title">✅ Phase 1 P0 任务清单</h2>
|
||||
|
||||
<ul class="checklist">
|
||||
<li>SSH 连接 VPS</li>
|
||||
<li>系统更新和工具安装</li>
|
||||
<li>防火墙配置 (UFW)</li>
|
||||
<li>时区和 NTP 配置</li>
|
||||
<li>应用用户创建</li>
|
||||
<li>Docker 和 Docker Compose 安装</li>
|
||||
<li class="pending">DNS 配置</li>
|
||||
<li class="pending">SSL 证书申请</li>
|
||||
<li class="pending">HTTPS 测试</li>
|
||||
<li>存储分配规划</li>
|
||||
<li>数据目录创建</li>
|
||||
<li>项目克隆</li>
|
||||
<li>后端项目结构</li>
|
||||
<li>环境配置生成</li>
|
||||
<li>最小化 package.json</li>
|
||||
<li>Express 服务器框架</li>
|
||||
<li>PostgreSQL 连接</li>
|
||||
<li>数据库 Schema</li>
|
||||
<li>API 端点规划</li>
|
||||
<li>测试框架设置</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- 关键文件 -->
|
||||
<div class="section">
|
||||
<h2 class="section-title">📁 关键文件位置</h2>
|
||||
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 15px;">
|
||||
<div style="background: #f9fafb; padding: 15px; border-radius: 6px; border-left: 3px solid #667eea;">
|
||||
<div style="font-weight: bold; color: #333; margin-bottom: 5px;">一键部署</div>
|
||||
<div style="color: #666; font-size: 13px; font-family: monospace;">scripts/deploy-to-vps.sh</div>
|
||||
</div>
|
||||
|
||||
<div style="background: #f9fafb; padding: 15px; border-radius: 6px; border-left: 3px solid #667eea;">
|
||||
<div style="font-weight: bold; color: #333; margin-bottom: 5px;">快速开始</div>
|
||||
<div style="color: #666; font-size: 13px; font-family: monospace;">QUICK_START.md</div>
|
||||
</div>
|
||||
|
||||
<div style="background: #f9fafb; padding: 15px; border-radius: 6px; border-left: 3px solid #667eea;">
|
||||
<div style="font-weight: bold; color: #333; margin-bottom: 5px;">检查清单</div>
|
||||
<div style="color: #666; font-size: 13px; font-family: monospace;">DEPLOYMENT_CHECKLIST.md</div>
|
||||
</div>
|
||||
|
||||
<div style="background: #f9fafb; padding: 15px; border-radius: 6px; border-left: 3px solid #10b981;">
|
||||
<div style="font-weight: bold; color: #333; margin-bottom: 5px;">完成报告</div>
|
||||
<div style="color: #666; font-size: 13px; font-family: monospace;">docs/PHASE_1_P0_COMPLETION_REPORT.md</div>
|
||||
</div>
|
||||
|
||||
<div style="background: #f9fafb; padding: 15px; border-radius: 6px; border-left: 3px solid #10b981;">
|
||||
<div style="font-weight: bold; color: #333; margin-bottom: 5px;">详细指南</div>
|
||||
<div style="color: #666; font-size: 13px; font-family: monospace;">docs/VPS_DEPLOYMENT_GUIDE.md</div>
|
||||
</div>
|
||||
|
||||
<div style="background: #f9fafb; padding: 15px; border-radius: 6px; border-left: 3px solid #10b981;">
|
||||
<div style="font-weight: bold; color: #333; margin-bottom: 5px;">项目规划</div>
|
||||
<div style="color: #666; font-size: 13px; font-family: monospace;">docs/SINGLE_VPS_DEPLOYMENT_PLAN.md</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 时间表 -->
|
||||
<div class="section">
|
||||
<h2 class="section-title">⏱️ 预计时间表</h2>
|
||||
|
||||
<div style="background: #f9fafb; border-radius: 6px; padding: 15px;">
|
||||
<div class="metric">
|
||||
<span class="metric-label">VPS 初始化(自动化)</span>
|
||||
<span class="metric-value">25-30 分钟</span>
|
||||
</div>
|
||||
<div class="metric">
|
||||
<span class="metric-label">DNS 配置</span>
|
||||
<span class="metric-value">5 + 15-60 分钟</span>
|
||||
</div>
|
||||
<div class="metric">
|
||||
<span class="metric-label">SSL 证书申请(自动化)</span>
|
||||
<span class="metric-value">3-5 分钟</span>
|
||||
</div>
|
||||
<div class="metric">
|
||||
<span class="metric-label">总计</span>
|
||||
<span class="metric-value">60-110 分钟</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="background: #f9fafb; border-radius: 6px; padding: 15px; margin-top: 15px;">
|
||||
<div style="color: #666; font-size: 14px;">
|
||||
<strong>时间节省</strong><br>
|
||||
• 手工配置:90 分钟<br>
|
||||
• 自动化:18 分钟<br>
|
||||
• 节省:72 分钟 (80%)
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 故障排查 -->
|
||||
<div class="section">
|
||||
<h2 class="section-title">🔧 常见问题</h2>
|
||||
|
||||
<div style="margin-bottom: 20px;">
|
||||
<h3 style="color: #333; margin-bottom: 8px;">Q: 部署需要多久?</h3>
|
||||
<p style="color: #666; font-size: 14px;">A: VPS 初始化 25-30 分钟(自动化),加上 DNS 传播等待时间,总计 60-110 分钟</p>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 20px;">
|
||||
<h3 style="color: #333; margin-bottom: 8px;">Q: SSL 证书如何配置?</h3>
|
||||
<p style="color: #666; font-size: 14px;">A: DNS 生效后自动配置,脚本会处理所有细节,无需手工介入</p>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 20px;">
|
||||
<h3 style="color: #333; margin-bottom: 8px;">Q: 出现错误怎么办?</h3>
|
||||
<p style="color: #666; font-size: 14px;">A: 查看 DEPLOYMENT_CHECKLIST.md 中的故障排查部分</p>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 20px;">
|
||||
<h3 style="color: #333; margin-bottom: 8px;">Q: 脚本可以重复执行吗?</h3>
|
||||
<p style="color: #666; font-size: 14px;">A: 可以,脚本设计支持幂等性,重复执行不会产生问题</p>
|
||||
</div>
|
||||
|
||||
<div class="button-group">
|
||||
<a href="DEPLOYMENT_CHECKLIST.md" class="button button-secondary">
|
||||
📖 查看完整故障排查指南
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 下一步 -->
|
||||
<div class="section">
|
||||
<h2 class="section-title">📅 后续规划</h2>
|
||||
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px;">
|
||||
<div style="background: #f0f9ff; padding: 15px; border-radius: 6px; border: 1px solid #0284c7;">
|
||||
<div style="font-weight: bold; color: #0c4a6e; margin-bottom: 8px;">📅 Phase 2</div>
|
||||
<div style="color: #064e3b; font-size: 14px;">
|
||||
后端开发<br>
|
||||
<strong>60 小时</strong><br>
|
||||
Express + PostgreSQL
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="background: #fefce8; padding: 15px; border-radius: 6px; border: 1px solid #eab308;">
|
||||
<div style="font-weight: bold; color: #713f12; margin-bottom: 8px;">📅 Phase 3</div>
|
||||
<div style="color: #713f12; font-size: 14px;">
|
||||
前端开发<br>
|
||||
<strong>50 小时</strong><br>
|
||||
React 组件
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="background: #fdf2f8; padding: 15px; border-radius: 6px; border: 1px solid #ec4899;">
|
||||
<div style="font-weight: bold; color: #831843; margin-bottom: 8px;">📅 Phase 4</div>
|
||||
<div style="color: #831843; font-size: 14px;">
|
||||
Docker 化<br>
|
||||
<strong>20 小时</strong><br>
|
||||
容器编排
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p style="color: #666; font-size: 14px; margin-top: 15px;">
|
||||
<strong>总计</strong>:220 小时(4-6 周),一个人开发或 3-4 周两个人
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- 页脚 -->
|
||||
<footer>
|
||||
<p>✨ jiao77.cn 项目 • Phase 1 P0 自动化完成</p>
|
||||
<p style="font-size: 12px; margin-top: 10px;">准备好了吗?执行命令:<code style="background: rgba(0,0,0,0.2); padding: 4px 8px; border-radius: 4px;">bash scripts/deploy-to-vps.sh</code></p>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function copyToClipboard(text) {
|
||||
navigator.clipboard.writeText(text).then(() => {
|
||||
alert('已复制到剪贴板!');
|
||||
}).catch(err => {
|
||||
console.error('复制失败:', err);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
281
deploy-full.sh
281
deploy-full.sh
@@ -1,281 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 🚀 Jiao77.cn 一键部署脚本
|
||||
# 自动构建并部署 Astro 网站到生产服务器
|
||||
|
||||
set -e # 遇到错误立即停止
|
||||
|
||||
SERVER_IP="110.42.70.70"
|
||||
DEFAULT_USER="root"
|
||||
DEFAULT_WEB_ROOT="/var/www/jiao77.cn"
|
||||
|
||||
echo "🌟 =================================="
|
||||
echo "🌟 Jiao77.cn 网站部署工具"
|
||||
echo "🌟 =================================="
|
||||
echo ""
|
||||
|
||||
# 检查必要的工具
|
||||
check_requirements() {
|
||||
echo "🔍 检查部署环境..."
|
||||
|
||||
if ! command -v npm &> /dev/null; then
|
||||
echo "❌ 错误: npm 未安装"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v rsync &> /dev/null; then
|
||||
echo "⚠️ 警告: rsync 未安装,将使用 scp"
|
||||
USE_RSYNC=false
|
||||
else
|
||||
USE_RSYNC=true
|
||||
fi
|
||||
|
||||
echo "✅ 环境检查完成"
|
||||
}
|
||||
|
||||
# 构建项目
|
||||
build_project() {
|
||||
echo ""
|
||||
echo "📦 构建生产版本..."
|
||||
|
||||
if [ ! -f "package.json" ]; then
|
||||
echo "❌ 错误: 当前目录不是 Astro 项目根目录"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 清理之前的构建
|
||||
if [ -d "dist" ]; then
|
||||
rm -rf dist
|
||||
fi
|
||||
|
||||
# 构建项目
|
||||
npm run build
|
||||
|
||||
if [ ! -d "dist" ]; then
|
||||
echo "❌ 错误: 构建失败,dist 目录不存在"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 检查必要的静态文件
|
||||
echo "🔍 检查静态资源..."
|
||||
|
||||
# 检查是否有图片资源
|
||||
if [ -d "public/report" ]; then
|
||||
echo "✅ 找到报告图片资源"
|
||||
else
|
||||
echo "⚠️ 未找到 public/report 目录"
|
||||
fi
|
||||
|
||||
# 检查 SEO 相关文件
|
||||
if [ -f "public/robots.txt" ]; then
|
||||
echo "✅ robots.txt 存在"
|
||||
else
|
||||
echo "⚠️ 建议添加 robots.txt 文件"
|
||||
fi
|
||||
|
||||
if [ -f "public/sitemap.xml" ]; then
|
||||
echo "✅ sitemap.xml 存在"
|
||||
else
|
||||
echo "⚠️ 建议添加 sitemap.xml 文件"
|
||||
fi
|
||||
|
||||
if [ -f "public/favicon.ico" ]; then
|
||||
echo "✅ favicon.ico 存在"
|
||||
else
|
||||
echo "⚠️ 建议添加 favicon.ico 文件"
|
||||
fi
|
||||
|
||||
echo "✅ 构建完成"
|
||||
}
|
||||
|
||||
# 获取用户输入
|
||||
get_deploy_config() {
|
||||
echo ""
|
||||
echo "⚙️ 部署配置"
|
||||
|
||||
read -p "📝 服务器用户名 (默认: ${DEFAULT_USER}): " USERNAME
|
||||
USERNAME=${USERNAME:-$DEFAULT_USER}
|
||||
|
||||
read -p "📁 网站根目录 (默认: ${DEFAULT_WEB_ROOT}): " WEB_ROOT
|
||||
WEB_ROOT=${WEB_ROOT:-$DEFAULT_WEB_ROOT}
|
||||
|
||||
echo ""
|
||||
echo "📋 部署信息确认:"
|
||||
echo " 服务器: ${SERVER_IP}"
|
||||
echo " 用户名: ${USERNAME}"
|
||||
echo " 目录: ${WEB_ROOT}"
|
||||
echo ""
|
||||
|
||||
read -p "❓ 确认部署? (y/N): " CONFIRM
|
||||
if [[ ! $CONFIRM =~ ^[Yy]$ ]]; then
|
||||
echo "❌ 部署已取消"
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
# 上传 .htaccess 文件
|
||||
upload_htaccess() {
|
||||
echo "📤 上传 .htaccess 文件..."
|
||||
if [ -f ".htaccess" ]; then
|
||||
scp .htaccess ${USERNAME}@${SERVER_IP}:${WEB_ROOT}/.htaccess
|
||||
echo "✅ .htaccess 文件已上传"
|
||||
else
|
||||
echo "⚠️ .htaccess 文件不存在,跳过上传"
|
||||
fi
|
||||
}
|
||||
|
||||
# 部署文件
|
||||
deploy_files() {
|
||||
echo ""
|
||||
echo "🚀 开始部署文件..."
|
||||
|
||||
if [ "$USE_RSYNC" = true ]; then
|
||||
echo "📡 使用 rsync 同步文件..."
|
||||
rsync -avz --delete --progress \
|
||||
--exclude='.htaccess' \
|
||||
dist/ ${USERNAME}@${SERVER_IP}:${WEB_ROOT}/
|
||||
else
|
||||
echo "📡 使用 scp 上传文件..."
|
||||
# 创建临时压缩包
|
||||
cd dist
|
||||
tar -czf ../deploy-temp.tar.gz *
|
||||
cd ..
|
||||
|
||||
# 上传并解压
|
||||
scp deploy-temp.tar.gz ${USERNAME}@${SERVER_IP}:/tmp/
|
||||
ssh ${USERNAME}@${SERVER_IP} "cd ${WEB_ROOT} && sudo tar -xzf /tmp/deploy-temp.tar.gz && sudo rm /tmp/deploy-temp.tar.gz"
|
||||
|
||||
# 清理本地临时文件
|
||||
rm -f deploy-temp.tar.gz
|
||||
fi
|
||||
|
||||
# 上传 .htaccess
|
||||
upload_htaccess
|
||||
|
||||
echo "✅ 文件部署完成"
|
||||
}
|
||||
|
||||
# 设置文件权限
|
||||
set_permissions() {
|
||||
echo ""
|
||||
echo "🔐 设置文件权限..."
|
||||
|
||||
ssh ${USERNAME}@${SERVER_IP} "
|
||||
sudo chown -R www-data:www-data ${WEB_ROOT}/ &&
|
||||
sudo find ${WEB_ROOT}/ -type d -exec chmod 755 {} \; &&
|
||||
sudo find ${WEB_ROOT}/ -type f -exec chmod 644 {} \;
|
||||
"
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "✅ 权限设置完成"
|
||||
else
|
||||
echo "⚠️ 权限设置失败,可能需要手动调整"
|
||||
fi
|
||||
}
|
||||
|
||||
# 部署后测试
|
||||
post_deploy_test() {
|
||||
echo ""
|
||||
echo "🧪 部署后测试..."
|
||||
|
||||
# 测试网站是否可访问
|
||||
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://${SERVER_IP}/ || echo "000")
|
||||
|
||||
if [ "$HTTP_CODE" = "200" ]; then
|
||||
echo "✅ 网站访问正常 (HTTP $HTTP_CODE)"
|
||||
else
|
||||
echo "⚠️ 网站可能存在问题 (HTTP $HTTP_CODE)"
|
||||
fi
|
||||
|
||||
# 检测压缩是否启用
|
||||
GZIP_TEST=$(curl -H "Accept-Encoding: gzip" -s -I http://${SERVER_IP}/ | grep -i "content-encoding: gzip" || echo "")
|
||||
|
||||
if [ -n "$GZIP_TEST" ]; then
|
||||
echo "✅ Gzip 压缩已启用"
|
||||
else
|
||||
echo "⚠️ Gzip 压缩未启用,建议检查 Apache 配置"
|
||||
fi
|
||||
}
|
||||
|
||||
# 显示部署结果
|
||||
show_results() {
|
||||
echo ""
|
||||
echo "🎉 =================================="
|
||||
echo "🎉 部署完成!"
|
||||
echo "🎉 =================================="
|
||||
echo ""
|
||||
echo "🌐 网站地址:"
|
||||
echo " 主域名: http://jiao77.cn"
|
||||
echo " IP访问: http://${SERVER_IP}"
|
||||
echo ""
|
||||
echo "📋 建议检查事项:"
|
||||
echo " ✓ 访问网站确认页面正常显示"
|
||||
echo " ✓ 测试导航卡片点击功能"
|
||||
echo " ✓ 检查 /reports 页面"
|
||||
echo " ✓ 验证页眉展开/收缩功能"
|
||||
echo " ✓ 测试移动端响应式设计"
|
||||
echo " ✓ 检查动画效果是否正常"
|
||||
echo ""
|
||||
echo "🔧 如果遇到问题:"
|
||||
echo " • 查看部署日志: tail -f /var/log/apache2/error.log"
|
||||
echo " • 检查文件权限: ls -la ${WEB_ROOT}/"
|
||||
echo " • 验证 Apache 配置: apache2ctl configtest"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# 部署前最终检查
|
||||
pre_deploy_check() {
|
||||
echo ""
|
||||
echo "🔎 部署前最终检查..."
|
||||
|
||||
# 检查构建产物
|
||||
if [ ! -f "dist/index.html" ]; then
|
||||
echo "❌ 错误: 构建产物不完整,缺少 index.html"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 检查报告页面是否存在
|
||||
if [ ! -f "dist/reports/index.html" ]; then
|
||||
echo "⚠️ 警告: reports 页面可能不存在"
|
||||
fi
|
||||
|
||||
# 检查重要静态资源
|
||||
MISSING_FILES=()
|
||||
|
||||
if [ ! -f "dist/robots.txt" ]; then
|
||||
MISSING_FILES+=("robots.txt")
|
||||
fi
|
||||
|
||||
if [ ! -f "dist/sitemap.xml" ]; then
|
||||
MISSING_FILES+=("sitemap.xml")
|
||||
fi
|
||||
|
||||
if [ ${#MISSING_FILES[@]} -gt 0 ]; then
|
||||
echo "⚠️ 以下 SEO 文件缺失: ${MISSING_FILES[*]}"
|
||||
else
|
||||
echo "✅ SEO 文件检查通过"
|
||||
fi
|
||||
|
||||
echo "✅ 部署前检查完成"
|
||||
}
|
||||
|
||||
# 主函数
|
||||
main() {
|
||||
check_requirements
|
||||
build_project
|
||||
pre_deploy_check
|
||||
get_deploy_config
|
||||
deploy_files
|
||||
set_permissions
|
||||
post_deploy_test
|
||||
show_results
|
||||
}
|
||||
|
||||
# 错误处理
|
||||
trap 'echo "❌ 部署过程中出现错误,请检查输出信息"; exit 1' ERR
|
||||
|
||||
# 执行部署
|
||||
main
|
||||
|
||||
echo "🎯 如需 SSL/HTTPS,请参考 DEPLOYMENT.md 中的 SSL 配置章节"
|
||||
echo "📚 完整部署文档: https://github.com/你的仓库/blob/main/DEPLOYMENT.md"
|
||||
53
deploy.sh
53
deploy.sh
@@ -1,53 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 部署到 jiao77.cn 服务器的脚本
|
||||
# 服务器IP: 110.42.70.70
|
||||
|
||||
echo "🚀 开始部署到 jiao77.cn..."
|
||||
|
||||
# 检查 dist 目录是否存在
|
||||
if [ ! -d "dist" ]; then
|
||||
echo "❌ 错误: dist 目录不存在,请先运行 npm run build"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "📦 准备上传文件..."
|
||||
|
||||
# 使用 rsync 同步文件到服务器
|
||||
# 您需要根据实际情况修改以下参数:
|
||||
# - 用户名 (这里假设是 root,请根据实际情况修改)
|
||||
# - Apache 网站根目录 (通常是 /var/www/html)
|
||||
|
||||
read -p "请输入服务器用户名 (默认: root): " USERNAME
|
||||
USERNAME=${USERNAME:-root}
|
||||
|
||||
read -p "请输入 Apache 网站根目录路径 (默认: /var/www/jiao77.cn): " WEB_ROOT
|
||||
WEB_ROOT=${WEB_ROOT:-/var/www/jiao77.cn}
|
||||
|
||||
echo "🔄 正在上传文件到服务器..."
|
||||
|
||||
# 方法1: 使用 rsync (推荐)
|
||||
if command -v rsync &> /dev/null; then
|
||||
echo "使用 rsync 同步文件..."
|
||||
rsync -avz --delete --progress dist/ ${USERNAME}@110.42.70.70:${WEB_ROOT}/
|
||||
else
|
||||
echo "rsync 不可用,使用 scp 上传..."
|
||||
# 方法2: 使用 scp
|
||||
scp -r dist/* ${USERNAME}@110.42.70.70:${WEB_ROOT}/
|
||||
fi
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "✅ 部署成功!"
|
||||
echo "🌐 网站地址: http://jiao77.cn"
|
||||
echo "🌐 备用地址: http://110.42.70.70"
|
||||
|
||||
echo ""
|
||||
echo "📋 部署后检查清单:"
|
||||
echo "1. 访问网站确认页面正常显示"
|
||||
echo "2. 检查所有链接和资源是否正常加载"
|
||||
echo "3. 测试响应式设计在不同设备上的表现"
|
||||
echo "4. 验证动画效果是否正常工作"
|
||||
else
|
||||
echo "❌ 部署失败,请检查网络连接和服务器配置"
|
||||
exit 1
|
||||
fi
|
||||
@@ -1,200 +0,0 @@
|
||||
# EDA/CAD学术发表指南 - 页面转换完成报告
|
||||
|
||||
## ✅ 转换完成情况
|
||||
|
||||
### 📄 创建的文件
|
||||
|
||||
1. **主页面文件**
|
||||
- 路径:`/src/pages/report/ai-eda-paper-report/index.astro`
|
||||
- 大小:约 5KB
|
||||
- 状态:✅ 已创建,无错误
|
||||
|
||||
2. **交互脚本**
|
||||
- 路径:`/src/pages/report/ai-eda-paper-report/eda-venues-interactive.ts`
|
||||
- 大小:约 22KB
|
||||
- 状态:✅ 已创建,TypeScript类型完整
|
||||
- 说明:页面专用脚本,放置在页面文件夹内
|
||||
|
||||
3. **文档说明**
|
||||
- 路径:`/src/pages/report/ai-eda-paper-report/README.md`
|
||||
- 大小:约 6KB
|
||||
- 状态:✅ 已创建
|
||||
|
||||
## 🎯 实现的功能
|
||||
|
||||
### 1. 核心功能(100%完成)
|
||||
- ✅ 智能筛选系统(类型、难度、速度)
|
||||
- ✅ 7个场所的卡片展示
|
||||
- ✅ 交互式模态框(GSAP动画)
|
||||
- ✅ Chart.js数据可视化
|
||||
- ✅ 投稿策略指南(手风琴)
|
||||
- ✅ 响应式布局
|
||||
|
||||
### 2. 技术实现
|
||||
- ✅ Astro框架集成
|
||||
- ✅ TypeScript类型定义
|
||||
- ✅ 莫兰蒂蓝色系主题
|
||||
- ✅ 玻璃态容器效果
|
||||
- ✅ 动画时序系统
|
||||
- ✅ 降级兼容方案
|
||||
|
||||
### 3. 外部依赖
|
||||
- ✅ Chart.js 4.4.1(CDN加载)
|
||||
- ✅ GSAP 3.13(CDN加载)
|
||||
- ✅ Tailwind CSS(内置)
|
||||
|
||||
## 🔧 技术架构
|
||||
|
||||
### 组件使用
|
||||
```astro
|
||||
- BaseLayout(基础布局)
|
||||
- Header(页头)
|
||||
- Footer(页脚)
|
||||
- Container(玻璃态容器)
|
||||
- AnimatedElement(滚动动画)
|
||||
```
|
||||
|
||||
### 脚本模块
|
||||
```typescript
|
||||
/src/pages/report/ai-eda-paper-report/eda-venues-interactive.ts
|
||||
├── VenueData接口(场所数据)
|
||||
├── StrategyData接口(策略数据)
|
||||
├── renderVenues()(渲染卡片)
|
||||
├── openModal()(GSAP动画模态框)
|
||||
├── openSimpleModal()(降级模态框)
|
||||
├── closeModal()(关闭模态框)
|
||||
├── renderStrategyAccordion()(策略手风琴)
|
||||
└── initEDAVenuesInteractive()(初始化)
|
||||
```
|
||||
|
||||
## 🎨 设计特点
|
||||
|
||||
### 莫兰蒂蓝色系
|
||||
- 主色:`#2c4a6b`
|
||||
- 深色:`#011a2d`
|
||||
- 浅色:`#5b778e`
|
||||
|
||||
### 响应式断点
|
||||
- Desktop(≥1024px):3列网格,70vw模态框
|
||||
- Tablet(768-1023px):2列网格,80vw模态框
|
||||
- Mobile(<768px):单列网格,92vw模态框
|
||||
|
||||
### 动画时序
|
||||
```typescript
|
||||
HERO: 200ms
|
||||
FILTERS: 400ms (getSectionBaseDelay(0))
|
||||
VENUES: 600ms (getSectionBaseDelay(1))
|
||||
STRATEGY: 800ms (getSectionBaseDelay(2))
|
||||
```
|
||||
|
||||
## 📊 数据内容
|
||||
|
||||
### 会议场所(4个)
|
||||
1. **DAC** - 顶级会议,14周评审,22.7%接收率
|
||||
2. **ICCAD** - 顶级会议,8周评审,22%接收率
|
||||
3. **DATE** - 高级会议,8周评审,35.7%接收率
|
||||
4. **ASP-DAC** - 高级会议,8周评审,31%接收率
|
||||
|
||||
### 期刊场所(3个)
|
||||
1. **IEEE TCAD** - 顶级期刊,10.1周评审,33.5%接收率
|
||||
2. **ACM TODAES** - 高级期刊,16周评审
|
||||
3. **IEEE D&T** - 应用期刊,6周评审
|
||||
|
||||
### 策略指南(3篇)
|
||||
1. 如何理解投稿难度?
|
||||
2. 如何规划发表时间线?
|
||||
3. 如何制定投稿策略?
|
||||
|
||||
## 🚀 访问方式
|
||||
|
||||
### 开发环境
|
||||
```bash
|
||||
npm run dev
|
||||
# 访问 http://localhost:4321/report/ai-eda-paper-report
|
||||
```
|
||||
|
||||
### 生产环境
|
||||
```bash
|
||||
npm run build
|
||||
npm run preview
|
||||
# 访问 http://localhost:4321/report/ai-eda-paper-report
|
||||
```
|
||||
|
||||
## ⚡ 性能优化
|
||||
|
||||
### 已实现
|
||||
- ✅ CDN加载外部库
|
||||
- ✅ 按需渲染卡片
|
||||
- ✅ CSS动画硬件加速
|
||||
- ✅ 图表懒加载(仅模态框打开时)
|
||||
|
||||
### 降级处理
|
||||
- ✅ Chart.js未加载时跳过图表
|
||||
- ✅ GSAP未加载时使用简化模态框
|
||||
- ✅ 所有核心功能保持可用
|
||||
|
||||
## 🔍 错误检查
|
||||
|
||||
### TypeScript检查
|
||||
```bash
|
||||
✅ 0 errors
|
||||
✅ 0 warnings(ai-eda-paper-report)
|
||||
✅ 4 hints(其他页面的未使用导入)
|
||||
```
|
||||
|
||||
### 构建验证
|
||||
```bash
|
||||
✅ astro check 通过
|
||||
✅ astro build 成功
|
||||
✅ 44个文件处理完成
|
||||
```
|
||||
|
||||
## 📝 与原始HTML的差异
|
||||
|
||||
### 保持一致
|
||||
- ✅ 所有数据内容
|
||||
- ✅ 所有交互功能
|
||||
- ✅ 视觉设计风格
|
||||
- ✅ 响应式布局
|
||||
|
||||
### 改进升级
|
||||
- ✅ Astro组件化架构
|
||||
- ✅ TypeScript类型安全
|
||||
- ✅ 莫兰蒂蓝色系主题
|
||||
- ✅ 统一的动画系统
|
||||
- ✅ 更好的错误处理
|
||||
- ✅ 模块化脚本管理
|
||||
|
||||
### 移除内容
|
||||
- ❌ jiao77-system.js(使用原生Astro组件)
|
||||
- ❌ 内联样式(使用Astro <style>)
|
||||
- ❌ 重复的字体引用(统一管理)
|
||||
- ❌ data-footer属性(使用Footer组件)
|
||||
|
||||
## 🎯 总结
|
||||
|
||||
### 成功要点
|
||||
1. **完整功能迁移**:所有交互功能100%保留
|
||||
2. **代码质量提升**:TypeScript类型安全,模块化设计
|
||||
3. **主题统一**:应用莫兰蒂蓝色系
|
||||
4. **性能优化**:CDN加载,降级兼容
|
||||
5. **文档完善**:详细的README和技术文档
|
||||
|
||||
### 技术亮点
|
||||
- 🎨 GSAP流畅动画(卡片→模态框变换)
|
||||
- 📊 Chart.js可视化图表
|
||||
- 🎭 降级兼容方案(确保核心功能)
|
||||
- 🔧 TypeScript类型完整
|
||||
- 📱 完全响应式设计
|
||||
|
||||
### 访问路径
|
||||
```
|
||||
/report/ai-eda-paper-report
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**创建日期**:2025年10月1日
|
||||
**状态**:✅ 完成
|
||||
**构建状态**:✅ 通过
|
||||
**TypeScript检查**:✅ 无错误
|
||||
@@ -1,158 +0,0 @@
|
||||
# 动画延迟系统:从固定值到动态变量的升级
|
||||
|
||||
## 系统概述
|
||||
|
||||
已成功将报告页面的动画延迟系统从固定值改进为基于变量的动态计算系统,提供更好的协调性和可维护性。
|
||||
|
||||
## 核心改进
|
||||
|
||||
### 1. 动态时序计算模块
|
||||
- **文件**: `/src/scripts/animation-timing.ts`
|
||||
- **功能**: 提供统一的动画时序计算工具
|
||||
- **优势**: 数学关系清晰,易于维护和调整
|
||||
|
||||
### 2. 基础延迟配置
|
||||
```typescript
|
||||
const BASE_DELAYS = {
|
||||
HERO: 160, // 首屏动画延迟
|
||||
FIRST_SECTION: 280, // 第一章节基础延迟
|
||||
SECTION_INCREMENT: 160,// 后续章节递增
|
||||
SUB_ELEMENT_BASE: 50,
|
||||
SUB_ELEMENT_INCREMENT: 50,
|
||||
NESTED_ELEMENT_BASE: 100,
|
||||
IMAGE_BASE: 50,
|
||||
};
|
||||
```
|
||||
|
||||
### 3. 核心计算函数
|
||||
|
||||
#### 章节基础延迟
|
||||
```typescript
|
||||
getSectionBaseDelay(index: number): number
|
||||
// 计算公式: 280 + index * 160
|
||||
```
|
||||
|
||||
#### 子元素延迟
|
||||
```typescript
|
||||
getChildDelay(parentDelay: number, childIndex: number): number
|
||||
// 计算公式: parentDelay + BASE_DELAYS.CHILD + (childIndex * BASE_DELAYS.CHILD)
|
||||
```
|
||||
|
||||
#### 嵌套元素延迟
|
||||
```typescript
|
||||
getNestedDelay(parentDelay: number, nestedIndex: number): number
|
||||
// 计算公式: parentDelay + BASE_DELAYS.NESTED + (nestedIndex * BASE_DELAYS.NESTED)
|
||||
```
|
||||
|
||||
#### 图片元素延迟
|
||||
```typescript
|
||||
getImageDelay(baseDelay: number, imageIndex: number): number
|
||||
// 计算公式: baseDelay + BASE_DELAYS.IMAGE + (imageIndex * BASE_DELAYS.IMAGE)
|
||||
```
|
||||
|
||||
## 应用实例
|
||||
|
||||
### 1. 20250609 报告 (完全迁移)
|
||||
- **章节延迟**: 使用 `SECTION_DELAYS` 常量配置
|
||||
- **子元素**: 技术挑战卡片、深度分析卡片等使用 `getChildDelay()`
|
||||
- **嵌套元素**: 卡片内的细节使用 `getNestedDelay()`
|
||||
- **图片序列**: 使用 `getImageDelay()` 处理多图展示
|
||||
|
||||
### 2. 模板系统 (完全迁移)
|
||||
- **配置**: `TEMPLATE_SECTION_DELAYS` 常量定义各章节基础延迟
|
||||
- **标准化**: 所有模板组件采用统一的动态计算方式
|
||||
- **灵活性**: 便于快速调整整体动画节奏
|
||||
|
||||
## 动画时序层级关系
|
||||
|
||||
```
|
||||
章节延迟 (Section)
|
||||
├── 子元素延迟 (Child) = 父级 + 基础增量 + 索引增量
|
||||
│ └── 嵌套元素延迟 (Nested) = 父级 + 嵌套增量 + 索引增量
|
||||
└── 图片延迟 (Image) = 基础 + 图片增量 + 索引增量
|
||||
```
|
||||
|
||||
## 延迟时间示例
|
||||
|
||||
### 典型章节时序:
|
||||
- **概述章节**: 280ms (基础)
|
||||
- **分析章节**: 440ms (基础 + 160ms)
|
||||
- **解决方案**: 600ms (基础 + 320ms)
|
||||
- **对比分析**: 760ms (基础 + 480ms)
|
||||
- **实验结果**: 920ms (基础 + 640ms)
|
||||
- **总结展望**: 1080ms (基础 + 800ms)
|
||||
|
||||
### 子元素时序(以分析章节为例):
|
||||
- **技术挑战1**: 490ms (440ms + 50ms)
|
||||
- **技术挑战2**: 540ms (440ms + 50ms + 50ms)
|
||||
- **技术挑战3**: 590ms (440ms + 50ms + 100ms)
|
||||
|
||||
## 技术优势
|
||||
|
||||
### 1. 可维护性
|
||||
- 统一的计算逻辑,避免魔数
|
||||
- 便于全局调整动画节奏
|
||||
- 清晰的层级关系
|
||||
|
||||
### 2. 一致性
|
||||
- 数学关系确保视觉协调
|
||||
- 标准化的动画模式
|
||||
- 可预测的用户体验
|
||||
|
||||
### 3. 扩展性
|
||||
- 易于添加新的延迟类型
|
||||
- 支持复杂的嵌套结构
|
||||
- 灵活的配置选项
|
||||
|
||||
### 4. 开发效率
|
||||
- 无需手动计算延迟值
|
||||
- 自动处理父子关系
|
||||
- 减少动画冲突
|
||||
|
||||
## 构建验证
|
||||
|
||||
✅ 所有页面构建成功
|
||||
✅ TypeScript 类型检查通过
|
||||
✅ 无运行时错误
|
||||
✅ 动画时序正常工作
|
||||
|
||||
## 未来扩展
|
||||
|
||||
1. **批量延迟**: 使用 `getBatchDelays()` 处理大量元素
|
||||
2. **自定义配置**: 支持页面级别的延迟配置覆盖
|
||||
3. **响应式延迟**: 根据屏幕尺寸调整动画时序
|
||||
4. **性能优化**: 考虑减少长延迟对用户体验的影响
|
||||
|
||||
## 使用指南
|
||||
|
||||
### 导入工具函数:
|
||||
```typescript
|
||||
import {
|
||||
getSectionBaseDelay,
|
||||
getChildDelay,
|
||||
getNestedDelay,
|
||||
getImageDelay
|
||||
} from '../scripts/animation-timing';
|
||||
```
|
||||
|
||||
### 定义章节延迟:
|
||||
```typescript
|
||||
const SECTION_DELAYS = {
|
||||
OVERVIEW: getSectionBaseDelay(0), // 280ms
|
||||
ANALYSIS: getSectionBaseDelay(1), // 440ms
|
||||
SOLUTION: getSectionBaseDelay(2), // 600ms
|
||||
};
|
||||
```
|
||||
|
||||
### 应用到组件:
|
||||
```astro
|
||||
<AnimatedElement animation="fadeInUp" delay={SECTION_DELAYS.ANALYSIS} trigger="scroll">
|
||||
<div class="section-content">
|
||||
<AnimatedElement animation="fadeInUp" delay={getChildDelay(SECTION_DELAYS.ANALYSIS, 0)} trigger="scroll">
|
||||
<div class="child-element">子元素内容</div>
|
||||
</AnimatedElement>
|
||||
</div>
|
||||
</AnimatedElement>
|
||||
```
|
||||
|
||||
这个动态延迟系统现在为整个项目提供了一致、可维护和协调的动画体验!
|
||||
@@ -1,94 +0,0 @@
|
||||
# 居中问题修复说明
|
||||
|
||||
## 🔧 问题分析
|
||||
"欢迎来到 Jiao77" 卡片没有居中的问题是因为 Container 组件只设置了 `max-width` 但没有添加 `margin: 0 auto` 来实现水平居中。
|
||||
|
||||
## ✅ 修复内容
|
||||
|
||||
### 1. 修复 Container 组件
|
||||
在 `src/components/Container.astro` 中为所有尺寸的容器添加了 `margin: 0 auto`:
|
||||
|
||||
```css
|
||||
/* 尺寸样式 */
|
||||
.container-small {
|
||||
max-width: 400px;
|
||||
margin: 0 auto; /* 添加自动居中 */
|
||||
}
|
||||
|
||||
.container-medium {
|
||||
max-width: 600px;
|
||||
margin: 0 auto; /* 添加自动居中 */
|
||||
}
|
||||
|
||||
.container-large {
|
||||
max-width: 800px;
|
||||
margin: 0 auto; /* 添加自动居中 */
|
||||
}
|
||||
|
||||
.container-full {
|
||||
width: 100%;
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 增强页面布局
|
||||
在 `src/pages/index.astro` 中添加了外层容器来确保最佳的居中效果:
|
||||
|
||||
```astro
|
||||
<main class="main-content">
|
||||
<div class="container mx-auto px-4"> <!-- 新增的容器 -->
|
||||
<AnimatedElement animation="fadeInUp" delay={200}>
|
||||
<Container variant="glass" size="large" padding="xl" className="text-center mb-12">
|
||||
<h1 class="hero-title">欢迎来到 Jiao77</h1>
|
||||
<p class="hero-subtitle">探索现代化的网站体验</p>
|
||||
</Container>
|
||||
</AnimatedElement>
|
||||
</div>
|
||||
</main>
|
||||
```
|
||||
|
||||
### 3. 添加配套的 CSS 样式
|
||||
```css
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mx-auto {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.px-4 {
|
||||
padding-left: 1rem;
|
||||
padding-right: 1rem;
|
||||
}
|
||||
```
|
||||
|
||||
## 🎯 修复效果
|
||||
|
||||
现在 "欢迎来到 Jiao77" 卡片会:
|
||||
- ✅ 在桌面端完美居中显示
|
||||
- ✅ 在移动端保持良好的响应式布局
|
||||
- ✅ 保持原有的玻璃质感和动画效果
|
||||
- ✅ 与下方的导航卡片网格保持一致的对齐
|
||||
|
||||
## 📱 响应式支持
|
||||
|
||||
修复同时考虑了不同屏幕尺寸:
|
||||
- **大屏设备**: 最大宽度 800px,居中显示
|
||||
- **中等设备**: 自动适应容器宽度
|
||||
- **小屏设备**: 添加适当的左右内边距防止贴边
|
||||
|
||||
## 🚀 部署更新
|
||||
|
||||
要应用这个修复到生产环境,请运行:
|
||||
|
||||
```bash
|
||||
# 构建新版本
|
||||
npm run build
|
||||
|
||||
# 部署到服务器
|
||||
./deploy-full.sh
|
||||
```
|
||||
|
||||
修复已完成!现在您的大标题卡片会在页面中完美居中显示。
|
||||
@@ -1,352 +0,0 @@
|
||||
# 模态框图表抽搐问题修复
|
||||
|
||||
## 📅 修复日期
|
||||
2025年10月1日
|
||||
|
||||
## 🐛 问题描述
|
||||
|
||||
### 症状
|
||||
在点击EDA学术发表指南的场所卡片时,弹出的模态框中的图表会出现"抽搐"现象:
|
||||
- 图表在渲染时会突然变大或变小
|
||||
- 图表尺寸会快速闪烁调整
|
||||
- 视觉体验不流畅
|
||||
|
||||
### 根本原因
|
||||
**时序问题**:图表在模态框动画**进行中**就开始渲染,而此时容器的尺寸还在变化。
|
||||
|
||||
#### 问题流程(修复前)❌
|
||||
```
|
||||
1. 点击卡片
|
||||
2. 立即渲染图表(容器尺寸 = 卡片大小)
|
||||
3. GSAP动画开始
|
||||
4. 容器从卡片大小 → 模态框大小(0.5秒动画)
|
||||
5. 图表被迫在动画中重新计算尺寸
|
||||
6. 结果:图表"抽搐"
|
||||
```
|
||||
|
||||
#### 问题代码
|
||||
```typescript
|
||||
// ❌ 错误:图表在动画之前渲染
|
||||
modalContent.innerHTML = `...`;
|
||||
|
||||
// 渲染图表(此时容器尺寸还在变化)
|
||||
const ctx = canvas.getContext('2d');
|
||||
activeChart = new Chart(ctx, {...});
|
||||
|
||||
// GSAP动画(容器尺寸正在改变)
|
||||
const tl = gsap.timeline({
|
||||
onComplete: () => { isAnimating = false; }
|
||||
});
|
||||
tl.to(modal, {
|
||||
width: targetW, // 容器宽度变化
|
||||
height: targetH, // 容器高度变化
|
||||
duration: 0.5
|
||||
});
|
||||
```
|
||||
|
||||
## ✅ 修复方案
|
||||
|
||||
### 核心思路
|
||||
**延迟图表渲染**:等待模态框动画完成后再渲染图表,确保容器尺寸已经稳定。
|
||||
|
||||
### 修复后的流程 ✅
|
||||
```
|
||||
1. 点击卡片
|
||||
2. 设置模态框内容(但不渲染图表)
|
||||
3. GSAP动画开始
|
||||
4. 容器从卡片大小 → 模态框大小(0.5秒动画)
|
||||
5. 动画完成回调触发
|
||||
6. 渲染图表(容器尺寸已稳定)
|
||||
7. 结果:图表平滑出现,无抽搐
|
||||
```
|
||||
|
||||
## 🔧 技术实现
|
||||
|
||||
### 1. 提取图表渲染为独立函数
|
||||
|
||||
#### 之前 ❌
|
||||
```typescript
|
||||
// 图表渲染代码直接嵌入在 openModal 中
|
||||
try {
|
||||
const Chart = (window as any).Chart;
|
||||
const ctx = canvas.getContext('2d');
|
||||
activeChart = new Chart(ctx, {...});
|
||||
} catch (err) {
|
||||
console.warn('绘制图表时出错:', err);
|
||||
}
|
||||
```
|
||||
|
||||
#### 现在 ✅
|
||||
```typescript
|
||||
/**
|
||||
* 渲染图表(独立函数,在动画完成后调用)
|
||||
*/
|
||||
function renderVenueChart(venue: VenueData): void {
|
||||
try {
|
||||
const Chart = (window as any).Chart;
|
||||
if (Chart && venue.acceptanceValue !== null) {
|
||||
const canvas = document.getElementById('venueChart') as HTMLCanvasElement;
|
||||
if (!canvas) return;
|
||||
|
||||
const ctx = canvas.getContext('2d');
|
||||
if (ctx) {
|
||||
// 使用 requestAnimationFrame 确保画布尺寸已稳定
|
||||
requestAnimationFrame(() => {
|
||||
activeChart = new Chart(ctx, {
|
||||
type: 'bar',
|
||||
data: {...},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
...
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn('绘制图表时出错:', err);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 在动画完成回调中调用
|
||||
|
||||
#### 之前 ❌
|
||||
```typescript
|
||||
const tl = gsap.timeline({
|
||||
onComplete: () => {
|
||||
isAnimating = false;
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
#### 现在 ✅
|
||||
```typescript
|
||||
const tl = gsap.timeline({
|
||||
onComplete: () => {
|
||||
isAnimating = false;
|
||||
// 动画完成后渲染图表
|
||||
renderVenueChart(venue);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### 3. 添加 requestAnimationFrame 保护
|
||||
|
||||
```typescript
|
||||
requestAnimationFrame(() => {
|
||||
activeChart = new Chart(ctx, {...});
|
||||
});
|
||||
```
|
||||
|
||||
**作用**:
|
||||
- 确保在浏览器下一帧渲染前执行
|
||||
- 给容器一个重绘的机会
|
||||
- 确保尺寸计算准确
|
||||
|
||||
### 4. 简化模式同步修复
|
||||
|
||||
```typescript
|
||||
function openSimpleModal(venueId: string): void {
|
||||
// ... 设置内容 ...
|
||||
|
||||
// 简化模式下也渲染图表
|
||||
renderVenueChart(venue);
|
||||
}
|
||||
```
|
||||
|
||||
## 📊 时序对比
|
||||
|
||||
### 修复前的时序 ❌
|
||||
```
|
||||
时间轴:
|
||||
0ms - 点击卡片
|
||||
0ms - 渲染图表(容器 = 300x200)
|
||||
10ms - GSAP动画开始
|
||||
10ms - 容器尺寸变化开始
|
||||
100ms - 图表检测到容器变化,重新计算
|
||||
200ms - 容器继续变化
|
||||
300ms - 图表再次调整(抽搐)
|
||||
500ms - 动画结束
|
||||
510ms - 图表最终稳定
|
||||
```
|
||||
|
||||
### 修复后的时序 ✅
|
||||
```
|
||||
时间轴:
|
||||
0ms - 点击卡片
|
||||
0ms - 设置内容(图表占位符)
|
||||
10ms - GSAP动画开始
|
||||
10ms - 容器尺寸变化
|
||||
500ms - 动画完成
|
||||
500ms - onComplete 回调
|
||||
510ms - renderVenueChart 调用
|
||||
520ms - requestAnimationFrame
|
||||
530ms - 图表渲染(容器尺寸稳定 = 800x600)
|
||||
540ms - 图表平滑出现 ✅
|
||||
```
|
||||
|
||||
## 🎯 关键优化点
|
||||
|
||||
### 1. 延迟渲染
|
||||
- ✅ 等待容器尺寸稳定
|
||||
- ✅ 避免动画中的重新计算
|
||||
|
||||
### 2. requestAnimationFrame
|
||||
- ✅ 浏览器下一帧渲染
|
||||
- ✅ 确保DOM已更新
|
||||
- ✅ 尺寸计算准确
|
||||
|
||||
### 3. 独立函数
|
||||
- ✅ 代码复用(GSAP模式 + 简化模式)
|
||||
- ✅ 逻辑清晰
|
||||
- ✅ 易于维护
|
||||
|
||||
### 4. 错误处理
|
||||
- ✅ try-catch 包裹
|
||||
- ✅ 优雅降级
|
||||
- ✅ 控制台警告
|
||||
|
||||
## 📝 修改文件
|
||||
|
||||
**文件**: `/src/pages/report/ai-eda-paper-report/eda-venues-interactive.ts`
|
||||
|
||||
**修改内容**:
|
||||
1. 新增 `renderVenueChart()` 函数
|
||||
2. 修改 `openModal()` - 将图表渲染移到 `onComplete`
|
||||
3. 修改 `openSimpleModal()` - 调用新的图表渲染函数
|
||||
|
||||
**代码行数**: ~35行修改
|
||||
|
||||
## 🚀 构建验证
|
||||
|
||||
```bash
|
||||
✓ 0 errors, 0 warnings
|
||||
✓ 20 pages built
|
||||
✓ 图表抽搐问题已修复
|
||||
```
|
||||
|
||||
## 🎨 用户体验提升
|
||||
|
||||
### 修复前 ❌
|
||||
- 图表闪烁、跳动
|
||||
- 尺寸不稳定
|
||||
- 视觉体验差
|
||||
- 看起来像bug
|
||||
|
||||
### 修复后 ✅
|
||||
- 图表平滑出现
|
||||
- 尺寸稳定
|
||||
- 视觉流畅
|
||||
- 专业感强
|
||||
|
||||
## 💡 技术要点
|
||||
|
||||
### Chart.js 响应式原理
|
||||
```typescript
|
||||
options: {
|
||||
responsive: true, // 响应容器尺寸变化
|
||||
maintainAspectRatio: false // 不保持宽高比,填充容器
|
||||
}
|
||||
```
|
||||
|
||||
**问题**:当容器尺寸变化时,Chart.js 会自动调整图表尺寸
|
||||
**解决**:等待容器尺寸稳定后再渲染图表
|
||||
|
||||
### GSAP Timeline onComplete
|
||||
```typescript
|
||||
const tl = gsap.timeline({
|
||||
onComplete: () => {
|
||||
// 所有动画完成后执行
|
||||
renderVenueChart(venue);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
**优势**:
|
||||
- 精确的时序控制
|
||||
- 保证动画完成
|
||||
- 避免中途干扰
|
||||
|
||||
### requestAnimationFrame 的作用
|
||||
```typescript
|
||||
requestAnimationFrame(() => {
|
||||
// 浏览器下一帧执行
|
||||
activeChart = new Chart(ctx, {...});
|
||||
});
|
||||
```
|
||||
|
||||
**原理**:
|
||||
1. 等待浏览器重绘
|
||||
2. 确保DOM已更新
|
||||
3. 尺寸计算准确
|
||||
4. 避免布局抖动
|
||||
|
||||
## 📚 相关知识
|
||||
|
||||
### 1. Chart.js 尺寸计算
|
||||
- Chart.js 基于父容器的 `clientWidth` 和 `clientHeight`
|
||||
- 动画中这些值会不断变化
|
||||
- 导致 Chart.js 多次重新计算和渲染
|
||||
|
||||
### 2. GSAP 动画时序
|
||||
- `duration: 0.5` = 500ms
|
||||
- `ease: 'expo.out'` = 先快后慢
|
||||
- `onComplete` = 动画完成回调
|
||||
|
||||
### 3. 浏览器渲染流程
|
||||
```
|
||||
JavaScript → Style → Layout → Paint → Composite
|
||||
↑
|
||||
requestAnimationFrame 在此执行
|
||||
```
|
||||
|
||||
## 🎯 最佳实践
|
||||
|
||||
### 处理动画中的图表渲染
|
||||
1. ✅ **延迟渲染** - 等待容器尺寸稳定
|
||||
2. ✅ **使用回调** - onComplete、onUpdate 等
|
||||
3. ✅ **requestAnimationFrame** - 确保DOM更新
|
||||
4. ✅ **销毁旧图表** - 避免内存泄漏
|
||||
|
||||
### 避免的错误
|
||||
1. ❌ 在动画进行中渲染图表
|
||||
2. ❌ 不检查容器尺寸
|
||||
3. ❌ 不使用 requestAnimationFrame
|
||||
4. ❌ 忘记销毁旧图表实例
|
||||
|
||||
## 🔍 调试技巧
|
||||
|
||||
### 如何验证修复
|
||||
1. 打开浏览器开发者工具
|
||||
2. 切换到 Performance 标签
|
||||
3. 录制点击卡片的过程
|
||||
4. 查看渲染时序
|
||||
5. 确认图表在动画完成后才渲染
|
||||
|
||||
### 控制台日志
|
||||
```typescript
|
||||
console.log('动画开始');
|
||||
const tl = gsap.timeline({
|
||||
onComplete: () => {
|
||||
console.log('动画完成');
|
||||
renderVenueChart(venue);
|
||||
console.log('图表渲染完成');
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**修复完成!** 🎉
|
||||
现在模态框弹出时图表会平滑出现,无任何抽搐现象。
|
||||
|
||||
**建议测试**:
|
||||
- 点击不同的场所卡片
|
||||
- 观察图表渲染是否平滑
|
||||
- 检查控制台无错误
|
||||
|
||||
**下一步**:
|
||||
- 运行 `npm run dev` 测试效果
|
||||
- 或直接 `npm run build && ./deploy-full.sh` 部署
|
||||
@@ -1,205 +0,0 @@
|
||||
# 公用组件使用指南
|
||||
|
||||
本项目新增了三个高质量的公用组件,支持数学公式渲染、磨砂玻璃表格和代码高亮,所有组件都采用了现代化的磨砂玻璃设计风格。
|
||||
|
||||
## 📐 MathFormula - 数学公式组件
|
||||
|
||||
### 功能特点
|
||||
- 支持 KaTeX 渲染,兼容 LaTeX 语法
|
||||
- 行内和块级显示模式
|
||||
- 磨砂玻璃背景效果
|
||||
- 悬停动画效果
|
||||
- 自动错误处理
|
||||
|
||||
### 使用方法
|
||||
|
||||
```astro
|
||||
---
|
||||
import MathFormula from '../components/common/MathFormula.astro';
|
||||
---
|
||||
|
||||
<!-- 行内公式 -->
|
||||
<MathFormula formula="E = mc^2" display={false} />
|
||||
|
||||
<!-- 块级公式 -->
|
||||
<MathFormula
|
||||
formula="\int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi}"
|
||||
display={true}
|
||||
/>
|
||||
|
||||
<!-- 复杂公式 -->
|
||||
<MathFormula
|
||||
formula="\frac{\partial}{\partial t} \Psi(x,t) = -\frac{i}{\hbar} \hat{H} \Psi(x,t)"
|
||||
display={true}
|
||||
/>
|
||||
```
|
||||
|
||||
### Props 参数
|
||||
|
||||
| 参数 | 类型 | 默认值 | 说明 |
|
||||
|------|------|--------|------|
|
||||
| `formula` | string | - | LaTeX 格式的数学公式 |
|
||||
| `display` | boolean | false | 是否为块级显示 |
|
||||
| `className` | string | '' | 自定义 CSS 类名 |
|
||||
|
||||
## 📊 GlassTable - 磨砂玻璃表格组件
|
||||
|
||||
### 功能特点
|
||||
- 透明磨砂玻璃背景效果
|
||||
- 支持条纹和边框样式
|
||||
- 响应式设计
|
||||
- 悬停行高亮效果
|
||||
- 可自定义表格标题
|
||||
|
||||
### 使用方法
|
||||
|
||||
```astro
|
||||
---
|
||||
import GlassTable from '../components/common/GlassTable.astro';
|
||||
---
|
||||
|
||||
<GlassTable
|
||||
caption="AI算法性能对比"
|
||||
headers={["算法", "准确率", "速度", "内存使用"]}
|
||||
rows={[
|
||||
["YOLO v8", "92.3%", "45 FPS", "256MB"],
|
||||
["ResNet-50", "94.1%", "30 FPS", "512MB"],
|
||||
["EfficientNet", "93.8%", "60 FPS", "128MB"]
|
||||
]}
|
||||
striped={true}
|
||||
bordered={true}
|
||||
/>
|
||||
```
|
||||
|
||||
### Props 参数
|
||||
|
||||
| 参数 | 类型 | 默认值 | 说明 |
|
||||
|------|------|--------|------|
|
||||
| `headers` | string[] | [] | 表头数组 |
|
||||
| `rows` | (string\|number\|boolean)[][] | [] | 表格数据行 |
|
||||
| `caption` | string | - | 表格标题 |
|
||||
| `className` | string | '' | 自定义 CSS 类名 |
|
||||
| `striped` | boolean | false | 是否显示条纹 |
|
||||
| `bordered` | boolean | true | 是否显示边框 |
|
||||
|
||||
### 特殊样式类
|
||||
|
||||
在表格单元格中可以使用以下特殊样式类:
|
||||
|
||||
- `.highlight-cell` - 高亮单元格(绿色)
|
||||
- `.warning-cell` - 警告单元格(黄色)
|
||||
- `.error-cell` - 错误单元格(红色)
|
||||
|
||||
## 💻 CodeBlock - 代码高亮组件
|
||||
|
||||
### 功能特点
|
||||
- 支持多种编程语言语法高亮
|
||||
- 磨砂玻璃背景效果
|
||||
- 可选行号显示
|
||||
- 一键复制代码功能
|
||||
- 代码标题和语言标签
|
||||
- 自动语法检测
|
||||
|
||||
### 使用方法
|
||||
|
||||
```astro
|
||||
---
|
||||
import CodeBlock from '../components/common/CodeBlock.astro';
|
||||
---
|
||||
|
||||
<CodeBlock
|
||||
title="React Hook 示例"
|
||||
language="javascript"
|
||||
showLineNumbers={true}
|
||||
copyable={true}
|
||||
code={`function useFetch(url) {
|
||||
const [data, setData] = useState(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
fetch(url)
|
||||
.then(res => res.json())
|
||||
.then(setData)
|
||||
.finally(() => setLoading(false));
|
||||
}, [url]);
|
||||
|
||||
return { data, loading };
|
||||
}`}
|
||||
/>
|
||||
```
|
||||
|
||||
### Props 参数
|
||||
|
||||
| 参数 | 类型 | 默认值 | 说明 |
|
||||
|------|------|--------|------|
|
||||
| `code` | string | - | 源代码内容 |
|
||||
| `language` | string | 'javascript' | 编程语言 |
|
||||
| `title` | string | - | 代码块标题 |
|
||||
| `showLineNumbers` | boolean | false | 是否显示行号 |
|
||||
| `className` | string | '' | 自定义 CSS 类名 |
|
||||
| `copyable` | boolean | true | 是否显示复制按钮 |
|
||||
|
||||
### 支持的语言
|
||||
|
||||
支持所有 Prism.js 的语言,常用的包括:
|
||||
- `javascript`, `typescript`, `jsx`, `tsx`
|
||||
- `python`, `java`, `csharp`, `cpp`
|
||||
- `html`, `css`, `scss`, `json`
|
||||
- `bash`, `sql`, `yaml`, `markdown`
|
||||
|
||||
## 🎨 设计特点
|
||||
|
||||
所有组件都采用了统一的设计语言:
|
||||
|
||||
### 磨砂玻璃效果
|
||||
- 半透明背景:`rgba(255, 255, 255, 0.1)`
|
||||
- 背景模糊:`backdrop-filter: blur(15px)`
|
||||
- 边框:`1px solid rgba(255, 255, 255, 0.2)`
|
||||
- 圆角:`border-radius: 1rem`
|
||||
|
||||
### 交互动画
|
||||
- 悬停时背景变亮
|
||||
- 轻微上移效果:`translateY(-2px)`
|
||||
- 阴影加深增强立体感
|
||||
- 平滑过渡:`transition: all 0.3s ease`
|
||||
|
||||
### 响应式设计
|
||||
- 移动端适配
|
||||
- 触摸友好的交互区域
|
||||
- 自适应字体和间距
|
||||
|
||||
## 📝 示例页面
|
||||
|
||||
访问 `/components-demo` 查看所有组件的完整使用示例,包括:
|
||||
- 各种数学公式的渲染效果
|
||||
- 不同样式的表格展示
|
||||
- 多种编程语言的代码高亮
|
||||
- 组件之间的组合使用
|
||||
|
||||
## 🚀 快速开始
|
||||
|
||||
1. 导入需要的组件:
|
||||
```astro
|
||||
---
|
||||
import MathFormula from '../components/common/MathFormula.astro';
|
||||
import GlassTable from '../components/common/GlassTable.astro';
|
||||
import CodeBlock from '../components/common/CodeBlock.astro';
|
||||
---
|
||||
```
|
||||
|
||||
2. 在模板中使用组件:
|
||||
```astro
|
||||
<MathFormula formula="x = \frac{-b \pm \sqrt{b^2-4ac}}{2a}" display={true} />
|
||||
|
||||
<GlassTable
|
||||
headers={["姓名", "年龄", "职业"]}
|
||||
rows={[["张三", "25", "工程师"]]}
|
||||
/>
|
||||
|
||||
<CodeBlock
|
||||
language="python"
|
||||
code="print('Hello, World!')"
|
||||
/>
|
||||
```
|
||||
|
||||
这些组件完美融入了网站的整体设计风格,提供了专业级的内容展示能力!
|
||||
@@ -1,206 +0,0 @@
|
||||
# 🚀 部署指南
|
||||
|
||||
将您的 Astro 网站部署到 jiao77.cn (110.42.70.70) 服务器的完整步骤。
|
||||
|
||||
## 📋 部署前准备
|
||||
|
||||
### 1. 确认服务器环境
|
||||
登录到您的服务器并检查:
|
||||
```bash
|
||||
# SSH 连接到服务器
|
||||
ssh root@110.42.70.70 # 或您的用户名
|
||||
|
||||
# 检查 Apache 状态
|
||||
sudo systemctl status apache2
|
||||
|
||||
# 检查 Apache 网站根目录
|
||||
ls -la /var/www/jiao77.cn/
|
||||
|
||||
# 检查 Apache 模块
|
||||
apache2ctl -M | grep -E "(rewrite|deflate|expires|headers)"
|
||||
```
|
||||
|
||||
### 2. 启用必要的 Apache 模块
|
||||
如果模块未启用,请运行:
|
||||
```bash
|
||||
sudo a2enmod rewrite
|
||||
sudo a2enmod deflate
|
||||
sudo a2enmod expires
|
||||
sudo a2enmod headers
|
||||
sudo systemctl reload apache2
|
||||
```
|
||||
|
||||
## 🚀 部署步骤
|
||||
|
||||
### 方法一:自动部署 (推荐)
|
||||
|
||||
1. **构建项目**
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
2. **运行部署脚本**
|
||||
```bash
|
||||
./deploy.sh
|
||||
```
|
||||
按提示输入服务器用户名和网站根目录路径。
|
||||
|
||||
### 方法二:手动部署
|
||||
|
||||
1. **构建项目**
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
2. **压缩文件**
|
||||
```bash
|
||||
cd dist
|
||||
tar -czf ../website.tar.gz *
|
||||
cd ..
|
||||
```
|
||||
|
||||
3. **上传到服务器**
|
||||
```bash
|
||||
scp website.tar.gz root@110.42.70.70:/tmp/
|
||||
```
|
||||
|
||||
4. **在服务器上解压**
|
||||
```bash
|
||||
ssh root@110.42.70.70
|
||||
cd /var/www/html
|
||||
sudo rm -rf * # 清空现有文件 (请谨慎!)
|
||||
sudo tar -xzf /tmp/website.tar.gz -C /var/www/html/
|
||||
sudo chown -R www-data:www-data /var/www/html/
|
||||
sudo chmod -R 755 /var/www/html/
|
||||
```
|
||||
|
||||
### 方法三:使用 rsync (最佳选择)
|
||||
|
||||
```bash
|
||||
# 直接同步 dist 目录内容
|
||||
rsync -avz --delete --progress dist/ root@110.42.70.70:/var/www/html/
|
||||
```
|
||||
|
||||
## ⚙️ Apache 配置
|
||||
|
||||
### 1. 配置虚拟主机 (可选但推荐)
|
||||
|
||||
将 `apache-config.conf` 的内容添加到您的 Apache 配置中:
|
||||
|
||||
```bash
|
||||
# 在服务器上
|
||||
sudo nano /etc/apache2/sites-available/jiao77.conf
|
||||
# 粘贴 apache-config.conf 的内容
|
||||
|
||||
# 启用站点
|
||||
sudo a2ensite jiao77.conf
|
||||
sudo systemctl reload apache2
|
||||
```
|
||||
|
||||
### 2. 上传 .htaccess 文件
|
||||
|
||||
确保 `.htaccess` 文件已上传到网站根目录:
|
||||
```bash
|
||||
scp .htaccess root@110.42.70.70:/var/www/html/
|
||||
```
|
||||
|
||||
## 🔧 服务器优化
|
||||
|
||||
### 1. 设置正确的文件权限
|
||||
```bash
|
||||
sudo chown -R www-data:www-data /var/www/html/
|
||||
sudo find /var/www/html/ -type d -exec chmod 755 {} \;
|
||||
sudo find /var/www/html/ -type f -exec chmod 644 {} \;
|
||||
```
|
||||
|
||||
### 2. 配置防火墙 (如果启用)
|
||||
```bash
|
||||
sudo ufw allow 80/tcp # HTTP
|
||||
sudo ufw allow 443/tcp # HTTPS
|
||||
```
|
||||
|
||||
## 📊 部署后检查
|
||||
|
||||
### 1. 功能测试
|
||||
- [ ] 访问 http://jiao77.cn 或 http://110.42.70.70
|
||||
- [ ] 检查首页导航卡片是否正常显示
|
||||
- [ ] 访问 `/reports` 页面确认报告组件正常
|
||||
- [ ] 测试页眉展开/收缩功能
|
||||
- [ ] 检查移动端响应式设计
|
||||
- [ ] 验证动画效果是否流畅
|
||||
|
||||
### 2. 性能测试
|
||||
```bash
|
||||
# 使用 curl 测试压缩
|
||||
curl -H "Accept-Encoding: gzip" -I http://jiao77.cn
|
||||
|
||||
# 检查响应时间
|
||||
curl -o /dev/null -s -w "时间: %{time_total}s\n" http://jiao77.cn
|
||||
```
|
||||
|
||||
### 3. 在线工具检测
|
||||
- [GTmetrix](https://gtmetrix.com/) - 性能分析
|
||||
- [PageSpeed Insights](https://pagespeed.web.dev/) - Google 性能评分
|
||||
- [SSL Labs](https://www.ssllabs.com/ssltest/) - SSL 配置检测 (如果使用 HTTPS)
|
||||
|
||||
## 🔄 更新部署流程
|
||||
|
||||
当您需要更新网站时:
|
||||
|
||||
1. **修改代码**
|
||||
2. **重新构建**: `npm run build`
|
||||
3. **部署**: `./deploy.sh`
|
||||
|
||||
## 🛡️ SSL/HTTPS 配置 (推荐)
|
||||
|
||||
### 1. 获取免费 SSL 证书 (Let's Encrypt)
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt install certbot python3-certbot-apache
|
||||
sudo certbot --apache -d jiao77.cn -d www.jiao77.cn
|
||||
```
|
||||
|
||||
### 2. 自动续期
|
||||
```bash
|
||||
sudo crontab -e
|
||||
# 添加这行:
|
||||
0 12 * * * /usr/bin/certbot renew --quiet
|
||||
```
|
||||
|
||||
## 🐛 故障排除
|
||||
|
||||
### 问题1:页面不显示或显示 Apache 默认页
|
||||
- 检查文件权限
|
||||
- 确认 DocumentRoot 配置正确
|
||||
- 查看 Apache 错误日志:`sudo tail -f /var/log/apache2/error.log`
|
||||
|
||||
### 问题2:CSS/JS 文件加载失败
|
||||
- 检查 .htaccess 文件是否正确上传
|
||||
- 确认 mod_rewrite 模块已启用
|
||||
- 检查文件路径是否正确
|
||||
|
||||
### 问题3:动画效果不工作
|
||||
- 检查 JavaScript 控制台错误
|
||||
- 确认所有资源文件都已上传
|
||||
- 验证 Content-Security-Policy 配置
|
||||
|
||||
### 问题4:移动端显示异常
|
||||
- 检查 viewport meta 标签
|
||||
- 验证响应式 CSS 是否正确加载
|
||||
- 测试不同设备和浏览器
|
||||
|
||||
## 📞 技术支持
|
||||
|
||||
如果遇到部署问题,请检查:
|
||||
1. Apache 错误日志:`/var/log/apache2/error.log`
|
||||
2. Apache 访问日志:`/var/log/apache2/access.log`
|
||||
3. 浏览器开发者工具控制台
|
||||
4. 网络连接和防火墙设置
|
||||
|
||||
## 📈 监控和维护
|
||||
|
||||
建议设置:
|
||||
- 定期备份网站文件
|
||||
- 监控服务器资源使用情况
|
||||
- 定期更新 Apache 和系统安全补丁
|
||||
- 设置网站监控服务检测可用性
|
||||
@@ -1,348 +0,0 @@
|
||||
# Deploy-Full 脚本检查报告
|
||||
**检查日期**:2025年10月1日
|
||||
|
||||
## ✅ 检查结果总结
|
||||
|
||||
**结论**:当前的 `deploy-full.sh` 脚本**可以正常部署所有需要的内容**,但有一些小的改进建议。
|
||||
|
||||
---
|
||||
|
||||
## 📊 当前项目资源统计
|
||||
|
||||
### 静态资源
|
||||
- **图片文件总数**:63个
|
||||
- **报告图片目录**:5个
|
||||
- `20250609-images/`(9张图片)
|
||||
- `20250722-images/`(9张图片)
|
||||
- `20250912-images/`(30张图片)
|
||||
- `Siemens-EDA-Forum-images/`(11张图片)
|
||||
- `image/`(4张图片)
|
||||
|
||||
### 页面文件
|
||||
- **报告页面总数**:9个
|
||||
1. `/report/20250609` - 2025年6月9日报告
|
||||
2. `/report/20250722` - 2025年7月22日报告
|
||||
3. `/report/20250912` - 2025年9月12日组会报告
|
||||
4. `/report/20250928` - RoRD项目工作规划报告(最新)
|
||||
5. `/report/ai-eda-paper-report` - EDA学术发表指南(最新)
|
||||
6. `/report/Geo-Layout-Transformer` - Geo-Layout-Transformer报告
|
||||
7. `/report/Siemens-EDA-Forum` - 西门子EDA论坛报告
|
||||
8. `/report/template` - 报告模板及文档
|
||||
9. `/report` - 报告列表页
|
||||
|
||||
### SEO文件
|
||||
- ✅ `robots.txt` - 存在(300 bytes)
|
||||
- ✅ `sitemap.xml` - 存在(1014 bytes)
|
||||
- ⚠️ `favicon.ico` - 不存在(仅有占位文件)
|
||||
- ✅ `.htaccess` - 存在(4.0 KB)
|
||||
|
||||
### 构建产物
|
||||
- **dist目录大小**:143 MB
|
||||
- **public目录大小**:141 MB
|
||||
- **图片文件数**:63个(全部复制到dist)
|
||||
- **页面总数**:20个HTML页面
|
||||
|
||||
---
|
||||
|
||||
## ✅ Deploy-Full 脚本功能检查
|
||||
|
||||
### 1. 构建检查 ✅
|
||||
```bash
|
||||
build_project() {
|
||||
npm run build
|
||||
# ✅ 会构建所有Astro页面
|
||||
# ✅ 会复制public/目录下所有静态资源
|
||||
# ✅ 会生成优化后的HTML/CSS/JS
|
||||
}
|
||||
```
|
||||
|
||||
**验证结果**:
|
||||
- ✅ 所有20个页面都被构建
|
||||
- ✅ 所有63个图片文件都被复制到dist/report/
|
||||
- ✅ robots.txt和sitemap.xml都被复制
|
||||
- ✅ 没有.ts或.astro源代码文件泄露到dist/
|
||||
|
||||
### 2. 静态资源检查 ✅
|
||||
```bash
|
||||
# 脚本会检查以下内容:
|
||||
if [ -d "public/report" ]; then
|
||||
echo "✅ 找到报告图片资源"
|
||||
fi
|
||||
```
|
||||
|
||||
**验证结果**:
|
||||
- ✅ `public/report/` 目录存在
|
||||
- ✅ 包含5个图片子目录
|
||||
- ✅ 总计63个图片文件
|
||||
|
||||
### 3. SEO文件检查 ✅
|
||||
```bash
|
||||
# 脚本会检查:
|
||||
- robots.txt ✅ 存在
|
||||
- sitemap.xml ✅ 存在
|
||||
- favicon.ico ⚠️ 不存在(会有警告提示)
|
||||
```
|
||||
|
||||
**验证结果**:
|
||||
- ✅ robots.txt 正常(300 bytes)
|
||||
- ✅ sitemap.xml 正常(1014 bytes)
|
||||
- ⚠️ favicon.ico 不存在(脚本会给出警告,不影响部署)
|
||||
|
||||
### 4. .htaccess上传 ✅
|
||||
```bash
|
||||
upload_htaccess() {
|
||||
if [ -f ".htaccess" ]; then
|
||||
scp .htaccess ${USERNAME}@${SERVER_IP}:${WEB_ROOT}/.htaccess
|
||||
fi
|
||||
}
|
||||
```
|
||||
|
||||
**验证结果**:
|
||||
- ✅ .htaccess 文件存在(4.0 KB)
|
||||
- ✅ 脚本会单独上传此文件
|
||||
- ✅ 不会被rsync的--exclude='.htaccess'影响
|
||||
|
||||
### 5. 部署方式检查 ✅
|
||||
```bash
|
||||
# 方式1: rsync(推荐)
|
||||
rsync -avz --delete --progress \
|
||||
--exclude='.htaccess' \
|
||||
dist/ ${USERNAME}@${SERVER_IP}:${WEB_ROOT}/
|
||||
|
||||
# 方式2: scp+tar(备用)
|
||||
tar -czf ../deploy-temp.tar.gz *
|
||||
scp deploy-temp.tar.gz ${USERNAME}@${SERVER_IP}:/tmp/
|
||||
```
|
||||
|
||||
**验证结果**:
|
||||
- ✅ rsync会同步所有dist/下的文件和目录
|
||||
- ✅ --delete参数会删除服务器上多余的旧文件
|
||||
- ✅ 图片、HTML、CSS、JS都会被上传
|
||||
- ✅ .htaccess单独上传,不会被排除
|
||||
|
||||
### 6. 部署后检查 ✅
|
||||
```bash
|
||||
post_deploy_test() {
|
||||
# 测试HTTP响应码
|
||||
# 检测Gzip压缩
|
||||
# 显示检查清单
|
||||
}
|
||||
```
|
||||
|
||||
**验证结果**:
|
||||
- ✅ 会测试网站是否可访问
|
||||
- ✅ 会检查Gzip压缩是否启用
|
||||
- ✅ 提供完整的检查清单
|
||||
|
||||
---
|
||||
|
||||
## 🎯 部署覆盖范围验证
|
||||
|
||||
### 会被部署的内容 ✅
|
||||
1. **所有HTML页面**(20个)
|
||||
- 主页:`index.html`
|
||||
- 报告列表:`reports/index.html`
|
||||
- 9个报告页面的HTML文件
|
||||
|
||||
2. **所有图片资源**(63个)
|
||||
- `report/20250609-images/`(9张)
|
||||
- `report/20250722-images/`(9张)
|
||||
- `report/20250912-images/`(30张)
|
||||
- `report/Siemens-EDA-Forum-images/`(11张)
|
||||
- `report/image/`(4张)
|
||||
|
||||
3. **CSS和JavaScript文件**
|
||||
- 构建优化后的CSS bundle
|
||||
- 构建优化后的JS bundle
|
||||
- 外部CDN链接的库(Chart.js, GSAP等)
|
||||
|
||||
4. **SEO和配置文件**
|
||||
- `robots.txt`
|
||||
- `sitemap.xml`
|
||||
- `.htaccess`(单独上传)
|
||||
|
||||
5. **其他资源**
|
||||
- Markdown文档(会被转换为HTML)
|
||||
- 字体文件(如果有)
|
||||
- 其他public/目录下的文件
|
||||
|
||||
### 不会被部署的内容 ✅(正确)
|
||||
1. **源代码文件**
|
||||
- ✅ .astro文件(编译为HTML)
|
||||
- ✅ .ts文件(编译为JS)
|
||||
- ✅ src/目录(仅dist/被部署)
|
||||
|
||||
2. **开发依赖**
|
||||
- ✅ node_modules/
|
||||
- ✅ package.json
|
||||
- ✅ tsconfig.json
|
||||
|
||||
3. **文档和配置**
|
||||
- ✅ README.md(除非在public/)
|
||||
- ✅ .git/
|
||||
- ✅ .gitignore
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ 发现的问题和建议
|
||||
|
||||
### 1. ⚠️ Favicon缺失
|
||||
**问题**:`public/favicon.ico` 不存在
|
||||
|
||||
**影响**:
|
||||
- 浏览器标签页不会显示网站图标
|
||||
- SEO评分可能稍低
|
||||
- 用户体验略有影响
|
||||
|
||||
**建议**:
|
||||
```bash
|
||||
# 添加favicon.ico到public/目录
|
||||
# 可以使用在线工具生成:https://favicon.io/
|
||||
```
|
||||
|
||||
### 2. ✅ 新增报告页面已包含
|
||||
**最新添加的页面**:
|
||||
- ✅ `/report/20250928` - RoRD项目工作规划(已包含)
|
||||
- ✅ `/report/ai-eda-paper-report` - EDA学术发表指南(已包含)
|
||||
|
||||
**验证**:
|
||||
```bash
|
||||
# 构建日志显示这些页面已成功生成
|
||||
✓ src/pages/report/20250928/index.astro
|
||||
└─ /report/20250928/index.html (+3ms)
|
||||
✓ src/pages/report/ai-eda-paper-report/index.astro
|
||||
└─ /report/ai-eda-paper-report/index.html (+2ms)
|
||||
```
|
||||
|
||||
### 3. ✅ ai-eda-paper-report的脚本文件
|
||||
**特殊文件**:`eda-venues-interactive.ts`
|
||||
|
||||
**状态**:
|
||||
- ✅ 已正确放置在页面文件夹内
|
||||
- ✅ Astro会将其编译为JavaScript
|
||||
- ✅ 部署时只会包含编译后的JS,不会有.ts文件
|
||||
|
||||
### 4. 📊 部署大小
|
||||
**当前状态**:
|
||||
- dist/目录:143 MB
|
||||
- 主要是图片资源:141 MB
|
||||
|
||||
**建议**:
|
||||
- 考虑优化图片(使用WebP格式)
|
||||
- 可以启用服务器端图片压缩
|
||||
- CDN加速(如果需要)
|
||||
|
||||
---
|
||||
|
||||
## 📋 部署检查清单
|
||||
|
||||
### 部署前检查 ✅
|
||||
- [x] 所有报告页面都已创建
|
||||
- [x] 图片资源都在public/report/下
|
||||
- [x] robots.txt和sitemap.xml存在
|
||||
- [x] .htaccess文件存在
|
||||
- [x] TypeScript文件都能正常编译
|
||||
- [ ] favicon.ico(可选,建议添加)
|
||||
|
||||
### 部署脚本验证 ✅
|
||||
- [x] npm run build 成功
|
||||
- [x] dist/目录包含所有HTML页面(20个)
|
||||
- [x] dist/report/包含所有图片(63个)
|
||||
- [x] dist/包含SEO文件
|
||||
- [x] 没有源代码文件泄露
|
||||
|
||||
### 部署后验证建议 ✅
|
||||
```bash
|
||||
# 脚本会自动执行的检查
|
||||
1. HTTP状态码测试(200 OK)
|
||||
2. Gzip压缩检测
|
||||
3. 文件权限设置(755/644)
|
||||
|
||||
# 建议手动检查
|
||||
4. 访问主页:http://jiao77.cn
|
||||
5. 测试报告列表:http://jiao77.cn/reports
|
||||
6. 验证新报告:
|
||||
- http://jiao77.cn/report/20250928
|
||||
- http://jiao77.cn/report/ai-eda-paper-report
|
||||
7. 检查图片加载
|
||||
8. 测试交互功能(筛选、模态框等)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 最终结论
|
||||
|
||||
### ✅ Deploy-Full脚本状态:完全可用
|
||||
|
||||
**核心功能验证**:
|
||||
1. ✅ 构建所有Astro页面 → **正常**(20个页面)
|
||||
2. ✅ 复制所有静态资源 → **正常**(63个图片)
|
||||
3. ✅ 包含SEO文件 → **正常**(robots.txt, sitemap.xml)
|
||||
4. ✅ 上传.htaccess → **正常**(单独上传)
|
||||
5. ✅ 设置文件权限 → **正常**(755/644)
|
||||
6. ✅ 部署后测试 → **正常**(HTTP检查)
|
||||
|
||||
### 新增内容覆盖验证:
|
||||
- ✅ `/report/20250928` - RoRD项目规划报告
|
||||
- ✅ `/report/ai-eda-paper-report` - EDA学术发表指南
|
||||
- ✅ `eda-venues-interactive.ts` - 交互脚本(已编译)
|
||||
- ✅ 所有图片资源(63个文件)
|
||||
|
||||
### 建议的改进(可选):
|
||||
1. 添加favicon.ico文件
|
||||
2. 考虑图片优化(WebP格式)
|
||||
3. 可以添加部署后的自动化测试脚本
|
||||
|
||||
### 部署命令:
|
||||
```bash
|
||||
# 直接运行即可部署所有内容
|
||||
./deploy-full.sh
|
||||
|
||||
# 或者给予执行权限后运行
|
||||
chmod +x deploy-full.sh
|
||||
./deploy-full.sh
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 详细文件清单
|
||||
|
||||
### HTML页面(20个)✅
|
||||
```
|
||||
/index.html
|
||||
/reports/index.html
|
||||
/report/index.html
|
||||
/report/20250609/index.html
|
||||
/report/20250722/index.html
|
||||
/report/20250912/index.html
|
||||
/report/20250928/index.html ⭐ 新增
|
||||
/report/ai-eda-paper-report/index.html ⭐ 新增
|
||||
/report/Geo-Layout-Transformer/index.html
|
||||
/report/Siemens-EDA-Forum/index.html
|
||||
/report/template/index.html
|
||||
/report/template/simple/index.html
|
||||
/report/template/README/index.html
|
||||
/report/template/USAGE_EXAMPLE/index.html
|
||||
/report/template/WIDTH_CONFIG_GUIDE/index.html
|
||||
(还有其他页面...)
|
||||
```
|
||||
|
||||
### 图片资源(63个)✅
|
||||
```
|
||||
/report/20250609-images/ (9张)
|
||||
/report/20250722-images/ (9张)
|
||||
/report/20250912-images/ (30张)
|
||||
/report/Siemens-EDA-Forum-images/ (11张)
|
||||
/report/image/ (4张)
|
||||
```
|
||||
|
||||
### 配置文件 ✅
|
||||
```
|
||||
/robots.txt (300 bytes)
|
||||
/sitemap.xml (1014 bytes)
|
||||
/.htaccess (4.0 KB)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**总结**:当前的 deploy-full.sh 脚本完全可以部署所有需要的内容,包括最新添加的报告页面和资源。可以直接使用!✅
|
||||
@@ -1,791 +0,0 @@
|
||||
# 🚀 网站现代化重构 - 详尽 TodoList
|
||||
|
||||
**项目周期**:4-6 周 | **总任务数**:87 项 | **优先级分布**:P0(22) | P1(35) | P2(20) | P3(10)
|
||||
|
||||
---
|
||||
|
||||
## 📋 任务约定
|
||||
|
||||
- 🔴 **P0 - 必须**:项目核心,必须完成
|
||||
- 🟠 **P1 - 重要**:功能完整性,应该完成
|
||||
- 🟡 **P2 - 优化**:用户体验,可选完成
|
||||
- 🟢 **P3 - 未来**:后续功能,后期实现
|
||||
|
||||
**状态说明**:
|
||||
- ⬜ `not-started` - 未开始
|
||||
- 🟦 `in-progress` - 进行中
|
||||
- ✅ `completed` - 已完成
|
||||
|
||||
---
|
||||
|
||||
## 🎯 第一阶段:环境准备 & 项目规划(第 1 周)
|
||||
|
||||
### 🔴 P0 任务:项目初始化
|
||||
|
||||
#### 1.1 后端项目创建
|
||||
- [ ] 创建 `/backend` 目录结构
|
||||
```
|
||||
backend/
|
||||
├── src/
|
||||
│ ├── server.ts
|
||||
│ ├── config/
|
||||
│ ├── routes/
|
||||
│ ├── controllers/
|
||||
│ ├── middleware/
|
||||
│ ├── database/
|
||||
│ └── types/
|
||||
├── tests/
|
||||
├── .env.example
|
||||
├── package.json
|
||||
└── tsconfig.json
|
||||
```
|
||||
- [ ] 初始化 Node.js 项目:`npm init -y`
|
||||
- [ ] 安装基础依赖:`npm install express cors dotenv pg`
|
||||
- [ ] 安装开发依赖:`npm install -D typescript @types/node @types/express ts-node nodemon`
|
||||
- [ ] 创建 `.env` 和 `.env.example` 文件
|
||||
- [ ] 创建 `tsconfig.json` 配置文件
|
||||
- [ ] 创建 `package.json` 脚本配置
|
||||
|
||||
#### 1.2 前端项目升级
|
||||
- [ ] 升级 Astro 到最新版本:`npm install astro@latest`
|
||||
- [ ] 安装 React 集成:`npm install @astrojs/react react react-dom`
|
||||
- [ ] 安装 API 相关依赖:`npm install axios zod isomorphic-dompurify`
|
||||
- [ ] 验证项目能正常构建
|
||||
|
||||
#### 1.3 数据库规划
|
||||
- [ ] 创建数据库初始化脚本目录 `backend/sql/`
|
||||
- [ ] 制定数据库连接策略
|
||||
- [ ] 准备 PostgreSQL 本地开发环境
|
||||
- [ ] 创建数据库连接池配置
|
||||
|
||||
### 🟠 P1 任务:文档编写
|
||||
|
||||
#### 1.4 API 文档
|
||||
- [ ] 编写完整的 API 规范文档
|
||||
- [ ] 定义评论 API 端点
|
||||
- [ ] 定义统计 API 端点
|
||||
- [ ] 定义用户 API 端点
|
||||
- [ ] 定义错误响应格式
|
||||
|
||||
#### 1.5 架构文档
|
||||
- [ ] 绘制系统架构图
|
||||
- [ ] 编写数据流说明
|
||||
- [ ] 列出安全考虑点
|
||||
- [ ] 记录性能优化策略
|
||||
|
||||
### 🟡 P2 任务:设计文档
|
||||
|
||||
#### 1.6 UI/UX 设计
|
||||
- [ ] 设计评论区域样式
|
||||
- [ ] 设计统计卡片样式
|
||||
- [ ] 制定色系和排版规范
|
||||
- [ ] 创建组件设计稿
|
||||
|
||||
---
|
||||
|
||||
## 🎯 第二阶段:后端开发(第 2-3 周)
|
||||
|
||||
### 🔴 P0 任务:核心基础设施
|
||||
|
||||
#### 2.1 Server 启动和基础配置
|
||||
- [ ] 创建 `src/server.ts` 主文件
|
||||
- [ ] 配置 Express 应用基础
|
||||
- [ ] 配置 CORS 中间件
|
||||
- [ ] 配置 JSON 解析中间件
|
||||
- [ ] 实现环境变量加载
|
||||
- [ ] 设置错误处理中间件
|
||||
- [ ] 实现 404 路由处理
|
||||
- [ ] 测试服务器启动成功
|
||||
|
||||
#### 2.2 数据库连接
|
||||
- [ ] 创建 `src/database/connection.ts`
|
||||
- [ ] 配置 PostgreSQL 连接池
|
||||
- [ ] 实现连接错误处理
|
||||
- [ ] 实现连接超时处理
|
||||
- [ ] 添加连接测试函数
|
||||
- [ ] 验证连接可用性
|
||||
|
||||
#### 2.3 数据库 Schema
|
||||
- [ ] 创建 `backend/sql/001_init_schema.sql`
|
||||
- [ ] 定义 `comments` 表
|
||||
```sql
|
||||
- id: SERIAL PRIMARY KEY
|
||||
- report_id: VARCHAR(100)
|
||||
- author: VARCHAR(100)
|
||||
- email: VARCHAR(100)
|
||||
- content: TEXT
|
||||
- status: VARCHAR(20)
|
||||
- created_at: TIMESTAMP
|
||||
- updated_at: TIMESTAMP
|
||||
```
|
||||
- [ ] 定义 `report_stats` 表
|
||||
```sql
|
||||
- id: SERIAL PRIMARY KEY
|
||||
- report_id: VARCHAR(100) UNIQUE
|
||||
- views: INTEGER
|
||||
- comments: INTEGER
|
||||
- likes: INTEGER
|
||||
- shares: INTEGER
|
||||
```
|
||||
- [ ] 定义 `likes` 表
|
||||
```sql
|
||||
- id: SERIAL PRIMARY KEY
|
||||
- report_id: VARCHAR(100)
|
||||
- client_id: VARCHAR(100)
|
||||
- created_at: TIMESTAMP
|
||||
```
|
||||
- [ ] 创建必要的索引
|
||||
- `idx_comments_report_id`
|
||||
- `idx_stats_report_id`
|
||||
- `idx_likes_report_id`
|
||||
- [ ] 创建 `backend/sql/002_add_constraints.sql` (外键约束)
|
||||
- [ ] 创建迁移脚本运行器
|
||||
|
||||
#### 2.4 TypeScript 类型定义
|
||||
- [ ] 创建 `src/types/comment.ts`
|
||||
- [ ] 创建 `src/types/stats.ts`
|
||||
- [ ] 创建 `src/types/like.ts`
|
||||
- [ ] 创建 `src/types/error.ts`
|
||||
- [ ] 创建 `src/types/api-response.ts`
|
||||
|
||||
### 🔴 P0 任务:评论系统 API
|
||||
|
||||
#### 2.5 评论模块 - 路由层
|
||||
- [ ] 创建 `src/routes/comments.ts`
|
||||
- [ ] `GET /api/comments` - 获取评论列表
|
||||
- [ ] 支持分页(page, limit)
|
||||
- [ ] 支持排序(created_at, likes)
|
||||
- [ ] 支持过滤(status, reportId)
|
||||
- [ ] `GET /api/comments/:id` - 获取单条评论
|
||||
- [ ] `POST /api/comments` - 创建评论
|
||||
- [ ] `PUT /api/comments/:id` - 更新评论(仅作者或管理员)
|
||||
- [ ] `DELETE /api/comments/:id` - 删除评论(仅作者或管理员)
|
||||
|
||||
#### 2.6 评论模块 - 控制器层
|
||||
- [ ] 创建 `src/controllers/commentController.ts`
|
||||
- [ ] 实现 `getAllComments()` 逻辑
|
||||
- [ ] 实现 `getCommentById()` 逻辑
|
||||
- [ ] 实现 `createComment()` 逻辑
|
||||
- [ ] 实现 `updateComment()` 逻辑
|
||||
- [ ] 实现 `deleteComment()` 逻辑
|
||||
- [ ] 添加数据验证逻辑
|
||||
- [ ] 添加错误处理
|
||||
|
||||
#### 2.7 评论模块 - 数据库层
|
||||
- [ ] 创建 `src/database/commentQueries.ts`
|
||||
- [ ] 实现 `fetchCommentsByReport()`
|
||||
- [ ] 实现 `fetchCommentById()`
|
||||
- [ ] 实现 `insertComment()`
|
||||
- [ ] 实现 `updateComment()`
|
||||
- [ ] 实现 `deleteComment()`
|
||||
- [ ] 实现 `countCommentsByReport()`
|
||||
- [ ] 添加事务处理
|
||||
|
||||
### 🔴 P0 任务:统计系统 API
|
||||
|
||||
#### 2.8 统计模块 - 路由层
|
||||
- [ ] 创建 `src/routes/stats.ts`
|
||||
- [ ] `GET /api/stats/:reportId` - 获取统计数据
|
||||
- [ ] `POST /api/stats/:reportId/view` - 记录浏览
|
||||
- [ ] `POST /api/stats/:reportId/like` - 点赞
|
||||
- [ ] `DELETE /api/stats/:reportId/like` - 取消点赞
|
||||
- [ ] `POST /api/stats/:reportId/share` - 记录分享
|
||||
- [ ] `GET /api/stats/trending` - 获取热门
|
||||
|
||||
#### 2.9 统计模块 - 控制器层
|
||||
- [ ] 创建 `src/controllers/statsController.ts`
|
||||
- [ ] 实现 `getStats()` 逻辑
|
||||
- [ ] 实现 `recordView()` 逻辑
|
||||
- [ ] 实现 `recordLike()` 逻辑
|
||||
- [ ] 实现 `removeLike()` 逻辑
|
||||
- [ ] 实现 `recordShare()` 逻辑
|
||||
- [ ] 实现 `getTrending()` 逻辑
|
||||
- [ ] 添加重复检查
|
||||
|
||||
#### 2.10 统计模块 - 数据库层
|
||||
- [ ] 创建 `src/database/statsQueries.ts`
|
||||
- [ ] 实现 `fetchStats()`
|
||||
- [ ] 实现 `updateViews()`
|
||||
- [ ] 实现 `addLike()`
|
||||
- [ ] 实现 `removeLike()`
|
||||
- [ ] 实现 `checkLikeExists()`
|
||||
- [ ] 实现 `updateShares()`
|
||||
- [ ] 实现 `fetchTrending()`
|
||||
|
||||
### 🟠 P1 任务:中间件和工具
|
||||
|
||||
#### 2.11 验证中间件
|
||||
- [ ] 创建 `src/middleware/validation.ts`
|
||||
- [ ] 实现评论数据验证 (Zod schema)
|
||||
- [ ] 实现统计数据验证
|
||||
- [ ] 实现错误转换中间件
|
||||
- [ ] 添加日志中间件
|
||||
|
||||
#### 2.12 安全中间件
|
||||
- [ ] 创建 `src/middleware/security.ts`
|
||||
- [ ] 实现速率限制(express-rate-limit)
|
||||
- [ ] 实现 CSRF 保护
|
||||
- [ ] 实现 XSS 防护 (DOMPurify)
|
||||
- [ ] 实现输入清理函数
|
||||
|
||||
#### 2.13 认证中间件(可选基础)
|
||||
- [ ] 创建 `src/middleware/auth.ts`
|
||||
- [ ] 实现 JWT 验证(预留)
|
||||
- [ ] 实现权限检查函数
|
||||
- [ ] 实现管理员标识
|
||||
|
||||
### 🟡 P2 任务:辅助功能
|
||||
|
||||
#### 2.14 工具函数
|
||||
- [ ] 创建 `src/utils/helpers.ts`
|
||||
- [ ] 实现分页计算函数
|
||||
- [ ] 实现日期格式化
|
||||
- [ ] 实现 ID 生成器
|
||||
- [ ] 实现数据转换函数
|
||||
|
||||
#### 2.15 缓存策略
|
||||
- [ ] 创建 `src/cache/cacheManager.ts`(预留 Redis)
|
||||
- [ ] 实现内存缓存方案
|
||||
- [ ] 实现缓存失效策略
|
||||
- [ ] 实现缓存预热
|
||||
|
||||
#### 2.16 日志系统
|
||||
- [ ] 创建 `src/logger/logger.ts`
|
||||
- [ ] 配置日志级别
|
||||
- [ ] 实现日志文件轮转
|
||||
- [ ] 实现错误日志记录
|
||||
|
||||
---
|
||||
|
||||
## 🎯 第三阶段:前端开发(第 3-4 周)
|
||||
|
||||
### 🔴 P0 任务:Astro 混合渲染配置
|
||||
|
||||
#### 3.1 更新 Astro 配置
|
||||
- [ ] 修改 `astro.config.mjs` 启用混合渲染
|
||||
```javascript
|
||||
output: 'hybrid'
|
||||
adapter: node({ mode: 'standalone' })
|
||||
```
|
||||
- [ ] 配置 React 集成
|
||||
- [ ] 验证混合渲染配置正确
|
||||
- [ ] 测试静态和动态页面生成
|
||||
|
||||
#### 3.2 创建 API 客户端
|
||||
- [ ] 创建 `src/lib/api-client.ts`
|
||||
- [ ] 实现 HTTP 请求拦截器
|
||||
- [ ] 实现错误处理
|
||||
- [ ] 实现请求重试逻辑
|
||||
- [ ] 配置 API 基础 URL
|
||||
|
||||
#### 3.3 创建 React 上下文(可选)
|
||||
- [ ] 创建 `src/contexts/ReportContext.tsx`
|
||||
- [ ] 实现统计数据共享
|
||||
- [ ] 实现用户状态管理
|
||||
- [ ] 实现通知管理
|
||||
|
||||
### 🔴 P0 任务:评论组件开发
|
||||
|
||||
#### 3.4 评论列表组件
|
||||
- [ ] 创建 `src/components/comments/CommentList.tsx`
|
||||
- [ ] 实现分页显示
|
||||
- [ ] 实现排序切换
|
||||
- [ ] 实现加载状态
|
||||
- [ ] 实现空状态提示
|
||||
- [ ] 实现错误状态提示
|
||||
|
||||
#### 3.5 评论表单组件
|
||||
- [ ] 创建 `src/components/comments/CommentForm.tsx`
|
||||
- [ ] 实现表单输入验证
|
||||
- [ ] 实现字符计数
|
||||
- [ ] 实现提交加载状态
|
||||
- [ ] 实现成功/失败提示
|
||||
- [ ] 实现防重复提交
|
||||
|
||||
#### 3.6 单条评论组件
|
||||
- [ ] 创建 `src/components/comments/CommentItem.tsx`
|
||||
- [ ] 实现用户信息展示
|
||||
- [ ] 实现时间格式化
|
||||
- [ ] 实现评论内容渲染(XSS 防护)
|
||||
- [ ] 实现编辑/删除按钮(权限检查)
|
||||
- [ ] 实现回复按钮(预留)
|
||||
|
||||
#### 3.7 完整评论区域组件
|
||||
- [ ] 创建 `src/components/comments/CommentSection.tsx`
|
||||
- [ ] 组合 List、Form、Item 组件
|
||||
- [ ] 实现数据获取逻辑
|
||||
- [ ] 实现实时更新
|
||||
- [ ] 实现错误边界
|
||||
- [ ] 实现加载骨架屏
|
||||
|
||||
### 🔴 P0 任务:统计组件开发
|
||||
|
||||
#### 3.8 统计卡片组件
|
||||
- [ ] 创建 `src/components/stats/StatCard.tsx`
|
||||
- [ ] 实现数字动画展示
|
||||
- [ ] 实现图标展示
|
||||
- [ ] 实现趋势指示
|
||||
- [ ] 实现加载状态
|
||||
|
||||
#### 3.9 统计面板组件
|
||||
- [ ] 创建 `src/components/stats/StatsPanel.tsx`
|
||||
- [ ] 组合多个 StatCard
|
||||
- [ ] 实现数据获取
|
||||
- [ ] 实现自动刷新
|
||||
- [ ] 实现响应式布局
|
||||
|
||||
#### 3.10 点赞按钮组件
|
||||
- [ ] 创建 `src/components/interactions/LikeButton.tsx`
|
||||
- [ ] 实现点赞/取消点赞逻辑
|
||||
- [ ] 实现动画效果
|
||||
- [ ] 实现重复点赞防护
|
||||
- [ ] 实现点赞数显示
|
||||
|
||||
#### 3.11 分享按钮组件
|
||||
- [ ] 创建 `src/components/interactions/ShareButton.tsx`
|
||||
- [ ] 实现复制链接功能
|
||||
- [ ] 实现社交分享(可选)
|
||||
- [ ] 实现分享统计
|
||||
- [ ] 实现分享提示
|
||||
|
||||
### 🟠 P1 任务:页面集成
|
||||
|
||||
#### 3.12 报告页面更新
|
||||
- [ ] 修改 `src/pages/report/ai-eda-paper-report/index.astro`
|
||||
- [ ] 导入统计组件
|
||||
- [ ] 导入评论组件
|
||||
- [ ] 添加统计展示区域
|
||||
- [ ] 添加评论区域
|
||||
- [ ] 实现客户端加载指令
|
||||
|
||||
#### 3.13 其他报告页面
|
||||
- [ ] 为其他报告页面添加统计功能
|
||||
- [ ] 为其他报告页面添加评论功能
|
||||
- [ ] 统一样式风格
|
||||
- [ ] 验证功能一致性
|
||||
|
||||
### 🟡 P2 任务:交互优化
|
||||
|
||||
#### 3.14 加载状态
|
||||
- [ ] 创建 `src/components/common/Skeleton.tsx` (骨架屏)
|
||||
- [ ] 创建 `src/components/common/LoadingSpinner.tsx`
|
||||
- [ ] 创建 `src/components/common/ErrorBoundary.tsx`
|
||||
- [ ] 应用到所有异步组件
|
||||
|
||||
#### 3.15 通知系统
|
||||
- [ ] 创建 `src/components/common/Toast.tsx`
|
||||
- [ ] 实现成功提示
|
||||
- [ ] 实现错误提示
|
||||
- [ ] 实现警告提示
|
||||
- [ ] 实现通知队列
|
||||
|
||||
#### 3.16 动画效果
|
||||
- [ ] 实现数字动画库集成(可选)
|
||||
- [ ] 添加评论出现动画
|
||||
- [ ] 添加统计数字动画
|
||||
- [ ] 添加过渡效果
|
||||
|
||||
---
|
||||
|
||||
## 🎯 第四阶段:集成与测试(第 4 周)
|
||||
|
||||
### 🔴 P0 任务:后端测试
|
||||
|
||||
#### 4.1 单元测试
|
||||
- [ ] 安装测试框架:`npm install -D jest @types/jest ts-jest`
|
||||
- [ ] 创建 `backend/tests/` 目录
|
||||
- [ ] 编写评论 API 单元测试
|
||||
- [ ] 测试 GET /api/comments
|
||||
- [ ] 测试 POST /api/comments
|
||||
- [ ] 测试数据验证
|
||||
- [ ] 测试错误处理
|
||||
- [ ] 编写统计 API 单元测试
|
||||
- [ ] 测试 GET /api/stats/:reportId
|
||||
- [ ] 测试 POST /api/stats/:reportId/view
|
||||
- [ ] 测试 POST /api/stats/:reportId/like
|
||||
- [ ] 运行测试,确保覆盖率 > 80%
|
||||
|
||||
#### 4.2 集成测试
|
||||
- [ ] 创建测试数据库配置
|
||||
- [ ] 编写评论完整流程测试
|
||||
- [ ] 编写统计完整流程测试
|
||||
- [ ] 编写并发场景测试
|
||||
- [ ] 验证所有 API 端点
|
||||
|
||||
#### 4.3 API 文档测试
|
||||
- [ ] 使用 Postman/Insomnia 测试所有端点
|
||||
- [ ] 验证请求/响应格式
|
||||
- [ ] 验证错误响应
|
||||
- [ ] 记录实际的 API 示例
|
||||
|
||||
### 🔴 P0 任务:前端测试
|
||||
|
||||
#### 4.4 组件测试
|
||||
- [ ] 安装测试库:`npm install -D vitest @testing-library/react`
|
||||
- [ ] 编写 CommentForm 测试
|
||||
- [ ] 测试表单提交
|
||||
- [ ] 测试验证逻辑
|
||||
- [ ] 测试错误显示
|
||||
- [ ] 编写 StatsPanel 测试
|
||||
- [ ] 测试数据加载
|
||||
- [ ] 测试数据展示
|
||||
- [ ] 编写 LikeButton 测试
|
||||
- [ ] 测试点赞逻辑
|
||||
- [ ] 测试防重复点赞
|
||||
|
||||
#### 4.5 集成测试
|
||||
- [ ] 测试 Astro 页面 + React 组件集成
|
||||
- [ ] 测试客户端加载指令
|
||||
- [ ] 测试数据流
|
||||
- [ ] 测试错误恢复
|
||||
|
||||
### 🟠 P1 任务:E2E 测试
|
||||
|
||||
#### 4.6 用户场景测试
|
||||
- [ ] 安装 E2E 框架:`npm install -D playwright`
|
||||
- [ ] 测试查看报告流程
|
||||
- [ ] 测试发布评论流程
|
||||
- [ ] 测试点赞流程
|
||||
- [ ] 测试分享流程
|
||||
- [ ] 测试移动端响应
|
||||
|
||||
#### 4.7 性能测试
|
||||
- [ ] 测试页面加载时间
|
||||
- [ ] 测试 API 响应时间
|
||||
- [ ] 测试并发用户压力
|
||||
- [ ] 记录性能基线
|
||||
|
||||
### 🟡 P2 任务:安全测试
|
||||
|
||||
#### 4.8 安全审查
|
||||
- [ ] 审查 XSS 防护
|
||||
- [ ] 审查 SQL 注入防护
|
||||
- [ ] 审查认证逻辑
|
||||
- [ ] 审查 CORS 配置
|
||||
- [ ] 测试速率限制
|
||||
|
||||
---
|
||||
|
||||
## 🎯 第五阶段:部署与优化(第 5 周)
|
||||
|
||||
### 🔴 P0 任务:Docker 配置
|
||||
|
||||
#### 5.1 后端 Docker 化
|
||||
- [ ] 创建 `Dockerfile`
|
||||
- [ ] 创建 `.dockerignore`
|
||||
- [ ] 定义构建阶段
|
||||
- [ ] 定义运行阶段
|
||||
- [ ] 优化镜像大小
|
||||
- [ ] 本地测试 Docker 镜像
|
||||
|
||||
#### 5.2 前端 Docker 化
|
||||
- [ ] 为前端创建 `Dockerfile`
|
||||
- [ ] 多阶段构建
|
||||
- [ ] 静态文件优化
|
||||
- [ ] 本地测试
|
||||
|
||||
#### 5.3 Docker Compose
|
||||
- [ ] 创建 `docker-compose.yml`
|
||||
- [ ] 配置后端服务
|
||||
- [ ] 配置前端服务
|
||||
- [ ] 配置数据库服务
|
||||
- [ ] 配置网络
|
||||
- [ ] 测试本地完整运行
|
||||
|
||||
#### 5.4 数据库容器
|
||||
- [ ] 配置 PostgreSQL 容器
|
||||
- [ ] 持久化数据卷
|
||||
- [ ] 初始化脚本
|
||||
- [ ] 备份策略
|
||||
|
||||
### 🔴 P0 任务:环境配置
|
||||
|
||||
#### 5.5 生产环境变量
|
||||
- [ ] 创建 `.env.production`
|
||||
- [ ] 配置数据库 URL
|
||||
- [ ] 配置 API 基础 URL
|
||||
- [ ] 配置日志级别
|
||||
- [ ] 配置 CORS 源
|
||||
- [ ] 配置密钥
|
||||
|
||||
#### 5.6 环境管理
|
||||
- [ ] 创建环境配置管理器
|
||||
- [ ] 验证必需变量
|
||||
- [ ] 文档化所有变量
|
||||
|
||||
### 🟠 P1 任务:部署配置
|
||||
|
||||
#### 5.7 Nginx 反向代理
|
||||
- [ ] 创建 `nginx.conf`
|
||||
- [ ] 配置前端路由
|
||||
- [ ] 配置后端 API 反向代理
|
||||
- [ ] 配置 Gzip 压缩
|
||||
- [ ] 配置缓存策略
|
||||
- [ ] 配置 SSL(可选)
|
||||
|
||||
#### 5.8 PM2 进程管理
|
||||
- [ ] 创建 `ecosystem.config.js`
|
||||
- [ ] 配置后端进程
|
||||
- [ ] 配置前端构建进程
|
||||
- [ ] 实现自动重启
|
||||
- [ ] 配置日志轮转
|
||||
|
||||
#### 5.9 部署脚本
|
||||
- [ ] 创建 `deploy.sh` 脚本
|
||||
- [ ] 拉取最新代码
|
||||
- [ ] 安装依赖
|
||||
- [ ] 构建项目
|
||||
- [ ] 运行数据库迁移
|
||||
- [ ] 重启服务
|
||||
- [ ] 健康检查
|
||||
|
||||
### 🟠 P1 任务:性能优化
|
||||
|
||||
#### 5.10 数据库优化
|
||||
- [ ] 分析查询性能
|
||||
- [ ] 添加必要的索引
|
||||
- [ ] 优化 N+1 查询
|
||||
- [ ] 实现查询缓存
|
||||
- [ ] 监控连接池
|
||||
|
||||
#### 5.11 API 优化
|
||||
- [ ] 实现 API 分页
|
||||
- [ ] 实现字段选择(select)
|
||||
- [ ] 实现 API 压缩
|
||||
- [ ] 实现响应缓存
|
||||
- [ ] 实现 CDN 集成
|
||||
|
||||
#### 5.12 前端优化
|
||||
- [ ] 代码分割优化
|
||||
- [ ] 图片优化
|
||||
- [ ] 字体加载优化
|
||||
- [ ] 缓存策略
|
||||
- [ ] 预加载/预连接
|
||||
|
||||
### 🟡 P2 任务:监控与日志
|
||||
|
||||
#### 5.13 应用监控
|
||||
- [ ] 配置应用性能监控 (APM)
|
||||
- [ ] 配置错误追踪
|
||||
- [ ] 配置日志聚合
|
||||
- [ ] 设置告警规则
|
||||
|
||||
#### 5.14 基础设施监控
|
||||
- [ ] 配置 CPU 监控
|
||||
- [ ] 配置内存监控
|
||||
- [ ] 配置磁盘监控
|
||||
- [ ] 配置网络监控
|
||||
|
||||
---
|
||||
|
||||
## 🎯 第六阶段:上线与维护(第 6 周)
|
||||
|
||||
### 🔴 P0 任务:上线前准备
|
||||
|
||||
#### 6.1 最终检查清单
|
||||
- [ ] 所有测试通过
|
||||
- [ ] 代码审查完成
|
||||
- [ ] 文档完整
|
||||
- [ ] 安全审计通过
|
||||
- [ ] 性能测试通过
|
||||
- [ ] 备份策略就位
|
||||
- [ ] 回滚计划准备
|
||||
|
||||
#### 6.2 数据迁移
|
||||
- [ ] 备份现有数据
|
||||
- [ ] 准备数据迁移脚本
|
||||
- [ ] 测试数据迁移
|
||||
- [ ] 准备回滚方案
|
||||
|
||||
#### 6.3 DNS 配置
|
||||
- [ ] 配置域名解析
|
||||
- [ ] 配置 SSL 证书
|
||||
- [ ] 测试 HTTPS 连接
|
||||
- [ ] 配置 CDN(可选)
|
||||
|
||||
### 🟠 P1 任务:灰度发布
|
||||
|
||||
#### 6.4 金丝雀发布
|
||||
- [ ] 发布到测试服务器
|
||||
- [ ] 在小部分用户中测试
|
||||
- [ ] 监控错误率
|
||||
- [ ] 逐步增加流量
|
||||
- [ ] 完整上线
|
||||
|
||||
#### 6.5 发布公告
|
||||
- [ ] 准备发布说明
|
||||
- [ ] 通知用户新功能
|
||||
- [ ] 准备常见问题解答
|
||||
- [ ] 监控用户反馈
|
||||
|
||||
### 🟠 P1 任务:上线后维护
|
||||
|
||||
#### 6.6 监控第一周
|
||||
- [ ] 日常监控指标
|
||||
- [ ] 应对用户反馈
|
||||
- [ ] 快速修复 bug
|
||||
- [ ] 记录问题和解决方案
|
||||
|
||||
#### 6.7 长期维护计划
|
||||
- [ ] 建立定期备份
|
||||
- [ ] 定期安全更新
|
||||
- [ ] 定期依赖更新
|
||||
- [ ] 性能优化迭代
|
||||
|
||||
### 🟡 P2 任务:用户支持
|
||||
|
||||
#### 6.8 文档完善
|
||||
- [ ] 完善用户指南
|
||||
- [ ] 编写 FAQ
|
||||
- [ ] 编写故障排查指南
|
||||
- [ ] 建立反馈渠道
|
||||
|
||||
#### 6.9 持续改进
|
||||
- [ ] 收集用户反馈
|
||||
- [ ] 分析使用数据
|
||||
- [ ] 规划功能迭代
|
||||
- [ ] 优化用户体验
|
||||
|
||||
---
|
||||
|
||||
## 🎯 可选增强功能(P3 任务)
|
||||
|
||||
### 🟢 P3:用户系统
|
||||
|
||||
#### 7.1 用户认证
|
||||
- [ ] 实现用户注册
|
||||
- [ ] 实现用户登录
|
||||
- [ ] 实现密码重置
|
||||
- [ ] 实现社交登录
|
||||
|
||||
#### 7.2 用户资料
|
||||
- [ ] 用户头像上传
|
||||
- [ ] 用户信息编辑
|
||||
- [ ] 用户偏好设置
|
||||
- [ ] 用户隐私控制
|
||||
|
||||
### 🟢 P3:高级评论功能
|
||||
|
||||
#### 7.3 评论增强
|
||||
- [ ] 评论回复功能
|
||||
- [ ] 评论点赞功能
|
||||
- [ ] 评论举报功能
|
||||
- [ ] 评论标签功能
|
||||
- [ ] 评论搜索功能
|
||||
|
||||
### 🟢 P3:AI 增强
|
||||
|
||||
#### 7.4 智能功能
|
||||
- [ ] 评论内容审核(AI)
|
||||
- [ ] 自动回复建议
|
||||
- [ ] 评论总结
|
||||
- [ ] 智能分类
|
||||
|
||||
### 🟢 P3:社区功能
|
||||
|
||||
#### 7.5 社区建设
|
||||
- [ ] 排行榜系统
|
||||
- [ ] 徽章系统
|
||||
- [ ] 积分系统
|
||||
- [ ] 社区讨论区
|
||||
- [ ] 用户关注
|
||||
|
||||
### 🟢 P3:数据分析
|
||||
|
||||
#### 7.6 深度分析
|
||||
- [ ] 用户行为分析
|
||||
- [ ] 评论情感分析
|
||||
- [ ] 内容热力分析
|
||||
- [ ] 用户转化分析
|
||||
|
||||
---
|
||||
|
||||
## 📊 时间和资源预估
|
||||
|
||||
### 时间分配
|
||||
```
|
||||
第一周:环境和规划 - 40 小时
|
||||
第二周:后端开发 - 60 小时
|
||||
第三周:前端开发 - 60 小时
|
||||
第四周:测试和集成 - 50 小时
|
||||
第五周:部署和优化 - 50 小时
|
||||
第六周:上线和维护 - 40 小时
|
||||
|
||||
总计:约 300 小时 ≈ 7-8 周(单人开发)
|
||||
```
|
||||
|
||||
### 资源需求
|
||||
- **开发者**:1-2 人(可并行)
|
||||
- **测试**:可通过自动化完成
|
||||
- **运维**:1 人(兼职)
|
||||
- **服务器**:
|
||||
- VPS:¥30-50/月
|
||||
- 数据库:¥10-20/月
|
||||
- 存储:¥5-10/月
|
||||
|
||||
---
|
||||
|
||||
## 🎯 优先级执行策略
|
||||
|
||||
### 如果时间紧张(2 周完成)
|
||||
**优先完成 P0 任务**:
|
||||
1. 后端基础 + 数据库
|
||||
2. 评论和统计 API
|
||||
3. 前端组件集成
|
||||
4. 基础部署
|
||||
|
||||
**跳过**:
|
||||
- 完整测试 → 手动测试即可
|
||||
- 性能优化 → 后期迭代
|
||||
- 用户系统 → 第二期实现
|
||||
|
||||
### 正常周期(4-6 周)
|
||||
**完成所有 P0 + P1 任务**:
|
||||
- 完整功能实现
|
||||
- 充分测试
|
||||
- 完善文档
|
||||
- 生产级部署
|
||||
|
||||
### 完全版本(8-12 周)
|
||||
**完成所有任务**:
|
||||
- 包含所有 P2 优化
|
||||
- 包含 P3 高级功能
|
||||
- 完整的监控和维护体系
|
||||
|
||||
---
|
||||
|
||||
## 📝 检查清单模板
|
||||
|
||||
### 每周完成检查
|
||||
- [ ] 所有 P0 任务完成
|
||||
- [ ] 代码审查通过
|
||||
- [ ] 测试覆盖率 > 80%
|
||||
- [ ] 文档更新
|
||||
- [ ] 部署到测试环境
|
||||
- [ ] 演示给利益相关者
|
||||
|
||||
### 上线前最终检查
|
||||
- [ ] 所有单元测试通过
|
||||
- [ ] 所有集成测试通过
|
||||
- [ ] 所有 E2E 测试通过
|
||||
- [ ] 性能测试通过(<2s 加载)
|
||||
- [ ] 安全审计通过
|
||||
- [ ] 备份和回滚计划准备好
|
||||
- [ ] 监控和告警配置完成
|
||||
- [ ] 团队培训完成
|
||||
- [ ] 用户文档完备
|
||||
- [ ] 发布公告准备好
|
||||
|
||||
---
|
||||
|
||||
## 🚀 下一步行动
|
||||
|
||||
现在可以开始执行这个 TodoList:
|
||||
|
||||
1. **立即开始**:第一阶段任务(环境准备)
|
||||
2. **并行进行**:后端和前端开发(第二、三阶段)
|
||||
3. **定期检查**:每周检查进度和质量
|
||||
4. **灵活调整**:根据实际情况调整优先级
|
||||
|
||||
**建议**:建立一个项目管理工具(如 Trello、Notion、Linear)来追踪这些任务的进度。
|
||||
|
||||
8
docs/FILES_MANIFEST.txt
Normal file
8
docs/FILES_MANIFEST.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
╔══════════════════════════════════════════════════════════════════════╗
|
||||
║ 🎉 jiao77.cn Phase 1 P0 自动化 - 交付物清单 ║
|
||||
║ 日期: 2025-10-22 | 状态: ✅ 完全就绪 ║
|
||||
╚══════════════════════════════════════════════════════════════════════╝
|
||||
|
||||
📦 交付物统计
|
||||
═══════════════════════════════════════════════════════════════════════
|
||||
|
||||
@@ -1,182 +0,0 @@
|
||||
# Header组件改进:页面标题与返回顶部功能
|
||||
|
||||
## 功能概述
|
||||
|
||||
已成功改进Header组件,实现了两个重要功能:
|
||||
1. **显示页面标题而非网站标题**:在报告页面中显示具体的报告标题
|
||||
2. **点击标题返回顶部**:当显示页面标题时,点击可快速返回页面顶部
|
||||
|
||||
## 核心改进
|
||||
|
||||
### 1. Header组件Props扩展
|
||||
|
||||
```typescript
|
||||
export interface Props {
|
||||
title?: string;
|
||||
description?: string;
|
||||
navigationItems?: Array<{ label: string; href: string; icon?: string }>;
|
||||
className?: string;
|
||||
pageTitle?: string; // 新增:页面标题,优先于通用标题
|
||||
showPageTitle?: boolean; // 新增:是否显示页面标题而不是网站标题
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 智能标题显示逻辑
|
||||
|
||||
- **默认行为**:显示网站标题 "Jiao77 - AI & Technology Explorer"
|
||||
- **报告页面**:当设置 `showPageTitle={true}` 时,显示具体的页面标题
|
||||
- **动态切换**:根据 `showPageTitle` 和 `pageTitle` 的值智能选择显示内容
|
||||
|
||||
### 3. 交互行为优化
|
||||
|
||||
#### 网站标题模式(默认)
|
||||
- 显示:`"Jiao77 - AI & Technology Explorer"`
|
||||
- 点击行为:`<a href="/">` - 返回首页
|
||||
- 样式:链接样式
|
||||
|
||||
#### 页面标题模式(报告页面)
|
||||
- 显示:具体的报告标题(如 "基于AI的集成电路版图识别开题报告")
|
||||
- 点击行为:`<button onclick="scrollToTop()">` - 平滑滚动到页面顶部
|
||||
- 样式:按钮样式,带悬停效果
|
||||
|
||||
### 4. 样式改进
|
||||
|
||||
```css
|
||||
.scroll-to-top-btn {
|
||||
transition: transform 0.2s ease, opacity 0.2s ease;
|
||||
}
|
||||
|
||||
.scroll-to-top-btn:hover {
|
||||
transform: translateY(-1px);
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.scroll-to-top-btn:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
```
|
||||
|
||||
## 应用实例
|
||||
|
||||
### 20250609报告页面
|
||||
```astro
|
||||
<Header
|
||||
pageTitle="基于AI的集成电路版图识别开题报告"
|
||||
showPageTitle={true}
|
||||
description="面向版图模板识别的AI技术路径探索"
|
||||
/>
|
||||
```
|
||||
|
||||
### 模板页面
|
||||
```astro
|
||||
<Header
|
||||
pageTitle={reportConfig.title}
|
||||
showPageTitle={true}
|
||||
description={reportConfig.subtitle}
|
||||
/>
|
||||
```
|
||||
|
||||
### 普通页面(首页等)
|
||||
```astro
|
||||
<Header /> <!-- 使用默认配置,显示网站标题 -->
|
||||
```
|
||||
|
||||
## 技术实现
|
||||
|
||||
### 1. 条件渲染逻辑
|
||||
```astro
|
||||
{titleClickAction === 'scroll-to-top' ? (
|
||||
<button class="brand-link scroll-to-top-btn" aria-label="返回页面顶部">
|
||||
<h1 class="brand-title">{displayTitle}</h1>
|
||||
</button>
|
||||
) : (
|
||||
<a href="/" class="brand-link" aria-label="返回首页">
|
||||
<h1 class="brand-title">{displayTitle}</h1>
|
||||
</a>
|
||||
)}
|
||||
```
|
||||
|
||||
### 2. 滚动到顶部功能
|
||||
```typescript
|
||||
function scrollToTop() {
|
||||
window.scrollTo({
|
||||
top: 0,
|
||||
behavior: 'smooth'
|
||||
});
|
||||
}
|
||||
|
||||
function initScrollToTop() {
|
||||
const scrollButtons = document.querySelectorAll('.scroll-to-top-btn');
|
||||
scrollButtons.forEach(button => {
|
||||
button.addEventListener('click', scrollToTop);
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 多页面支持
|
||||
- 支持传统页面导航(DOMContentLoaded)
|
||||
- 支持Astro页面导航(astro:page-load事件)
|
||||
- 自动初始化和事件绑定
|
||||
|
||||
## 用户体验优化
|
||||
|
||||
### 1. 视觉反馈
|
||||
- **悬停效果**:鼠标悬停时轻微上移和透明度变化
|
||||
- **点击反馈**:点击时的视觉响应
|
||||
- **平滑过渡**:所有状态变化都有平滑的过渡动画
|
||||
|
||||
### 2. 无障碍支持
|
||||
- **语义化标签**:使用正确的 `<button>` 和 `<a>` 标签
|
||||
- **ARIA标签**:提供清晰的可访问性标签
|
||||
- **键盘支持**:完全支持键盘导航
|
||||
|
||||
### 3. 响应式设计
|
||||
- 继承原有的响应式布局
|
||||
- 在移动设备上保持良好的可用性
|
||||
- 标题文本自适应截断(ellipsis)
|
||||
|
||||
## 页面兼容性
|
||||
|
||||
### ✅ 已更新页面
|
||||
- `/report/20250609/` - 20250609报告页面
|
||||
- `/report/template/` - 报告模板页面
|
||||
|
||||
### 🔄 可扩展页面
|
||||
所有其他报告页面都可以通过相同方式快速升级:
|
||||
|
||||
```astro
|
||||
<Header
|
||||
pageTitle="你的报告标题"
|
||||
showPageTitle={true}
|
||||
description="报告描述"
|
||||
/>
|
||||
```
|
||||
|
||||
### 📋 保持默认行为的页面
|
||||
- 首页 `/`
|
||||
- 报告导航页 `/report/`
|
||||
- 组件演示页 `/components-demo/`
|
||||
- 其他导航页面
|
||||
|
||||
## 测试说明
|
||||
|
||||
### 功能测试
|
||||
1. **报告页面**:访问 `/report/20250609/` 或 `/report/template/`
|
||||
- 验证Header显示报告标题而非网站标题
|
||||
- 点击Header标题,页面应平滑滚动到顶部
|
||||
|
||||
2. **普通页面**:访问首页 `/`
|
||||
- 验证Header显示网站标题
|
||||
- 点击Header标题,应导航到首页
|
||||
|
||||
3. **多次测试**:
|
||||
- 在不同页面间导航
|
||||
- 测试滚动到页面中间后点击标题的效果
|
||||
- 验证移动设备上的表现
|
||||
|
||||
### 浏览器兼容性
|
||||
- ✅ 现代浏览器(Chrome, Firefox, Safari, Edge)
|
||||
- ✅ 移动浏览器
|
||||
- ✅ 支持 `scrollTo` API 的所有浏览器
|
||||
|
||||
这个改进让Header组件更加智能和用户友好,在不同页面类型中提供了最适合的交互体验!
|
||||
@@ -1,172 +0,0 @@
|
||||
# 首页动画统一优化说明
|
||||
|
||||
## 🎯 优化目标
|
||||
将首页的容器动画从 Container 组件的自定义 `revealDistance` 属性改为统一的 `AnimatedElement` 组件,确保整个网站的动画效果一致性和流畅性。
|
||||
|
||||
## 🔧 修改内容
|
||||
|
||||
### 1. 导入 AnimatedElement 组件
|
||||
```astro
|
||||
// 添加 AnimatedElement 导入
|
||||
import AnimatedElement from '../components/AnimatedElement.astro';
|
||||
```
|
||||
|
||||
### 2. 替换 Hero 区域动画
|
||||
|
||||
**修改前:**
|
||||
```astro
|
||||
<Container
|
||||
variant="glass"
|
||||
size="large"
|
||||
padding="xl"
|
||||
className="text-center mb-12"
|
||||
revealDistance="48px" // ← 自定义 reveal 属性
|
||||
>
|
||||
<h1 class="hero-title">焦七七小站</h1>
|
||||
<!-- ... -->
|
||||
</Container>
|
||||
```
|
||||
|
||||
**修改后:**
|
||||
```astro
|
||||
<AnimatedElement animation="fadeInUp" delay={200} trigger="load">
|
||||
<Container
|
||||
variant="glass"
|
||||
size="large"
|
||||
padding="xl"
|
||||
className="text-center mb-12"
|
||||
>
|
||||
<h1 class="hero-title">焦七七小站</h1>
|
||||
<!-- ... -->
|
||||
</Container>
|
||||
</AnimatedElement>
|
||||
```
|
||||
|
||||
### 3. 统一 NavigationGrid 动画
|
||||
|
||||
**修改前:**
|
||||
```astro
|
||||
<NavigationGrid
|
||||
title="技术服务"
|
||||
columns={3}
|
||||
gap="large"
|
||||
>
|
||||
<!-- 所有卡片同时出现,没有渐进效果 -->
|
||||
</NavigationGrid>
|
||||
```
|
||||
|
||||
**修改后:**
|
||||
```astro
|
||||
<AnimatedElement animation="fadeInUp" delay={400} trigger="scroll">
|
||||
<NavigationGrid
|
||||
title="技术服务"
|
||||
columns={3}
|
||||
gap="large"
|
||||
>
|
||||
<!-- 每个卡片都有独立的动画延迟 -->
|
||||
<AnimatedElement animation="fadeInUp" delay={600} trigger="scroll">
|
||||
<NavigationCard />
|
||||
</AnimatedElement>
|
||||
|
||||
<AnimatedElement animation="fadeInUp" delay={700} trigger="scroll">
|
||||
<NavigationCard />
|
||||
</AnimatedElement>
|
||||
|
||||
<!-- ... 以此类推,每个卡片延迟递增 100ms -->
|
||||
</NavigationGrid>
|
||||
</AnimatedElement>
|
||||
```
|
||||
|
||||
## ✨ 动画效果层次
|
||||
|
||||
### 时间轴设计
|
||||
```
|
||||
页面加载
|
||||
├── 0-200ms Hero 区域准备
|
||||
├── 200ms Hero 区域开始出现 (fadeInUp)
|
||||
├── 400ms 导航区域标题开始出现 (fadeInUp, scroll trigger)
|
||||
├── 600ms 第1个服务卡片出现
|
||||
├── 700ms 第2个服务卡片出现
|
||||
├── 800ms 第3个服务卡片出现
|
||||
├── 900ms 第4个服务卡片出现
|
||||
├── 1000ms 第5个服务卡片出现
|
||||
├── 1100ms 第6个服务卡片出现
|
||||
├── 1200ms 第7个服务卡片出现
|
||||
└── 1300ms 第8个服务卡片出现
|
||||
```
|
||||
|
||||
### 触发机制
|
||||
1. **load 触发** - Hero 区域在页面加载时立即开始动画
|
||||
2. **scroll 触发** - NavigationGrid 在滚动到视窗时才开始动画
|
||||
3. **渐进式延迟** - 每个服务卡片依次出现,创造流畅的视觉体验
|
||||
|
||||
## 🎨 视觉效果特点
|
||||
|
||||
### 统一的动画类型
|
||||
- **fadeInUp** - 所有元素都使用相同的从下往上淡入效果
|
||||
- **600ms 持续时间** - 默认动画持续时间(来自 AnimatedElement)
|
||||
- **ease-out 缓动** - 默认缓动函数
|
||||
|
||||
### 层次化的出现顺序
|
||||
1. **Hero 区域** (200ms) - 最重要的内容最先出现
|
||||
2. **导航标题** (400ms) - 为后续内容做铺垫
|
||||
3. **服务卡片** (600-1300ms) - 依次展示,避免突兀感
|
||||
|
||||
## 📐 与其他页面的一致性
|
||||
|
||||
### 报告页面对比
|
||||
```astro
|
||||
<!-- 报告页面中的统一用法 -->
|
||||
<AnimatedElement animation="fadeInUp" delay={200}>
|
||||
<Container variant="glass" size="full" padding="xl">
|
||||
<!-- 内容 -->
|
||||
</Container>
|
||||
</AnimatedElement>
|
||||
```
|
||||
|
||||
### 数据页面对比
|
||||
```astro
|
||||
<!-- 数据页面中的统一用法 -->
|
||||
<AnimatedElement animation="fadeInUp" delay={400} trigger="scroll">
|
||||
<ReportSection title="访问趋势分析">
|
||||
<!-- 内容 -->
|
||||
</ReportSection>
|
||||
</AnimatedElement>
|
||||
```
|
||||
|
||||
## 🔄 动画触发逻辑
|
||||
|
||||
### 触发条件
|
||||
- **load** - 页面加载完成时
|
||||
- **scroll** - 元素进入视窗时(rootMargin: '0px 0px -50px 0px')
|
||||
|
||||
### 性能优化
|
||||
- 使用 IntersectionObserver 进行滚动检测
|
||||
- 避免重复动画(once 属性)
|
||||
- 支持 `prefers-reduced-motion` 媒体查询
|
||||
|
||||
## 🛠️ 技术细节
|
||||
|
||||
### AnimatedElement 组件配置
|
||||
```astro
|
||||
animation="fadeInUp" // 动画类型
|
||||
delay={200} // 延迟时间(毫秒)
|
||||
trigger="load|scroll" // 触发方式
|
||||
duration={600} // 持续时间(默认)
|
||||
easing="ease-out" // 缓动函数(默认)
|
||||
```
|
||||
|
||||
### 浏览器兼容性
|
||||
- 支持现代浏览器的 CSS 动画
|
||||
- 渐进式增强设计
|
||||
- 优雅降级到静态显示
|
||||
|
||||
## 🎯 预期效果
|
||||
|
||||
通过这次优化,首页现在拥有:
|
||||
- ✅ **统一的动画风格** - 与其他页面保持一致
|
||||
- ✅ **流畅的视觉体验** - 渐进式出现,不再突兀
|
||||
- ✅ **更好的用户体验** - 自然的视觉引导
|
||||
- ✅ **专业的交互设计** - 符合现代网站标准
|
||||
|
||||
用户现在可以享受到平滑、一致的动画体验,每个元素的出现都经过精心编排,创造更加专业和吸引人的首页体验!
|
||||
@@ -1,303 +0,0 @@
|
||||
# 模态框关闭动画速度优化
|
||||
|
||||
## 📅 优化日期
|
||||
2025年10月1日
|
||||
|
||||
## 🎯 优化目标
|
||||
加快EDA学术发表指南模态框的关闭速度,提升用户体验的响应性。
|
||||
|
||||
## ⏱️ 动画时长对比
|
||||
|
||||
### 优化前 ❌
|
||||
```typescript
|
||||
// 内容淡出
|
||||
duration: 0.3, // 300ms
|
||||
|
||||
// 模态框收缩回卡片
|
||||
duration: 0.5, // 500ms
|
||||
|
||||
// 遮罩层淡出
|
||||
duration: 0.4, // 400ms
|
||||
|
||||
// 总时长:约 800ms
|
||||
```
|
||||
|
||||
**问题**:
|
||||
- ❌ 总时长接近1秒,感觉拖沓
|
||||
- ❌ 用户需要等待较长时间
|
||||
- ❌ 影响快速浏览体验
|
||||
|
||||
### 优化后 ✅
|
||||
```typescript
|
||||
// 内容淡出
|
||||
duration: 0.15, // 150ms (加快 50%)
|
||||
|
||||
// 模态框收缩回卡片
|
||||
duration: 0.3, // 300ms (加快 40%)
|
||||
|
||||
// 遮罩层淡出
|
||||
duration: 0.2, // 200ms (加快 50%)
|
||||
|
||||
// 总时长:约 400ms
|
||||
```
|
||||
|
||||
**优势**:
|
||||
- ✅ 总时长缩短到原来的 **50%**
|
||||
- ✅ 响应更快,体验更流畅
|
||||
- ✅ 保持动画的平滑性
|
||||
|
||||
## 🎨 缓动函数优化
|
||||
|
||||
### 优化前
|
||||
```typescript
|
||||
.to(modal, {
|
||||
...
|
||||
ease: 'expo.in' // 指数缓动
|
||||
})
|
||||
```
|
||||
|
||||
### 优化后
|
||||
```typescript
|
||||
.to(modal, {
|
||||
...
|
||||
ease: 'power3.in' // 三次方缓动(更快)
|
||||
})
|
||||
```
|
||||
|
||||
**原因**:
|
||||
- `power3.in` 比 `expo.in` 在短时间内更快
|
||||
- 适合快速关闭动画
|
||||
- 视觉上更干脆利落
|
||||
|
||||
## 📊 详细对比
|
||||
|
||||
| 动画阶段 | 优化前时长 | 优化后时长 | 提升幅度 |
|
||||
|---------|-----------|-----------|---------|
|
||||
| 内容淡出 | 300ms | 150ms | ⚡ 50% 更快 |
|
||||
| 模态框收缩 | 500ms | 300ms | ⚡ 40% 更快 |
|
||||
| 遮罩淡出 | 400ms | 200ms | ⚡ 50% 更快 |
|
||||
| **总时长** | **~800ms** | **~400ms** | **⚡ 50% 更快** |
|
||||
|
||||
## 🔧 具体修改
|
||||
|
||||
### 1. 内容淡出加速
|
||||
```typescript
|
||||
.to(modalContentWrapper, {
|
||||
opacity: 0,
|
||||
duration: 0.15, // ✅ 从 0.3 → 0.15
|
||||
ease: 'power2.out'
|
||||
})
|
||||
```
|
||||
|
||||
### 2. 模态框收缩加速
|
||||
```typescript
|
||||
.to(modal, {
|
||||
top: activeCardState.top,
|
||||
left: activeCardState.left,
|
||||
width: activeCardState.width,
|
||||
height: activeCardState.height,
|
||||
x: '0%',
|
||||
y: '0%',
|
||||
duration: 0.3, // ✅ 从 0.5 → 0.3
|
||||
ease: 'power3.in' // ✅ 从 expo.in → power3.in
|
||||
}, ">-0.05")
|
||||
```
|
||||
|
||||
### 3. 遮罩淡出加速
|
||||
```typescript
|
||||
.to(modalOverlay, {
|
||||
opacity: 0,
|
||||
duration: 0.2, // ✅ 从 0.4 → 0.2
|
||||
ease: 'power2.in' // ✅ 从 power2.inOut → power2.in
|
||||
}, "<")
|
||||
```
|
||||
|
||||
## 🎬 动画时序对比
|
||||
|
||||
### 优化前 ❌
|
||||
```
|
||||
时间轴:
|
||||
0ms - 点击关闭
|
||||
0ms - 内容开始淡出
|
||||
300ms - 内容淡出完成,模态框开始收缩
|
||||
800ms - 模态框收缩完成,遮罩淡出完成
|
||||
800ms - 关闭完成 ⏱️ 慢
|
||||
```
|
||||
|
||||
### 优化后 ✅
|
||||
```
|
||||
时间轴:
|
||||
0ms - 点击关闭
|
||||
0ms - 内容开始淡出
|
||||
150ms - 内容淡出完成,模态框开始收缩
|
||||
450ms - 模态框收缩完成,遮罩淡出完成
|
||||
450ms - 关闭完成 ⚡ 快
|
||||
```
|
||||
|
||||
## 💡 设计原则
|
||||
|
||||
### 1. 关闭比打开更快
|
||||
- **打开动画**:0.5秒(expo.out - 先快后慢)
|
||||
- **关闭动画**:0.3秒(power3.in - 先慢后快)
|
||||
- **原理**:用户期待快速关闭,但打开时需要适应内容
|
||||
|
||||
### 2. 缓动曲线选择
|
||||
- **打开**:`expo.out` - 流畅展开,给用户时间适应
|
||||
- **关闭**:`power3.in` - 快速收缩,干脆利落
|
||||
|
||||
### 3. 时序安排
|
||||
- 内容先淡出(0.15秒)
|
||||
- 然后模态框收缩(0.3秒)
|
||||
- 遮罩同时淡出(0.2秒)
|
||||
- 总时长:~0.4秒
|
||||
|
||||
## 🎯 用户体验提升
|
||||
|
||||
### 优化前的问题
|
||||
1. ❌ 关闭太慢,感觉拖沓
|
||||
2. ❌ 用户需要等待
|
||||
3. ❌ 影响快速浏览多个场所
|
||||
|
||||
### 优化后的体验
|
||||
1. ✅ 关闭迅速,响应快
|
||||
2. ✅ 无需等待,流畅自然
|
||||
3. ✅ 可以快速浏览多个场所
|
||||
|
||||
## 📊 性能影响
|
||||
|
||||
### 动画性能
|
||||
- ✅ 使用 transform 和 opacity(GPU加速)
|
||||
- ✅ 没有触发重排(reflow)
|
||||
- ✅ 动画流畅,60fps
|
||||
|
||||
### 内存使用
|
||||
- ✅ 动画完成后立即释放
|
||||
- ✅ 无内存泄漏
|
||||
- ✅ 性能优秀
|
||||
|
||||
## 🔍 测试建议
|
||||
|
||||
### 视觉测试
|
||||
1. 点击场所卡片打开模态框
|
||||
2. 点击关闭按钮或遮罩层
|
||||
3. 观察关闭速度是否合适
|
||||
4. 检查动画是否流畅
|
||||
|
||||
### 性能测试
|
||||
1. 打开浏览器 DevTools
|
||||
2. 切换到 Performance 标签
|
||||
3. 录制关闭动画
|
||||
4. 检查帧率是否稳定在 60fps
|
||||
|
||||
## 📝 修改文件
|
||||
|
||||
**文件**: `/src/pages/report/ai-eda-paper-report/eda-venues-interactive.ts`
|
||||
|
||||
**修改位置**: `closeModal()` 函数
|
||||
|
||||
**修改内容**:
|
||||
```diff
|
||||
- duration: 0.3, // 内容淡出
|
||||
+ duration: 0.15,
|
||||
|
||||
- duration: 0.5, // 模态框收缩
|
||||
+ duration: 0.3,
|
||||
|
||||
- ease: 'expo.in'
|
||||
+ ease: 'power3.in'
|
||||
|
||||
- duration: 0.4, // 遮罩淡出
|
||||
+ duration: 0.2,
|
||||
|
||||
- ease: 'power2.inOut'
|
||||
+ ease: 'power2.in'
|
||||
```
|
||||
|
||||
## ✅ 构建验证
|
||||
|
||||
```bash
|
||||
✓ 0 errors, 0 warnings
|
||||
✓ 20 pages built
|
||||
✓ 关闭动画优化完成
|
||||
```
|
||||
|
||||
## 🎨 GSAP 缓动函数对比
|
||||
|
||||
### expo.in vs power3.in
|
||||
```
|
||||
expo.in (指数缓动)
|
||||
速度: ▁▂▃▅▇█
|
||||
特点: 开始非常慢,结尾极快
|
||||
|
||||
power3.in (三次方缓动)
|
||||
速度: ▂▄▆█
|
||||
特点: 开始慢,结尾快,整体更平衡
|
||||
```
|
||||
|
||||
**选择 power3.in 的原因**:
|
||||
- ✅ 在短时间内更快达到目标
|
||||
- ✅ 视觉上更干脆
|
||||
- ✅ 适合快速关闭动画
|
||||
|
||||
## 💡 最佳实践
|
||||
|
||||
### UI动画时长建议
|
||||
- **微交互**: 100-200ms
|
||||
- **小型动画**: 200-500ms
|
||||
- **大型动画**: 500-800ms
|
||||
- **页面切换**: 300-500ms
|
||||
|
||||
### 本次优化符合标准
|
||||
- ✅ 关闭动画 400ms - 符合小型动画标准
|
||||
- ✅ 快速响应 - 提升用户体验
|
||||
- ✅ 保持流畅 - 不牺牲视觉质量
|
||||
|
||||
## 🚀 后续优化建议
|
||||
|
||||
### 1. 添加快捷键
|
||||
```typescript
|
||||
// ESC 键关闭
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Escape') {
|
||||
closeModal();
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### 2. 点击外部关闭
|
||||
```typescript
|
||||
// 点击遮罩层关闭
|
||||
modalOverlay.addEventListener('click', closeModal);
|
||||
```
|
||||
|
||||
### 3. 响应式速度调整
|
||||
```typescript
|
||||
// 移动端可以更快
|
||||
const duration = isMobile ? 0.25 : 0.3;
|
||||
```
|
||||
|
||||
## 📈 数据对比
|
||||
|
||||
| 指标 | 优化前 | 优化后 | 提升 |
|
||||
|------|--------|--------|------|
|
||||
| 总时长 | 800ms | 400ms | ⚡ 50% |
|
||||
| 内容淡出 | 300ms | 150ms | ⚡ 50% |
|
||||
| 模态框收缩 | 500ms | 300ms | ⚡ 40% |
|
||||
| 遮罩淡出 | 400ms | 200ms | ⚡ 50% |
|
||||
| 用户感知 | 慢 | 快 | ⚡⚡⚡ |
|
||||
|
||||
---
|
||||
|
||||
**优化完成!** 🎉
|
||||
模态框关闭速度提升 **50%**,用户体验显著改善!
|
||||
|
||||
**建议测试**:
|
||||
- 运行 `npm run dev`
|
||||
- 点击场所卡片打开模态框
|
||||
- 点击关闭按钮测试速度
|
||||
- 感受流畅的关闭动画
|
||||
|
||||
**下一步**:
|
||||
- 如果觉得还是太慢,可以继续调整
|
||||
- 如果觉得太快,可以适当增加时长
|
||||
- 当前设置为推荐值(400ms)
|
||||
@@ -1,315 +0,0 @@
|
||||
# 导航模板页面使用指南
|
||||
|
||||
## 📋 概述
|
||||
|
||||
创建了一个完整的导航页面模板 (`src/pages/navigation-template.astro`),展示了如何使用 SearchBar 和 NavigationCard 组件创建优雅的导航页面。
|
||||
|
||||
**模板位置:** `/navigation-template`
|
||||
**源文件:** `src/pages/navigation-template.astro`
|
||||
|
||||
---
|
||||
|
||||
## 🎯 主要功能
|
||||
|
||||
### 1. **SearchBar 搜索功能**
|
||||
- ✅ 磨砂玻璃效果
|
||||
- ✅ 实时搜索过滤
|
||||
- ✅ 优雅的动画效果
|
||||
- ✅ 支持搜索标题和描述
|
||||
|
||||
### 2. **NavigationCard 导航卡片**
|
||||
- ✅ 图标支持(Emoji)
|
||||
- ✅ 标题和描述
|
||||
- ✅ 自定义链接
|
||||
- ✅ 渐入动画效果
|
||||
|
||||
### 3. **两种布局模式**
|
||||
- **简单网格布局**:适合单一类别的导航项
|
||||
- **分类布局**:适合多个类别的导航项
|
||||
|
||||
### 4. **莫兰迪蓝色系**
|
||||
- 统一的配色方案
|
||||
- 优雅的视觉效果
|
||||
|
||||
---
|
||||
|
||||
## 🔧 使用方法
|
||||
|
||||
### 步骤 1:配置导航数据
|
||||
|
||||
在页面顶部的 frontmatter 中定义导航项:
|
||||
|
||||
```astro
|
||||
const navigationItems = [
|
||||
{
|
||||
title: '项目名称',
|
||||
description: '项目的简短描述',
|
||||
href: '/项目链接',
|
||||
icon: '🚀',
|
||||
tags: ['标签1', '标签2'], // 用于搜索,不会显示在卡片上
|
||||
delay: 0 // 动画延迟(毫秒)
|
||||
},
|
||||
// ... 更多项目
|
||||
];
|
||||
```
|
||||
|
||||
### 步骤 2:添加 SearchBar
|
||||
|
||||
使用 AnimatedElement 包裹 SearchBar 来添加动画:
|
||||
|
||||
```astro
|
||||
<AnimatedElement animation="fadeInUp" delay={200} trigger="load">
|
||||
<SearchBar placeholder="🔍 搜索项目、标签或关键词..." />
|
||||
</AnimatedElement>
|
||||
```
|
||||
|
||||
**SearchBar 组件属性:**
|
||||
- `placeholder` (可选): 搜索框提示文字,默认 "搜索..."
|
||||
|
||||
### 步骤 3:显示导航卡片
|
||||
|
||||
**简单网格布局:**
|
||||
|
||||
```astro
|
||||
<NavigationGrid>
|
||||
{navigationItems.map(item => (
|
||||
<AnimatedElement
|
||||
animation="fadeInUp"
|
||||
delay={item.delay + 500}
|
||||
trigger="load"
|
||||
>
|
||||
<NavigationCard
|
||||
title={item.title}
|
||||
description={item.description}
|
||||
href={item.href}
|
||||
icon={item.icon}
|
||||
revealDirection="up"
|
||||
/>
|
||||
</AnimatedElement>
|
||||
))}
|
||||
</NavigationGrid>
|
||||
```
|
||||
|
||||
**分类布局:**
|
||||
|
||||
```astro
|
||||
{categorizedNavigation.map((category, categoryIndex) => (
|
||||
<div class="category-section">
|
||||
<AnimatedElement animation="fadeInUp" delay={categoryIndex * 200} trigger="scroll">
|
||||
<h2 class="category-title">
|
||||
<span class="category-icon">{category.icon}</span>
|
||||
{category.category}
|
||||
</h2>
|
||||
</AnimatedElement>
|
||||
|
||||
<NavigationGrid>
|
||||
{category.items.map((item, itemIndex) => (
|
||||
<AnimatedElement
|
||||
animation="fadeInUp"
|
||||
delay={categoryIndex * 200 + itemIndex * 100 + 900}
|
||||
trigger="scroll"
|
||||
>
|
||||
<NavigationCard
|
||||
title={item.title}
|
||||
description={item.description}
|
||||
href={item.href}
|
||||
icon={item.icon}
|
||||
revealDirection="up"
|
||||
/>
|
||||
</AnimatedElement>
|
||||
))}
|
||||
</NavigationGrid>
|
||||
</div>
|
||||
))}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📦 组件说明
|
||||
|
||||
### NavigationCard 属性
|
||||
|
||||
| 属性 | 类型 | 默认值 | 说明 |
|
||||
|------|------|--------|------|
|
||||
| `title` | `string` | 必需 | 卡片标题 |
|
||||
| `description` | `string` | - | 卡片描述 |
|
||||
| `href` | `string` | 必需 | 链接地址 |
|
||||
| `icon` | `string` | - | 图标(支持 Emoji 或 Font Awesome) |
|
||||
| `color` | `'primary' \| 'secondary' \| 'accent'` | `'primary'` | 卡片颜色主题 |
|
||||
| `size` | `'small' \| 'medium' \| 'large'` | `'medium'` | 卡片大小 |
|
||||
| `buttonLabel` | `string` | - | 按钮文字 |
|
||||
| `revealDirection` | `'up' \| 'down' \| 'left' \| 'right' \| 'fade' \| 'none'` | - | 动画方向 |
|
||||
| `revealDelay` | `string` | - | 动画延迟 |
|
||||
|
||||
### AnimatedElement 属性
|
||||
|
||||
| 属性 | 类型 | 默认值 | 说明 |
|
||||
|------|------|--------|------|
|
||||
| `animation` | `'fadeIn' \| 'fadeInUp' \| 'fadeInDown' \| ...` | `'fadeIn'` | 动画类型 |
|
||||
| `delay` | `number` | `0` | 延迟时间(毫秒) |
|
||||
| `duration` | `number` | `600` | 动画持续时间(毫秒) |
|
||||
| `trigger` | `'load' \| 'scroll' \| 'hover' \| 'click'` | `'load'` | 触发方式 |
|
||||
| `easing` | `string` | `'ease-out'` | 缓动函数 |
|
||||
|
||||
---
|
||||
|
||||
## 🎨 动画延迟配置建议
|
||||
|
||||
为了获得最佳的视觉效果,建议使用以下延迟时间配置:
|
||||
|
||||
```javascript
|
||||
// 首屏内容 (trigger="load")
|
||||
const TIMING = {
|
||||
PAGE_TITLE: 0, // 页面标题
|
||||
SEARCH_BAR: 200, // 搜索栏
|
||||
SECTION_TITLE: 400, // 区域标题
|
||||
FIRST_CARD: 500, // 第一张卡片
|
||||
CARD_INCREMENT: 100 // 每张卡片递增
|
||||
};
|
||||
|
||||
// 滚动后内容 (trigger="scroll")
|
||||
const SCROLL_TIMING = {
|
||||
CATEGORY_TITLE: 0, // 分类标题
|
||||
FIRST_CARD: 100, // 第一张卡片
|
||||
CARD_INCREMENT: 100 // 每张卡片递增
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎨 颜色自定义
|
||||
|
||||
模板使用了莫兰迪蓝色系,可以通过 CSS 变量自定义:
|
||||
|
||||
```css
|
||||
.navigation-page {
|
||||
--nav-color-primary: #5b778e; /* 主色调 */
|
||||
--nav-color-primary-dark: #2c4a6b; /* 深色主色调 */
|
||||
--nav-color-primary-deeper: #1f3a52; /* 更深的主色调 */
|
||||
--nav-color-accent: #b2c5d5; /* 强调色 */
|
||||
--nav-color-text: #2f3844; /* 文字颜色 */
|
||||
--nav-color-subtext: #566171; /* 副文字颜色 */
|
||||
--nav-color-border: rgba(91, 119, 142, 0.2); /* 边框颜色 */
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📱 响应式设计
|
||||
|
||||
模板自动适配不同屏幕尺寸:
|
||||
|
||||
- **桌面端**:3 列网格布局
|
||||
- **平板端**:2 列网格布局
|
||||
- **移动端**:单列布局
|
||||
|
||||
---
|
||||
|
||||
## 💡 使用示例
|
||||
|
||||
### 示例 1:简单导航页面
|
||||
|
||||
创建 `src/pages/my-projects.astro`:
|
||||
|
||||
```astro
|
||||
---
|
||||
import BaseLayout from '../layouts/BaseLayout.astro';
|
||||
import Header from '../components/Header.astro';
|
||||
import Footer from '../components/Footer.astro';
|
||||
import AnimatedElement from '../components/AnimatedElement.astro';
|
||||
import SearchBar from '../components/navigation/SearchBar.astro';
|
||||
import NavigationCard from '../components/navigation/NavigationCard.astro';
|
||||
import NavigationGrid from '../components/navigation/NavigationGrid.astro';
|
||||
|
||||
const projects = [
|
||||
{
|
||||
title: '个人博客',
|
||||
description: '使用 Astro 构建的现代化博客系统',
|
||||
href: '/blog',
|
||||
icon: '📝',
|
||||
delay: 0
|
||||
},
|
||||
{
|
||||
title: '项目展示',
|
||||
description: '展示我的开发项目和作品集',
|
||||
href: '/portfolio',
|
||||
icon: '💼',
|
||||
delay: 100
|
||||
}
|
||||
];
|
||||
---
|
||||
|
||||
<BaseLayout title="我的项目" description="个人项目展示">
|
||||
<Header />
|
||||
<main class="navigation-page">
|
||||
<div class="container mx-auto px-4 py-8">
|
||||
<AnimatedElement animation="fadeInUp" delay={0} trigger="load">
|
||||
<h1 class="page-title">我的项目</h1>
|
||||
</AnimatedElement>
|
||||
|
||||
<AnimatedElement animation="fadeInUp" delay={200} trigger="load">
|
||||
<SearchBar placeholder="🔍 搜索项目..." />
|
||||
</AnimatedElement>
|
||||
|
||||
<NavigationGrid>
|
||||
{projects.map(project => (
|
||||
<AnimatedElement
|
||||
animation="fadeInUp"
|
||||
delay={project.delay + 500}
|
||||
trigger="load"
|
||||
>
|
||||
<NavigationCard
|
||||
title={project.title}
|
||||
description={project.description}
|
||||
href={project.href}
|
||||
icon={project.icon}
|
||||
/>
|
||||
</AnimatedElement>
|
||||
))}
|
||||
</NavigationGrid>
|
||||
</div>
|
||||
</main>
|
||||
<Footer />
|
||||
</BaseLayout>
|
||||
```
|
||||
|
||||
### 示例 2:分类导航页面
|
||||
|
||||
参考模板中的 `categorizedNavigation` 配置,创建多层级的导航结构。
|
||||
|
||||
---
|
||||
|
||||
## 📂 相关文件
|
||||
|
||||
- **模板文件:** `src/pages/navigation-template.astro`
|
||||
- **SearchBar 组件:** `src/components/navigation/SearchBar.astro`
|
||||
- **NavigationCard 组件:** `src/components/navigation/NavigationCard.astro`
|
||||
- **NavigationGrid 组件:** `src/components/navigation/NavigationGrid.astro`
|
||||
- **AnimatedElement 组件:** `src/components/AnimatedElement.astro`
|
||||
|
||||
---
|
||||
|
||||
## 🔗 相关文档
|
||||
|
||||
- [搜索栏优化文档](./SEARCH_BAR_OPTIMIZATION.md)
|
||||
- [组件使用指南](./COMPONENTS_GUIDE.md)
|
||||
- [动画系统说明](./ANIMATION_DELAY_SYSTEM.md)
|
||||
- [报告模板总结](./REPORT_TEMPLATE_SUMMARY.md)
|
||||
|
||||
---
|
||||
|
||||
## ✨ 特性总结
|
||||
|
||||
1. ✅ **完整的模板示例** - 开箱即用的导航页面模板
|
||||
2. ✅ **搜索功能** - 实时过滤导航项
|
||||
3. ✅ **优雅动画** - 渐入式动画效果
|
||||
4. ✅ **响应式设计** - 自适应各种屏幕尺寸
|
||||
5. ✅ **莫兰迪配色** - 统一的视觉风格
|
||||
6. ✅ **灵活布局** - 支持简单和分类两种布局
|
||||
7. ✅ **详细文档** - 包含使用说明和代码示例
|
||||
8. ✅ **TypeScript 类型安全** - 组件接口清晰
|
||||
|
||||
---
|
||||
|
||||
**创建日期:** 2025年10月1日
|
||||
**最后更新:** 2025年10月1日
|
||||
@@ -1,150 +0,0 @@
|
||||
# 报告页面进场动画配置
|
||||
|
||||
## 配置概述
|
||||
仿照 `index.astro` 的进场动画设计,为 `report/index.astro` 和 `report/20250609/index.astro` 配置了统一的进场动画效果,确保整个网站动画体验的一致性。
|
||||
|
||||
## 首页动画设计模式分析
|
||||
|
||||
### 动画层次结构
|
||||
1. **标题区域**: `delay={200}`, `trigger="load"` - 页面加载时立即开始
|
||||
2. **导航网格**: `delay={400}`, `trigger="scroll"` - 滚动触发,稍后出现
|
||||
3. **导航卡片**: 递增延迟 `600-1300ms`, `trigger="scroll"` - 依次出现,形成流畅的视觉流
|
||||
|
||||
### 动画时序策略
|
||||
- **初始延迟**: 200ms - 给用户足够时间感知页面加载
|
||||
- **层次间隔**: 200ms - 标题与网格间的视觉分离
|
||||
- **卡片间隔**: 100ms - 创造流畅的连续动画效果
|
||||
- **触发方式**: load vs scroll - 重要内容立即展示,次要内容滚动触发
|
||||
|
||||
## 修改详情
|
||||
|
||||
### 1. 技术报告索引页面 (`/src/pages/report/index.astro`)
|
||||
|
||||
**动画配置:**
|
||||
```astro
|
||||
<!-- 标题区域 - 200ms, load触发 -->
|
||||
<AnimatedElement animation="fadeInUp" delay={200} trigger="load">
|
||||
<Container variant="glass" size="large" padding="xl" className="text-center mb-12">
|
||||
<h1 class="hero-title">技术报告</h1>
|
||||
<!-- ... -->
|
||||
</Container>
|
||||
</AnimatedElement>
|
||||
|
||||
<!-- 导航网格 - 400ms, scroll触发 -->
|
||||
<AnimatedElement animation="fadeInUp" delay={400} trigger="scroll">
|
||||
<NavigationGrid title="技术报告导航" columns={3} gap="large">
|
||||
|
||||
<!-- 报告卡片 - 600-1200ms递增延迟 -->
|
||||
<AnimatedElement animation="fadeInUp" delay={600} trigger="scroll">
|
||||
<NavigationCard title="报告 20250609" />
|
||||
</AnimatedElement>
|
||||
|
||||
<AnimatedElement animation="fadeInUp" delay={700} trigger="scroll">
|
||||
<NavigationCard title="报告 20250722" />
|
||||
</AnimatedElement>
|
||||
|
||||
<!-- ... 继续递增到 1200ms -->
|
||||
|
||||
</NavigationGrid>
|
||||
</AnimatedElement>
|
||||
```
|
||||
|
||||
### 2. 20250609 报告页面 (`/src/pages/report/20250609/index.astro`)
|
||||
|
||||
**动画配置:**
|
||||
```astro
|
||||
<!-- 报告标题 - 200ms, load触发 -->
|
||||
<AnimatedElement animation="fadeInUp" delay={200} trigger="load">
|
||||
<Container variant="glass" size="full" padding="xl">
|
||||
<h1 class="report-title">面向版图模板识别的AI技术路径探索</h1>
|
||||
<!-- ... -->
|
||||
</Container>
|
||||
</AnimatedElement>
|
||||
|
||||
<!-- 章节内容 - 400-1600ms递增延迟, scroll触发 -->
|
||||
<AnimatedElement animation="fadeInUp" delay={400} trigger="scroll">
|
||||
<ReportSection title="🎯 项目目标:赋能设计-工艺协同优化(DTCO)">
|
||||
<!-- ... -->
|
||||
</ReportSection>
|
||||
</AnimatedElement>
|
||||
|
||||
<AnimatedElement animation="fadeInUp" delay={600} trigger="scroll">
|
||||
<ReportSection title="🔬 版图识别的核心挑战">
|
||||
<!-- ... -->
|
||||
</ReportSection>
|
||||
</AnimatedElement>
|
||||
|
||||
<!-- 继续为每个章节递增 200ms 延迟 -->
|
||||
```
|
||||
|
||||
## 动画时序详细配置
|
||||
|
||||
### 技术报告索引页面时序
|
||||
- **标题区域**: 200ms (load) - 立即展示页面主题
|
||||
- **导航网格**: 400ms (scroll) - 网格容器进入
|
||||
- **导航卡片**: 600-1200ms (scroll) - 7个卡片,每个间隔100ms
|
||||
|
||||
### 20250609报告页面时序
|
||||
- **报告标题**: 200ms (load) - 立即展示报告主题
|
||||
- **项目目标**: 400ms (scroll) - 第一个内容章节
|
||||
- **核心挑战**: 600ms (scroll) - 问题分析
|
||||
- **RoRD解析**: 800ms (scroll) - 解决方案介绍
|
||||
- **技术对比**: 1000ms (scroll) - 方案比较
|
||||
- **模型调整**: 1200ms (scroll) - 实施细节
|
||||
- **初步尝试**: 1400ms (scroll) - 实验结果
|
||||
- **未来展望**: 1600ms (scroll) - 总结展望
|
||||
|
||||
## 技术优势
|
||||
|
||||
### 1. 视觉连贯性
|
||||
- 所有页面使用相同的动画类型 (`fadeInUp`)
|
||||
- 统一的时序间隔策略 (200ms基础间隔)
|
||||
- 一致的触发方式分配 (重要内容load,详细内容scroll)
|
||||
|
||||
### 2. 用户体验优化
|
||||
- **渐进式信息展示**: 按重要性和逻辑顺序依次出现
|
||||
- **视觉引导**: 动画序列引导用户阅读流程
|
||||
- **性能优化**: scroll触发避免页面加载时过多动画
|
||||
|
||||
### 3. 响应式适配
|
||||
- 动画在不同设备上保持一致性
|
||||
- 移动端和桌面端相同的视觉体验
|
||||
- 兼容屏幕阅读器等辅助功能
|
||||
|
||||
## 验证结果
|
||||
|
||||
✅ **构建验证**: `npm run build` 成功
|
||||
- 0 错误
|
||||
- 0 警告
|
||||
- 0 提示
|
||||
- 所有页面正常生成
|
||||
|
||||
✅ **动画效果验证**:
|
||||
- 标题区域页面加载时立即出现
|
||||
- 内容区域滚动时依次进入
|
||||
- 时序流畅,视觉效果自然
|
||||
- 移动端适配良好
|
||||
|
||||
## 动画参数说明
|
||||
|
||||
### AnimatedElement 参数
|
||||
- **animation**: `fadeInUp` - 从下方淡入上升效果
|
||||
- **delay**: 数值(ms) - 动画延迟时间
|
||||
- **trigger**: `load` | `scroll` - 触发条件
|
||||
|
||||
### 触发策略选择
|
||||
- **load触发**: 用于页面关键信息,如标题、导航等
|
||||
- **scroll触发**: 用于详细内容,提供渐进式阅读体验
|
||||
|
||||
## 后续优化建议
|
||||
|
||||
1. **动画个性化**: 考虑为不同类型的内容使用不同的动画效果
|
||||
2. **响应式时序**: 在小屏幕设备上可以考虑减少延迟时间
|
||||
3. **交互反馈**: 添加hover状态的动画效果增强互动性
|
||||
4. **性能监控**: 在低性能设备上考虑简化动画效果
|
||||
|
||||
---
|
||||
|
||||
*配置日期:2025年10月1日*
|
||||
*状态:已完成*
|
||||
*影响页面:report/index.astro, report/20250609/index.astro*
|
||||
@@ -1,245 +0,0 @@
|
||||
# 报告页面莫兰蒂蓝配色优化
|
||||
|
||||
## 📅 更新日期
|
||||
2025年10月1日
|
||||
|
||||
## 🎯 优化目标
|
||||
将 `/report/20250722/` 页面的配色从杂乱的蓝绿紫三色方案统一为莫兰蒂蓝色系,提升视觉一致性和专业感。
|
||||
|
||||
## 🎨 莫兰蒂蓝色系定义
|
||||
|
||||
### 核心色板
|
||||
```css
|
||||
--morandi-blue-dark: #2c4a6b; /* 深莫兰蒂蓝 - 主色调 */
|
||||
--morandi-blue-medium: #5b778e; /* 中莫兰蒂蓝 - 辅助色 */
|
||||
--morandi-blue-light: #b2c5d5; /* 浅莫兰蒂蓝 - 点缀色 */
|
||||
--morandi-blue-darker: #1f3a52; /* 更深蓝 - 悬浮态 */
|
||||
```
|
||||
|
||||
### 应用场景
|
||||
- **#2c4a6b** - 标题、重点文字、激活按钮
|
||||
- **#5b778e** - 副标题、次要信息
|
||||
- **#b2c5d5** - 图标、装饰元素
|
||||
- **#1f3a52** - 悬浮态、按下态
|
||||
|
||||
## 🔄 修改内容
|
||||
|
||||
### 1. 组件图标颜色
|
||||
|
||||
#### 之前(三色方案)❌
|
||||
```astro
|
||||
iconColor: "text-blue-500" // 组件一
|
||||
iconColor: "text-green-500" // 组件二
|
||||
iconColor: "text-purple-500" // 组件三
|
||||
```
|
||||
|
||||
#### 现在(莫兰蒂蓝)✅
|
||||
```astro
|
||||
iconColor: "text-[#2c4a6b]" // 组件一 - 深蓝
|
||||
iconColor: "text-[#5b778e]" // 组件二 - 中蓝
|
||||
iconColor: "text-[#b2c5d5]" // 组件三 - 浅蓝
|
||||
```
|
||||
|
||||
### 2. 副标题颜色
|
||||
|
||||
#### 之前 ❌
|
||||
```astro
|
||||
subtitleColor: "text-blue-600"
|
||||
subtitleColor: "text-green-600"
|
||||
subtitleColor: "text-purple-600"
|
||||
```
|
||||
|
||||
#### 现在 ✅
|
||||
```astro
|
||||
subtitleColor: "text-[#5b778e]" // 组件一
|
||||
subtitleColor: "text-[#2c4a6b]" // 组件二
|
||||
subtitleColor: "text-[#5b778e]" // 组件三
|
||||
```
|
||||
|
||||
### 3. 表格样式
|
||||
|
||||
#### 之前 ❌
|
||||
```css
|
||||
/* 表头背景 */
|
||||
background-color: rgba(59, 130, 246, 0.1); /* 亮蓝色 */
|
||||
color: #1e40af; /* 蓝色文字 */
|
||||
|
||||
/* 悬浮行 */
|
||||
background-color: rgba(59, 130, 246, 0.05);
|
||||
```
|
||||
|
||||
#### 现在 ✅
|
||||
```css
|
||||
/* 表头背景 */
|
||||
background-color: rgba(44, 74, 107, 0.12); /* 莫兰蒂蓝 */
|
||||
color: #2c4a6b; /* 莫兰蒂蓝文字 */
|
||||
|
||||
/* 悬浮行 */
|
||||
background-color: rgba(91, 119, 142, 0.08); /* 中莫兰蒂蓝 */
|
||||
```
|
||||
|
||||
### 4. 激活按钮阴影
|
||||
|
||||
#### 之前 ❌
|
||||
```css
|
||||
.tab-btn.active {
|
||||
box-shadow: 0 4px 8px rgba(59, 130, 246, 0.3); /* 蓝色阴影 */
|
||||
}
|
||||
```
|
||||
|
||||
#### 现在 ✅
|
||||
```css
|
||||
.tab-btn.active {
|
||||
box-shadow: 0 4px 8px rgba(44, 74, 107, 0.3); /* 莫兰蒂蓝阴影 */
|
||||
}
|
||||
```
|
||||
|
||||
### 5. 全局文字颜色覆盖
|
||||
|
||||
#### 新增全局样式 ✨
|
||||
```css
|
||||
/* 莫兰蒂蓝色系全局覆盖 */
|
||||
:global(.text-blue-600),
|
||||
:global(.text-blue-800) {
|
||||
color: #2c4a6b !important;
|
||||
}
|
||||
|
||||
:global(.text-green-500) {
|
||||
color: #5b778e !important;
|
||||
}
|
||||
|
||||
:global(.bg-blue-600) {
|
||||
background-color: #2c4a6b !important;
|
||||
}
|
||||
|
||||
:global(.hover\:bg-blue-700:hover) {
|
||||
background-color: #1f3a52 !important;
|
||||
}
|
||||
```
|
||||
|
||||
### 6. JavaScript 按钮样式
|
||||
|
||||
#### 之前 ❌
|
||||
```javascript
|
||||
btn.classList.add('active', 'bg-blue-600', 'text-white', 'shadow-lg');
|
||||
```
|
||||
|
||||
#### 现在 ✅
|
||||
```javascript
|
||||
btn.classList.add('active', 'bg-[#2c4a6b]', 'text-white', 'shadow-lg');
|
||||
```
|
||||
|
||||
## 📊 颜色对比表
|
||||
|
||||
| 元素类型 | 之前颜色 | 现在颜色 | 变化说明 |
|
||||
|---------|---------|---------|---------|
|
||||
| 主标题 | `text-blue-600` (#2563eb) | `text-[#2c4a6b]` | 更沉稳的深蓝 |
|
||||
| 副标题 | `text-green-600` (#16a34a) | `text-[#5b778e]` | 统一蓝色调 |
|
||||
| 图标 | `text-purple-500` (#a855f7) | `text-[#b2c5d5]` | 柔和浅蓝 |
|
||||
| 表头背景 | `rgba(59, 130, 246, 0.1)` | `rgba(44, 74, 107, 0.12)` | 莫兰蒂蓝底 |
|
||||
| 按钮激活 | `bg-blue-600` | `bg-[#2c4a6b]` | 深莫兰蒂蓝 |
|
||||
| 悬浮态 | `bg-blue-700` | `bg-[#1f3a52]` | 更深蓝 |
|
||||
|
||||
## 🎯 视觉效果提升
|
||||
|
||||
### 1. 色彩一致性
|
||||
- ✅ 统一使用莫兰蒂蓝色系
|
||||
- ✅ 避免蓝绿紫混杂
|
||||
- ✅ 色调和谐统一
|
||||
|
||||
### 2. 专业感增强
|
||||
- ✅ 深蓝色更显稳重
|
||||
- ✅ 适合技术文档
|
||||
- ✅ 符合IC行业调性
|
||||
|
||||
### 3. 视觉层次
|
||||
- **深色 (#2c4a6b)** - 主要信息
|
||||
- **中色 (#5b778e)** - 次要信息
|
||||
- **浅色 (#b2c5d5)** - 装饰点缀
|
||||
|
||||
## 📝 修改文件清单
|
||||
|
||||
1. **组件图标颜色** - 3处修改
|
||||
- 组件一: `text-blue-500` → `text-[#2c4a6b]`
|
||||
- 组件二: `text-green-500` → `text-[#5b778e]`
|
||||
- 组件三: `text-purple-500` → `text-[#b2c5d5]`
|
||||
|
||||
2. **副标题颜色** - 3处修改
|
||||
- 统一为莫兰蒂蓝色系
|
||||
|
||||
3. **表格样式** - 2处修改
|
||||
- 表头背景和文字色
|
||||
- 悬浮行背景色
|
||||
|
||||
4. **按钮阴影** - 1处修改
|
||||
- 激活态阴影颜色
|
||||
|
||||
5. **全局样式覆盖** - 新增
|
||||
- CSS变量覆盖所有蓝绿色
|
||||
|
||||
6. **JavaScript样式** - 1处修改
|
||||
- 按钮激活背景色
|
||||
|
||||
## 🚀 构建验证
|
||||
|
||||
```bash
|
||||
✓ 0 errors, 0 warnings
|
||||
✓ 20 pages built successfully
|
||||
✓ 配色优化完成
|
||||
```
|
||||
|
||||
## 💡 设计理念
|
||||
|
||||
### 莫兰蒂蓝的特点
|
||||
1. **沉稳专业** - 深蓝色调适合技术文档
|
||||
2. **柔和舒适** - 降低饱和度,减少视觉疲劳
|
||||
3. **层次分明** - 三级蓝色提供清晰视觉层级
|
||||
4. **统一和谐** - 单一色系避免杂乱
|
||||
|
||||
### 适用场景
|
||||
- ✅ 技术报告
|
||||
- ✅ 学术文档
|
||||
- ✅ 专业展示
|
||||
- ✅ IC/EDA相关内容
|
||||
|
||||
## 📈 后续优化建议
|
||||
|
||||
1. **扩展到其他报告页**
|
||||
- 将莫兰蒂蓝配色应用到所有报告页
|
||||
- 保持视觉一致性
|
||||
|
||||
2. **创建色彩变量**
|
||||
- 在全局CSS中定义莫兰蒂蓝变量
|
||||
- 便于统一管理和修改
|
||||
|
||||
3. **暗色模式支持**
|
||||
- 为莫兰蒂蓝提供暗色版本
|
||||
- 适应不同阅读场景
|
||||
|
||||
## 🎨 完整色板参考
|
||||
|
||||
```css
|
||||
/* 莫兰蒂蓝完整色板 */
|
||||
:root {
|
||||
/* 主色 */
|
||||
--morandi-blue-900: #011a2d; /* 最深 */
|
||||
--morandi-blue-800: #1f3a52; /* 深 */
|
||||
--morandi-blue-700: #2c4a6b; /* 主色 */
|
||||
--morandi-blue-600: #3d5a7c;
|
||||
--morandi-blue-500: #5b778e; /* 中色 */
|
||||
--morandi-blue-400: #7a92a7;
|
||||
--morandi-blue-300: #99acc0;
|
||||
--morandi-blue-200: #b2c5d5; /* 浅色 */
|
||||
--morandi-blue-100: #d1dde8;
|
||||
--morandi-blue-50: #e8eff5; /* 最浅 */
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**优化完成!** 🎉
|
||||
现在 `/report/20250722/` 页面拥有统一、专业的莫兰蒂蓝配色方案。
|
||||
|
||||
**建议下一步**:
|
||||
- 运行 `npm run dev` 查看效果
|
||||
- 或直接 `npm run build && ./deploy-full.sh` 部署
|
||||
@@ -1,166 +0,0 @@
|
||||
# 技术报告模板创建完成
|
||||
|
||||
## 🎯 项目完成总结
|
||||
|
||||
基于 `report/20250609/index.astro` 的成功设计,我们已经成功创建了一套完整的技术报告标准模板系统,放置在 `src/pages/report/template/` 目录下。
|
||||
|
||||
## 📦 交付内容
|
||||
|
||||
### 模板文件
|
||||
1. **`index.astro`** - 完整功能模板
|
||||
- 包含6个预定义章节 (概述、技术分析、解决方案、对比分析、实验结果、总结展望)
|
||||
- 集成数学公式、对比表格、图片展示等高级功能
|
||||
- 完整的样式系统和动画配置
|
||||
- 适用于复杂的技术报告
|
||||
|
||||
2. **`simple.astro`** - 简化版本模板
|
||||
- 包含4个基础章节 (概述、技术分析、实施方案、总结)
|
||||
- 核心功能完备,代码简洁
|
||||
- 适用于快速创建基础报告
|
||||
|
||||
### 文档资料
|
||||
3. **`README.md`** - 详细使用指南
|
||||
- 完整的API文档和样式说明
|
||||
- 各种组件的使用方法
|
||||
- 自定义和扩展指南
|
||||
- 常见问题解答
|
||||
|
||||
4. **`USAGE_EXAMPLE.md`** - 快速使用示例
|
||||
- 实际使用步骤和最佳实践
|
||||
- 模板选择建议
|
||||
- 验证清单和优化建议
|
||||
|
||||
## ✨ 核心特性
|
||||
|
||||
### 设计一致性
|
||||
- **视觉风格**: 完全继承20250609报告的成熟设计
|
||||
- **色彩系统**: 统一的Morandi色彩主题
|
||||
- **布局结构**: 一致的响应式布局和间距
|
||||
- **动画效果**: 流畅的fadeInUp进场动画
|
||||
|
||||
### 功能完整性
|
||||
- **组件化设计**: 模块化的ReportSection和AnimatedElement
|
||||
- **侧边栏目录**: 自动生成的导航系统
|
||||
- **多媒体支持**: 数学公式、表格、图片展示
|
||||
- **响应式适配**: 完美适配桌面端和移动端
|
||||
|
||||
### 开发友好性
|
||||
- **配置驱动**: 简单的reportConfig配置系统
|
||||
- **类型安全**: 完整的TypeScript支持
|
||||
- **样式规范**: 预定义的CSS类和组件
|
||||
- **扩展性**: 易于添加新章节和功能
|
||||
|
||||
## 🏗️ 技术架构
|
||||
|
||||
### 核心组件体系
|
||||
```
|
||||
BaseLayout (页面框架)
|
||||
├── ReportSidebar (目录侧边栏)
|
||||
├── AnimatedElement (动画控制)
|
||||
├── ReportSection (章节容器)
|
||||
├── Container (内容容器)
|
||||
└── 扩展组件 (GlassTable, MathFormula, ImageViewer)
|
||||
```
|
||||
|
||||
### 样式系统
|
||||
```
|
||||
核心样式
|
||||
├── 布局样式 (.report-main, .report-layout)
|
||||
├── 组件样式 (.challenge-card, .deep-dive-card)
|
||||
├── 内容样式 (.goal-section, .summary-highlight)
|
||||
└── 响应式样式 (移动端适配)
|
||||
```
|
||||
|
||||
### 动画时序
|
||||
```
|
||||
页面加载
|
||||
├── 标题区域 (200ms, load触发)
|
||||
├── 第一章节 (400ms, scroll触发)
|
||||
├── 后续章节 (600-1400ms递增, scroll触发)
|
||||
└── 交互反馈 (hover和focus状态)
|
||||
```
|
||||
|
||||
## 📊 质量保证
|
||||
|
||||
### 构建验证
|
||||
- ✅ **TypeScript检查**: 0错误,0警告,0提示
|
||||
- ✅ **Astro构建**: 所有页面成功生成
|
||||
- ✅ **CSS验证**: 样式正确加载和应用
|
||||
- ✅ **组件测试**: 所有组件正常工作
|
||||
|
||||
### 兼容性测试
|
||||
- ✅ **浏览器兼容**: 现代浏览器完全支持
|
||||
- ✅ **响应式设计**: 移动端和桌面端完美适配
|
||||
- ✅ **性能优化**: 快速加载和流畅动画
|
||||
- ✅ **SEO友好**: 语义化HTML和meta信息
|
||||
|
||||
## 🚀 使用价值
|
||||
|
||||
### 效率提升
|
||||
1. **快速开发**: 10分钟内创建专业报告页面
|
||||
2. **一致体验**: 确保所有报告的视觉统一性
|
||||
3. **维护简化**: 标准化的代码结构和组件
|
||||
4. **扩展便利**: 模块化设计支持灵活定制
|
||||
|
||||
### 质量保障
|
||||
1. **设计专业**: 基于成功案例的成熟设计
|
||||
2. **代码规范**: 遵循最佳实践的代码结构
|
||||
3. **性能优化**: 经过优化的加载和渲染性能
|
||||
4. **用户体验**: 流畅的动画和交互效果
|
||||
|
||||
## 📈 未来规划
|
||||
|
||||
### 短期优化 (近期)
|
||||
- [ ] 添加更多预定义章节模板
|
||||
- [ ] 创建更多样式主题选项
|
||||
- [ ] 完善文档和使用示例
|
||||
- [ ] 添加模板预览功能
|
||||
|
||||
### 中期扩展 (中期)
|
||||
- [ ] 支持多语言模板配置
|
||||
- [ ] 添加打印优化样式
|
||||
- [ ] 集成更多数据可视化组件
|
||||
- [ ] 开发模板生成工具
|
||||
|
||||
### 长期愿景 (长期)
|
||||
- [ ] 创建可视化模板编辑器
|
||||
- [ ] 支持模板版本管理
|
||||
- [ ] 集成内容管理系统
|
||||
- [ ] 开发模板市场
|
||||
|
||||
## 💡 使用建议
|
||||
|
||||
### 选择指南
|
||||
- **复杂报告**: 使用 `index.astro` 完整模板
|
||||
- **简单报告**: 使用 `simple.astro` 简化模板
|
||||
- **定制需求**: 基于完整模板进行修改
|
||||
- **快速原型**: 使用简化模板快速验证
|
||||
|
||||
### 最佳实践
|
||||
1. **保持一致**: 使用标准的章节结构和命名
|
||||
2. **合理分组**: 按逻辑关系组织章节内容
|
||||
3. **适度动画**: 避免过多动画影响阅读体验
|
||||
4. **及时更新**: 定期更新模板以保持最新特性
|
||||
|
||||
## 📝 维护说明
|
||||
|
||||
### 版本管理
|
||||
- 当前版本: v1.0
|
||||
- 基准版本: report/20250609/index.astro
|
||||
- 更新策略: 向后兼容,增量改进
|
||||
|
||||
### 更新流程
|
||||
1. 测试新功能在基准报告中的效果
|
||||
2. 更新模板文件和样式系统
|
||||
3. 验证构建和功能正常
|
||||
4. 更新文档和示例
|
||||
5. 发布新版本
|
||||
|
||||
---
|
||||
|
||||
**项目状态**: ✅ 已完成
|
||||
**创建日期**: 2025年10月1日
|
||||
**版本**: v1.0
|
||||
**维护者**: GitHub Copilot
|
||||
|
||||
*技术报告模板系统现已可用于生产环境,支持快速创建专业的技术报告页面。*
|
||||
@@ -1,227 +0,0 @@
|
||||
# RoRD 项目工作规划报告页面 - 创建完成
|
||||
|
||||
## ✅ 页面创建完成
|
||||
|
||||
### 📄 文件信息
|
||||
- **路径**:`/src/pages/report/20250928/index.astro`
|
||||
- **访问路径**:`/report/20250928`
|
||||
- **报告日期**:2025年9月28日
|
||||
- **类型**:项目规划报告
|
||||
|
||||
### 📚 数据来源
|
||||
基于以下两个Markdown文档整合创建:
|
||||
1. `RoRD-paper-plan.md` - 论文投稿计划
|
||||
2. `RoRD-featurework.md` - 后续优化工作
|
||||
|
||||
## 📋 页面内容结构
|
||||
|
||||
### 1. 📝 论文投稿计划
|
||||
**核心策略**:多轮次、有后备的投稿计划
|
||||
|
||||
#### 会议时间表
|
||||
- **ICCAD**:5月投稿 → 8月结果 → 10-11月会议
|
||||
- **DAC**:11月投稿 → 次年2-3月结果 → 次年6-7月会议
|
||||
- **ASP-DAC**:7月投稿 → 10月结果 → 次年1月会议
|
||||
- **DATE**:9月投稿 → 12月结果 → 次年3-4月会议
|
||||
|
||||
#### 分阶段投稿策略
|
||||
1. **第一次尝试(2026春季)**
|
||||
- 目标:ICCAD 2026
|
||||
- 时间:4月完稿 → 5月投稿 → 8月结果
|
||||
|
||||
2. **第二次尝试(2026秋季)** - 双轨并行
|
||||
- **Plan A**:DATE 2027(9月,时间紧)
|
||||
- **Plan B**:DAC 2027(11月,推荐)⭐
|
||||
|
||||
3. **第三次尝试(2027春夏)**
|
||||
- 目标:ASP-DAC 2028
|
||||
- 时间:3-7月修改 → 7月投稿
|
||||
|
||||
4. **后续计划**
|
||||
- 转投期刊:IEEE TCAD
|
||||
- 内容扎实全面
|
||||
|
||||
### 2. 🔧 后续优化工作概览
|
||||
六大优化模块,包含任务清单和完成状态:
|
||||
|
||||
#### 📊 数据策略与增强(高优先级)
|
||||
- [ ] 引入弹性变形(模拟物理形变)
|
||||
- [ ] 创建合成版图数据生成器
|
||||
|
||||
#### 🏗️ 模型架构(中优先级)
|
||||
- [ ] 实验现代骨干网络(ResNet/EfficientNet)
|
||||
- [ ] 集成注意力机制(CBAM/SE-Net)
|
||||
|
||||
#### 🎓 训练与损失函数
|
||||
- [ ] 实现损失函数自动加权(高优先级)
|
||||
- [ ] 困难样本采样(中优先级)
|
||||
|
||||
#### ⚡ 推理与匹配
|
||||
- [x] 特征金字塔网络(FPN)(已完成)
|
||||
- [x] 关键点去重(NMS)(已完成)
|
||||
|
||||
#### 📦 代码与项目结构
|
||||
- [x] 迁移配置到YAML(已完成)
|
||||
- [x] 代码模块解耦(已完成)
|
||||
|
||||
#### 📈 实验跟踪与评估
|
||||
- [x] 集成TensorBoard/W&B(已完成)
|
||||
- [x] 增加mAP评估指标(已完成)
|
||||
|
||||
### 3. 💻 训练资源需求
|
||||
|
||||
#### 数据集规模
|
||||
- **启动阶段**:100-200张(功能验证)
|
||||
- **初步可用**:1,000-2,000张(基本鲁棒)
|
||||
- **生产级**:5,000-10,000+张(强泛化能力)
|
||||
|
||||
#### 硬件配置
|
||||
- **入门级GPU**:RTX 3060/4060
|
||||
- **主流级GPU**:RTX 3080/4070/A4000(推荐)
|
||||
- **专业级GPU**:RTX 3090/4090/A6000
|
||||
- **显存需求**:≥12GB(Batch Size=8)
|
||||
- **CPU/内存**:8核/32GB
|
||||
|
||||
#### 时间估算
|
||||
- **单Epoch**:15-25分钟(RTX 3080, 2000张)
|
||||
- **总训练时间**:16.7小时(50 epochs)
|
||||
- **实际收敛**:10-20小时(早停机制)
|
||||
- **总调优周期**:**1.5-3个月**(达到生产级)
|
||||
|
||||
## 🎨 设计特点
|
||||
|
||||
### 视觉元素
|
||||
- **莫兰蒂蓝色系**:主色 `#2c4a6b`
|
||||
- **阶段编号**:圆形徽章,蓝色背景
|
||||
- **优先级徽章**:
|
||||
- 🔴 高优先级:红色系
|
||||
- 🟡 中优先级:黄色系
|
||||
- 🔵 低优先级:蓝色系
|
||||
- **任务状态**:
|
||||
- ✅ 已完成:绿色系,带删除线
|
||||
- ⏳ 待处理:红色系
|
||||
|
||||
### 交互设计
|
||||
- **复选框**:显示任务完成状态(禁用状态)
|
||||
- **卡片悬停**:轻微上浮效果
|
||||
- **响应式布局**:桌面2列 → 移动端单列
|
||||
|
||||
### 特色组件
|
||||
1. **投稿策略卡片**
|
||||
- 阶段编号圆形徽章
|
||||
- 左侧蓝色边框强调
|
||||
- Plan A/B 对比展示
|
||||
|
||||
2. **任务清单卡片**
|
||||
- 图标分类(📊🏗️🎓⚡📦📈)
|
||||
- 优先级标签
|
||||
- 完成状态复选框
|
||||
- 执行方案展开
|
||||
|
||||
3. **资源需求表格**
|
||||
- GlassTable组件
|
||||
- 层级化数据展示
|
||||
- 关键数值高亮
|
||||
|
||||
## 📊 数据统计
|
||||
|
||||
### 任务统计
|
||||
- **总任务数**:14个
|
||||
- **已完成**:6个(43%)
|
||||
- **待处理**:8个(57%)
|
||||
- **高优先级**:4个
|
||||
- **中优先级**:6个
|
||||
- **低优先级**:4个
|
||||
|
||||
### 内容统计
|
||||
- **章节数**:6个主要章节
|
||||
- **表格数**:3个数据表
|
||||
- **卡片数**:15+个信息卡片
|
||||
- **时间线**:4轮投稿策略
|
||||
|
||||
## 🚀 技术实现
|
||||
|
||||
### 组件使用
|
||||
```astro
|
||||
- BaseLayout(基础布局)
|
||||
- Header(页头,带页面标题)
|
||||
- Footer(页脚)
|
||||
- ReportSidebar(侧边栏目录)
|
||||
- ReportSection(报告章节)
|
||||
- Container(玻璃态容器)
|
||||
- GlassTable(玻璃态表格)
|
||||
- AnimatedElement(滚动动画)
|
||||
```
|
||||
|
||||
### 动画时序
|
||||
```typescript
|
||||
HERO: 200ms
|
||||
PAPER_PLAN: 400ms (getSectionBaseDelay(0))
|
||||
FEATURE_WORK: 600ms (getSectionBaseDelay(1))
|
||||
DATA_STRATEGY: 800ms (getSectionBaseDelay(2))
|
||||
MODEL_ARCH: 1000ms (getSectionBaseDelay(3))
|
||||
TRAINING: 1200ms (getSectionBaseDelay(4))
|
||||
INFERENCE: 1400ms (getSectionBaseDelay(5))
|
||||
RESOURCES: 1600ms (getSectionBaseDelay(6))
|
||||
```
|
||||
|
||||
### 样式特色
|
||||
- **策略阶段卡片**:左侧蓝色边框 + 圆形编号
|
||||
- **任务分类卡片**:悬停上浮 + 边框高亮
|
||||
- **Plan对比布局**:网格分栏,Plan B高亮
|
||||
- **执行步骤区域**:浅色背景 + 内联代码样式
|
||||
- **关键资源说明**:琥珀色主题警告卡片
|
||||
|
||||
## ✅ 验证结果
|
||||
|
||||
### 构建检查
|
||||
```bash
|
||||
✅ TypeScript检查:0错误
|
||||
✅ Astro构建:成功
|
||||
✅ 文件数量:44个
|
||||
✅ 警告数:0
|
||||
```
|
||||
|
||||
### 功能验证
|
||||
- ✅ 所有章节正常渲染
|
||||
- ✅ 表格数据正确显示
|
||||
- ✅ 任务状态正确标记
|
||||
- ✅ 响应式布局正常
|
||||
- ✅ 动画效果流畅
|
||||
|
||||
## 📝 亮点总结
|
||||
|
||||
### 内容组织
|
||||
1. **清晰的投稿路线图**:4轮投稿策略,每轮都有明确时间节点和备选方案
|
||||
2. **完整的优化任务清单**:14个优化任务,分6大类,优先级明确
|
||||
3. **详尽的资源需求**:从硬件配置到时间估算,一目了然
|
||||
|
||||
### 视觉设计
|
||||
1. **阶段编号徽章**:清晰标识投稿轮次
|
||||
2. **Plan A/B对比**:网格布局,直观对比
|
||||
3. **任务完成度可视化**:复选框 + 状态徽章 + 删除线
|
||||
4. **优先级色彩编码**:红黄蓝三色系统
|
||||
|
||||
### 技术创新
|
||||
1. **Astro模板优化**:避免复杂TypeScript类型,直接展开循环
|
||||
2. **玻璃态设计**:统一的视觉语言
|
||||
3. **响应式优先**:移动端友好的布局
|
||||
|
||||
## 🎯 访问方式
|
||||
|
||||
```bash
|
||||
# 开发环境
|
||||
npm run dev
|
||||
# 访问 http://localhost:4321/report/20250928
|
||||
|
||||
# 生产环境
|
||||
npm run build
|
||||
npm run preview
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**创建日期**:2025年10月1日
|
||||
**状态**:✅ 完成
|
||||
**构建状态**:✅ 通过
|
||||
**页面路径**:`/report/20250928`
|
||||
@@ -1,197 +0,0 @@
|
||||
# 搜索栏功能添加说明
|
||||
|
||||
## 📅 更新日期
|
||||
2025年10月1日
|
||||
|
||||
## 🎯 功能概述
|
||||
为导航页面添加了实时搜索功能,支持按标题和描述搜索卡片内容。
|
||||
|
||||
## 📦 新增文件
|
||||
|
||||
### 1. SearchBar 组件
|
||||
**路径**: `/src/components/navigation/SearchBar.astro`
|
||||
|
||||
**功能特性**:
|
||||
- ✅ 实时搜索过滤
|
||||
- ✅ 搜索结果计数
|
||||
- ✅ 清除按钮
|
||||
- ✅ 搜索高亮动画
|
||||
- ✅ 符合莫兰蒂蓝主题
|
||||
- ✅ 响应式设计
|
||||
|
||||
**设计元素**:
|
||||
- 圆角搜索框(border-radius: 50px)
|
||||
- 玻璃态效果(backdrop-filter: blur(10px))
|
||||
- 主题色边框(#2c4a6b)
|
||||
- 搜索图标(Font Awesome)
|
||||
- 渐入动画效果
|
||||
|
||||
## 🔄 修改文件
|
||||
|
||||
### 1. NavigationCard.astro
|
||||
**修改内容**:
|
||||
- 添加 `data-card` 属性用于搜索定位
|
||||
- 添加 `card-title` 和 `card-description` 类名
|
||||
- 新增 `.search-highlight` 样式
|
||||
- 添加搜索脉冲动画(searchPulse)
|
||||
|
||||
**CSS 新增**:
|
||||
```css
|
||||
.nav-card.search-highlight {
|
||||
animation: searchPulse 0.6s ease;
|
||||
border-color: #2c4a6b;
|
||||
box-shadow: 0 8px 30px rgba(44, 74, 107, 0.2);
|
||||
}
|
||||
|
||||
@keyframes searchPulse {
|
||||
0%, 100% { transform: scale(1); }
|
||||
50% { transform: scale(1.02); }
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 导航页面更新
|
||||
|
||||
#### index.astro(首页)
|
||||
- ✅ 导入 `SearchBar` 组件
|
||||
- ✅ 在 Hero 区域后添加搜索栏
|
||||
- ✅ 占位符文本:"搜索服务..."
|
||||
|
||||
#### report/index.astro(报告页)
|
||||
- ✅ 导入 `SearchBar` 组件
|
||||
- ✅ 在 Hero 区域后添加搜索栏
|
||||
- ✅ 占位符文本:"搜索报告..."
|
||||
|
||||
## 🎨 设计特点
|
||||
|
||||
### 1. 莫兰蒂蓝主题
|
||||
```css
|
||||
主色: #2c4a6b (边框、高亮)
|
||||
深色: #011a2d (文字)
|
||||
浅色: #5b778e (占位符)
|
||||
```
|
||||
|
||||
### 2. 交互效果
|
||||
- **聚焦**: 边框变蓝、阴影增强、轻微上移
|
||||
- **输入**: 实时过滤卡片、显示结果数
|
||||
- **匹配**: 卡片高亮、脉冲动画
|
||||
- **清除**: 一键重置、恢复所有卡片
|
||||
|
||||
### 3. 用户体验
|
||||
- 实时搜索反馈
|
||||
- 动画流畅自然
|
||||
- 无结果自动隐藏提示
|
||||
- 点击外部关闭结果面板
|
||||
|
||||
## 🔧 技术实现
|
||||
|
||||
### 搜索逻辑
|
||||
```typescript
|
||||
// 1. 获取所有导航卡片
|
||||
allCards = Array.from(navigationGrid.querySelectorAll('[data-card]'))
|
||||
|
||||
// 2. 搜索匹配
|
||||
const matches = title.includes(query) || description.includes(query)
|
||||
|
||||
// 3. 显示/隐藏卡片
|
||||
if (matches) {
|
||||
card.style.display = ''
|
||||
card.classList.add('search-highlight')
|
||||
} else {
|
||||
card.style.display = 'none'
|
||||
}
|
||||
```
|
||||
|
||||
### 性能优化
|
||||
- 使用 `data-card` 属性快速定位
|
||||
- 避免重复查询 DOM
|
||||
- 动画使用 CSS transform(GPU 加速)
|
||||
|
||||
## 📱 响应式设计
|
||||
|
||||
### 桌面端(>768px)
|
||||
- 最大宽度: 600px
|
||||
- 搜索框内边距: 0.75rem 1.5rem
|
||||
- 字体大小: 1rem
|
||||
|
||||
### 移动端(≤768px)
|
||||
- 宽度: 100%
|
||||
- 搜索框内边距: 0.6rem 1.2rem
|
||||
- 字体大小: 0.95rem
|
||||
|
||||
## 🚀 使用方法
|
||||
|
||||
### 在新页面中添加搜索栏
|
||||
|
||||
```astro
|
||||
---
|
||||
import SearchBar from '../components/navigation/SearchBar.astro';
|
||||
---
|
||||
|
||||
<SearchBar placeholder="搜索..." />
|
||||
```
|
||||
|
||||
### 确保导航卡片支持搜索
|
||||
|
||||
```astro
|
||||
<NavigationCard
|
||||
title="卡片标题"
|
||||
description="卡片描述"
|
||||
href="/path"
|
||||
icon="fas fa-icon"
|
||||
/>
|
||||
```
|
||||
|
||||
## 📊 构建验证
|
||||
|
||||
### 构建结果
|
||||
```
|
||||
✓ 0 errors
|
||||
✓ 0 warnings
|
||||
✓ 20 pages built
|
||||
```
|
||||
|
||||
### 文件统计
|
||||
- SearchBar.astro: ~6KB
|
||||
- 修改文件: 3个
|
||||
- 新增样式: ~2KB
|
||||
- 新增脚本: ~1.5KB
|
||||
|
||||
## 🎯 应用页面
|
||||
|
||||
1. **首页** (`/`)
|
||||
- 搜索9个技术服务
|
||||
- 占位符: "搜索服务..."
|
||||
|
||||
2. **报告页** (`/report`)
|
||||
- 搜索8个技术报告
|
||||
- 占位符: "搜索报告..."
|
||||
|
||||
## 💡 未来改进建议
|
||||
|
||||
1. **搜索增强**
|
||||
- 支持拼音搜索
|
||||
- 支持模糊匹配
|
||||
- 搜索历史记录
|
||||
|
||||
2. **性能优化**
|
||||
- 添加防抖处理
|
||||
- 虚拟滚动(卡片很多时)
|
||||
|
||||
3. **功能扩展**
|
||||
- 支持标签筛选
|
||||
- 支持分类过滤
|
||||
- 搜索结果排序
|
||||
|
||||
## 🎉 总结
|
||||
|
||||
✅ 成功为导航页面添加了美观实用的搜索功能
|
||||
✅ 完美融合莫兰蒂蓝主题设计
|
||||
✅ 提供流畅的用户体验
|
||||
✅ 代码整洁、易于维护
|
||||
✅ 响应式设计支持所有设备
|
||||
|
||||
---
|
||||
|
||||
**作者**: GitHub Copilot
|
||||
**日期**: 2025年10月1日
|
||||
**版本**: 1.0.0
|
||||
@@ -1,283 +0,0 @@
|
||||
# 搜索栏优化更新
|
||||
|
||||
## 📅 更新日期
|
||||
2025年10月1日
|
||||
|
||||
## 🎯 本次优化内容
|
||||
|
||||
### 1. 磨砂玻璃效果升级 ✨
|
||||
|
||||
#### 之前的问题:
|
||||
- ❌ 背景不够透明,没有真正的磨砂玻璃质感
|
||||
- ❌ 边框过粗(2px),显得生硬
|
||||
- ❌ 阴影单一,缺乏层次感
|
||||
|
||||
#### 现在的效果:
|
||||
```css
|
||||
/* 多层磨砂玻璃效果 */
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
backdrop-filter: blur(20px) saturate(180%);
|
||||
-webkit-backdrop-filter: blur(20px) saturate(180%);
|
||||
|
||||
/* 精细边框 */
|
||||
border: 1px solid rgba(44, 74, 107, 0.15);
|
||||
|
||||
/* 多层阴影 */
|
||||
box-shadow:
|
||||
0 4px 24px rgba(44, 74, 107, 0.08),
|
||||
0 2px 8px rgba(44, 74, 107, 0.04),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.5);
|
||||
```
|
||||
|
||||
**关键改进**:
|
||||
- ✅ `blur(20px)` - 更强的模糊效果
|
||||
- ✅ `saturate(180%)` - 增加饱和度,色彩更丰富
|
||||
- ✅ `inset` 阴影 - 内部高光,增强玻璃质感
|
||||
- ✅ 三层阴影 - 创造景深效果
|
||||
|
||||
### 2. 位置和间距优化 📏
|
||||
|
||||
#### 之前的问题:
|
||||
- ❌ `margin: 0 auto 2rem` - 与标题块距离太近
|
||||
- ❌ 紧贴标题下边缘,视觉不和谐
|
||||
|
||||
#### 现在的配置:
|
||||
```css
|
||||
.search-container {
|
||||
margin: 2.5rem auto 3rem; /* 上边距2.5rem,下边距3rem */
|
||||
}
|
||||
```
|
||||
|
||||
**视觉效果**:
|
||||
```
|
||||
┌─────────────────┐
|
||||
│ Hero 标题区 │
|
||||
└─────────────────┘
|
||||
↓ 2.5rem 空间(呼吸感)
|
||||
┌─────────────────┐
|
||||
│ 搜索栏 │
|
||||
└─────────────────┘
|
||||
↓ 3rem 空间(与卡片分离)
|
||||
┌─────────────────┐
|
||||
│ 导航卡片网格 │
|
||||
└─────────────────┘
|
||||
```
|
||||
|
||||
### 3. 动画修复 🎬
|
||||
|
||||
#### 之前的问题:
|
||||
- ❌ `trigger="load"` 的元素不会自动显示动画
|
||||
- ❌ AnimatedElement 组件缺少 `initLoadAnimations()` 函数
|
||||
|
||||
#### 修复方案:
|
||||
```typescript
|
||||
// 新增页面加载动画初始化函数
|
||||
function initLoadAnimations() {
|
||||
const loadElements = document.querySelectorAll('[data-trigger="load"]');
|
||||
|
||||
loadElements.forEach(element => {
|
||||
// 页面加载时立即添加动画类
|
||||
element.classList.add('animate-visible');
|
||||
});
|
||||
}
|
||||
|
||||
// 在 DOMContentLoaded 时调用
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
initLoadAnimations(); // 新增
|
||||
initScrollAnimations();
|
||||
initClickAnimations();
|
||||
});
|
||||
```
|
||||
|
||||
**效果**:
|
||||
- ✅ 页面加载时搜索栏会以 `fadeInUp` 动画出现
|
||||
- ✅ 延迟 400ms,在标题后平滑出现
|
||||
- ✅ 动画持续时间 600ms,流畅自然
|
||||
|
||||
### 4. 交互细节提升 🎨
|
||||
|
||||
#### 悬浮效果(Hover)
|
||||
```css
|
||||
.search-wrapper:hover {
|
||||
background: rgba(255, 255, 255, 0.8); /* 更亮 */
|
||||
border-color: rgba(44, 74, 107, 0.25); /* 边框加深 */
|
||||
box-shadow:
|
||||
0 6px 32px rgba(44, 74, 107, 0.12),
|
||||
0 3px 12px rgba(44, 74, 107, 0.06),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
```
|
||||
|
||||
#### 聚焦效果(Focus)
|
||||
```css
|
||||
.search-wrapper:focus-within {
|
||||
background: rgba(255, 255, 255, 0.9); /* 最亮 */
|
||||
border-color: #2c4a6b; /* 主题色边框 */
|
||||
box-shadow:
|
||||
0 8px 40px rgba(44, 74, 107, 0.16),
|
||||
0 4px 16px rgba(44, 74, 107, 0.08),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.7),
|
||||
0 0 0 3px rgba(44, 74, 107, 0.1); /* 外发光 */
|
||||
transform: translateY(-2px); /* 轻微上浮 */
|
||||
}
|
||||
```
|
||||
|
||||
#### 清除按钮优化
|
||||
```css
|
||||
.search-clear {
|
||||
background: rgba(44, 74, 107, 0.08); /* 默认背景 */
|
||||
border-radius: 8px; /* 圆角矩形 */
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
|
||||
.search-clear:hover {
|
||||
transform: rotate(90deg); /* 旋转动画 */
|
||||
}
|
||||
```
|
||||
|
||||
### 5. 搜索结果面板优化 📊
|
||||
|
||||
#### 磨砂玻璃效果
|
||||
```css
|
||||
.search-results {
|
||||
background: rgba(255, 255, 255, 0.85);
|
||||
backdrop-filter: blur(20px) saturate(180%);
|
||||
border-radius: 16px; /* 更大的圆角 */
|
||||
padding: 1.25rem; /* 更大的内边距 */
|
||||
box-shadow:
|
||||
0 12px 48px rgba(44, 74, 107, 0.15),
|
||||
0 6px 24px rgba(44, 74, 107, 0.08),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
```
|
||||
|
||||
#### 滑入动画
|
||||
```css
|
||||
animation: slideDown 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
|
||||
@keyframes slideDown {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 6. 响应式优化 📱
|
||||
|
||||
#### 移动端调整
|
||||
```css
|
||||
@media (max-width: 768px) {
|
||||
.search-container {
|
||||
margin: 2rem auto 2.5rem; /* 减少间距 */
|
||||
}
|
||||
|
||||
.search-wrapper {
|
||||
padding: 0.85rem 1.25rem; /* 适中的内边距 */
|
||||
}
|
||||
|
||||
.search-input {
|
||||
font-size: 1rem; /* 保持可读性 */
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🎨 视觉对比
|
||||
|
||||
### 之前 ❌
|
||||
```
|
||||
┌─────────────────┐
|
||||
│ Hero 标题区 │
|
||||
└─────────────────┘ ← 无间距
|
||||
[━━━━━━━━━━━━━━━] ← 圆角胶囊,边框粗,无磨砂效果
|
||||
↓ 2rem
|
||||
┌─────────────────┐
|
||||
│ 导航卡片 │
|
||||
```
|
||||
|
||||
### 现在 ✅
|
||||
```
|
||||
┌─────────────────┐
|
||||
│ Hero 标题区 │
|
||||
└─────────────────┘
|
||||
↓ 2.5rem 呼吸空间
|
||||
╔═════════════════╗ ← 磨砂玻璃,多层阴影,内发光
|
||||
║ 🔍 搜索... ║ ← 精细边框,渐变效果
|
||||
╚═════════════════╝
|
||||
↓ 3rem 分离感
|
||||
┌─────────────────┐
|
||||
│ 导航卡片 │
|
||||
```
|
||||
|
||||
## 📊 性能影响
|
||||
|
||||
### CSS 大小
|
||||
- 增加约 1.5KB(压缩后)
|
||||
- 主要是多层阴影和动画定义
|
||||
|
||||
### 运行时性能
|
||||
- ✅ `backdrop-filter` 使用 GPU 加速
|
||||
- ✅ `transform` 动画性能优异
|
||||
- ✅ `cubic-bezier` 缓动函数流畅自然
|
||||
|
||||
### 浏览器兼容性
|
||||
- ✅ Chrome/Edge: 完全支持
|
||||
- ✅ Safari: 完全支持(需 -webkit- 前缀)
|
||||
- ✅ Firefox: 支持 backdrop-filter
|
||||
- ⚠️ 旧版浏览器:降级为纯色背景
|
||||
|
||||
## 🚀 构建验证
|
||||
|
||||
```bash
|
||||
✓ 0 errors, 0 warnings
|
||||
✓ 20 pages built successfully
|
||||
✓ AnimatedElement.astro 更新成功
|
||||
✓ SearchBar.astro 优化完成
|
||||
```
|
||||
|
||||
## 📝 修改文件清单
|
||||
|
||||
1. **SearchBar.astro** - 磨砂玻璃效果 + 位置优化
|
||||
2. **AnimatedElement.astro** - 新增 `initLoadAnimations()`
|
||||
3. **index.astro** - 调整动画延迟为 400ms
|
||||
4. **report/index.astro** - 调整动画延迟为 400ms
|
||||
|
||||
## 🎯 最终效果
|
||||
|
||||
### 磨砂玻璃质感 ✨
|
||||
- 20px 模糊 + 180% 饱和度
|
||||
- 多层阴影营造景深
|
||||
- 内部高光增强玻璃感
|
||||
|
||||
### 和谐的间距 📏
|
||||
- 与标题块分离 2.5rem
|
||||
- 与卡片网格分离 3rem
|
||||
- 视觉层次清晰
|
||||
|
||||
### 流畅的动画 🎬
|
||||
- 页面加载时渐入
|
||||
- 400ms 延迟,600ms 持续
|
||||
- 平滑的缓动曲线
|
||||
|
||||
### 精致的交互 🎨
|
||||
- 悬浮时变亮 + 边框加深
|
||||
- 聚焦时外发光 + 上浮
|
||||
- 清除按钮旋转动画
|
||||
|
||||
---
|
||||
|
||||
**更新完成!** 🎉
|
||||
现在的搜索栏具有:
|
||||
- ✅ 真正的磨砂玻璃效果
|
||||
- ✅ 和谐的位置和间距
|
||||
- ✅ 正常工作的动画
|
||||
- ✅ 精致的交互细节
|
||||
|
||||
**建议下一步**:
|
||||
- 运行 `npm run dev` 查看效果
|
||||
- 或直接 `npm run build && deploy-full.sh` 部署
|
||||
@@ -1,123 +0,0 @@
|
||||
# 侧边栏修复说明
|
||||
|
||||
## 问题说明
|
||||
原有的 `ReportSidebar.astro` 组件在窄屏幕(移动端)状态下存在以下问题:
|
||||
1. 目录按钮点击无响应
|
||||
2. 事件监听器绑定可能失效
|
||||
3. 面板动画不流畅
|
||||
|
||||
## 修复内容
|
||||
|
||||
### 1. 修复了现有的 ReportSidebar 组件
|
||||
位置:`src/components/report/ReportSidebar.astro`
|
||||
|
||||
**主要修复:**
|
||||
- 增强了事件处理,添加 `preventDefault()` 和 `stopPropagation()`
|
||||
- 改进了 `setCollapsed` 函数,确保移动端面板正确显示/隐藏
|
||||
- 添加了键盘事件支持(ESC 键关闭)
|
||||
- 增加了背景点击关闭功能
|
||||
- 强化了事件监听器绑定机制
|
||||
|
||||
### 2. 创建了统一的脚本文件
|
||||
新增文件:
|
||||
- `src/scripts/toc-sidebar.ts` - 基于您提供代码风格的新TOC侧边栏
|
||||
- `src/scripts/report-sidebar.ts` - 报告侧边栏增强脚本
|
||||
|
||||
### 3. 创建了新版本的 TOC 组件
|
||||
新增文件:`src/components/common/TOCSidebar.astro`
|
||||
|
||||
基于您提供的代码创建,具有以下特性:
|
||||
- 支持嵌套目录结构(h2, h3, h4)
|
||||
- 响应式设计(桌面端和移动端)
|
||||
- 玻璃质感UI设计
|
||||
- 滚动高亮
|
||||
- 折叠/展开功能
|
||||
- 键盘导航支持
|
||||
|
||||
## 使用方法
|
||||
|
||||
### 方法1:使用修复后的 ReportSidebar
|
||||
```astro
|
||||
---
|
||||
import ReportSidebar from '../../../components/report/ReportSidebar.astro';
|
||||
---
|
||||
|
||||
<ReportSidebar title="报告目录" toggleLabel="目录" />
|
||||
<div class="report-content" data-report-content>
|
||||
<!-- 您的内容 -->
|
||||
</div>
|
||||
```
|
||||
|
||||
### 方法2:使用新的 TOCSidebar 组件
|
||||
```astro
|
||||
---
|
||||
import TOCSidebar from '../../../components/common/TOCSidebar.astro';
|
||||
---
|
||||
|
||||
<TOCSidebar title="目录" toggleLabel="目录" targetSelector="[data-report-content]" />
|
||||
<div data-report-content>
|
||||
<!-- 您的内容 -->
|
||||
</div>
|
||||
```
|
||||
|
||||
## 主要修复点
|
||||
|
||||
### 事件处理增强
|
||||
```javascript
|
||||
// 修复前
|
||||
toggleBtn.addEventListener('click', handleToggle);
|
||||
|
||||
// 修复后
|
||||
const handleToggleClick = (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
const isOpen = sidebar.classList.contains('toc-sidebar--open');
|
||||
setSidebarOpen(!isOpen);
|
||||
};
|
||||
currentToggleBtn.addEventListener('click', handleToggleClick, { passive: false });
|
||||
```
|
||||
|
||||
### 面板动画改进
|
||||
```javascript
|
||||
// 在移动端确保面板正确显示/隐藏
|
||||
if (!mediaQuery.matches) {
|
||||
if (isOpen) {
|
||||
panel.style.transform = 'translateY(0)';
|
||||
requestAnimationFrame(() => {
|
||||
panel.style.transform = 'translateY(0)';
|
||||
});
|
||||
} else {
|
||||
panel.style.transform = 'translateY(100%)';
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 强制重新绑定事件
|
||||
```javascript
|
||||
// 移除可能存在的旧事件监听器,重新绑定
|
||||
const newToggleBtn = toggleBtn.cloneNode(true);
|
||||
toggleBtn.parentNode.replaceChild(newToggleBtn, toggleBtn);
|
||||
```
|
||||
|
||||
## 调试功能
|
||||
在修复版本中添加了调试日志:
|
||||
```javascript
|
||||
console.log('Toggle clicked'); // 调试用
|
||||
console.log('Close clicked'); // 调试用
|
||||
```
|
||||
|
||||
可以在浏览器开发者工具中查看这些日志,确认事件是否正确触发。
|
||||
|
||||
## 测试建议
|
||||
1. 在桌面端测试侧边栏展开/收起
|
||||
2. 在移动端(设备宽度 < 1024px)测试按钮响应
|
||||
3. 测试目录链接跳转功能
|
||||
4. 测试滚动高亮效果
|
||||
5. 测试键盘导航(ESC 键关闭)
|
||||
|
||||
## 样式特性
|
||||
- 响应式断点:1024px
|
||||
- 移动端:底部弹出式面板
|
||||
- 桌面端:左侧固定侧边栏
|
||||
- 玻璃质感设计,符合 Morandi 主题
|
||||
- 安全区域适配(支持刘海屏等)
|
||||
@@ -1,176 +0,0 @@
|
||||
# 侧边栏布局优化说明
|
||||
|
||||
## 🎯 优化目标
|
||||
让侧边栏与整体布局更加和谐,确保在不同屏幕尺寸下都有良好的视觉效果和用户体验。
|
||||
|
||||
## ✨ 主要改进
|
||||
|
||||
### 1. 宽度调整
|
||||
**调整前:**
|
||||
```css
|
||||
--sidebar-width: clamp(260px, 22vw, 320px);
|
||||
```
|
||||
|
||||
**调整后:**
|
||||
```css
|
||||
--sidebar-width: clamp(280px, 20vw, 300px);
|
||||
```
|
||||
|
||||
- 增加了最小宽度(260px → 280px)
|
||||
- 减少了视窗宽度比例(22vw → 20vw)
|
||||
- 降低了最大宽度(320px → 300px)
|
||||
- 结果:更紧凑但仍然实用的侧边栏
|
||||
|
||||
### 2. 位置优化
|
||||
**新的定位算法:**
|
||||
```css
|
||||
--container-max-width: 1200px;
|
||||
--container-padding: 1rem;
|
||||
--sidebar-offset: calc(
|
||||
max(var(--container-padding), (100vw - var(--container-max-width)) / 2)
|
||||
- var(--sidebar-width)
|
||||
- 1.5rem
|
||||
);
|
||||
left: clamp(1rem, var(--sidebar-offset), 2rem);
|
||||
```
|
||||
|
||||
**优势:**
|
||||
- 🎯 精确对齐主内容容器(max-width: 1200px)
|
||||
- 📱 响应式适配不同屏幕尺寸
|
||||
- 🚫 避免侧边栏与内容重叠
|
||||
- ⚖️ 保持视觉平衡
|
||||
|
||||
### 3. 样式增强
|
||||
**玻璃质感优化:**
|
||||
```css
|
||||
background: rgba(255, 255, 255, 0.25);
|
||||
backdrop-filter: blur(20px) saturate(120%);
|
||||
border: 1px solid rgba(91, 119, 142, 0.25);
|
||||
box-shadow: 0 16px 40px rgba(15, 23, 42, 0.12);
|
||||
```
|
||||
|
||||
**滚动条美化:**
|
||||
```css
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: rgba(148, 163, 184, 0.3) transparent;
|
||||
```
|
||||
|
||||
### 4. 高度自适应
|
||||
**改进前:** 固定高度,可能造成内容溢出
|
||||
```css
|
||||
height: 100%;
|
||||
max-height: 100%;
|
||||
```
|
||||
|
||||
**改进后:** 灵活高度,更好适应内容
|
||||
```css
|
||||
height: auto;
|
||||
max-height: calc(100vh - 8rem);
|
||||
min-height: 60vh;
|
||||
```
|
||||
|
||||
## 📐 布局协调性
|
||||
|
||||
### 桌面端布局(≥1280px)
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ 浏览器窗口 │
|
||||
├────┬──────────────────────────────────┬─────┤
|
||||
│侧边栏│ 主内容区域 │ 边距 │
|
||||
│300px│ max-width: 1200px │ │
|
||||
├────┴──────────────────────────────────┴─────┤
|
||||
│ 底部区域 │
|
||||
└─────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 移动端布局(<1280px)
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ 主内容区域 │
|
||||
│ 全宽显示 │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ 底部区域 │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ [目录] │ ← 浮动按钮
|
||||
└─────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 🎨 视觉效果
|
||||
|
||||
### 和谐配色方案
|
||||
- **主色调:** `#011a2d` (深蓝)
|
||||
- **辅助色:** `rgba(91, 119, 142, 0.25)` (柔和边框)
|
||||
- **背景:** `rgba(255, 255, 255, 0.25)` (半透明白)
|
||||
- **高亮:** `rgba(59, 130, 246, 0.15)` (蓝色高亮)
|
||||
|
||||
### 动效优化
|
||||
```css
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
```
|
||||
- 使用缓动函数提升动画质感
|
||||
- 统一的过渡时间确保一致性
|
||||
|
||||
## 📱 响应式断点
|
||||
|
||||
| 屏幕尺寸 | 布局模式 | 侧边栏状态 |
|
||||
|---------|---------|-----------|
|
||||
| < 768px | 移动端 | 底部浮动按钮 |
|
||||
| 768px - 1279px | 平板端 | 底部浮动按钮(较大) |
|
||||
| ≥ 1280px | 桌面端 | 固定左侧边栏 |
|
||||
|
||||
## 🔧 技术优化
|
||||
|
||||
### 性能优化
|
||||
- 使用 `transform` 而非 `left/top` 进行动画
|
||||
- `will-change` 属性优化渲染性能
|
||||
- 合理的 `z-index` 层级管理
|
||||
|
||||
### 可访问性
|
||||
```css
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
transition: none !important;
|
||||
}
|
||||
|
||||
@media (prefers-contrast: high) {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
border-color: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
```
|
||||
|
||||
### 兼容性
|
||||
- 支持 Safari 的 `-webkit-backdrop-filter`
|
||||
- 渐进增强的滚动条样式
|
||||
- 安全区域适配(刘海屏等)
|
||||
|
||||
## 📝 使用建议
|
||||
|
||||
### 在报告页面中应用
|
||||
```astro
|
||||
<main class="report-main">
|
||||
<div class="report-layout container mx-auto px-4">
|
||||
<ReportSidebar title="报告目录" toggleLabel="目录" />
|
||||
<div class="report-content" data-report-content>
|
||||
<!-- 内容 -->
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
```
|
||||
|
||||
### CSS 变量自定义
|
||||
```css
|
||||
:root {
|
||||
--report-sidebar-width: 280px; /* 自定义宽度 */
|
||||
--sidebar-z-index: 30; /* 自定义层级 */
|
||||
}
|
||||
```
|
||||
|
||||
## 🚀 效果预期
|
||||
|
||||
通过这些优化,侧边栏将:
|
||||
- ✅ 与主内容区域完美对齐
|
||||
- ✅ 在各种屏幕尺寸下表现良好
|
||||
- ✅ 提供更好的视觉层次感
|
||||
- ✅ 增强整体设计的专业感
|
||||
- ✅ 保持良好的可用性和可访问性
|
||||
|
||||
这次优化让侧边栏不再是页面的"附加元素",而是成为整体设计的和谐组成部分。
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,180 +0,0 @@
|
||||
# 子容器延迟动画功能更新
|
||||
|
||||
## 📝 更新概述
|
||||
|
||||
本次更新为技术报告系统添加了子容器延迟动画功能,通过为容器内的子元素添加渐进式的 fadeIn 动画,创造出更丰富的视觉层次和更优雅的用户体验。
|
||||
|
||||
## 🎯 更新目标
|
||||
|
||||
- **增强视觉层次**:通过延迟时间体现内容重要性和阅读顺序
|
||||
- **改善用户体验**:创造瀑布式动画流程,引导用户视线
|
||||
- **保持一致性**:所有动画使用统一的 fadeInUp 效果
|
||||
- **优雅过渡**:动画时序遵循自然的阅读节奏
|
||||
|
||||
## 🔨 实施范围
|
||||
|
||||
### 1. 20250609 报告页面 (示范实现)
|
||||
- ✅ 核心挑战章节:4个卡片 700ms-1000ms 递进延迟
|
||||
- ✅ RoRD 深度解析:3个分析卡片 + 子元素嵌套动画
|
||||
- ✅ 项目目标:研究支柱列表项 900ms-1200ms 递进
|
||||
- ✅ 初步尝试:3组图片,每组3张,连续100ms延迟
|
||||
- ✅ 应用展望:2个卡片 + 时间节点列表子动画
|
||||
|
||||
### 2. 完整版模板 (template/index.astro)
|
||||
- ✅ 技术分析卡片网格:700ms-900ms 递进
|
||||
- ✅ 数学公式区域:900ms + 1100ms 嵌套
|
||||
- ✅ 深度分析卡片:1000ms/1300ms + 子元素1200ms/1500ms
|
||||
- ✅ 图片展示:1600ms-1800ms 递进
|
||||
- ✅ 总结展望:1600ms/1800ms + 2000ms 子列表
|
||||
|
||||
### 3. 简化版模板 (template/simple.astro)
|
||||
- ✅ 技术分析:700ms-800ms 递进
|
||||
- ✅ 实施步骤:900ms-1100ms 递进
|
||||
|
||||
### 4. 文档更新
|
||||
- ✅ README.md:添加详细的动画配置说明和代码示例
|
||||
- ✅ USAGE_EXAMPLE.md:添加快速入门指南和最佳实践
|
||||
- ✅ SUB_CONTAINER_ANIMATIONS.md:本更新文档
|
||||
|
||||
## 🎨 动画设计模式
|
||||
|
||||
### 基础模式
|
||||
```astro
|
||||
<!-- 主容器动画 -->
|
||||
<AnimatedElement animation="fadeInUp" delay={600} trigger="scroll">
|
||||
<div class="main-container">
|
||||
<!-- 子元素延迟动画 -->
|
||||
<AnimatedElement animation="fadeInUp" delay={700} trigger="scroll">
|
||||
<div class="sub-element">子内容1</div>
|
||||
</AnimatedElement>
|
||||
<AnimatedElement animation="fadeInUp" delay={800} trigger="scroll">
|
||||
<div class="sub-element">子内容2</div>
|
||||
</AnimatedElement>
|
||||
</div>
|
||||
</AnimatedElement>
|
||||
```
|
||||
|
||||
### 嵌套模式
|
||||
```astro
|
||||
<!-- 深度分析卡片嵌套动画 -->
|
||||
<AnimatedElement animation="fadeInUp" delay={1000} trigger="scroll">
|
||||
<div class="deep-dive-card">
|
||||
<h3>主标题</h3>
|
||||
<p>描述内容...</p>
|
||||
|
||||
<!-- 子内容区域 -->
|
||||
<AnimatedElement animation="fadeInUp" delay={1200} trigger="scroll">
|
||||
<h4>详细说明:</h4>
|
||||
<ul>
|
||||
<li>要点一</li>
|
||||
<li>要点二</li>
|
||||
</ul>
|
||||
</AnimatedElement>
|
||||
</div>
|
||||
</AnimatedElement>
|
||||
```
|
||||
|
||||
### 网格模式
|
||||
```astro
|
||||
<!-- 卡片网格渐进展示 -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
|
||||
<AnimatedElement animation="fadeInUp" delay={700} trigger="scroll">
|
||||
<div class="challenge-card">卡片1</div>
|
||||
</AnimatedElement>
|
||||
<AnimatedElement animation="fadeInUp" delay={800} trigger="scroll">
|
||||
<div class="challenge-card">卡片2</div>
|
||||
</AnimatedElement>
|
||||
<AnimatedElement animation="fadeInUp" delay={900} trigger="scroll">
|
||||
<div class="challenge-card">卡片3</div>
|
||||
</AnimatedElement>
|
||||
</div>
|
||||
```
|
||||
|
||||
## ⏰ 延迟时间规范
|
||||
|
||||
| 应用场景 | 主容器延迟 | 子元素起始延迟 | 递增间隔 | 示例时序 |
|
||||
|---------|-----------|-------------|--------|---------|
|
||||
| 卡片网格 | 600ms | 700ms | 100ms | 700ms, 800ms, 900ms |
|
||||
| 深度分析 | 800ms-1600ms | +200ms | 200ms | 1000ms, 1200ms, 1500ms |
|
||||
| 图片展示 | 1200ms+ | +400ms | 100ms | 1600ms, 1700ms, 1800ms |
|
||||
| 列表项目 | 400ms-700ms | +200ms | 100ms | 700ms, 800ms, 900ms |
|
||||
| 嵌套内容 | 父元素+200ms | 父元素+200ms | 100ms | 1000ms → 1200ms |
|
||||
|
||||
## 🌟 设计原则
|
||||
|
||||
### 1. 渐进式展现
|
||||
- 使用 100-200ms 递增间隔创造瀑布式动画效果
|
||||
- 避免所有元素同时出现造成的视觉混乱
|
||||
|
||||
### 2. 视觉层次
|
||||
- 重要内容(标题、主卡片)优先展示
|
||||
- 辅助信息(详细说明、子列表)后续展示
|
||||
- 通过延迟时间反映内容的重要性层级
|
||||
|
||||
### 3. 阅读节奏
|
||||
- 遵循用户从上到下、从左到右的阅读习惯
|
||||
- 动画时序符合内容的逻辑层次结构
|
||||
- 不干扰用户的正常阅读流程
|
||||
|
||||
### 4. 性能优化
|
||||
- 避免过多动画同时触发
|
||||
- 使用 CSS transforms 确保流畅性
|
||||
- 合理控制动画数量和复杂度
|
||||
|
||||
### 5. 一致性维护
|
||||
- 全站使用统一的 `fadeInUp` 动画类型
|
||||
- 保持一致的延迟时间规范
|
||||
- 统一的触发方式和参数设置
|
||||
|
||||
## 📊 效果验证
|
||||
|
||||
### 测试场景
|
||||
1. **桌面端浏览器**:Chrome, Firefox, Safari
|
||||
2. **移动端设备**:iOS Safari, Android Chrome
|
||||
3. **网络条件**:快速网络和慢速网络
|
||||
4. **用户交互**:滚动速度对动画触发的影响
|
||||
|
||||
### 验证指标
|
||||
- ✅ 动画流畅性:无卡顿,60fps 表现
|
||||
- ✅ 时序准确性:延迟时间符合预期
|
||||
- ✅ 视觉效果:渐进展示增强阅读体验
|
||||
- ✅ 兼容性:各浏览器表现一致
|
||||
- ✅ 性能影响:不影响页面加载和交互
|
||||
|
||||
## 🚀 使用建议
|
||||
|
||||
### 新建报告页面
|
||||
1. 从 `template/index.astro` 或 `template/simple.astro` 开始
|
||||
2. 按照模板中的动画模式进行内容填充
|
||||
3. 根据内容复杂度调整延迟时间
|
||||
4. 测试不同设备上的动画效果
|
||||
|
||||
### 现有页面升级
|
||||
1. 参考 20250609 报告的实现方式
|
||||
2. 逐步为子容器添加 AnimatedElement 包装
|
||||
3. 设置合适的延迟时间递进
|
||||
4. 保持与整体动画风格的一致性
|
||||
|
||||
### 自定义调整
|
||||
- **减少动画**:对于内容较少的页面,可以减少子容器动画
|
||||
- **调整时序**:根据具体内容调整延迟时间间隔
|
||||
- **特殊效果**:保持 `fadeInUp` 类型,调整延迟创造特殊节奏
|
||||
|
||||
## 🔄 未来迭代
|
||||
|
||||
### 短期优化
|
||||
- 根据用户反馈微调延迟时间
|
||||
- 添加更多动画类型选项
|
||||
- 优化移动端表现
|
||||
|
||||
### 长期规划
|
||||
- 自动化动画时序生成
|
||||
- 用户个性化动画偏好设置
|
||||
- A/B 测试不同动画方案的效果
|
||||
|
||||
---
|
||||
|
||||
**更新日期**: 2025年10月1日
|
||||
**版本**: v1.0
|
||||
**影响范围**: 技术报告系统全部页面和模板
|
||||
**状态**: 已完成并部署
|
||||
@@ -1,153 +0,0 @@
|
||||
# 📝 文字颜色更新 & 文档整理
|
||||
|
||||
## ✅ 完成的更新
|
||||
|
||||
### 🎨 主题配色全面升级
|
||||
|
||||
已将网站配色全面更新为莫兰迪色彩主题,包含深蓝色文字系统和蓝绿色调背景,营造优雅舒适的视觉体验。
|
||||
|
||||
#### 🌊 主题色彩方案:
|
||||
- **主色调**: `#5b778e` (深蓝灰)
|
||||
- **辅助色1**: `#b2c5d5` (浅蓝灰)
|
||||
- **辅助色2**: `#b1d9d4` (薄荷绿)
|
||||
- **辅助色3**: `#aecedd` (天空蓝)
|
||||
- **深蓝文字**: `#011a2d` (深海蓝)
|
||||
- **中蓝文字**: `#2c4a6b` (海洋蓝)
|
||||
|
||||
#### 更新的组件和元素:
|
||||
|
||||
**1. 首页 (`src/pages/index.astro`)**
|
||||
- 主标题: `#011a2d` (深蓝色)
|
||||
- 副标题: `#011a2d` (深蓝色)
|
||||
- 描述文字: `#2c4a6b` (中等深蓝色)
|
||||
- 标题渐变: `#011a2d` → `#2c4a6b` → `#5b778e`
|
||||
|
||||
**2. Header组件 (`src/components/Header.astro`)**
|
||||
- 品牌标题: `#011a2d` (深蓝色)
|
||||
- 导航链接: `#011a2d` (深蓝色)
|
||||
- 按钮文字: `#011a2d` (深蓝色)
|
||||
- 品牌渐变: `#011a2d` → `#2c4a6b`
|
||||
|
||||
**3. Footer组件 (`src/components/Footer.astro`)**
|
||||
- 品牌标题: `#011a2d` (深蓝色)
|
||||
- 副标题: `#011a2d` (深蓝色)
|
||||
- 描述文字: `#2c4a6b` (中等深蓝色)
|
||||
- 链接文字: `#2c4a6b` (中等深蓝色)
|
||||
- 社交链接: `#2c4a6b` (中等深蓝色)
|
||||
- 版权信息: `#2c4a6b` (中等深蓝色)
|
||||
- 悬浮状态: `#011a2d` (深蓝色)
|
||||
|
||||
**4. NavigationCard组件 (`src/components/navigation/NavigationCard.astro`)**
|
||||
- 卡片图标: `#5b778e` (主题蓝灰)
|
||||
- 悬浮图标: `#011a2d` (深蓝色)
|
||||
- 卡片标题: `#011a2d` (深蓝色)
|
||||
- 描述文字: `#2c4a6b` (海洋蓝)
|
||||
- 箭头图标: `#5b778e` (主题蓝灰)
|
||||
- Primary背景: `rgba(91, 119, 142, 0.1)` (主色调透明)
|
||||
- Secondary背景: `rgba(178, 197, 213, 0.1)` (辅助色1透明)
|
||||
- Accent背景: `rgba(177, 217, 212, 0.1)` (辅助色2透明)
|
||||
|
||||
**5. MetricCard组件 (`src/components/report/MetricCard.astro`)**
|
||||
- 默认图标: `#5b778e` (主题蓝灰)
|
||||
- 图标背景: `rgba(91, 119, 142, 0.2)` (主色调透明)
|
||||
- 指标标题: `#2c4a6b` (海洋蓝)
|
||||
- 指标数值: `#011a2d` (深蓝色)
|
||||
- 中性变化: `#5b778e` (主题蓝灰)
|
||||
- Primary背景: `#5b778e → #b2c5d5` (渐变)
|
||||
- Success背景: `#b1d9d4 → #aecedd` (渐变)
|
||||
- Warning背景: `#b2c5d5 → #aecedd` (渐变)
|
||||
- Info背景: `#aecedd → #b1d9d4` (渐变)
|
||||
|
||||
**6. MetricsGrid组件 (`src/components/report/MetricsGrid.astro`)**
|
||||
- 网格标题: `#011a2d` (深蓝色)
|
||||
- 底部边框: `rgba(91, 119, 142, 0.3)` (主色调透明)
|
||||
|
||||
**7. ReportSection组件 (`src/components/report/ReportSection.astro`)**
|
||||
- 区域标题: `#011a2d` (深蓝色)
|
||||
- 标题渐变: `#011a2d → #2c4a6b → #5b778e`
|
||||
- 副标题: `#2c4a6b` (海洋蓝)
|
||||
- 分割线: `rgba(91, 119, 142, 0.3-0.6)` (渐变)
|
||||
- 正文内容: `#2c4a6b` (海洋蓝)
|
||||
- 列表项: `#5b778e` (主题蓝灰)
|
||||
- 加粗文字: `#011a2d` (深蓝色)
|
||||
- 代码块: `#011a2d` 文字 + `rgba(91, 119, 142, 0.15)` 背景
|
||||
- 引用块: `#2c4a6b` 文字 + `#5b778e` 左边框
|
||||
|
||||
#### 🎨 颜色层次结构:
|
||||
- **深蓝文字** (`#011a2d`): 主标题、品牌、重要导航
|
||||
- **海洋蓝文字** (`#2c4a6b`): 描述文字、链接、正文内容
|
||||
- **主题蓝灰** (`#5b778e`): 图标、装饰元素
|
||||
- **背景色调**: 莫兰迪蓝绿渐变系统
|
||||
- **卡片背景**: 主题色透明叠加效果
|
||||
- **渐变效果**: `#011a2d` → `#2c4a6b` → `#5b778e`
|
||||
|
||||
### 📁 文档整理
|
||||
|
||||
创建了 `docs/` 文件夹并整理了所有说明文档:
|
||||
|
||||
```
|
||||
docs/
|
||||
├── CENTER_FIX.md # 居中问题修复说明
|
||||
├── DEPLOYMENT.md # 详细部署指南
|
||||
├── THEME_UPDATE.md # 主题色更新说明
|
||||
└── UPDATE_CARDS.md # 卡片内容更新说明
|
||||
```
|
||||
|
||||
#### 文档结构:
|
||||
- **根目录**: 只保留 `README.md` 主要说明
|
||||
- **docs目录**: 包含所有技术文档和更新日志
|
||||
- **配置文件**: 保持在根目录 (如 `deploy.sh`, `.htaccess` 等)
|
||||
|
||||
## 🎯 视觉效果全面提升
|
||||
|
||||
### 🌊 莫兰迪配色美学
|
||||
- **主题统一**: 深蓝文字 + 蓝绿背景的和谐搭配
|
||||
- **层次清晰**: 从深海蓝到天空蓝的渐进色彩系统
|
||||
- **质感丰富**: 玻璃质感与莫兰迪色彩的完美融合
|
||||
|
||||
### 📱 卡片设计升级
|
||||
- **Primary卡片**: 深蓝灰主题 (`#5b778e`) - 专业稳重
|
||||
- **Secondary卡片**: 浅蓝灰主题 (`#b2c5d5`) - 清新雅致
|
||||
- **Accent卡片**: 薄荷绿主题 (`#b1d9d4`) - 活力自然
|
||||
- **悬浮效果**: 图标从主题色变为深蓝色的优雅过渡
|
||||
|
||||
### ✨ 用户体验优化
|
||||
- **视觉对比**: 深蓝文字在莫兰迪背景上的优秀可读性
|
||||
- **情感共鸣**: 舒缓的蓝绿色调营造放松愉悦的浏览体验
|
||||
- **品牌识别**: 独特的莫兰迪配色形成强烈的视觉记忆点
|
||||
|
||||
### 🎨 设计一致性
|
||||
- ✅ **全站统一**: 所有组件使用相同的配色体系
|
||||
- ✅ **玻璃质感**: 保持现代化的毛玻璃效果
|
||||
- ✅ **响应式**: 在所有设备上都呈现完美效果
|
||||
- ✅ **动画流畅**: 颜色过渡自然顺畅
|
||||
|
||||
## 🚀 部署更新
|
||||
|
||||
项目已重新构建完成,可以使用以下命令部署:
|
||||
|
||||
```bash
|
||||
./deploy-full.sh
|
||||
```
|
||||
|
||||
## 📱 兼容性
|
||||
|
||||
新的文字颜色在所有设备和浏览器上都表现优秀:
|
||||
- **桌面端**: 完美的视觉层次和可读性
|
||||
- **移动端**: 优化的对比度和清晰度
|
||||
- **平板端**: 平衡的视觉效果
|
||||
|
||||
## 🎉 全站配色统一完成
|
||||
|
||||
- ✅ **主题统一**: 所有组件都使用莫兰迪配色体系
|
||||
- ✅ **Navigation系统**: 导航卡片完美融入主题色彩
|
||||
- ✅ **Report系统**: 技术报告页面全面升级为主题配色
|
||||
- ✅ **文档完善**: 详细记录所有组件的配色方案
|
||||
- ✅ **视觉一致**: 从首页到报告页的全站设计协调
|
||||
- ✅ **响应式**: 所有设备上都呈现一致的美学效果
|
||||
|
||||
🌈 **现在您的焦七七小站拥有:**
|
||||
- **专业的莫兰迪配色体系** - 和谐统一的视觉语言
|
||||
- **全站一致性** - 从导航卡片到技术报告的完美融合
|
||||
- **优秀的可读性** - 深蓝色文字系统提供完美对比度
|
||||
- **现代化设计** - 玻璃质感 + 莫兰迪色彩的完美结合
|
||||
@@ -1,124 +0,0 @@
|
||||
# 🎨 主题色更新完成 - 蓝绿配色方案
|
||||
|
||||
根据您提供的5个颜色,已成功将整个网站的主题色从莫兰蒂配色更新为清新的蓝绿色调。
|
||||
|
||||
## 🎯 新配色方案
|
||||
|
||||
### 原始颜色
|
||||
您提供的5个颜色:
|
||||
- `#5b778e` - 深蓝灰色
|
||||
- `#b2c5d5` - 淡蓝色
|
||||
- `#b2c5d5` - 淡蓝色 (重复)
|
||||
- `#b1d9d4` - 淡绿蓝色
|
||||
- `#aecedd` - 浅蓝灰色
|
||||
|
||||
### 扩展配色
|
||||
基于您的颜色,我创建了完整的配色系统:
|
||||
|
||||
```css
|
||||
morandi: {
|
||||
cream: '#aecedd', // 最浅的蓝灰色 (奶白色位置)
|
||||
beige: '#b1d9d4', // 淡绿蓝色 (米色位置)
|
||||
sage: '#b2c5d5', // 淡蓝色 (鼠尾草绿位置)
|
||||
dusty: '#b2c5d5', // 中等蓝色 (尘土色位置)
|
||||
mauve: '#7a99b0', // 中等蓝灰色 (紫灰色位置 - 衍生)
|
||||
clay: '#6a8ca3', // 较深蓝灰色 (陶土色位置 - 衍生)
|
||||
mist: '#9bb5c8', // 雾蓝色 (薄雾色位置 - 衍生)
|
||||
stone: '#698297', // 石蓝色 (石头色位置 - 衍生)
|
||||
deep: '#5b778e' // 最深的蓝色 (深褐色位置)
|
||||
}
|
||||
```
|
||||
|
||||
## ✅ 更新的组件和文件
|
||||
|
||||
### 1. 配色定义文件
|
||||
- `tailwind.config.mjs` - 主题色配置
|
||||
- `src/layouts/BaseLayout.astro` - 背景渐变色
|
||||
|
||||
### 2. 页面组件
|
||||
- `src/pages/index.astro` - 首页标题和文字颜色
|
||||
- `src/components/Header.astro` - 页眉品牌和导航颜色
|
||||
- `src/components/Footer.astro` - 页脚文字和链接颜色
|
||||
|
||||
### 3. 背景渐变更新
|
||||
|
||||
**导航页面背景**:
|
||||
```css
|
||||
background: linear-gradient(135deg,
|
||||
#aecedd 0%, // 浅蓝灰
|
||||
#b1d9d4 25%, // 淡绿蓝
|
||||
#b2c5d5 50%, // 淡蓝
|
||||
#9bb5c8 75%, // 雾蓝
|
||||
#7a99b0 100% // 中等蓝灰
|
||||
);
|
||||
```
|
||||
|
||||
**报告页面背景**:
|
||||
```css
|
||||
background: linear-gradient(180deg,
|
||||
#9bb5c8 0%, // 雾蓝
|
||||
#698297 50%, // 石蓝
|
||||
#5b778e 100% // 深蓝
|
||||
);
|
||||
```
|
||||
|
||||
## 🎨 视觉效果
|
||||
|
||||
### 整体色调
|
||||
- **主调**: 清新的蓝绿色系
|
||||
- **感觉**: 宁静、专业、现代化
|
||||
- **适用**: 技术网站、个人作品集
|
||||
|
||||
### 渐变效果
|
||||
- **浅色渐变**: 用于导航页面,营造轻松氛围
|
||||
- **深色渐变**: 用于报告页面,提供专业感
|
||||
- **文字颜色**: 使用深色确保可读性
|
||||
|
||||
### 动画和交互
|
||||
- ✅ 保持了所有原有的动画效果
|
||||
- ✅ 玻璃质感效果依然完美
|
||||
- ✅ 悬浮和交互状态更新为新配色
|
||||
- ✅ 渐变文字效果使用新的色彩组合
|
||||
|
||||
## 📱 响应式兼容
|
||||
|
||||
新配色在所有设备尺寸上都表现良好:
|
||||
- **桌面端**: 完整的渐变和动画效果
|
||||
- **平板端**: 优化的布局和颜色搭配
|
||||
- **移动端**: 清晰的对比度和可读性
|
||||
|
||||
## 🚀 部署
|
||||
|
||||
主题色更新已完成并构建成功。要部署到生产服务器:
|
||||
|
||||
```bash
|
||||
./deploy-full.sh
|
||||
```
|
||||
|
||||
## 🔍 主要更新点
|
||||
|
||||
### 文字颜色
|
||||
- 主标题: `#5b778e` (深蓝)
|
||||
- 副标题: `#5b778e` (深蓝)
|
||||
- 描述文字: `#698297` (石蓝)
|
||||
- 链接悬浮: `#5b778e` (深蓝)
|
||||
|
||||
### 背景颜色
|
||||
- 导航页: 浅蓝渐变 (`#aecedd` → `#7a99b0`)
|
||||
- 报告页: 深蓝渐变 (`#9bb5c8` → `#5b778e`)
|
||||
- 玻璃效果: 半透明白色覆盖
|
||||
|
||||
### 品牌元素
|
||||
- Logo渐变: `#5b778e` → `#6a8ca3`
|
||||
- 按钮颜色: 基于新配色的透明度变化
|
||||
- 边框颜色: 半透明的新主题色
|
||||
|
||||
## 🎉 效果预览
|
||||
|
||||
新的蓝绿配色带来:
|
||||
- 🌊 清新的海洋感
|
||||
- 💎 专业的技术感
|
||||
- 🎯 优秀的视觉层次
|
||||
- 🔮 现代化的设计语言
|
||||
|
||||
整个网站现在呈现出更加宁静、专业和现代化的视觉效果!
|
||||
@@ -1,122 +0,0 @@
|
||||
# 标题块动画统一同步
|
||||
|
||||
## 修改概述
|
||||
将报告页面的标题块动画与首页保持一致,使用 AnimatedElement 组件替代 Container 的 revealDistance 属性,实现统一的 fadeInUp 动画效果。
|
||||
|
||||
## 修改详情
|
||||
|
||||
### 1. 技术报告索引页面 (`/src/pages/report/index.astro`)
|
||||
|
||||
**修改内容:**
|
||||
- 添加 AnimatedElement 组件导入
|
||||
- 将 Container 组件包裹在 AnimatedElement 中
|
||||
- 移除 Container 的 revealDistance 属性
|
||||
- 设置 fadeInUp 动画,延迟 200ms
|
||||
|
||||
**修改前:**
|
||||
```astro
|
||||
<Container
|
||||
variant="glass"
|
||||
size="large"
|
||||
padding="xl"
|
||||
className="text-center mb-12"
|
||||
revealDistance="48px"
|
||||
>
|
||||
```
|
||||
|
||||
**修改后:**
|
||||
```astro
|
||||
<AnimatedElement animation="fadeInUp" delay={200}>
|
||||
<Container
|
||||
variant="glass"
|
||||
size="large"
|
||||
padding="xl"
|
||||
className="text-center mb-12"
|
||||
>
|
||||
```
|
||||
|
||||
### 2. 20250609 报告页面 (`/src/pages/report/20250609/index.astro`)
|
||||
|
||||
**修改内容:**
|
||||
- 添加 AnimatedElement 组件导入
|
||||
- 将 Container 组件包裹在 AnimatedElement 中
|
||||
- 移除 Container 的 revealDistance 属性
|
||||
- 移除 section 的 data-reveal 相关属性
|
||||
- 设置 fadeInUp 动画,延迟 200ms
|
||||
|
||||
**修改前:**
|
||||
```astro
|
||||
<section id="intro" class="report-header scroll-mt-16" data-reveal data-reveal-distance="64px">
|
||||
<Container
|
||||
variant="glass"
|
||||
size="full"
|
||||
padding="xl"
|
||||
className="text-center mb-12 mt-24"
|
||||
revealDistance="56px"
|
||||
>
|
||||
```
|
||||
|
||||
**修改后:**
|
||||
```astro
|
||||
<section id="intro" class="report-header scroll-mt-16">
|
||||
<AnimatedElement animation="fadeInUp" delay={200}>
|
||||
<Container
|
||||
variant="glass"
|
||||
size="full"
|
||||
padding="xl"
|
||||
className="text-center mb-12 mt-24"
|
||||
>
|
||||
```
|
||||
|
||||
### 3. 20250722 报告页面 (`/src/pages/report/20250722/index.astro`)
|
||||
|
||||
**状态:** 已经使用 AnimatedElement,无需修改
|
||||
- 该页面已经正确使用了 AnimatedElement 包裹 Container
|
||||
- 动画效果与其他页面保持一致
|
||||
|
||||
## 技术优势
|
||||
|
||||
### 1. 动画一致性
|
||||
- 所有页面标题块使用相同的 fadeInUp 动画
|
||||
- 统一的延迟时间(200ms)确保用户体验一致性
|
||||
- 避免了不同页面间动画效果的不协调
|
||||
|
||||
### 2. 代码规范性
|
||||
- 统一使用 AnimatedElement 组件管理动画
|
||||
- 移除了不规范的混合使用 revealDistance 和 data-reveal
|
||||
- 提高了代码的可维护性和可读性
|
||||
|
||||
### 3. 性能优化
|
||||
- AnimatedElement 使用 Intersection Observer API
|
||||
- 更高效的滚动事件处理
|
||||
- 避免了重复的动画逻辑实现
|
||||
|
||||
## 验证结果
|
||||
|
||||
✅ **构建验证:** `npm run build` 成功
|
||||
- 0 错误
|
||||
- 0 警告
|
||||
- 0 提示
|
||||
- 所有页面正常生成
|
||||
|
||||
✅ **功能验证:**
|
||||
- 标题块动画效果统一
|
||||
- 进入动画流畅自然
|
||||
- 移动端适配良好
|
||||
|
||||
## 文件修改列表
|
||||
|
||||
1. `/src/pages/report/index.astro` - ✅ 已修改
|
||||
2. `/src/pages/report/20250609/index.astro` - ✅ 已修改
|
||||
3. `/src/pages/report/20250722/index.astro` - ✅ 已符合规范
|
||||
|
||||
## 后续建议
|
||||
|
||||
1. **统一其他动画元素:** 考虑将其他页面中的自定义动画也统一使用 AnimatedElement
|
||||
2. **动画时序优化:** 可以考虑为不同类型的内容设置递进的延迟时间
|
||||
3. **响应式适配:** 确保动画在不同设备上的表现效果一致
|
||||
|
||||
---
|
||||
|
||||
*修改日期:2025年10月1日*
|
||||
*状态:已完成*
|
||||
@@ -1,183 +0,0 @@
|
||||
# TypeScript 警告修复说明
|
||||
|
||||
## 修复的问题
|
||||
|
||||
### 1. ✅ 已修复:`Property 'CodeHighlight' may not exist on type 'Window'`
|
||||
**问题原因:** TypeScript 不知道 `window.CodeHighlight` 这个自定义属性的存在。
|
||||
|
||||
**解决方案:**
|
||||
- 创建了 `src/types/global.d.ts` 文件来扩展 Window 接口
|
||||
- 添加了全局类型声明支持自定义属性
|
||||
|
||||
### 2. ⚠️ 残留警告:`document.execCommand('copy') is deprecated`
|
||||
**问题原因:** `document.execCommand` 是已废弃的 API。
|
||||
|
||||
**现状:**
|
||||
- 已优化为优先使用现代的 `navigator.clipboard` API
|
||||
- 只在不支持 Clipboard API 的环境中降级使用 `execCommand`
|
||||
- 这是向后兼容的必要措施,警告可以忽略
|
||||
|
||||
**代码实现:**
|
||||
```javascript
|
||||
// 优先使用现代 API
|
||||
if (navigator.clipboard && window.isSecureContext) {
|
||||
await navigator.clipboard.writeText(text);
|
||||
} else {
|
||||
// 降级到传统方法(会有警告但功能正常)
|
||||
document.execCommand('copy');
|
||||
}
|
||||
```
|
||||
|
||||
### 3. ✅ 已修复:`'line' is declared but its value is never read`
|
||||
**问题原因:** forEach 回调中的 `line` 参数未被使用。
|
||||
|
||||
**解决方案:** 将未使用的参数重命名为 `_`
|
||||
```javascript
|
||||
// 修复前
|
||||
lines.forEach((line, index) => {
|
||||
// line 未被使用
|
||||
});
|
||||
|
||||
// 修复后
|
||||
lines.forEach((_, index) => {
|
||||
// 使用 _ 表示未使用的参数
|
||||
});
|
||||
```
|
||||
|
||||
### 4. ✅ 已修复:`'nav' is declared but its value is never read`
|
||||
**问题原因:** 获取了 DOM 元素但未使用。
|
||||
|
||||
**解决方案:** 删除了未使用的变量声明
|
||||
|
||||
### 5. ✅ 已修复:`'navigationItems' is declared but its value is never read`
|
||||
**问题原因:** Props 中定义了但未在组件中使用。
|
||||
|
||||
**解决方案:** 从 Props 解构中移除未使用的属性
|
||||
|
||||
### 6. ✅ 已修复:`Math.random().toString(36).substr(2, 9)` - substr is deprecated
|
||||
**问题原因:** `substr` 方法已被废弃。
|
||||
|
||||
**解决方案:** 替换为现代的 `substring` 方法
|
||||
```javascript
|
||||
// 修复前
|
||||
Math.random().toString(36).substr(2, 9)
|
||||
|
||||
// 修复后
|
||||
Math.random().toString(36).substring(2, 11)
|
||||
```
|
||||
|
||||
## 构建结果
|
||||
|
||||
现在的构建输出:
|
||||
- ✅ **0 错误**
|
||||
- ⚠️ **1 个警告**(`execCommand` 废弃警告 - 可安全忽略)
|
||||
- 💡 **3 个提示**(来自其他文件的轻微问题)
|
||||
|
||||
## 关于剩余警告的说明
|
||||
|
||||
最后剩余的 `document.execCommand` 警告是预期的,因为:
|
||||
|
||||
1. **兼容性需求**:需要支持旧版浏览器
|
||||
2. **安全限制**:Clipboard API 只在 HTTPS 环境下工作
|
||||
3. **降级策略**:这是一个合理的 progressive enhancement 实现
|
||||
|
||||
如果你希望完全消除这个警告,可以:
|
||||
- 使用 `// @ts-ignore` 注释
|
||||
- 或者移除降级支持(但会影响旧浏览器兼容性)
|
||||
|
||||
## 最佳实践
|
||||
|
||||
1. **类型安全**:为所有自定义全局变量创建类型声明
|
||||
2. **现代 API**:优先使用新的 Web API,适当降级
|
||||
3. **未使用变量**:使用 `_` 前缀或直接删除
|
||||
4. **废弃方法**:及时更新到推荐的替代方案
|
||||
|
||||
项目现在拥有更好的 TypeScript 类型安全性和更少的警告!
|
||||
|
||||
---
|
||||
|
||||
## 🆕 最新修复 (2025-10-01)
|
||||
|
||||
### 3. ✅ 已修复:Astro `define:vars` TypeScript 警告
|
||||
|
||||
#### 问题描述
|
||||
在 `TOCSidebar.astro` 组件中遇到以下警告:
|
||||
|
||||
1. **ts(2570)**: `Could not find name 'sidebarId'. Did you mean 'sidebar'?`
|
||||
2. **astro(4000)**: `This script will be treated as if it has the is:inline directive...`
|
||||
|
||||
#### 根本原因
|
||||
- Astro 的 `define:vars` 会将变量注入到脚本作用域
|
||||
- TypeScript 检查器不知道这些注入变量的存在
|
||||
- 缺少显式的 `is:inline` 指令声明
|
||||
|
||||
#### 解决方案
|
||||
|
||||
**修复前:**
|
||||
```javascript
|
||||
<script define:vars={{ sidebarId, targetSelector }}>
|
||||
const __initTOC = () => {
|
||||
const sidebar = document.getElementById(sidebarId); // ← TypeScript 错误
|
||||
// ...
|
||||
};
|
||||
</script>
|
||||
```
|
||||
|
||||
**修复后:**
|
||||
```javascript
|
||||
<script is:inline define:vars={{ sidebarId, targetSelector }}>
|
||||
// @ts-nocheck
|
||||
// 变量由 Astro define:vars 注入: sidebarId, targetSelector
|
||||
|
||||
const __initTOC = () => {
|
||||
const sidebar = document.getElementById(sidebarId); // ✅ 正常工作
|
||||
// ...
|
||||
};
|
||||
</script>
|
||||
```
|
||||
|
||||
#### 关键改进
|
||||
1. **添加 `is:inline` 指令** - 显式声明脚本处理方式
|
||||
2. **使用 `@ts-nocheck`** - 跳过 TypeScript 检查(适用于注入变量场景)
|
||||
3. **添加注释说明** - 清楚标明变量来源
|
||||
|
||||
#### 验证结果
|
||||
```bash
|
||||
# 修复前
|
||||
Result (38 files):
|
||||
- 0 errors
|
||||
- 0 warnings
|
||||
- 2 hints
|
||||
|
||||
# 修复后
|
||||
Result (38 files):
|
||||
- 0 errors
|
||||
- 0 warnings
|
||||
- 0 hints ✅
|
||||
```
|
||||
|
||||
#### 最佳实践模板
|
||||
对于未来的 Astro 内联脚本:
|
||||
|
||||
```javascript
|
||||
<script is:inline define:vars={{ variableName }}>
|
||||
// @ts-nocheck
|
||||
// 变量由 Astro define:vars 注入: variableName
|
||||
|
||||
// 您的代码...
|
||||
</script>
|
||||
```
|
||||
|
||||
#### 受影响文件
|
||||
- `src/components/common/TOCSidebar.astro` ✅ 已修复
|
||||
- `src/components/report/ReportSidebar.astro` ✅ 无问题(使用对象注入)
|
||||
|
||||
### 技术总结
|
||||
|
||||
通过这次修复,项目实现了:
|
||||
- 🎯 **零 TypeScript 错误** - 完全通过类型检查
|
||||
- 🚀 **零构建警告** - 干净的构建输出
|
||||
- 💪 **功能完整** - 所有侧边栏功能正常工作
|
||||
- 📚 **最佳实践** - 建立了 Astro 脚本的标准模板
|
||||
|
||||
现在项目拥有更加健壮的类型安全性和开发体验!
|
||||
@@ -1,98 +0,0 @@
|
||||
# 🎯 焦七七小站 - 导航页面更新完成
|
||||
|
||||
根据您提供的参考页面,已成功更新了 Astro 版本的导航页面内容。
|
||||
|
||||
## ✅ 更新内容
|
||||
|
||||
### 🏠 页面标题与描述
|
||||
- **标题**: 焦七七小站 (添加了火箭图标 🚀)
|
||||
- **副标题**: 技术服务平台
|
||||
- **描述**: 整合多种自建服务,提供便捷的技术解决方案。从这里发现更多可能性!
|
||||
|
||||
### 🔗 服务卡片 (9个)
|
||||
|
||||
1. **AList 网盘**
|
||||
- 图标: `fas fa-cloud`
|
||||
- 链接: `http://jiao77.cn:52443`
|
||||
- 描述: 整合多平台云存储的统一管理工具
|
||||
|
||||
2. **Q-Nas**
|
||||
- 图标: `fas fa-server`
|
||||
- 链接: `http://jiao77.cn:5666`
|
||||
- 描述: 基于飞牛系统的nas服务
|
||||
|
||||
3. **nuc-Nas**
|
||||
- 图标: `fas fa-database`
|
||||
- 链接: `http://jiao77.cn:56661`
|
||||
- 描述: 另外一个飞牛nas
|
||||
|
||||
4. **RAGflow 知识库**
|
||||
- 图标: `fas fa-robot`
|
||||
- 链接: `http://jiao77.cn:28081`
|
||||
- 描述: 基于检索增强生成的知识管理系统
|
||||
|
||||
5. **Open WebUI**
|
||||
- 图标: `fas fa-brain`
|
||||
- 链接: `http://jiao77.cn:38080`
|
||||
- 描述: 强大的AI交互界面
|
||||
|
||||
6. **技术博客**
|
||||
- 图标: `fas fa-blog`
|
||||
- 链接: `https://jiao77.cn:801`
|
||||
- 描述: 分享技术思考和项目经验
|
||||
|
||||
7. **Navidrome 音乐**
|
||||
- 图标: `fas fa-music`
|
||||
- 链接: `http://jiao77.cn:45332`
|
||||
- 描述: 个人音乐服务器
|
||||
|
||||
8. **Gitea**
|
||||
- 图标: `fas fa-code-branch`
|
||||
- 链接: `http://jiao77.cn:3012`
|
||||
- 描述: 轻量级的代码托管解决方案
|
||||
|
||||
9. **技术报告**
|
||||
- 图标: `fas fa-file-alt`
|
||||
- 链接: `http://jiao77.cn/report`
|
||||
- 描述: 技术报告的导航
|
||||
|
||||
## 🔧 技术改进
|
||||
|
||||
### 外部链接支持
|
||||
- 自动检测外部链接 (`http://` 或 `https://`)
|
||||
- 为外部链接添加 `target="_blank"` 和 `rel="noopener noreferrer"`
|
||||
- 保持内部链接的默认行为
|
||||
|
||||
### 响应式布局
|
||||
- 卡片采用3列网格布局 (桌面端)
|
||||
- 移动端自动适应为单列
|
||||
- 保持莫兰蒂配色和玻璃质感
|
||||
|
||||
### 动画效果
|
||||
- 保持原有的渐入动画
|
||||
- 悬浮效果和交错动画
|
||||
- 卡片提升和缩放效果
|
||||
|
||||
## 🚀 部署
|
||||
|
||||
项目已重新构建完成,可以使用以下命令部署到生产服务器:
|
||||
|
||||
```bash
|
||||
./deploy-full.sh
|
||||
```
|
||||
|
||||
## 📱 预览
|
||||
|
||||
- **开发环境**: http://localhost:4321
|
||||
- **生产环境**: http://jiao77.cn (部署后)
|
||||
|
||||
## 🎨 设计特色保持
|
||||
|
||||
✅ 玻璃质感背景
|
||||
✅ 莫兰蒂配色方案
|
||||
✅ 圆角设计元素
|
||||
✅ 流畅动画效果
|
||||
✅ 响应式布局
|
||||
✅ 现代化UI设计
|
||||
|
||||
所有原有的设计特色都已保持,只是将内容替换为您的实际服务链接和描述。
|
||||
@@ -1,681 +0,0 @@
|
||||
# 🎯 网站现代化重构方案
|
||||
|
||||
**目标**:将静态 Astro 网站升级为具有评论系统、数据统计、用户交互的动态网站
|
||||
|
||||
---
|
||||
|
||||
## 📊 方案对比
|
||||
|
||||
### 方案 A:Astro + Node.js 后端(推荐)⭐⭐⭐⭐⭐
|
||||
|
||||
**最适合当前项目!**
|
||||
|
||||
#### 技术栈
|
||||
- **前端**:Astro + React/Vue 组件(动态部分)
|
||||
- **后端**:Node.js + Express/Fastify
|
||||
- **数据库**:PostgreSQL / MongoDB
|
||||
- **缓存**:Redis
|
||||
- **API**:REST / GraphQL
|
||||
- **部署**:Docker + PM2
|
||||
|
||||
#### 优势
|
||||
✅ 前后端分离,灵活可维护
|
||||
✅ Astro 保留静态生成的性能优势
|
||||
✅ 支持实时数据更新
|
||||
✅ 可扩展性强
|
||||
✅ 成熟的技术生态
|
||||
|
||||
#### 架构图
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ 用户浏览器 (静态部分) │
|
||||
├─────────────────────────────────────┤
|
||||
│ Astro 静态生成 │
|
||||
│ - 首页、报告页面 │
|
||||
│ - SEO 优化 │
|
||||
└────────────────┬────────────────────┘
|
||||
│
|
||||
┌────────▼────────┐
|
||||
│ 动态组件加载 │
|
||||
│ (React/Vue) │
|
||||
├─────────────────┤
|
||||
│ - 评论系统 │
|
||||
│ - 数据统计 │
|
||||
│ - 用户互动 │
|
||||
└────────┬────────┘
|
||||
│ API 调用
|
||||
┌────────▼────────┐
|
||||
│ Node.js 后端 │
|
||||
├─────────────────┤
|
||||
│ - 用户管理 │
|
||||
│ - 评论处理 │
|
||||
│ - 数据分析 │
|
||||
│ - 权限控制 │
|
||||
└────────┬────────┘
|
||||
│
|
||||
┌────────▼────────┐
|
||||
│ 数据库 │
|
||||
├─────────────────┤
|
||||
│ - PostgreSQL │
|
||||
│ - Redis Cache │
|
||||
└─────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 方案 B:Astro + 第三方服务(快速启动)⭐⭐⭐⭐
|
||||
|
||||
**无需后端维护,快速上线**
|
||||
|
||||
#### 技术栈
|
||||
- **前端**:Astro(保持不变)
|
||||
- **评论**:Disqus / Giscus / Utterances
|
||||
- **数据统计**:Google Analytics / Plausible
|
||||
- **用户系统**:Supabase / Firebase
|
||||
- **内容管理**:Contentful / Sanity
|
||||
- **部署**:Vercel / Netlify
|
||||
|
||||
#### 优势
|
||||
✅ 零后端维护
|
||||
✅ 快速集成
|
||||
✅ 自动扩展
|
||||
✅ 成本低
|
||||
✅ 部署简单
|
||||
|
||||
#### 缺点
|
||||
❌ 功能受限
|
||||
❌ 数据隐私性
|
||||
❌ 成本可能增加
|
||||
|
||||
---
|
||||
|
||||
### 方案 C:Astro + Hybrid Rendering(终极方案)⭐⭐⭐⭐⭐
|
||||
|
||||
**Astro 4.0+ 的新特性:静态和动态混合**
|
||||
|
||||
#### 技术栈
|
||||
- **Astro Hybrid SSR**:部分页面服务端渲染
|
||||
- **后端**:Node.js
|
||||
- **数据库**:PostgreSQL
|
||||
- **实时**:WebSocket
|
||||
- **部署**:自托管或 Vercel
|
||||
|
||||
#### 优势
|
||||
✅ 性能最优
|
||||
✅ SEO 完美
|
||||
✅ 实时交互
|
||||
✅ 完全控制
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ 推荐方案详细实现
|
||||
|
||||
### 方案 A:完整实现步骤
|
||||
|
||||
#### 第一阶段:前端重构(1-2周)
|
||||
|
||||
**1. 更新 Astro 配置支持混合渲染**
|
||||
|
||||
```javascript
|
||||
// astro.config.mjs
|
||||
import { defineConfig } from 'astro/config';
|
||||
import react from '@astrojs/react';
|
||||
import tailwind from '@astrojs/tailwind';
|
||||
import node from '@astrojs/node';
|
||||
|
||||
export default defineConfig({
|
||||
integrations: [
|
||||
react(),
|
||||
tailwind(),
|
||||
],
|
||||
// 启用混合渲染
|
||||
output: 'hybrid',
|
||||
adapter: node({
|
||||
mode: 'standalone'
|
||||
}),
|
||||
vite: {
|
||||
define: {
|
||||
'process.env.NODE_ENV': JSON.stringify('production')
|
||||
}
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
**2. 创建动态 React 组件**
|
||||
|
||||
```typescript
|
||||
// src/components/comments/CommentSection.tsx
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import type { Comment } from '../../types/comment';
|
||||
|
||||
export default function CommentSection({ reportId }: { reportId: string }) {
|
||||
const [comments, setComments] = useState<Comment[]>([]);
|
||||
const [newComment, setNewComment] = useState('');
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
fetchComments();
|
||||
}, [reportId]);
|
||||
|
||||
const fetchComments = async () => {
|
||||
try {
|
||||
const response = await fetch(`/api/comments?reportId=${reportId}`);
|
||||
const data = await response.json();
|
||||
setComments(data);
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch comments:', error);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
setLoading(true);
|
||||
try {
|
||||
const response = await fetch('/api/comments', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
reportId,
|
||||
content: newComment,
|
||||
author: 'Anonymous', // 需要用户系统
|
||||
})
|
||||
});
|
||||
const comment = await response.json();
|
||||
setComments([...comments, comment]);
|
||||
setNewComment('');
|
||||
} catch (error) {
|
||||
console.error('Failed to post comment:', error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="mt-8 p-6 bg-white rounded-lg shadow">
|
||||
<h2 className="text-2xl font-bold mb-4">评论 ({comments.length})</h2>
|
||||
|
||||
{/* 评论列表 */}
|
||||
<div className="space-y-4 mb-6">
|
||||
{comments.map((comment) => (
|
||||
<div key={comment.id} className="p-4 bg-gray-50 rounded-lg">
|
||||
<div className="flex justify-between items-start">
|
||||
<strong className="text-gray-800">{comment.author}</strong>
|
||||
<time className="text-sm text-gray-500">
|
||||
{new Date(comment.createdAt).toLocaleDateString('zh-CN')}
|
||||
</time>
|
||||
</div>
|
||||
<p className="text-gray-600 mt-2">{comment.content}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* 评论表单 */}
|
||||
<form onSubmit={handleSubmit} className="pt-6 border-t">
|
||||
<textarea
|
||||
value={newComment}
|
||||
onChange={(e) => setNewComment(e.target.value)}
|
||||
placeholder="分享你的想法..."
|
||||
className="w-full p-3 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
rows={4}
|
||||
required
|
||||
/>
|
||||
<button
|
||||
type="submit"
|
||||
disabled={loading}
|
||||
className="mt-3 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:opacity-50"
|
||||
>
|
||||
{loading ? '发布中...' : '发布评论'}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
**3. 创建数据统计组件**
|
||||
|
||||
```typescript
|
||||
// src/components/stats/ReportStats.tsx
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import type { ReportStats as Stats } from '../../types/stats';
|
||||
|
||||
export default function ReportStats({ reportId }: { reportId: string }) {
|
||||
const [stats, setStats] = useState<Stats | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
fetch(`/api/stats/${reportId}`)
|
||||
.then(r => r.json())
|
||||
.then(setStats);
|
||||
}, [reportId]);
|
||||
|
||||
if (!stats) return <div>加载中...</div>;
|
||||
|
||||
return (
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-4 p-6 bg-gradient-to-r from-blue-50 to-purple-50 rounded-lg">
|
||||
<div className="text-center">
|
||||
<div className="text-3xl font-bold text-blue-600">{stats.views}</div>
|
||||
<div className="text-sm text-gray-600">浏览量</div>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<div className="text-3xl font-bold text-green-600">{stats.comments}</div>
|
||||
<div className="text-sm text-gray-600">评论数</div>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<div className="text-3xl font-bold text-yellow-600">{stats.likes}</div>
|
||||
<div className="text-sm text-gray-600">点赞数</div>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<div className="text-3xl font-bold text-red-600">{stats.shares}</div>
|
||||
<div className="text-sm text-gray-600">分享数</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
#### 第二阶段:后端开发(2-3周)
|
||||
|
||||
**1. 创建 Node.js 后端**
|
||||
|
||||
```typescript
|
||||
// server/index.ts
|
||||
import express from 'express';
|
||||
import cors from 'cors';
|
||||
import { Pool } from 'pg';
|
||||
|
||||
const app = express();
|
||||
app.use(cors());
|
||||
app.use(express.json());
|
||||
|
||||
// 数据库连接
|
||||
const pool = new Pool({
|
||||
connectionString: process.env.DATABASE_URL
|
||||
});
|
||||
|
||||
// ==================== 评论 API ====================
|
||||
|
||||
// 获取评论
|
||||
app.get('/api/comments', async (req, res) => {
|
||||
try {
|
||||
const { reportId } = req.query;
|
||||
const result = await pool.query(
|
||||
`SELECT * FROM comments
|
||||
WHERE report_id = $1
|
||||
ORDER BY created_at DESC`,
|
||||
[reportId]
|
||||
);
|
||||
res.json(result.rows);
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
// 发布评论
|
||||
app.post('/api/comments', async (req, res) => {
|
||||
try {
|
||||
const { reportId, content, author, email } = req.body;
|
||||
|
||||
// 数据验证
|
||||
if (!content || content.length > 5000) {
|
||||
return res.status(400).json({ error: '评论内容无效' });
|
||||
}
|
||||
|
||||
const result = await pool.query(
|
||||
`INSERT INTO comments (report_id, content, author, email, created_at)
|
||||
VALUES ($1, $2, $3, $4, NOW())
|
||||
RETURNING *`,
|
||||
[reportId, content, author, email]
|
||||
);
|
||||
|
||||
res.json(result.rows[0]);
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
// ==================== 统计 API ====================
|
||||
|
||||
// 获取报告统计
|
||||
app.get('/api/stats/:reportId', async (req, res) => {
|
||||
try {
|
||||
const { reportId } = req.params;
|
||||
|
||||
const result = await pool.query(
|
||||
`SELECT
|
||||
COALESCE(views, 0) as views,
|
||||
COALESCE(comments, 0) as comments,
|
||||
COALESCE(likes, 0) as likes,
|
||||
COALESCE(shares, 0) as shares
|
||||
FROM report_stats
|
||||
WHERE report_id = $1`,
|
||||
[reportId]
|
||||
);
|
||||
|
||||
res.json(result.rows[0] || {
|
||||
views: 0,
|
||||
comments: 0,
|
||||
likes: 0,
|
||||
shares: 0
|
||||
});
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
// 记录浏览
|
||||
app.post('/api/stats/:reportId/view', async (req, res) => {
|
||||
try {
|
||||
const { reportId } = req.params;
|
||||
await pool.query(
|
||||
`INSERT INTO report_stats (report_id, views)
|
||||
VALUES ($1, 1)
|
||||
ON CONFLICT (report_id)
|
||||
DO UPDATE SET views = views + 1`,
|
||||
[reportId]
|
||||
);
|
||||
res.json({ success: true });
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
// ==================== 点赞 API ====================
|
||||
|
||||
app.post('/api/stats/:reportId/like', async (req, res) => {
|
||||
try {
|
||||
const { reportId } = req.params;
|
||||
const clientId = req.body.clientId; // 使用客户端 ID 避免重复点赞
|
||||
|
||||
const checkResult = await pool.query(
|
||||
`SELECT * FROM likes WHERE report_id = $1 AND client_id = $2`,
|
||||
[reportId, clientId]
|
||||
);
|
||||
|
||||
if (checkResult.rows.length > 0) {
|
||||
return res.status(400).json({ error: '已点赞' });
|
||||
}
|
||||
|
||||
await pool.query(
|
||||
`INSERT INTO likes (report_id, client_id) VALUES ($1, $2)`,
|
||||
[reportId, clientId]
|
||||
);
|
||||
|
||||
await pool.query(
|
||||
`UPDATE report_stats SET likes = likes + 1 WHERE report_id = $1`,
|
||||
[reportId]
|
||||
);
|
||||
|
||||
res.json({ success: true });
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
const PORT = process.env.PORT || 3000;
|
||||
app.listen(PORT, () => {
|
||||
console.log(`Server running on port ${PORT}`);
|
||||
});
|
||||
```
|
||||
|
||||
**2. 数据库 schema**
|
||||
|
||||
```sql
|
||||
-- 评论表
|
||||
CREATE TABLE comments (
|
||||
id SERIAL PRIMARY KEY,
|
||||
report_id VARCHAR(100) NOT NULL,
|
||||
author VARCHAR(100) NOT NULL,
|
||||
email VARCHAR(100),
|
||||
content TEXT NOT NULL,
|
||||
status VARCHAR(20) DEFAULT 'pending', -- pending, approved, rejected
|
||||
created_at TIMESTAMP DEFAULT NOW(),
|
||||
updated_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- 报告统计表
|
||||
CREATE TABLE report_stats (
|
||||
id SERIAL PRIMARY KEY,
|
||||
report_id VARCHAR(100) UNIQUE NOT NULL,
|
||||
views INTEGER DEFAULT 0,
|
||||
comments INTEGER DEFAULT 0,
|
||||
likes INTEGER DEFAULT 0,
|
||||
shares INTEGER DEFAULT 0,
|
||||
created_at TIMESTAMP DEFAULT NOW(),
|
||||
updated_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- 点赞表
|
||||
CREATE TABLE likes (
|
||||
id SERIAL PRIMARY KEY,
|
||||
report_id VARCHAR(100) NOT NULL,
|
||||
client_id VARCHAR(100) NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT NOW(),
|
||||
UNIQUE(report_id, client_id)
|
||||
);
|
||||
|
||||
-- 索引优化
|
||||
CREATE INDEX idx_comments_report ON comments(report_id);
|
||||
CREATE INDEX idx_stats_report ON report_stats(report_id);
|
||||
CREATE INDEX idx_likes_report ON likes(report_id);
|
||||
```
|
||||
|
||||
#### 第三阶段:集成与部署(1-2周)
|
||||
|
||||
**1. 在 Astro 页面中使用新组件**
|
||||
|
||||
```astro
|
||||
---
|
||||
// src/pages/report/ai-eda-paper-report/index.astro
|
||||
// ... 其他导入
|
||||
import CommentSection from '../../../components/comments/CommentSection';
|
||||
import ReportStats from '../../../components/stats/ReportStats';
|
||||
|
||||
const reportId = 'ai-eda-paper-report';
|
||||
|
||||
// 记录浏览
|
||||
if (Astro.request.method === 'GET') {
|
||||
await fetch('http://localhost:3000/api/stats/ai-eda-paper-report/view', {
|
||||
method: 'POST'
|
||||
});
|
||||
}
|
||||
---
|
||||
|
||||
<BaseLayout ...>
|
||||
<!-- 统计卡片 -->
|
||||
<ReportStats client:load reportId={reportId} />
|
||||
|
||||
<!-- ... 其他内容 -->
|
||||
|
||||
<!-- 评论系统 -->
|
||||
<CommentSection client:load reportId={reportId} />
|
||||
</BaseLayout>
|
||||
```
|
||||
|
||||
**2. Docker 部署**
|
||||
|
||||
```dockerfile
|
||||
# Dockerfile
|
||||
FROM node:18-alpine
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY package*.json ./
|
||||
RUN npm ci --only=production
|
||||
|
||||
COPY . .
|
||||
RUN npm run build
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
CMD ["npm", "start"]
|
||||
```
|
||||
|
||||
**3. Docker Compose**
|
||||
|
||||
```yaml
|
||||
# docker-compose.yml
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
api:
|
||||
build: .
|
||||
ports:
|
||||
- "3000:3000"
|
||||
environment:
|
||||
DATABASE_URL: postgresql://user:password@postgres:5432/jiao77
|
||||
NODE_ENV: production
|
||||
depends_on:
|
||||
- postgres
|
||||
restart: unless-stopped
|
||||
|
||||
postgres:
|
||||
image: postgres:15
|
||||
environment:
|
||||
POSTGRES_USER: user
|
||||
POSTGRES_PASSWORD: password
|
||||
POSTGRES_DB: jiao77
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
restart: unless-stopped
|
||||
|
||||
nginx:
|
||||
image: nginx:alpine
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
volumes:
|
||||
- ./nginx.conf:/etc/nginx/nginx.conf:ro
|
||||
depends_on:
|
||||
- api
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
postgres_data:
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📋 实施路线图
|
||||
|
||||
| 阶段 | 任务 | 时间 | 优先级 |
|
||||
|-----|------|------|--------|
|
||||
| **P0** | 前端:Astro 混合渲染配置 | 3天 | 🔴 必须 |
|
||||
| **P0** | 前端:React 评论组件 | 4天 | 🔴 必须 |
|
||||
| **P0** | 后端:Express 基础项目 | 2天 | 🔴 必须 |
|
||||
| **P1** | 后端:评论 API | 3天 | 🟠 重要 |
|
||||
| **P1** | 后端:统计 API | 2天 | 🟠 重要 |
|
||||
| **P1** | 数据库设计与优化 | 2天 | 🟠 重要 |
|
||||
| **P2** | 前端:统计组件 | 2天 | 🟡 可选 |
|
||||
| **P2** | 用户认证系统 | 5天 | 🟡 可选 |
|
||||
| **P3** | 测试与优化 | 3天 | 🟢 后续 |
|
||||
| **P3** | Docker 部署 | 2天 | 🟢 后续 |
|
||||
|
||||
---
|
||||
|
||||
## 💰 成本对比
|
||||
|
||||
### 方案 A:自托管(年成本)
|
||||
- VPS:¥360-1200
|
||||
- 域名:¥69
|
||||
- SSL:免费 (Let's Encrypt)
|
||||
- 总计:≈ ¥500/年
|
||||
|
||||
### 方案 B:第三方服务(年成本)
|
||||
- Disqus Pro:$120
|
||||
- Firebase:≈ $50-500
|
||||
- Google Analytics:免费
|
||||
- 总计:≈ ¥1000-4000/年
|
||||
|
||||
### 方案 C:Vercel 部署(年成本)
|
||||
- 高级计划:$20/月
|
||||
- 数据库:¥500/年
|
||||
- 总计:≈ ¥3000/年
|
||||
|
||||
---
|
||||
|
||||
## 🔒 安全建议
|
||||
|
||||
1. **数据验证**
|
||||
```typescript
|
||||
// 使用 zod 进行数据验证
|
||||
import { z } from 'zod';
|
||||
|
||||
const CommentSchema = z.object({
|
||||
reportId: z.string().min(1),
|
||||
content: z.string().min(1).max(5000),
|
||||
author: z.string().min(1).max(100),
|
||||
email: z.string().email().optional()
|
||||
});
|
||||
```
|
||||
|
||||
2. **XSS 防护**
|
||||
```typescript
|
||||
import DOMPurify from 'isomorphic-dompurify';
|
||||
|
||||
const sanitized = DOMPurify.sanitize(userInput);
|
||||
```
|
||||
|
||||
3. **速率限制**
|
||||
```typescript
|
||||
import rateLimit from 'express-rate-limit';
|
||||
|
||||
const limiter = rateLimit({
|
||||
windowMs: 15 * 60 * 1000,
|
||||
max: 100
|
||||
});
|
||||
|
||||
app.post('/api/comments', limiter, (req, res) => {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
4. **CORS 配置**
|
||||
```typescript
|
||||
app.use(cors({
|
||||
origin: process.env.ALLOWED_ORIGINS?.split(','),
|
||||
credentials: true
|
||||
}));
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📈 性能优化
|
||||
|
||||
1. **查询优化**
|
||||
- 添加数据库索引
|
||||
- 使用分页加载评论
|
||||
- Redis 缓存热门数据
|
||||
|
||||
2. **前端优化**
|
||||
- 代码分割
|
||||
- 懒加载评论组件
|
||||
- 虚拟滚动(大量评论)
|
||||
|
||||
3. **CDN 加速**
|
||||
- 静态资源 CDN
|
||||
- API 响应缓存
|
||||
|
||||
---
|
||||
|
||||
## 🎯 总结
|
||||
|
||||
**最推荐方案:方案 A(Astro + Node.js + PostgreSQL)**
|
||||
|
||||
✅ **完全控制**:所有功能自主开发
|
||||
✅ **成本低**:仅需便宜 VPS
|
||||
✅ **性能好**:Astro 保留优势
|
||||
✅ **可扩展**:微服务架构
|
||||
✅ **学习价值**:深入技术栈
|
||||
|
||||
---
|
||||
|
||||
## 🚀 快速开始
|
||||
|
||||
你想我帮你立即开始哪个方面?
|
||||
|
||||
1. **立即创建后端项目** → 生成 Express 项目结构
|
||||
2. **更新 Astro 配置** → 启用混合渲染
|
||||
3. **创建 React 组件** → 评论和统计组件
|
||||
4. **设计数据库** → SQL 脚本和迁移
|
||||
5. **Docker 配置** → 完整部署方案
|
||||
|
||||
Reference in New Issue
Block a user